android通過程式碼動態新增和刪除控制元件
阿新 • • 發佈:2021-01-18
原文:https://blog.csdn.net/chadeltu/article/details/42390047#
1.概述
android開發當中有可能會碰到以下這種情況,某個頁面,內容不確定,根據使用者需求增加或減少相應控制元件數。這種情況一般發生在編輯類頁面當中,比如你的應用包含使用者發帖功能,其內容組織結構和多少是可變的。
本文實現了一個動態新增和刪除控制元件的簡單例子!先上截圖:
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