尝试用数据填充视图时 AsyncLayoutInflater 崩溃
Crash with AsyncLayoutInflater when trying to populate the view with data
我有一个自定义的 ViewGroup,我正在尝试对其进行异步膨胀,但它因以下原因而崩溃:
进程:com.xxx.xxx.debug,PID:9391
java.lang.IllegalStateException: 指定的child已经有一个parent。您必须先在 child 的 parent 上调用 removeView()。
Process: com.xxx.xxx.debug, PID: 9391
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
AsyncLayoutInflater asyncLayoutInflater = new AsyncLayoutInflater(this.getContext());
asyncLayoutInflater.inflate(R.layout.my_row, myLayout,
new AsyncLayoutInflater.OnInflateFinishedListener() {
@Override
public void onInflateFinished(View view, int resid, ViewGroup parent) {
for (int i = 0; i < myData.size(); i++) {
TextView myTextView = (TextView) view.findViewById(android.R.id.text1);
tagTextView.setText(myData.get(i).getName());
ImageView myIcon = (ImageView) view.findViewById(android.R.id.icon);
picasso.load(myData.get(i).getIcon()).into(myIcon);
parent.addView(view);
}
}
});
您正在循环中调用 parent.addView(view)
。在第一次添加 View
之后,您将无法再次添加,因此出现异常。
每个 inflate()
调用只会膨胀一个 View
,它只能添加到其父级一次。如果你想膨胀多个 my_row
个实例,你必须为每个实例调用一次 inflate()
。
一个可能的解决方案是将循环移动到 inflate()
调用周围,并保留一个 int
字段来跟踪哪一行被传递给 onInflateFinished()
方法。由于膨胀请求在 AsyncLayoutInflater
中排队,它们将按顺序完成。
比如先声明行计数器和OnInflateFinishedListener
.
private int row;
private final AsyncLayoutInflater.OnInflateFinishedListener inflateListener =
new AsyncLayoutInflater.OnInflateFinishedListener() {
@Override
public void onInflateFinished(View view, int resid, ViewGroup parent) {
TextView myTextView = (TextView) view.findViewById(android.R.id.text1);
myTextView.setText(myData.get(row).getName());
ImageView myIcon = (ImageView) view.findViewById(android.R.id.icon);
picasso.load(myData.get(i).getIcon()).into(myIcon);
parent.addView(view);
row++;
}
};
然后修改循环和inflate()
块如下。
row = 0;
for (int i = 0; i < myData.size(); i++) {
asyncLayoutInflater.inflate(R.layout.my_row, myLayout, inflateListener);
}
如果您不需要 inflation 之后的数据收集,您可以在使用时从收集的开头移除每个元素,并放弃行计数器,这可能会更干净一些.
我有一个自定义的 ViewGroup,我正在尝试对其进行异步膨胀,但它因以下原因而崩溃: 进程:com.xxx.xxx.debug,PID:9391 java.lang.IllegalStateException: 指定的child已经有一个parent。您必须先在 child 的 parent 上调用 removeView()。
Process: com.xxx.xxx.debug, PID: 9391
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
AsyncLayoutInflater asyncLayoutInflater = new AsyncLayoutInflater(this.getContext());
asyncLayoutInflater.inflate(R.layout.my_row, myLayout,
new AsyncLayoutInflater.OnInflateFinishedListener() {
@Override
public void onInflateFinished(View view, int resid, ViewGroup parent) {
for (int i = 0; i < myData.size(); i++) {
TextView myTextView = (TextView) view.findViewById(android.R.id.text1);
tagTextView.setText(myData.get(i).getName());
ImageView myIcon = (ImageView) view.findViewById(android.R.id.icon);
picasso.load(myData.get(i).getIcon()).into(myIcon);
parent.addView(view);
}
}
});
您正在循环中调用 parent.addView(view)
。在第一次添加 View
之后,您将无法再次添加,因此出现异常。
每个 inflate()
调用只会膨胀一个 View
,它只能添加到其父级一次。如果你想膨胀多个 my_row
个实例,你必须为每个实例调用一次 inflate()
。
一个可能的解决方案是将循环移动到 inflate()
调用周围,并保留一个 int
字段来跟踪哪一行被传递给 onInflateFinished()
方法。由于膨胀请求在 AsyncLayoutInflater
中排队,它们将按顺序完成。
比如先声明行计数器和OnInflateFinishedListener
.
private int row;
private final AsyncLayoutInflater.OnInflateFinishedListener inflateListener =
new AsyncLayoutInflater.OnInflateFinishedListener() {
@Override
public void onInflateFinished(View view, int resid, ViewGroup parent) {
TextView myTextView = (TextView) view.findViewById(android.R.id.text1);
myTextView.setText(myData.get(row).getName());
ImageView myIcon = (ImageView) view.findViewById(android.R.id.icon);
picasso.load(myData.get(i).getIcon()).into(myIcon);
parent.addView(view);
row++;
}
};
然后修改循环和inflate()
块如下。
row = 0;
for (int i = 0; i < myData.size(); i++) {
asyncLayoutInflater.inflate(R.layout.my_row, myLayout, inflateListener);
}
如果您不需要 inflation 之后的数据收集,您可以在使用时从收集的开头移除每个元素,并放弃行计数器,这可能会更干净一些.