zoukankan      html  css  js  c++  java
  • android之自定义ViewGroup和自动换行的布局的实现(支持按钮间隔)

    viewgroup简单说就是可以装view的view.今天遇到一个问题,就是需要一个可以自动根据一行中view的宽度自动换行的布局,网上找了下,没有相关的例子,但是找到了思路:自定义一个viewgroup,然后在onlayout文件里面自动检测view的右边缘的横坐标值,和你的view的parent view的况度判断是否换行显示view就可以了。因为代码比较简单,就不多说了:

     1 public class MyViewGroup extends ViewGroup {
     2        private final static String TAG = "123";
     3        
     4        private final static int VIEW_MARGIN=2;
     5    
     6        public MyViewGroup(Context context, AttributeSet attrs){
     7            super(context, attrs);
     8        }
     9        
    10        public MyViewGroup(Context context) {
    11            super(context);
    12        }
    13        @Override
    14        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    15            Log.d(TAG, "widthMeasureSpec = "+widthMeasureSpec+" heightMeasureSpec = "+heightMeasureSpec);
    16            
    17            for (int index = 0; index < getChildCount(); index++) {
    18                final View child = getChildAt(index);
    19                // measure
    20                child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
    21            }
    22    
    23            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    24        }
    25        private int jiange = 10;//按钮之间的间隔
    26        @Override
    27        protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    28            Log.d(TAG, "changed = "+arg0+" left = "+arg1+" top = "+arg2+" right = "+arg3+" botom = "+arg4);
    29            final int count = getChildCount();
    30            int row=0;// which row lay you view relative to parent
    31            int lengthX=arg1 ;    // right position of child relative to parent
    32            int lengthY=arg2;    // bottom position of child relative to parent
    33            for(int i=0;i<count;i++){
    34                
    35                final View child = this.getChildAt(i);
    36                int width = child.getMeasuredWidth();
    37                int height = child.getMeasuredHeight();
    38                if(i == 0){
    39                    lengthX+=width+VIEW_MARGIN;//第一个的时候不需要加
    40                }else{
    41                    lengthX+=width+VIEW_MARGIN +jiange;//按钮之间的间隔
    42                }
    43                lengthY=row*(height+VIEW_MARGIN)+VIEW_MARGIN+height+arg2;
    44                //if it can't drawing on a same line , skip to next line
    45                if(lengthX>arg3){
    46                    lengthX=width+VIEW_MARGIN+arg1;
    47                    row++;
    48                    lengthY=row*(height+VIEW_MARGIN)+VIEW_MARGIN+height+arg2;
    49                }
    50                child.layout(lengthX-width, lengthY-height, lengthX, lengthY);
    51            }
    52        }
    53    }

    这里有个地方要注意,那就要明白ViewGroup的绘图流程:ViewGroup绘制包括两个步骤:1.measure 2.layout

      在两个步骤中分别调用回调函数:1.onMeasure()   2.onLayout()

      1.onMeasure() 在这个函数中,ViewGroup会接受childView的请求的大小,然后通过childView的 measure(newWidthMeasureSpec, heightMeasureSpec)函数存储到childView中,以便childView的getMeasuredWidth() andgetMeasuredHeight() 的值可以被后续工作得到。

      2.onLayout() 在这个函数中,ViewGroup会拿到childView的getMeasuredWidth() andgetMeasuredHeight(),用来布局所有的childView。

      3.View.MeasureSpec 与 LayoutParams 这两个类,是ViewGroup与childView协商大小用的。其中,View.MeasureSpec是ViewGroup用来部署 childView用的, LayoutParams是childView告诉ViewGroup 我需要多大的地方。

      4.在View 的onMeasure的最后要调用setMeasuredDimension()这个方法存储View的大小,这个方法决定了当前View的大小。

      

    Activity code:

     1 public class GooleActivity extends Activity {
     2     @Override
     3     public void onCreate(Bundle savedInstanceState) {
     4         super.onCreate(savedInstanceState);
     5         setContentView(R.layout.main);
     6         MyViewGroup myViewGroup = (MyViewGroup) this.findViewById(R.id.myviewgroup);
     7         for(int i = 0 ; i<15;i++){
     8             Button button = null;
     9             if(i%2==0){
    10                 button = new Button(this);
    11                 button.setText("偶数"+i);
    12             }else if(i%3==0){
    13                 button = new Button(this);
    14                 button.setText("奇数奇数奇数奇数"+i);
    15             }else{
    16                 button = new Button(this);
    17                 button.setText("超长的超长的超长的"+i);
    18             }
    19             
    20             myViewGroup.addView(button);
    21         }
    22     }
    23 }

    xml code:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="fill_parent"
     4     android:layout_height="fill_parent"
     5     android:orientation="vertical" >
     6 
     7     <com.xy.activity.MyViewGroup
     8         android:id="@+id/myviewgroup"
     9         android:layout_width="fill_parent"
    10         android:layout_height="fill_parent" />
    11 
    12 </LinearLayout>

      效果图:

     

  • 相关阅读:
    atitit.ntfs ext 文件系统新特性对比
    Atitit.图片木马的原理与防范 attilax 总结
    Atitit.图片木马的原理与防范 attilax 总结
    Atitit.jdk java8的语法特性详解 attilax 总结
    Atitit.jdk java8的语法特性详解 attilax 总结
    Atitit.远程接口 监控与木马   常用的api 标准化v2 q216
    Atitit.远程接口 监控与木马   常用的api 标准化v2 q216
    Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结
    Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结
    Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx
  • 原文地址:https://www.cnblogs.com/androidxiaoyang/p/2921888.html
Copyright © 2011-2022 走看看