1. 程式人生 > 其它 >android通過程式碼動態新增和刪除控制元件

android通過程式碼動態新增和刪除控制元件

原文:https://blog.csdn.net/chadeltu/article/details/42390047#
1.概述

android開發當中有可能會碰到以下這種情況,某個頁面,內容不確定,根據使用者需求增加或減少相應控制元件數。這種情況一般發生在編輯類頁面當中,比如你的應用包含使用者發帖功能,其內容組織結構和多少是可變的。

本文實現了一個動態新增和刪除控制元件的簡單例子!先上截圖:

截圖1

2.程式碼實現
(1)佈局檔案activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
    tools:context=".MainActivity" >
 
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none" >
 
        <LinearLayout
            android:id="@+id/content_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:isScrollContainer="true"
            android:orientation="vertical"
            android:padding="10.0dip" >
 
            <LinearLayout
                android:id="@+id/ll_one"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dip"
                android:background="#FFA2CD5A"
                android:orientation="vertical"
                android:padding="5dip" >
 
                <EditText
                    android:id="@+id/et_content1"
                    android:layout_width="match_parent"
                    android:layout_height="80dip"
                    android:background="#FFFFFFFF"
                    android:gravity="left"
                    android:inputType="textMultiLine"
                    android:paddingLeft="5dip"
                    android:textSize="16sp" />
 
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dip" >
 
                    <ImageButton
                        android:id="@+id/ibn_add1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:background="@drawable/ic_add" />
<!-- 
                    <ImageButton
                        android:id="@+id/ibn_del1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="10dip"
                        android:layout_toLeftOf="@id/ibn_add1"
                        android:background="@drawable/ic_delete" />
 -->
                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>
    </ScrollView>
 
</RelativeLayout>

簡單來講,一個ScrollView和內嵌的LinearLayout的組合實現了本例。LinearLayout內部控制元件可增可減,因為其包含在ScrollView裡,所以內容超出頁面顯示範圍時可以滾動。

該佈局檔案顯示效果如上面第一個截圖所示,包含一個編輯框(EditText)和“新增”按鈕。

(2)MainActivity檔案

package com.example.androiddynamiclayout;
 
import java.util.LinkedList;
 
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.text.InputType;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
 
public class MainActivity extends Activity {
 
	// 外圍的LinearLayout容器
	private LinearLayout llContentView;
	
	private EditText etContent1;
	
	// “+”按鈕控制元件List
	private LinkedList<ImageButton> listIBTNAdd;
	// “+”按鈕ID索引
	private int btnIDIndex = 1000;
	// “-”按鈕控制元件List
	private LinkedList<ImageButton> listIBTNDel;
	
	private int iETContentHeight = 0;	// EditText控制元件高度
	private float fDimRatio = 1.0f; // 尺寸比例(實際尺寸/xml檔案裡尺寸)
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		initCtrl();
	}
	
	/**
	 * 初始化控制元件
	 */
	private void initCtrl()
	{
		llContentView = (LinearLayout) this.findViewById(R.id.content_view);
		etContent1 = (EditText) this.findViewById(R.id.et_content1);
		listIBTNAdd = new LinkedList<ImageButton>();
		listIBTNDel = new LinkedList<ImageButton>();
		
		// “+”按鈕(第一個)
		ImageButton ibtnAdd1 = (ImageButton) this.findViewById(R.id.ibn_add1);
		ibtnAdd1.setOnClickListener(new View.OnClickListener() {
 
			@Override
			public void onClick(View v) {
				// 獲取尺寸變化比例
				iETContentHeight = etContent1.getHeight();
				fDimRatio = iETContentHeight / 80;
 
				addContent(v);
			}
		});
 
		listIBTNAdd.add(ibtnAdd1);
		listIBTNDel.add(null);	// 第一組隱藏了“-”按鈕,所以為null
	}
	
	/**
	 * 新增一組新控制元件
	 * @param v	事件觸發控制元件,其實就是觸發新增事件對應的“+”按鈕
	 */
	private void addContent(View v) {
		if (v == null) {
			return;
		}
		
		// 判斷第幾個“+”按鈕觸發了事件
		int iIndex = -1;
		for (int i = 0; i < listIBTNAdd.size(); i++) {
			if (listIBTNAdd.get(i) == v) {
				iIndex = i;
				break;
			}
		}
		
		if (iIndex >= 0) {
			// 控制元件實際新增位置為當前觸發位置點下一位
			iIndex += 1;
			
			// 開始新增控制元件
			
			// 1.建立外圍LinearLayout控制元件
			LinearLayout layout = new LinearLayout(MainActivity.this);
			LinearLayout.LayoutParams lLayoutlayoutParams = new LinearLayout.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			// 設定margin
			lLayoutlayoutParams.setMargins(0, (int) (fDimRatio * 5), 0, 0);
			layout.setLayoutParams(lLayoutlayoutParams);
			// 設定屬性
			layout.setBackgroundColor(Color.argb(255, 162, 205, 90));	// #FFA2CD5A
			layout.setPadding((int) (fDimRatio * 5), (int) (fDimRatio * 5),
					(int) (fDimRatio * 5), (int) (fDimRatio * 5));
			layout.setOrientation(LinearLayout.VERTICAL);
			
			// 2.建立內部EditText控制元件
			EditText etContent = new EditText(MainActivity.this);
			LinearLayout.LayoutParams etParam = new LinearLayout.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT, iETContentHeight);
			etContent.setLayoutParams(etParam);
			// 設定屬性
			etContent.setBackgroundColor(Color.argb(255, 255, 255, 255));	// #FFFFFFFF
			etContent.setGravity(Gravity.LEFT);
			etContent.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);
			etContent.setPadding((int) (fDimRatio * 5), 0, 0, 0);
			etContent.setTextSize(16);
			// 將EditText放到LinearLayout裡
			layout.addView(etContent);
			
			// 3.建立“+”和“-”按鈕外圍控制元件RelativeLayout
			RelativeLayout rlBtn = new RelativeLayout(MainActivity.this);
			RelativeLayout.LayoutParams rlParam = new RelativeLayout.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
