当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现淘宝选中商品尺寸的按钮组实例

Android实现淘宝选中商品尺寸的按钮组实例

2019年07月24日  | 移动技术网IT编程  | 我要评论

与仙共舞,恶龙军团优等生3,妹纸网

话不多说,先上个效果图:

现在我们就来说说里面的一些原理把!

一、原理:

1.其实这里我们用到的是一个viewgroup控件组,把这些按钮加进去就有这种效果了!不过这里要继承viewgroup(命名为:goodsviewgroup)重写里面的一些方法。

2.主要的方法有:

goodsviewgroup按钮组的控件大小

protected void onmeasure(int widthmeasurespec, int heightmeasurespec)

里面的按钮每个的位置坐标

protected void onlayout(boolean changed, int l, int t, int r, int b) 

这两个方法的具体使用大家可以网上查阅资料,这里就不多说了!

二、代码:

/**
 * created by shaolin on 2016/8/22.
 * 这里是类似淘宝中商品尺寸按钮组(这里做了支持button,textview)
 */
public class goodsviewgroup<x extends textview> extends viewgroup {

 public static final string btn_mode = "btnmode"; //按钮模式
 public static final string tev_mode = "tevmode"; //文本模式

 private static final string tag = "iviewgroup";
 private final int horinterval = 10; //水平间隔
 private final int verinterval = 10; //垂直间隔

 private int viewwidth; //控件的宽度
 private int viewheight; //控件的高度

 private arraylist<string> mtexts = new arraylist<>();
 private context mcontext;
 private int textmodepadding = 15;

 //正常样式
 private float itemtextsize = 18;
 private int itembgresnor = r.drawable.goods_item_btn_normal;
 private int itemtextcolornor = color.parsecolor("#000000");

 //选中的样式
 private int itembgrespre = r.drawable.goods_item_btn_selected;
 private int itemtextcolorpre = color.parsecolor("#ffffff");

 public goodsviewgroup(context context) {
  this(context, null);
 }

 public goodsviewgroup(context context, attributeset attrs) {
  super(context, attrs);
  mcontext = context;
 }

