android通过代码动态添加和删除控件

1.概述

android开发当中有可能会碰到以下这种情况,某个页面,内容不确定,根据用户需求增加或减少相应控件数。这种情况一般发生在编辑类页面当中,比如你的应用包含用户发帖功能,其内容组织结构和多少是可变的。

本文实现了一个动态添加和删除控件的简单例子!先上截图:

截图1






2.代码实现

(1)布局文件activity_main.xml

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="@android:color/darker_gray"  
  6.     tools:context=".MainActivity" >  
  7.   
  8.     <ScrollView  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="match_parent"  
  11.         android:scrollbars="none" >  
  12.   
  13.         <LinearLayout  
  14.             android:id="@+id/content_view"  
  15.             android:layout_width="match_parent"  
  16.             android:layout_height="wrap_content"  
  17.             android:isScrollContainer="true"  
  18.             android:orientation="vertical"  
  19.             android:padding="10.0dip" >  
  20.   
  21.             <LinearLayout  
  22.                 android:id="@+id/ll_one"  
  23.                 android:layout_width="match_parent"  
  24.                 android:layout_height="wrap_content"  
  25.                 android:layout_marginTop="5dip"  
  26.                 android:background="#FFA2CD5A"  
  27.                 android:orientation="vertical"  
  28.                 android:padding="5dip" >  
  29.   
  30.                 <EditText  
  31.                     android:id="@+id/et_content1"  
  32.                     android:layout_width="match_parent"  
  33.                     android:layout_height="80dip"  
  34.                     android:background="#FFFFFFFF"  
  35.                     android:gravity="left"  
  36.                     android:inputType="textMultiLine"  
  37.                     android:paddingLeft="5dip"  
  38.                     android:textSize="16sp" />  
  39.   
  40.                 <RelativeLayout  
  41.                     android:layout_width="match_parent"  
  42.                     android:layout_height="wrap_content"  
  43.                     android:layout_marginTop="5dip" >  
  44.   
  45.                     <ImageButton  
  46.                         android:id="@+id/ibn_add1"  
  47.                         android:layout_width="wrap_content"  
  48.                         android:layout_height="wrap_content"  
  49.                         android:layout_alignParentRight="true"  
  50.                         android:background="@drawable/ic_add" />  
  51. <!--   
  52.                     <ImageButton  
  53.                         android:id="@+id/ibn_del1"  
  54.                         android:layout_width="wrap_content"  
  55.                         android:layout_height="wrap_content"  
  56.                         android:layout_marginRight="10dip"  
  57.                         android:layout_toLeftOf="@id/ibn_add1"  
  58.                         android:background="@drawable/ic_delete" />  
  59.  -->  
  60.                 </RelativeLayout>  
  61.             </LinearLayout>  
  62.         </LinearLayout>  
  63.     </ScrollView>  
  64.   
  65. </RelativeLayout>  

简单来讲,一个ScrollView和内嵌的LinearLayout的组合实现了本例。LinearLayout内部控件可增可减,因为其包含在ScrollView里,所以内容超出页面显示范围时可以滚动。
该布局文件显示效果如上面第一个截图所示,包含一个编辑框(EditText)和“添加”按钮。

(2)MainActivity文件