//			rlParam.setMargins(0, (int) (fDimRatio * 5), 0, 0);
			rlBtn.setPadding(0, (int) (fDimRatio * 5), 0, 0);
			rlBtn.setLayoutParams(rlParam);
			
			// 4.建立“+”按鈕
			ImageButton btnAdd = new ImageButton(MainActivity.this);
			RelativeLayout.LayoutParams btnAddParam = new RelativeLayout.LayoutParams(
					ViewGroup.LayoutParams.WRAP_CONTENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			// 靠右放置
			btnAddParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
			btnAdd.setLayoutParams(btnAddParam);
			// 設定屬性
			btnAdd.setBackgroundResource(R.drawable.ic_add);
			btnAdd.setId(btnIDIndex);
			// 設定點選操作
			btnAdd.setOnClickListener(new View.OnClickListener() {
 
				@Override
				public void onClick(View v) {
					addContent(v);
				}
			});
			// 將“+”按鈕放到RelativeLayout裡
			rlBtn.addView(btnAdd);
			listIBTNAdd.add(iIndex, btnAdd);
			
			// 5.建立“-”按鈕
			ImageButton btnDelete = new ImageButton(MainActivity.this);
			btnDelete.setBackgroundResource(R.drawable.ic_delete);
			RelativeLayout.LayoutParams btnDeleteAddParam = new RelativeLayout.LayoutParams(
					ViewGroup.LayoutParams.WRAP_CONTENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			btnDeleteAddParam.setMargins(0, 0, (int) (fDimRatio * 5), 0);
			// “-”按鈕放在“+”按鈕左側
			btnDeleteAddParam.addRule(RelativeLayout.LEFT_OF, btnIDIndex);
			btnDelete.setOnClickListener(new View.OnClickListener() {
 
				@Override
				public void onClick(View v) {
					deleteContent(v);
				}
			});
			// 將“-”按鈕放到RelativeLayout裡
			rlBtn.addView(btnDelete, btnDeleteAddParam);
			listIBTNDel.add(iIndex, btnDelete);
			
			// 6.將RelativeLayout放到LinearLayout裡
			layout.addView(rlBtn);
			
			// 7.將layout同它內部的所有控制元件加到最外圍的llContentView容器裡
			llContentView.addView(layout, iIndex);
			
			btnIDIndex++;
		}
	}
	
	/**
	 * 刪除一組控制元件
	 * @param v	事件觸發控制元件,其實就是觸發刪除事件對應的“-”按鈕
	 */
	private void deleteContent(View v) {
		if (v == null) {
			return;
		}
 
		// 判斷第幾個“-”按鈕觸發了事件
		int iIndex = -1;
		for (int i = 0; i < listIBTNDel.size(); i++) {
			if (listIBTNDel.get(i) == v) {
				iIndex = i;
				break;
			}
		}
		if (iIndex >= 0) {
			listIBTNAdd.remove(iIndex);
			listIBTNDel.remove(iIndex);
			
			// 從外圍llContentView容器裡刪除第iIndex控制元件
			llContentView.removeViewAt(iIndex);
		}
	}
 
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
 
}

瀏覽這段程式碼需要注意以下幾兩點:

1.llContentView:這個變數對應的是上面佈局檔案提到的那個LinearLayout,通過llContentView.addView(layout, iIndex)往某一位置新增子控制元件,通過llContentView.removeViewAt(iIndex)刪除某一位置上的子控制元件。

2.List物件listIBTNAdd和listIBTNDel:儲存了當前所包含的所有“新增”和“刪除”按鈕物件,在發生新增或刪除事件時,用於定位觸發事件位置。

其他內容可以看程式碼註釋,詳細資訊可以下載原始碼跑一跑工程!

3.原始碼

原始碼下載地址:

http://download.csdn.net/detail/chadeltu/8324305