 /**
  * 计算控件的大小
  */
 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  super.onmeasure(widthmeasurespec, heightmeasurespec);
  viewwidth = measurewidth(widthmeasurespec);
  viewheight = measureheight(heightmeasurespec);
  log.e(tag, "onmeasure:" + viewwidth + ":" + viewheight);
  // 计算自定义的viewgroup中所有子控件的大小
  measurechildren(widthmeasurespec, heightmeasurespec);
  // 设置自定义的控件myviewgroup的大小
  setmeasureddimension(viewwidth, getviewheight());
 }


 private int measurewidth(int pwidthmeasurespec) {
  int result = 0;
  int widthmode = measurespec.getmode(pwidthmeasurespec);
  int widthsize = measurespec.getsize(pwidthmeasurespec);
  switch (widthmode) {
   /**
    * mode共有三种情况,取值分别为measurespec.unspecified, measurespec.exactly,
    * measurespec.at_most。
    *
    *
    * measurespec.exactly是精确尺寸,
    * 当我们将控件的layout_width或layout_height指定为具体数值时如andorid
    * :layout_width="50dip",或者为fill_parent是,都是控件大小已经确定的情况,都是精确尺寸。
    *
    *
    * measurespec.at_most是最大尺寸,
    * 当控件的layout_width或layout_height指定为wrap_content时
    * ,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可
    * 。因此,此时的mode是at_most,size给出了父控件允许的最大尺寸。
    *
    *
    * measurespec.unspecified是未指定尺寸,这种情况不多,一般都是父控件是adapterview,
    * 通过measure方法传入的模式。
    */
   case measurespec.at_most:
   case measurespec.exactly:
    result = widthsize;
    break;
  }
  return result;
 }

 private int measureheight(int pheightmeasurespec) {
  int result = 0;
  int heightmode = measurespec.getmode(pheightmeasurespec);
  int heightsize = measurespec.getsize(pheightmeasurespec);
  switch (heightmode) {
   case measurespec.unspecified:
    result = getsuggestedminimumheight();
    break;
   case measurespec.at_most:
   case measurespec.exactly:
    result = heightsize;
    break;
  }
  return result;
 }

 /**
  * 覆写onlayout,其目的是为了指定视图的显示位置,方法执行的前后顺序是在onmeasure之后,因为视图肯定是只有知道大小的情况下,
  * 才能确定怎么摆放
  */
 @override
 protected void onlayout(boolean changed, int l, int t, int r, int b) {
  // 遍历所有子视图
  int posleft = horinterval;
  int postop = verinterval;
  int posright;
  int posbottom;
  for (int i = 0; i < getchildcount(); i++) {
   view childview = getchildat(i);
   // 获取在onmeasure中计算的视图尺寸
   int measureheight = childview.getmeasuredheight();
   int measuredwidth = childview.getmeasuredwidth();
   if (posleft + getnexthorlastpos(i) > viewwidth) {
    posleft = horinterval;
    postop += (measureheight + verinterval);
   }
   posright = posleft + measuredwidth;
   posbottom = postop + measureheight;
   childview.layout(posleft, postop, posright, posbottom);
   posleft += (measuredwidth + horinterval);
  }
 }

 //获取控件的自适应高度
 private int getviewheight() {
  int viewwidth = horinterval;
  int viewheight = verinterval;
  if (getchildcount() > 0) {
   viewheight = getchildat(0).getmeasuredheight() + verinterval;
  }
  for (int i = 0; i < getchildcount(); i++) {
   view childview = getchildat(i);
   // 获取在onmeasure中计算的视图尺寸
   int measureheight = childview.getmeasuredheight();
   int measuredwidth = childview.getmeasuredwidth();
   if (viewwidth + getnexthorlastpos(i) > viewwidth) {
    viewwidth = horinterval;
    viewheight += (measureheight + verinterval);
   } else {
    viewwidth += (measuredwidth + horinterval);
   }
  }
  return viewheight;
 }

 private int getnexthorlastpos(int i) {
  return getchildat(i).getmeasuredwidth() + horinterval;
 }

 private ongroupitemclicklistener ongroupitemclicklistener;

 public void setgroupclicklistener(ongroupitemclicklistener listener) {
  ongroupitemclicklistener = listener;
  for (int i = 0; i < getchildcount(); i++) {
   final x childview = (x) getchildat(i);
   final int itempos = i;
   childview.setonclicklistener(new onclicklistener() {
    @override
    public void onclick(view view) {
     ongroupitemclicklistener.ongroupitemclick(itempos);
     chooseitemstyle(itempos);
    }
   });
  }
 }

 //选中那个的样式
 public void chooseitemstyle(int pos) {
  clearitemsstyle();
  if (pos < getchildcount()) {
   x childview = (x) getchildat(pos);
   childview.setbackgroundresource(itembgrespre);
   childview.settextcolor(itemtextcolorpre);
   setitempadding(childview);
  }
 }

 private void setitempadding(x view) {
  if (view instanceof button) {
   view.setpadding(textmodepadding, 0, textmodepadding, 0);
  } else {
   view.setpadding(textmodepadding, textmodepadding, textmodepadding, textmodepadding);
  }
 }

 //清除group所有的样式
 private void clearitemsstyle() {
  for (int i = 0; i < getchildcount(); i++) {
   x childview = (x) getchildat(i);
   childview.setbackgroundresource(itembgresnor);
   childview.settextcolor(itemtextcolornor);
   setitempadding(childview);
  }
 }

 public void additemviews(arraylist<string> texts, string mode) {
  mtexts = texts;
  removeallviews();
  for (string text : texts) {
   additemview(text, mode);
  }
 }

 private void additemview(string text, string mode) {
  x childview = null;
  switch (mode) {
   case btn_mode:
    childview = (x) new button(mcontext);
    break;
   case tev_mode:
    childview = (x) new textview(mcontext);
    break;
  }
  childview.setlayoutparams(new layoutparams(layoutparams.wrap_content,
    layoutparams.wrap_content));
  childview.settextsize(itemtextsize);
  childview.setbackgroundresource(itembgresnor);
  setitempadding(childview);
  childview.settextcolor(itemtextcolornor);
  childview.settext(text);
  this.addview(childview);
 }

 public string getchoosetext(int itemid) {
  if (itemid >= 0) {
   return mtexts.get(itemid);
  }
  return null;
 }

 public void setitemtextsize(float itemtextsize) {
  this.itemtextsize = itemtextsize;
 }

 public void setitembgresnor(int itembgresnor) {
  this.itembgresnor = itembgresnor;
 }

 public void setitemtextcolornor(int itemtextcolornor) {
  this.itemtextcolornor = itemtextcolornor;
 }

 public void setitembgrespre(int itembgrespre) {
  this.itembgrespre = itembgrespre;
 }

 public void setitemtextcolorpre(int itemtextcolorpre) {
  this.itemtextcolorpre = itemtextcolorpre;
 }

 public interface ongroupitemclicklistener {
  void ongroupitemclick(int item);
 }
}

