配置信息

Android 12.0

Android Studio Chipmunk | 2021.2.1

PS:Android 版本之间不兼容的问题很严重,不相同版本很有可能不能正常使用,请注意区分

Android动态添加View之addView的用法

Android动态添加View之addView的用法

方法的几种形式:

addView(View child)   // child-被添加的View
addView(View child, int index)   // index-被添加的View的索引
addView(View child, int width, int height)   // width,height被添加的View指定的宽高
addView(View view, ViewGroup.LayoutParams params)   // params被添加的View指定的布局参数
addView(View child, int index, LayoutParams params) 

在LinearLayout中的使用

首先新建一个Activity并在布局中指定一个LinearLayout作为容器。布局文件如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="com.example.android.testapp.MainActivity">

    //添加View的容器
    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:background="#ffa200"
        android:orientation="vertical">

        //事先存在的View
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="最初index为0"
            android:textColor="#ffffff"
            android:textSize="25sp" />

        //事先存在的View
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="最初index为1"
            android:textColor="#ffffff"
            android:textSize="25sp" />

    </LinearLayout>

    //点击按钮实现添加View
    <Button
        android:id="@+id/btn_add"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#ffff00"
        android:textAllCaps="false"
        android:text="Add View"/>

</LinearLayout >

界面的原始布局如图所示:
在这里插入图片描述

现在我们编写Activity的代码,对控件进行初始化以及点击事件的设置,如下所示

public class MainActivity extends AppCompatActivity {

    private LinearLayout mContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContainer = findViewById(R.id.container);
    }

    /**
     * 按钮点击事件,向容器中添加TextView
     * @param view
     */
    public void addView(View view) {
        TextView child = new TextView(this);
        child.setTextSize(20);
        child.setTextColor(getResources().getColor(R.color.colorAccent));
        // 获取当前的时间并转换为时间戳格式, 并设置给TextView
        String currentTime = dateToStamp(System.currentTimeMillis());
        child.setText(currentTime);
        // 调用一个参数的addView方法
        mContainer.addView(child);
    }

    /**
     * 将时间戳转换为时间
     */
    public String dateToStamp(long s) {
        String res;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date(s);
            res = simpleDateFormat.format(date);
        } catch (Exception e) {
            return "";
        }
        return res;
    }
}

现在,我们分别看一下点击一次按钮和点击三次按钮的效果图,如下所示:
在这里插入图片描述

问题的引入

博主在使用安卓开发的时候需要在一个layout内多次动态的添加其他layout文件。

例如该layout文件

在这里插入图片描述

表示一条新闻,博主想要的效果是如果数据库内读到了3条新闻信息,就动态的添加三个该layout进来

想要的效果如下:
在这里插入图片描述

由于需要用到非当前Activity的layout内的组件用到了以下加载布局的方法:

public View inflate (int resource, ViewGroup root, boolean attachToRoot) 该方法的三个参数依次为:

①要加载的布局对应的资源id

②为该布局的外部再嵌套一层父布局,如果不需要的话,写null就可以了!

③是否为加载的布局文件的最外层套一层root布局,不设置该参数的话, 如果root不为null的话,则默认为true 如果root为null的话,attachToRoot就没有作用了! root不为null,attachToRoot为true的话,会在加载的布局文件最外层嵌套一层root布局; 为false的话,则root失去作用! 简单理解就是:是否为加载的布局添加一个root的外层容器~!

错误示范

但博主在安卓使用addView添加多个组件的时候只有第一个能成功的添加进来,后面的组件都无法正常添加。

效果也就是差不多这样(但其实应该会有三条数据!)

在这里插入图片描述

错误的使用,指定了父布局(具体原因见下)

在这里插入图片描述

解决方法

请注意博主在最前面提到的public View inflate (int resource, ViewGroup root, boolean attachToRoot) 方法,由于博主多次添加都是用的是同一个layout,如果又指定的是同一个父布局的话由于一个子view只能拥有一个父view,后续的layout是无法正常添加的,甚至还有可能出现这个java.lang.IllegalStateException: The specified child already has a parent. You must call removeView()报错。

最最省心的方法就是把第二个参数root改为null
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