[java]  view plain  copy
  1. package com.example.androiddynamiclayout;  
  2.   
  3. import java.util.LinkedList;  
  4.   
  5. import android.os.Bundle;  
  6. import android.app.Activity;  
  7. import android.graphics.Color;  
  8. import android.text.InputType;  
  9. import android.view.Gravity;  
  10. import android.view.Menu;  
  11. import android.view.View;  
  12. import android.view.ViewGroup;  
  13. import android.widget.EditText;  
  14. import android.widget.ImageButton;  
  15. import android.widget.LinearLayout;  
  16. import android.widget.RelativeLayout;  
  17.   
  18. public class MainActivity extends Activity {  
  19.   
  20.     // 外围的LinearLayout容器  
  21.     private LinearLayout llContentView;  
  22.       
  23.     private EditText etContent1;  
  24.       
  25.     // “+”按钮控件List  
  26.     private LinkedList<ImageButton> listIBTNAdd;  
  27.     // “+”按钮ID索引  
  28.     private int btnIDIndex = 1000;  
  29.     // “-”按钮控件List  
  30.     private LinkedList<ImageButton> listIBTNDel;  
  31.       
  32.     private int iETContentHeight = 0;   // EditText控件高度  
  33.     private float fDimRatio = 1.0f; // 尺寸比例(实际尺寸/xml文件里尺寸)  
  34.       
  35.     @Override  
  36.     protected void onCreate(Bundle savedInstanceState) {  
  37.         super.onCreate(savedInstanceState);  
  38.         setContentView(R.layout.activity_main);  
  39.           
  40.         initCtrl();  
  41.     }  
  42.       
  43.     /** 
  44.      * 初始化控件 
  45.      */  
  46.     private void initCtrl()  
  47.     {  
  48.         llContentView = (LinearLayout) this.findViewById(R.id.content_view);  
  49.         etContent1 = (EditText) this.findViewById(R.id.et_content1);  
  50.         listIBTNAdd = new LinkedList<ImageButton>();  
  51.         listIBTNDel = new LinkedList<ImageButton>();  
  52.           
  53.         // “+”按钮(第一个)  
  54.         ImageButton ibtnAdd1 = (ImageButton) this.findViewById(R.id.ibn_add1);  
  55.         ibtnAdd1.setOnClickListener(new View.OnClickListener() {  
  56.   
  57.             @Override  
  58.             public void onClick(View v) {  
  59.                 // 获取尺寸变化比例  
  60.                 iETContentHeight = etContent1.getHeight();  
  61.                 fDimRatio = iETContentHeight / 80;  
  62.   
  63.                 addContent(v);  
  64.             }  
  65.         });  
  66.   
  67.         listIBTNAdd.add(ibtnAdd1);  
  68.         listIBTNDel.add(null);  // 第一组隐藏了“-”按钮,所以为null  
  69.     }  
  70.       
  71.     /** 
  72.      * 添加一组新控件 
  73.      * @param v 事件触发控件,其实就是触发添加事件对应的“+”按钮 
  74.      */  
  75.     private void addContent(View v) {  
  76.         if (v == null) {  
  77.             return;  
  78.         }  
  79.           
  80.         // 判断第几个“+”按钮触发了事件  
  81.         int iIndex = -1;  
  82.         for (int i = 0; i < listIBTNAdd.size(); i++) {  
  83.             if (listIBTNAdd.get(i) == v) {  
  84.                 iIndex = i;  
  85.                 break;  
  86.             }  
  87.         }  
  88.           
  89.         if (iIndex >= 0) {  
  90.             // 控件实际添加位置为当前触发位置点下一位  
  91.             iIndex += 1;  
  92.               
  93.             // 开始添加控件  
  94.               
  95.             // 1.创建外围LinearLayout控件  
  96.             LinearLayout layout = new LinearLayout(MainActivity.this);  
  97.             LinearLayout.LayoutParams lLayoutlayoutParams = new LinearLayout.LayoutParams(  
  98.                     ViewGroup.LayoutParams.MATCH_PARENT,  
  99.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  100.             // 设置margin  
  101.             lLayoutlayoutParams.setMargins(0, (int) (fDimRatio * 5), 00);  
  102.             layout.setLayoutParams(lLayoutlayoutParams);  
  103.             // 设置属性  
  104.             layout.setBackgroundColor(Color.argb(25516220590));   // #FFA2CD5A  
  105.             layout.setPadding((int) (fDimRatio * 5), (int) (fDimRatio * 5),  
  106.                     (int) (fDimRatio * 5), (int) (fDimRatio * 5));  
  107.             layout.setOrientation(LinearLayout.VERTICAL);  
  108.               
  109.             // 2.创建内部EditText控件  
  110.             EditText etContent = new EditText(MainActivity.this);  
  111.             LinearLayout.LayoutParams etParam = new LinearLayout.LayoutParams(  
  112.                     ViewGroup.LayoutParams.MATCH_PARENT, iETContentHeight);  
  113.             etContent.setLayoutParams(etParam);  
  114.             // 设置属性  
  115.             etContent.setBackgroundColor(Color.argb(255255255255));   // #FFFFFFFF  
  116.             etContent.setGravity(Gravity.LEFT);  
  117.             etContent.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);  
  118.             etContent.setPadding((int) (fDimRatio * 5), 000);  
  119.             etContent.setTextSize(16);  
  120.             // 将EditText放到LinearLayout里  
  121.             layout.addView(etContent);  
  122.               
  123.             // 3.创建“+”和“-”按钮外围控件RelativeLayout  
  124.             RelativeLayout rlBtn = new RelativeLayout(MainActivity.this);  
  125.             RelativeLayout.LayoutParams rlParam = new RelativeLayout.LayoutParams(  
  126.                     ViewGroup.LayoutParams.MATCH_PARENT,  
  127.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  128. //          rlParam.setMargins(0, (int) (fDimRatio * 5), 0, 0);  
  129.             rlBtn.setPadding(0, (int) (fDimRatio * 5), 00);  
  130.             rlBtn.setLayoutParams(rlParam);  
  131.               
  132.             // 4.创建“+”按钮  
  133.             ImageButton btnAdd = new ImageButton(MainActivity.this);  
  134.             RelativeLayout.LayoutParams btnAddParam = new RelativeLayout.LayoutParams(  
  135.                     ViewGroup.LayoutParams.WRAP_CONTENT,  
  136.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  137.             // 靠右放置  
  138.             btnAddParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);  
  139.             btnAdd.setLayoutParams(btnAddParam);  
  140.             // 设置属性  
  141.             btnAdd.setBackgroundResource(R.drawable.ic_add);  
  142.             btnAdd.setId(btnIDIndex);  
  143.             // 设置点击操作  
  144.             btnAdd.setOnClickListener(new View.OnClickListener() {  
  145.   
  146.                 @Override  
  147.                 public void onClick(View v) {  
  148.                     addContent(v);  
  149.                 }  
  150.             });  
  151.             // 将“+”按钮放到RelativeLayout里  
  152.             rlBtn.addView(btnAdd);  
  153.             listIBTNAdd.add(iIndex, btnAdd);  
  154.               
  155.             // 5.创建“-”按钮  
  156.             ImageButton btnDelete = new ImageButton(MainActivity.this);  
  157.             btnDelete.setBackgroundResource(R.drawable.ic_delete);  
  158.             RelativeLayout.LayoutParams btnDeleteAddParam = new RelativeLayout.LayoutParams(  
  159.                     ViewGroup.LayoutParams.WRAP_CONTENT,  
  160.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  161.             btnDeleteAddParam.setMargins(00, (int) (fDimRatio * 5), 0);  
  162.             // “-”按钮放在“+”按钮左侧  
  163.             btnDeleteAddParam.addRule(RelativeLayout.LEFT_OF, btnIDIndex);  
  164.             btnDelete.setOnClickListener(new View.OnClickListener() {  
  165.   
  166.                 @Override  
  167.                 public void onClick(View v) {  
  168.                     deleteContent(v);  
  169.                 }  
  170.             });  
  171.             // 将“-”按钮放到RelativeLayout里  
  172.             rlBtn.addView(btnDelete, btnDeleteAddParam);  
  173.             listIBTNDel.add(iIndex, btnDelete);  
  174.               
  175.             // 6.将RelativeLayout放到LinearLayout里  
  176.             layout.addView(rlBtn);  
  177.               
  178.             // 7.将layout同它内部的所有控件加到最外围的llContentView容器里  
  179.             llContentView.addView(layout, iIndex);  
  180.               
  181.             btnIDIndex++;  
  182.         }  
  183.     }  
  184.       
  185.     /** 
  186.      * 删除一组控件 
  187.      * @param v 事件触发控件,其实就是触发删除事件对应的“-”按钮 
  188.      */  
  189.     private void deleteContent(View v) {  
  190.         if (v == null) {  
  191.             return;  
  192.         }  
  193.   
  194.         // 判断第几个“-”按钮触发了事件  
  195.         int iIndex = -1;  
  196.         for (int i = 0; i < listIBTNDel.size(); i++) {  
  197.             if (listIBTNDel.get(i) == v) {  
  198.                 iIndex = i;  
  199.                 break;  
  200.             }  
  201.         }  
  202.         if (iIndex >= 0) {  
  203.             listIBTNAdd.remove(iIndex);  
  204.             listIBTNDel.remove(iIndex);  
  205.               
  206.             // 从外围llContentView容器里删除第iIndex控件  
  207.             llContentView.removeViewAt(iIndex);  
  208.         }  
  209.     }  
  210.   
  211.     /*@Override  
  212.     public boolean onCreateOptionsMenu(Menu menu) {  
  213.         // Inflate the menu; this adds items to the action bar if it is present.  
  214.         getMenuInflater().inflate(R.menu.activity_main, menu);  
  215.         return true;  
  216.     }  */
  217.   
  218. }  

浏览这段代码需要注意以下几两点:
1.llContentView:这个变量对应的是上面布局文件提到的那个LinearLayout,通过llContentView.addView(layout, iIndex)往某一位置添加子控件,通过llContentView.removeViewAt(iIndex)删除某一位置上的子控件。
2.List对象listIBTNAdd和listIBTNDel:存储了当前所包含的所有“添加”和“删除”按钮对象,在发生添加或删除事件时,用于定位触发事件位
置。

原文地址:https://blog.csdn.net/chadeltu/article/details/42390047

猜你喜欢

转载自blog.csdn.net/qq_36408196/article/details/80302205