Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義ViewGroup之子控件的自動換行和添加刪除

Android自定義ViewGroup之子控件的自動換行和添加刪除

編輯:關於Android編程

概述:

常用的布局類型並不能滿足所有需求,這時就會用到ViewGroup。

ViewGroup作為一個放置View的容器,並且我們在寫布局xml的時候,會告訴容器(凡是以layout為開頭的屬性,都是為用於告訴容器的),我們的寬度(layout_width)、高度(layout_height)、對齊方式(layout_gravity)等;當然還有margin等;於是乎,ViewGroup需要做的事情是:給childView計算出建議的寬和高和測量模式 ;決定childView的位置;為什麼只是建議的寬和高,而不是直接確定呢,別忘了childView寬和高可以設置為wrap_content,這樣只有childView才能計算出自己的寬和高。

博客名已經說明了這篇博客要將給出的內容,不用贅述。

先看效果圖:
這裡寫圖片描述

代碼注釋很詳細,直接看代碼即可,沒貼源碼,因為這是從一個項目裡面摳出來的。

Demo

先寫一個自定義LinearLayout,它的功能是自適應子控件:

public class ItemContainer extends LinearLayout {
    private int width;//組件寬
    private int height;//組件高
    private int childCount;
    private int childMarginLeft = SizeConvert.dip2px(getContext(),8);//子控件相對左邊控件的距離
    private int childMarginHorizonTal = SizeConvert.dip2px(getContext(),10);//子控件相對最左、最右的距離
    private int childMarginTop = SizeConvert.dip2px(getContext(),8);//子控件相對頂部控件的距離
    private int childWidth;//子控件寬
    private int childHeight;//子控件高

    public ItemContainer(Context context) {
        super(context);
    }

    public ItemContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        childCount = getChildCount();//得到子控件數量
        if(childCount>0) {
            childWidth = (width - childMarginLeft * 4) / 3;
            childHeight = SizeConvert.dip2px(getContext(),42);//給子控件的高度一個定值
            //根據子控件的高和子控件數目得到自身的高
            height = childHeight * ((childCount-1)/ 3+1) + childMarginHorizonTal * 2 + childMarginTop*((childCount-1)/3);
            Log.d(childHeight,childHeight+);
        }else {
            //如果木有子控件,自身高度為0,即不顯示
            height = 0;
        }
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        Log.d(height,height+);
        //根據自身的寬度約束子控件寬度
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        //設置自身寬度
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        /**
         * 遍歷所有子控件,並設置它們的位置和大小
         * 每行只能有三個子控件,且高度固定,寬度相同,且每行正好布滿
         */
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);//得到當前子控件
            childView.layout((i%3) * childWidth + (i%3+1)*childMarginLeft
                    , (i / 3)*childHeight + childMarginHorizonTal + (i / 3)*childMarginTop
                    , (i%3+1) * childWidth + (i%3+1)*childMarginLeft
                    , (i / 3+1)*childHeight + childMarginHorizonTal + (i / 3)*childMarginTop);
        }
    }

}

主活動完成的功能就是上面貼圖演示的功能,讓兩個自定義ViewGroup能夠添加刪除子控件,子控件是在代碼中動態搭建的,下面會給出方法:
活動:

public class ItemOperateActivity extends BaseActivity {
    private LinearLayout mContentNoItem;
    private LinearLayout mContentItemRemove;
    private ItemContainer mItemContainerAdd;
    private ItemContainer mItemContainerRemove;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item_operate);
        mContentNoItem = (LinearLayout) findViewById(R.id.linearlayout_attention_null);
        mContentItemRemove = (LinearLayout) findViewById(R.id.linearlayout_remove);
        mItemContainerAdd = (ItemContainer) findViewById(R.id.item_container_add);
        mItemContainerRemove = (ItemContainer) findViewById(R.id.item_container_remove);

        initItems(new String[]{隨時定位, 客戶拜訪}, new String[]{新增客戶, 客戶總量});

    }

    /**
     * 添加條目時需要調用的方法
     * @param name
     */
    private void addItem(String name) {
        mContentNoItem.setVisibility(View.GONE);
        Button button = new Button(getApplicationContext());
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT
                , 0);
        button.setLayoutParams(params);
        button.setText(name);
        button.setGravity(Gravity.CENTER);
        button.setBackgroundResource(R.drawable.item_select_bg);
        button.setTextSize(13);
        button.setTextColor(Color.argb(255, 47, 79, 79));//鉛灰色
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mItemContainerAdd.removeView(v);
                removeItem(((Button) v).getText().toString());
                if (mItemContainerAdd.getChildCount()== 0) {
                    mContentNoItem.setVisibility(View.VISIBLE);
                }
            }

        });
        mItemContainerAdd.addView(button);

    }

    /**
     * 刪除條目時需要調用的方法
     * @param name
     */
    private void removeItem(String name) {
        mContentItemRemove.setVisibility(View.VISIBLE);
        Button button = new Button(getApplicationContext());
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT
                , 0);
        button.setLayoutParams(params);
        button.setText(name);
        button.setGravity(Gravity.CENTER);
        button.setBackgroundResource(R.drawable.item_select_bg_below);
        button.setTextSize(13);
        button.setTextColor(Color.argb(255, 47, 79,79));//鉛灰色
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /**
                 * 點擊按鈕時,刪除
                 */
                mItemContainerRemove.removeView(v);
                addItem(((Button) v).getText().toString());

                if (mItemContainerRemove.getChildCount() == 0) {
                    mContentItemRemove.setVisibility(View.GONE);
                }
            }
        });
        mItemContainerRemove.addView(button);
    }

    /**
     * 初始化子控件
     * @param itemsAdd 已添加的子控件名數組
     * @param itemsRemove 可添加的子控件名數組
     */
    private void initItems(String[] itemsAdd, String[] itemsRemove) {
        for (String itemAdd : itemsAdd) {
            addItem(itemAdd);
        }
        for (String itemRemove : itemsRemove) {
            removeItem(itemRemove);
        }
    }
}

布局:




    
        
            

            
        

        

    

    

        

        
    

    

    

    
        
        
    

    

    
        

            

        

        

        
    

drawable下的文件:
item_bg:



    
    

item_select_bg:



    
    
    
    

item_select_bg_below:



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