上面提供了可以设置按钮组的item的一些样式,还有这个goodsviewgroup为什么要写成goodsviewgroup<x extends textview>这样呢?其实这里我是想做一个泛型,可以使用与buttontextview,而这里的button本生就是继承textview所以在代码中还要进行一个判断,可以看上面方法setitempadding(x view) 。那到了这里,有些好友可能就会问,为什么要搞两个呢?

其实这里因为textview的不会自动有设置padding的,而button是有自动设置padding。这个时候你就要看看你是先要那种效果!不过通过我的代码中如果是选择textview的话,这里也设置了一个padding给他,不然会很难看!

两种模式的写法:

1.button :

goodsviewgroup<button> mgroup;
mgroup.additemviews(viewtexts, goodsviewgroup.btn_mode);

2.textview

goodsviewgroup<textview> mgroup;
mgroup.additemviews(viewtexts, goodsviewgroup.tev_mode);

三、drawable文件:上面涉及到的按钮选中与正常的两个drawable

1.goods_item_btn_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item>
  <shape>
   <solid android:color="#f5f5f5" />
   <corners android:radius="15.0dip" />
  </shape>
 </item>
</layer-list>

2.goods_item_btn_selected.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item>
  <shape>
   <solid android:color="#fe4f00" />
   <corners android:radius="15.0dip" />
  </shape>
 </item>
</layer-list>

四、例子:

buttongroupactivity

/**
 * created by shaolin on 2016/8/22.
 */
public class buttongroupactivity extends activity implements goodsviewgroup.ongroupitemclicklistener, view.onclicklistener {

 private goodsviewgroup<textview> mgroup;
 private button msubmitbtn;
 private arraylist<string> viewtexts = new arraylist<>();

 private int chooseid = -1;
 private string choosetext;

 @override
 protected void oncreate(bundle savedinstancestate) {
  setcontentview(r.layout.activity_buttongroup);

  mgroup = (goodsviewgroup) findviewbyid(r.id.viewgroup);
  msubmitbtn = (button) findviewbyid(r.id.submitbtn);

  string text;
  for (int i = 0; i < 10; i++) {
   text = "l" + i;
   viewtexts.add(text);
  }
  mgroup.additemviews(viewtexts, goodsviewgroup.tev_mode);
  mgroup.setgroupclicklistener(this);
  msubmitbtn.setonclicklistener(this);
  super.oncreate(savedinstancestate);
 }

 @override
 public void ongroupitemclick(int item) {
  chooseid = item;
  choosetext = mgroup.getchoosetext(item);
 }

 @override
 public void onclick(view view) {
  if (chooseid >= 0) {
   showtoast("id:" + chooseid + ";text:" + choosetext);
  } else {
   showtoast("请选择");
  }
 }

 private void showtoast(string text) {
  toast.maketext(buttongroupactivity.this, text, toast.length_short).show();
 }
}

activity_buttongroup.xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/linear_ayout"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">

 <com.example.jisuanqi.goodsviewgroup
  android:id="@+id/viewgroup"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
 </com.example.jisuanqi.goodsviewgroup>

 <button
  android:id="@+id/submitbtn"
  android:text="确定"
  android:layout_width="match_parent"
  android:layout_height="wrap_content" />

</linearlayout>

总结

以上就是关于android实现淘宝选中商品不同尺寸的按钮组的全部内容了,如果本文有什么问题欢迎大家指出,大家共同进步!希望本文对大家的学习和工作能有所帮助哦~

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网