Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 自定義布局流程圖及使用

自定義布局流程圖及使用

編輯:關於Android編程

ACRA : Application crash report for android

作用: 為自己的應用找bug 使用步驟:參考文檔

自定義布局的實現:流程圖

\

參照流程圖:當有孩子時,是否需要對孩子控件大小進行布置,如果需要就得重寫onMeasure()這個方法調用child.layout()方法。需要孩子控件布局進行控制也要重寫onLayout()方法,需要對控件的顯示進行控制時要重寫onDraw()方法。

一般實現全部構造函數。

重寫

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
    //臨時top
    int topmt=0;
    int parentWidth = getMeasuredWidth();

    //獲得孩子個數
    int count =getChildCount();
    for(int i=0;i<count;i++){ 2="=0){" bottom="top+childHidth;" child="getChildAt(i);" childhidth="child.getMeasuredHeight();" childwidth="child.getMeasuredWidth();" int="" left="parentWidth-childWidth;" pre="" right="left+childWidth;" top="topmt;" view="">

還需要重寫onMeasure()

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    //獲得父親的寬高
    int widthsize=MeasureSpec.getSize(widthMeasureSpec);
    int heightsize=MeasureSpec.getSize(heightMeasureSpec);

    measureChildren(0, 0);//設置孩子,為0由父親安排寬高

    setMeasuredDimension(widthsize, heightsize);
}

自定義布局的使用:



    

     

     

    

      

如果需要切換布局,一般定義一個boolean類型值進行切換

FlowLayout

分析: 多行擺放 單行如果擺不下去,換行擺放

看下效果圖:

\

一下子看到這種布局說真的我無從下手,不知道這個怎麼實現,每行個數不一樣,列數不一樣,後來知道自定義布局可以實現。根據上面的view實現的流程圖可以知道,需要對控件的布局、大小進行控制,所以需要重寫onLayout()、onMeasure()的方法。再重寫方法之前,需要先分析每一行是怎麼布局的,以面向對象的思想封裝每一行需要的屬性、和方法。如下:

行的類

    class Line{
        //存儲孩子
        private List mChildViews=new LinkedList();

        private int usedWidth;//已經使用過的寬度
        private int lineHeight;//行最大的高度

        private int maxWidth;//行最大的寬度,父類給的
        private int horizontalSpace;//中間的間隔

        public Line(int maxWidth,int horizontalSpace){
            this.maxWidth=maxWidth;
            this.horizontalSpace=horizontalSpace;
        }
    //判斷該行是否能添加view
        public boolean canAddView(View view){
            //如果使用的寬度+准備加的View的寬度+中間的間隔>最大的寬度,加不上去

            //准備加的View的寬度
            int childwidth=view.getMeasuredWidth();

            int size=mChildViews.size();
            if(size==0){
                return true;
            }else if(usedWidth+childwidth+horizontalSpace>maxWidth){
                return false;
            }
            return true;
        }
    //添加view到布局
        public void addView(View view){
            //
            int childWidth=view.getMeasuredWidth();
            int childHeight=view.getMeasuredHeight();
            int size=mChildViews.size();

            if(size==0){
                //沒有孩子      已經使用的寬度
                if(childWidth>maxWidth){
                    usedWidth=maxWidth;
                }else{
                    usedWidth=childWidth;
                }
                //高度
                lineHeight=childHeight;

            }else{
                //已經使用的寬度
                usedWidth=usedWidth+childWidth+horizontalSpace;

                //高度
                lineHeight=lineHeight>childHeight?lineHeight:childHeight;
            }
            //加孩子
            mChildViews.add(view);
        }

//給行布局

        public void layout(int left,int top)
        {
            //給孩子布局
            int size=mChildViews.size();

            int tmpLeft=0;

            //將每一行右側無法顯示的空白部分平分給每一行顯示的每個控件
            int extraWidth=(int) ((maxWidth-usedWidth)*1f/size+0.5f);

            for(int i=0;i0){
                    //希望孩子再寬點,填充右側空白
                    int widthMeasureSpec=MeasureSpec.makeMeasureSpec(childWidth+extraWidth, MeasureSpec.EXACTLY);
                    int heightMeasureSpec=MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY);
                    child.measure(widthMeasureSpec, heightMeasureSpec);

                    //重新獲得寬高
                     childWidth=child.getMeasuredWidth();
                     childHeight=child.getMeasuredHeight();
                }

                int extraHeight=(int) ((lineHeight-childHeight)/2f+0.5f);

                int l=left+tmpLeft;
                int t=top+extraHeight;
                int r=l+childWidth;
                int b=t+childHeight;
                child.layout(l, t, r, b);

                //添加記錄
                tmpLeft +=childWidth + horizontalSpace;
            }

        }
}

重寫onLayout()方法:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
    int left=getPaddingLeft();
    int top=getPaddingTop();

    //讓行進行布局
    for(int i=0;i

重寫onMeasure()方法

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    //孩子個數記錄清空
    mLines.clear();
    mCurrentLine=null;

    int widthSize=MeasureSpec.getSize(widthMeasureSpec);
    int lineMaxWidth=widthSize-getPaddingLeft()-getPaddingRight();

    //測量孩子完成時,就記錄到行裡面
    int count=getChildCount();
    for(int i=0;i

在MainActivity中:

public class MainActivity extends Activity {

    private FlowLayout layout;

    private String []mDatas={"單機游戲","美女","游戲","單機游戲","美女","淘寶","單機游戲","美女","淘寶","游戲" ,"單機游戲","淘寶","游戲","單機游戲","美女","淘寶","游戲","單機游戲","美女","淘寶","游戲" ,"有道","天貓","汽車商城","新聞","運動","熊出沒之大逃跑"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout=(FlowLayout) findViewById(R.id.flow_layout);
        layout.setPadding(10, 10, 10, 10);
        initData();
    }
    private void initData()
    {
        for(int i=0;i<mdatas.length;i++){ pre="" textview="" tv="new">

使用自定義布局時:



    


到這裡,上圖的效果就已經出來,這種布局的邏輯判斷有點繁瑣,稍有差錯就顯示不出來了。記得要多看。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved