zoukankan      html  css  js  c++  java
  • 流式布局示例

    1.TextView的样式

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
     3     <solid android:color="#666666" />
     4     <corners android:radius="10dp" />
     5     <padding
     6         android:left="5dp"
     7         android:right="5dp"
     8         android:top="5dp"
     9         android:bottom="5dp"
    10         />
    11 
    12 </shape>
    View Code

    2.main布局

    1  <com.example.administrator.liushilayout.XCFlowLayout
    2         android:id="@+id/flowlayout"
    3         android:layout_width="match_parent"
    4         android:layout_height="match_parent" >
    5 
    6     </com.example.administrator.liushilayout.XCFlowLayout>
    View Code

    3.自定义ViewGroup

      1 public class XCFlowLayout extends ViewGroup{
      2     //存储所有子View
      3     private List<List<View>> mAllChildViews = new ArrayList<>();
      4     //每一行的高度
      5     private List<Integer> mLineHeight = new ArrayList<>();
      6 
      7     public XCFlowLayout(Context context) {
      8         this(context, null);
      9         // TODO Auto-generated constructor stub
     10     }
     11     public XCFlowLayout(Context context, AttributeSet attrs) {
     12         this(context, attrs, 0);
     13         // TODO Auto-generated constructor stub
     14     }
     15     public XCFlowLayout(Context context, AttributeSet attrs, int defStyle) {
     16         super(context, attrs, defStyle);
     17         // TODO Auto-generated constructor stub
     18     }
     19     @Override
     20     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     21         // TODO Auto-generated method stub
     22 
     23         //父控件传进来的宽度和高度以及对应的测量模式
     24         int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
     25         int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
     26         int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
     27         int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
     28 
     29         //如果当前ViewGroup的宽高为wrap_content的情况
     30         int width = 0;//自己测量的 宽度
     31         int height = 0;//自己测量的高度
     32         //记录每一行的宽度和高度
     33         int lineWidth = 0;
     34         int lineHeight = 0;
     35 
     36         //获取子view的个数
     37         int childCount = getChildCount();
     38         for(int i = 0;i < childCount; i ++){
     39             View child = getChildAt(i);
     40             //测量子View的宽和高
     41             measureChild(child, widthMeasureSpec, heightMeasureSpec);
     42             //得到LayoutParams
     43             MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
     44             //子View占据的宽度
     45             int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
     46             //子View占据的高度
     47             int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
     48             //换行时候
     49             if(lineWidth + childWidth > sizeWidth){
     50                 //对比得到最大的宽度
     51                 width = Math.max(width, lineWidth);
     52                 //重置lineWidth
     53                 lineWidth = childWidth;
     54                 //记录行高
     55                 height += lineHeight;
     56                 lineHeight = childHeight;
     57             }else{//不换行情况
     58                 //叠加行宽
     59                 lineWidth += childWidth;
     60                 //得到最大行高
     61                 lineHeight = Math.max(lineHeight, childHeight);
     62             }
     63             //处理最后一个子View的情况
     64             if(i == childCount -1){
     65                 width = Math.max(width, lineWidth);
     66                 height += lineHeight;
     67             }
     68         }
     69         //wrap_content
     70         setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width,
     71                 modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height);
     72         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     73     }
     74 
     75     @Override
     76     protected void onLayout(boolean changed, int l, int t, int r, int b) {
     77         // TODO Auto-generated method stub
     78         mAllChildViews.clear();
     79         mLineHeight.clear();
     80         //获取当前ViewGroup的宽度
     81         int width = getWidth();
     82 
     83         int lineWidth = 0;
     84         int lineHeight = 0;
     85         //记录当前行的view
     86         List<View> lineViews = new ArrayList<View>();
     87         int childCount = getChildCount();
     88         for(int i = 0;i < childCount; i ++){
     89             View child = getChildAt(i);
     90             MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
     91             int childWidth = child.getMeasuredWidth();
     92             int childHeight = child.getMeasuredHeight();
     93 
     94             //如果需要换行
     95             if(childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width){
     96                 //记录LineHeight
     97                 mLineHeight.add(lineHeight);
     98                 //记录当前行的Views
     99                 mAllChildViews.add(lineViews);
    100                 //重置行的宽高
    101                 lineWidth = 0;
    102                 lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
    103                 //重置view的集合
    104                 lineViews = new ArrayList();
    105             }
    106             lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
    107             lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
    108             lineViews.add(child);
    109         }
    110         //处理最后一行
    111         mLineHeight.add(lineHeight);
    112         mAllChildViews.add(lineViews);
    113 
    114         //设置子View的位置
    115         int left = 0;
    116         int top = 0;
    117         //获取行数
    118         int lineCount = mAllChildViews.size();
    119         for(int i = 0; i < lineCount; i ++){
    120             //当前行的views和高度
    121             lineViews = mAllChildViews.get(i);
    122             lineHeight = mLineHeight.get(i);
    123             for(int j = 0; j < lineViews.size(); j ++){
    124                 View child = lineViews.get(j);
    125                 //判断是否显示
    126                 if(child.getVisibility() == View.GONE){
    127                     continue;
    128                 }
    129                 MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
    130                 int cLeft = left + lp.leftMargin;
    131                 int cTop = top + lp.topMargin;
    132                 int cRight = cLeft + child.getMeasuredWidth();
    133                 int cBottom = cTop + child.getMeasuredHeight();
    134                 //进行子View进行布局
    135                 child.layout(cLeft, cTop, cRight, cBottom);
    136                 left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
    137             }
    138             left = 0;
    139             top += lineHeight;
    140         }
    141 
    142     }
    143     /**
    144      * 与当前ViewGroup对应的LayoutParams
    145      */
    146     @Override
    147     public LayoutParams generateLayoutParams(AttributeSet attrs) {
    148         // TODO Auto-generated method stub
    149 
    150         return new MarginLayoutParams(getContext(), attrs);
    151     }
    152 }
    View Code

    4.Ativity实现

     1 public class MainActivity extends AppCompatActivity {
     2     private String mNames[] = {
     3             "welcome","android","TextView",
     4             "apple","jamy","kobe bryant",
     5             "jordan","layout","viewgroup",
     6             "margin","padding","text",
     7             "name","type","search","logcat"
     8     };
     9     private XCFlowLayout mFlowLayout;
    10     @Override
    11     protected void onCreate(Bundle savedInstanceState) {
    12         super.onCreate(savedInstanceState);
    13         setContentView(R.layout.activity_main);
    14 
    15         initChildViews();
    16 
    17     }
    18     private void initChildViews() {
    19         // TODO Auto-generated method stub
    20         mFlowLayout = (XCFlowLayout) findViewById(R.id.flowlayout);
    21         ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
    22                 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    23         lp.leftMargin = 5;
    24         lp.rightMargin = 5;
    25         lp.topMargin = 5;
    26         lp.bottomMargin = 5;
    27         for(int i = 0; i < mNames.length; i ++){
    28             TextView view = new TextView(this);
    29             view.setText(mNames[i]);
    30             view.setTextColor(Color.WHITE);
    31             view.setBackgroundDrawable(getResources().getDrawable(R.drawable.shap));
    32             mFlowLayout.addView(view,lp);
    33         }
    34     }
    35 
    36 }
    View Code
    今天多一点积累,明天少一分烦恼
  • 相关阅读:
    charCodeAt() 和charAt()
    去除全角空格
    string字符串js操作
    取小数的常见操作
    js取最大最小值
    js加减法运算多出很多小数点
    js设置div透明度
    setTimeout设置不起作用
    node.js 找不到 xxx 模块解决办法
    servlet 监听器和过滤器入门
  • 原文地址:https://www.cnblogs.com/galibujianbusana/p/5601297.html
Copyright © 2011-2022 走看看