入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

Android 仿淘宝选中商品不同尺寸的按钮组

创建时间:2016-08-25 投稿人: 浏览次数:898

文章转载自 http://blog.csdn.net/qq_30552993/article/details/52304744

今天刚好有个同学他想做一个仿淘宝中的选中商品不同尺寸,比如衣服有L、M、XL等等的款式。这时候我们就需要一个button组来进行了,当时这个时候里面的尺寸可能有很多,那怎么办呢?这里我们就肯定要做个自适应的按钮组了,要不然弄出来也没用。废话不多说,先上个效果图:


是不是感觉起来效果蛮不错的呢?偷笑偷笑偷笑

现在我们就来说说里面的一些原理把!说句实话,我也不是大神,这个也是查询网上的一些原理问题弄出来的,希望大家不要嫌弃哦!么么哒!

一、原理:

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

2.主要的方法有:

GoodsViewGroup按钮组的控件大小

[java] view plain copy  在CODE上查看代码片派生到我的代码片
  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  


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

[java] view plain copy  在CODE上查看代码片派生到我的代码片
  1. protected void onLayout(boolean changed, int l, int t, int r, int b)   

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


二、代码:

[java] view plain copy  在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * Created by ShaoLin on 2016/8/22. 
  3.  * 这里是类似淘宝中商品尺寸按钮组(这里做了支持button,textview) 
  4.  */  
  5. public class GoodsViewGroup<X extends TextView> extends ViewGroup {  
  6.   
  7.     public static final String BTN_MODE = "BTNMODE"; //按钮模式  
  8.     public static final String TEV_MODE = "TEVMODE"; //文本模式  
  9.   
  10.     private static final String TAG = "IViewGroup";  
  11.     private final int HorInterval = 10;    //水平间隔  
  12.     private final int VerInterval = 10;    //垂直间隔  
  13.   
  14.     private int viewWidth;   //控件的宽度  
  15.     private int viewHeight;  //控件的高度  
  16.   
  17.     private ArrayList<String> mTexts = new ArrayList<>();  
  18.     private Context mContext;  
  19.     private int textModePadding = 15;  
  20.   
  21.     //正常样式  
  22.     private float itemTextSize = 18;  
  23.     private int itemBGResNor = R.drawable.goods_item_btn_normal;  
  24.     private int itemTextColorNor = Color.parseColor("#000000");  
  25.   
  26.     //选中的样式  
  27.     private int itemBGResPre = R.drawable.goods_item_btn_selected;  
  28.     private int itemTextColorPre = Color.parseColor("#ffffff");  
  29.   
  30.     public GoodsViewGroup(Context context) {  
  31.         this(context, null);  
  32.     }  
  33.   
  34.     public GoodsViewGroup(Context context, AttributeSet attrs) {  
  35.         super(context, attrs);  
  36.         mContext = context;  
  37.     }  
  38.   
  39.     /** 
  40.      * 计算控件的大小 
  41.      */  
  42.     @Override  
  43.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  44.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  45.         viewWidth = measureWidth(widthMeasureSpec);  
  46.         viewHeight = measureHeight(heightMeasureSpec);  
  47.         Log.e(TAG, "onMeasure:" + viewWidth + ":" + viewHeight);  
  48.         // 计算自定义的ViewGroup中所有子控件的大小  
  49.         measureChildren(widthMeasureSpec, heightMeasureSpec);  
  50.         // 设置自定义的控件MyViewGroup的大小  
  51.         setMeasuredDimension(viewWidth, getViewHeight());  
  52.     }  
  53.   
  54.   
  55.     private int measureWidth(int pWidthMeasureSpec) {  
  56.         int result = 0;  
  57.         int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);  
  58.         int widthSize = MeasureSpec.getSize(pWidthMeasureSpec);  
  59.         switch (widthMode) {  
  60.             /** 
  61.              * mode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, 
  62.              * MeasureSpec.AT_MOST。 
  63.              * 
  64.              * 
  65.              * MeasureSpec.EXACTLY是精确尺寸, 
  66.              * 当我们将控件的layout_width或layout_height指定为具体数值时如andorid 
  67.              * :layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。 
  68.              * 
  69.              * 
  70.              * MeasureSpec.AT_MOST是最大尺寸, 
  71.              * 当控件的layout_width或layout_height指定为WRAP_CONTENT时 
  72.              * ,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可 
  73.              * 。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。 
  74.              * 
  75.              * 
  76.              * MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView, 
  77.              * 通过measure方法传入的模式。 
  78.              */  
  79.             case MeasureSpec.AT_MOST:  
  80.             case MeasureSpec.EXACTLY:  
  81.                 result = widthSize;  
  82.                 break;  
  83.         }  
  84.         return result;  
  85.     }  
  86.   
  87.     private int measureHeight(int pHeightMeasureSpec) {  
  88.         int result = 0;  
  89.         int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);  
  90.         int heightSize = MeasureSpec.getSize(pHeightMeasureSpec);  
  91.         switch (heightMode) {  
  92.             case MeasureSpec.UNSPECIFIED:  
  93.                 result = getSuggestedMinimumHeight();  
  94.                 break;  
  95.             case MeasureSpec.AT_MOST:  
  96.             case MeasureSpec.EXACTLY:  
  97.                 result = heightSize;  
  98.                 break;  
  99.         }  
  100.         return result;  
  101.     }  
  102.   
  103.     /** 
  104.      * 覆写onLayout,其目的是为了指定视图的显示位置,方法执行的前后顺序是在onMeasure之后,因为视图肯定是只有知道大小的情况下, 
  105.      * 才能确定怎么摆放 
  106.      */  
  107.     @Override  
  108.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  109.         // 遍历所有子视图  
  110.         int posLeft = HorInterval;  
  111.         int posTop = VerInterval;  
  112.         int posRight;  
  113.         int posBottom;  
  114.         for (int i = 0; i < getChildCount(); i++) {  
  115.             View childView = getChildAt(i);  
  116.             // 获取在onMeasure中计算的视图尺寸  
  117.             int measureHeight = childView.getMeasuredHeight();  
  118.             int measuredWidth = childView.getMeasuredWidth();  
  119.             if (posLeft + getNextHorLastPos(i) > viewWidth) {  
  120.                 posLeft = HorInterval;  
  121.                 posTop += (measureHeight + VerInterval);  
  122.             }  
  123.             posRight = posLeft + measuredWidth;  
  124.             posBottom = posTop + measureHeight;  
  125.             childView.layout(posLeft, posTop, posRight, posBottom);  
  126.             posLeft += (measuredWidth + HorInterval);  
  127.         }  
  128.     }  
  129.   
  130.     //获取控件的自适应高度  
  131.     private int getViewHeight() {  
  132.         int viewwidth = HorInterval;  
  133.         int viewheight = VerInterval;  
  134.         if (getChildCount() > 0) {  
  135.             viewheight = getChildAt(0).getMeasuredHeight() + VerInterval;  
  136.         }  
  137.         for (int i = 0; i < getChildCount(); i++) {  
  138.             View childView = getChildAt(i);  
  139.             // 获取在onMeasure中计算的视图尺寸  
  140.             int measureHeight = childView.getMeasuredHeight();  
  141.             int measuredWidth = childView.getMeasuredWidth();  
  142.             if (viewwidth + getNextHorLastPos(i) > viewWidth) {  
  143.                 viewwidth = HorInterval;  
  144.                 viewheight += (measureHeight + VerInterval);  
  145.             } else {  
  146.                 viewwidth += (measuredWidth + HorInterval);  
  147.             }  
  148.         }  
  149.         return viewheight;  
  150.     }  
  151.   
  152.     private int getNextHorLastPos(int i) {  
  153.         return getChildAt(i).getMeasuredWidth() + HorInterval;  
  154.     }  
  155.   
  156.     private OnGroupItemClickListener onGroupItemClickListener;  
  157.   
  158.     public void setGroupClickListener(OnGroupItemClickListener listener) {  
  159.         onGroupItemClickListener = listener;  
  160.         for (int i = 0; i < getChildCount(); i++) {  
  161.             final X childView = (X) getChildAt(i);  
  162.             final int itemPos = i;  
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
  • 上一篇:没有了
  • 下一篇:没有了
未上传头像