美文网首页
自定义view之onLayout

自定义view之onLayout

作者: 小川君 | 来源:发表于2017-07-17 12:01 被阅读0次

                                                   自定义view-------onLayout

    view类的onLayout()是个空方法

    viewGroup的onLayout()是个抽象方法

    layou()中的onLayout() 是用来设置viewgroup中子view的位置的 ,而不是用来设置当前view的位置的

    /**     * 存储所有的View,按行记录      */ 

    private List> mAllViews = new ArrayList>()

    /**      * 记录每一行的最大高度      */     

    private ListmLineHeight = new ArrayList();

    @Override

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

    {

    mAllViews.clear();

    mLineHeight.clear();

    int width = getWidth();

    int lineWidth = 0;        // 记录每一行 每加入一个子view之后的当前行宽

    int lineHeight = 0 ;   // 记录每一行 每加入一个子view之后的当前行高(取最大值)

    ListlineViews = new ArrayList();

    int cCount = getChildCount();

    // 遍历所有的孩子         

    for (int i = 0; i < cCount; i++)          {             

    View child = getChildAt(i); 

    MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();       

      int childWidth = child.getMeasuredWidth();            

    int childHeight = child.getMeasuredHeight();               

    // 如果已经需要换行         

    if (childWidth + lp.leftMargin + lp.rightMargin + lineWidth > width)  {       

    // 记录这一行所有的View以及最大高度    

    mLineHeight.add(lineHeight);

     // 将当前行的childView保存,然后开启新的ArrayList保存下一行的childView                  mAllViews.add(lineViews);                 

    lineWidth = 0;// 重置行宽                 

    lineViews = new ArrayList();

    }

    /**

    * 如果不需要换行,则累加

    */

    lineWidth += childWidth + lp.leftMargin + lp.rightMargin;                                       

    lineHeight = Math.max(lineHeight, childHeight + lp.topMargin+ lp.bottomMargin);

    lineViews.add(child);

    }

    // 记录最后一行

    mLineHeight.add(lineHeight);

    mAllViews.add(lineViews);

    此循环小结

    // 获取到所有的子view 以及子view的Marginlayoutparams

    //  根据当前子view的宽度左右margin 以及当前行的lineWindth 判断是否换行

    // 如果换行 则 将行高加入保存下来  并重置行宽行高以及行集合

    // 并将行集合保存到总集合之中

    // 如果不换行  则记录下当前行的行宽行高 并将当前view加入行集合

    // 遍历完所有的集合之后将行高与行集合分别保存下来

    // (因为遍历完所有的子view之后,最后一行肯定是不换行,所以行高和行集合都没有保存)

    int left = 0;

    int top = 0; 

    // 得到总行数

    int lineNums = mAllViews.size();

    for (int i = 0; i < lineNums; i++)

    {

    // 每一行的所有的views

    lineViews = mAllViews.get(i);

    // 当前行的最大高度

    lineHeight = mLineHeight.get(i);

    Log.e(TAG, "第" + i + "行 :" + lineViews.size() + " , " + lineViews);

    Log.e(TAG, "第" + i + "行, :" + lineHeight);

    // 遍历当前行所有的View

    for (int j = 0; j < lineViews.size(); j++)

    {

    View child = lineViews.get(j);

    if (child.getVisibility() == View.GONE)

    {

    continue;

    }

    MarginLayoutParams lp = (MarginLayoutParams) child

    .getLayoutParams();

    //计算childView的left,top,right,bottom

    int lc = left + lp.leftMargin;          左                                      

    int tc = top + lp.topMargin;              上

    int rc =lc + child.getMeasuredWidth();    右

    int bc = tc + child.getMeasuredHeight();    下

    Log.e(TAG, child + " , l = " + lc + " , t = " + t + " , r ="

    + rc + " , b = " + bc);

    child.layout(lc, tc, rc, bc);

    left += child.getMeasuredWidth() + lp.rightMargin

    + lp.leftMargin;

    }

    left = 0;

    top += lineHeight;

    }

    }

    此循环小结

    // 之后遍历总集合  得到行集合  然后根据相应的下标获取到每一行的行高

    // 遍历行集合  得到每一行的子view  然后获取每个子view的    

    // 左上坐标  右下坐标  然后调用子view的layout()

    // 获取子view的左坐标  初始left为0  每次计算完之后 将当前view的宽度相加

    // 最后设置每个子view的layout()

    相关文章

      网友评论

          本文标题:自定义view之onLayout

          本文链接:https://www.haomeiwen.com/subject/vkywhxtx.html