是否无法使用 addView() 动态添加自定义布局?

Posted

技术标签:

【中文标题】是否无法使用 addView() 动态添加自定义布局?【英文标题】:Is it impossible to dynamically add custom layouts using addView()? 【发布时间】:2021-06-03 11:40:00 【问题描述】:

我正在创建一个窗口来打开dialog window 并写评论。

当您打开对话窗口时,有一个layout,您可以在其中输入您的第一条评论。

评论只能写在一行中,通过在输入字段中按EnterKey创建以下评论布局。

我最初将其实现为 RecyclerView,但现在我也在尝试其他方法。 (使用addView()

但是当我使用addView() 时出现以下错误。

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

here 中显示了此问题的解决方案。 (如果您能解释为什么会发生此错误,我将不胜感激。)

使用这个没有错误。 但是,不再添加任何项目。

对话框打开时只有first item存在,按下Enter key没有反应。

我想实时动态添加项目。

我该怎么办?


fragment_wc_dialog.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_
    android:layout_
    android:orientation="vertical"
    tools:context=".fragment.WritingCommentDialogFragment">
</LinearLayout>

wc_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/constraintLayout"
    android:layout_
    android:layout_
    tools:context=".fragment.WritingCommentDialogFragment">

    <EditText
        android:id="@+id/comment_edit"
        android:layout_
        android:layout_
        android:layout_marginTop="12dp"
        android:gravity="center_vertical"
        android:drawableLeft="@drawable/ic_bullet_point"
        android:drawablePadding="5dp"
        android:layout_marginHorizontal="10dp"
        android:background="@null"
        android:textSize="15sp"
        android:inputType="text"
        android:maxLines="1"
        android:maxLength="22"
        android:imeOptions="actionNone"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

WCDialogFragment.java

public class WritingCommentDialogFragment extends DialogFragment 
    LinearLayout mContainer; // input layout
    View inputView;
    EditText editText;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_writing_comment_dialog, container, false);

        initViews(view);

        mContainer.addView(inputView); // The first item to be present when the dialog is opened

        editText.setOnEditorActionListener(new TextView.OnEditorActionListener() 
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) 
                if(event.getAction() == KeyEvent.ACTION_DOWN) 
                    mContainer.addView(inputView);
                
                return true;
            
        );

        return view;
    

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) 
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.setCanceledOnTouchOutside(false);
        return dialog;
    

    @Override
    public void onResume() 
        super.onResume();
        Toast.makeText(getContext(), "onResume()", Toast.LENGTH_SHORT).show();
        setDialogSize();
    

    private void initViews(View view) 
        mContainer = view.findViewById(R.id.container);
        inputView = LayoutInflater.from(getContext()).inflate(R.layout.writing_comment_item, null);
        editText = inputView.findViewById(R.id.comment_edit);
    


添加

【问题讨论】:

【参考方案1】:

据我所知,您的问题和链接的问题是不同的。该链接有两个视图,他们想要在它们之间来回交换,因此答案是在添加第二个视图之前删除一个视图。您想建立一个视图列表,因此您必须使用不同的实例,而不是一遍又一遍地添加相同的视图。

如果您希望新添加的视图也响应 Enter 键,您也可以为新视图设置相同的侦听器:

if(event.getAction() == KeyEvent.ACTION_DOWN) 
    EditText addedView = (EditText) LayoutInflater.from(getContext()).inflate(R.layout.writing_comment_item, mContainer, false);
    addedView.setOnEditorActionListener(this);
    mContainer.addView(addedView);

【讨论】:

哇……谢谢。但是这里还有另一个问题。 EnterKey(Add View) 事件并非在所有创建的视图中都被触发,而只有 first view created 是添加项事件。有没有办法为添加的项目触发事件?有什么方法可以为添加的项目触发事件吗? 所以添加的视图是一个新的EditText?并且您希望能够输入新的EditText,按 Enter 并添加其他视图? 没错。这是同一个项目。我希望在添加的每个视图上触发 enter 键事件,而不仅仅是第一个视图。我上传了一张图片。我想要一个像照片这样的功能。在照片中,所有添加的项目 (cmets) 都会发生回车键事件。但我只为第一项开火。有没有办法为所有添加的项目添加视图事件? 谢谢。 onEditorAction() 是否在外部实现?我稍后再试。

以上是关于是否无法使用 addView() 动态添加自定义布局?的主要内容,如果未能解决你的问题,请参考以下文章

使用 WindowManager.addView 添加动态视图

自定义Groupview添加子view的问题

无法使用自定义域将 Firebase 动态链接添加到项目

如何使用 addView 将视图添加到布局?

AndroidResideMenu 自定义布局

在自定义模板中动态添加多个剑道下拉列表