android - Is it impossible to dynamically add custom layouts using addView()?
问题描述
I am making a window to open a dialog window
and write a comment.
When you open the dialog window, there is a layout
where you can enter your first comment.
Comment can only be written in one line and the following comment layout is created by pressing EnterKey
in the input field.
I originally implemented this as a RecyclerView, but now I am trying other methods as well. (using addView()
)
But when I used addView()
I got the following error.
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
The solution to this is shown in the here. (And I would appreciate it if you could explain why this error occurs.)
There is no error when using this. However, no more items are added.
There is only the first item
that existed when the dialog box was opened, and there is no response when pressing the Enter key
.
I want to add items dynamically in real time.
What should I do?
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_width="match_parent"
android:layout_height="wrap_content"
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_width="match_parent"
android:layout_height="wrap_content"
tools:context=".fragment.WritingCommentDialogFragment">
<EditText
android:id="@+id/comment_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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);
}
}
ADDED
解决方案
Your problem and the linked issue are different, as far as I can tell. The link has two views that they want to swap back and forth between, so the answer is to remove one view before adding the second. You want to build up a list of views, so you must use different instances rather than adding the same view over and over.
If you want the newly-added view to also respond to the Enter key, you can set the same listener to the new view too:
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);
}
推荐阅读
- c# - 将命名空间添加到 WCF 方法
- performancecounter - 无法在性能监视器中添加我的自定义性能计数器
- php - Laravel 8:如何检查表是否为空
- google-apps-script - 如何从 Google 表格自定义菜单将 MailApp noReply 从 true 设置为 false?
- hyperledger-fabric - 调用 javascript 链码时出错
- python - sys.setrecursionlimit 在 jupyter 笔记本中不起作用
- node.js - 以编程方式更新 node_modules 以匹配 package.json 版本?
- node.js - Mongoose/MongoDB PUT:如果对象 ID 在数组中是唯一的,则将对象推送到数组
- python - 问题标记 POS
- ios - 即使 App 被 IOS 中的用户杀死,如何每 10 秒调用一次 api?