安卓动态添加View
在安卓应用中,有很多时候需要动态添加View。比如从后台获取商品列表,根据商品数量在页面渲染对应数量的条目,这时候就需要动态添加View。
1.动态添加View的方法
动态添加View有两种方法:
- 由代码生成子View:这种方式很繁琐,布局效果也不直观,而且很多属性设置不了(也可能是我没找对方法);
- 从xml读取布局,然后动态设置信息:推荐该方式,配置xml时,可以直接看到效果,可设置的参数也更多。
接下来就用代码演示下如何使用这两种方式动态添加View。
注:子View也可以写在父View中,设置visible为GONE即可,在createItem最后添加一行item.setVisibility(View.VISIBLE);
。
2. 代码实现
父View布局activity_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="480dp"
android:layout_gravity="center_horizontal|top"
android:layout_margin="10dp">
<LinearLayout
android:id="@+id/list_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<Button
android:id="@+id/list_switch_model"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_gravity="center"
android:layout_marginRight="20dp"
android:text="Switch Model" />
<Button
android:id="@+id/list_add_item"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:text="Add Item" />
</LinearLayout>
</LinearLayout>
子View布局activity_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="right|center"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_img"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:src="@drawable/common_item" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="left|center"
android:orientation="vertical">
<TextView
android:id="@+id/item_index"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="index: item name"
android:textColor="@color/black"
android:textSize="6pt" />
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="name: item name"
android:textColor="@color/black"
android:textSize="6pt" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:gravity="right|center"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_edit"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:src="@drawable/common_edit" />
<ImageView
android:id="@+id/item_delete"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:src="@drawable/common_delete" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
activity类:
package org.tao.hetools.activities;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.activity.ComponentActivity;
import androidx.annotation.Nullable;
import org.tao.hetools.R;
import org.tao.hetools.entities.ItemInfo;
import java.util.ArrayList;
import java.util.List;
public class DynamicViewActivity extends ComponentActivity {
private int index = 0;
private boolean createViewFromXml = true;
private List<ItemInfo> itemInfos = new ArrayList<>();
private LinearLayout listItemsLayout;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
listItemsLayout = findViewById(R.id.list_items);
initButton();
initDynamicView();
}
private void initDynamicView() {
if (listItemsLayout == null) {
return;
}
listItemsLayout.removeAllViews();
for (ItemInfo itemInfo : itemInfos) {
listItemsLayout.addView(createViewFromXml ? createViewFromCode(itemInfo) : createViewFromCode(itemInfo));
}
}
private void initButton() {
findViewById(R.id.list_add_item).setOnClickListener(view -> {
if (listItemsLayout == null) {
return;
}
ItemInfo itemInfo = new ItemInfo(index, "name " + index, R.drawable.common_item);
index++;
itemInfos.add(itemInfo);
listItemsLayout.addView(createViewFromXml ? createItem(itemInfo) : createViewFromCode(itemInfo));
});
findViewById(R.id.list_switch_model).setOnClickListener(view -> {
itemInfos.clear();
listItemsLayout.removeAllViews();
createViewFromXml = !createViewFromXml;
});
}
/**
* 在代码中生成布局作为子view的布局
*
* @param itemInfo item信息
* @return item view
*/
private View createViewFromCode(ItemInfo itemInfo) {
// item开头的图标layout
ImageView itemImage = new ImageView(this);
itemImage.setImageResource(R.drawable.common_item);
itemImage.setMaxHeight(136);// 这个高度跟dp的换算,需要根据屏幕分辨率重新计算。下同
itemImage.setMaxWidth(136);
itemImage.setLeft(10);
itemImage.setRight(10);
itemImage.setPadding(5, 5, 5, 5);
itemImage.setAdjustViewBounds(true);
LinearLayout imageLayout = new LinearLayout(this);
imageLayout.setOrientation(LinearLayout.HORIZONTAL);
imageLayout.addView(itemImage);
// item信息layout
TextView index = new TextView(this);
index.setText("index: " + itemInfo.getIndex());
index.setTextSize(10);
TextView name = new TextView(this);
name.setText("name: " + itemInfo.getName());
name.setTextSize(10);
LinearLayout infoLayout = new LinearLayout(this);
infoLayout.setOrientation(LinearLayout.VERTICAL);
infoLayout.addView(index);
infoLayout.addView(name);
// 操作layout
ImageView edit = new ImageView(this);
edit.setImageResource(R.drawable.common_edit);
edit.setMaxHeight(136);
edit.setMaxWidth(136);
edit.setAdjustViewBounds(true);
ImageView delete = new ImageView(this);
delete.setImageResource(R.drawable.common_delete);
delete.setMaxHeight(136);
delete.setMaxWidth(136);
delete.setAdjustViewBounds(true);
LinearLayout operateLayout = new LinearLayout(this);
operateLayout.setOrientation(LinearLayout.HORIZONTAL);
operateLayout.addView(edit);
operateLayout.addView(delete);
// 子view的信息
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.HORIZONTAL);
layout.addView(imageLayout);
layout.addView(infoLayout);
layout.addView(operateLayout);
edit.setOnClickListener(view -> {
// todo 此处处理edit的点击事件
Log.i("itemInfoList: ", itemInfos.toString());
});
delete.setOnClickListener(view -> {
itemInfos.remove(itemInfo);
listItemsLayout.removeView(layout);
});
return layout;
}
/**
* 从xml文件获取布局作为子view的布局
*
* @param itemInfo item信息
* @return item view
*/
private View createItem(ItemInfo itemInfo) {
LinearLayout inflate = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_item, null);
LinearLayout item = inflate.findViewById(R.id.item);
((ImageView) item.findViewById(R.id.item_img)).setImageResource(itemInfo.getImageResourceId());
((TextView) item.findViewById(R.id.item_index)).setText("index: " + itemInfo.getIndex());
((TextView) item.findViewById(R.id.item_name)).setText("name: " + itemInfo.getName());
item.findViewById(R.id.item_edit).setOnClickListener(view -> {
// todo 此处处理edit的点击事件
Log.i("itemInfoList: ", itemInfos.toString());
});
item.findViewById(R.id.item_delete).setOnClickListener(view -> {
itemInfos.remove(itemInfo);
listItemsLayout.removeView(item);
});
((ViewGroup) item.getParent()).removeAllViews();
return item;
}
}