我正在尝试在ViewGroup中的onLayout中删除和添加视图,但这会导致某些子视图无法正确重绘。
考虑以下观点:
public static class MyViewGroup extends ViewGroup {
View view;
int count;
boolean removeInLayout = true;
public MyViewGroup(Context context) {
super(context);
init();
}
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
view = LayoutInflater.from(getContext()).inflate(R.layout.myview, this, false);
addView(view);
setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
count++;
requestLayout();
}
});
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (removeInLayout) {
removeViewInLayout(view);
}
invalidate();
final String text = "Count: " + count;
((TextView) view.findViewById(R.id.one)).setText(text);
((TextView) view.findViewById(R.id.two)).setText(text);
((TextView) view.findViewById(R.id.three)).setText(text);
((TextView) view.findViewById(R.id.four)).setText(text);
if (removeInLayout) {
LayoutParams lp = view.getLayoutParams();
addViewInLayout(view, 0, lp);
final int wms = MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.EXACTLY);
final int hms = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
view.measure(wms, hms);
}
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
measureChild(view, widthMeasureSpec, heightMeasureSpec);
}
}
将以下xml布局作为子项:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="84dp">
<TextView
android:id="@+id/one"
android:layout_width="100dp"
android:layout_height="84dp"
android:background="#FF00FF00"
tools:text="First View"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/one"
android:layout_toLeftOf="@+id/four"
android:layout_centerVertical="true"
android:layout_marginLeft="4dp"
android:paddingBottom="2dp"
android:orientation="vertical">
<TextView
android:id="@+id/two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Second View"/>
<TextView
android:id="@+id/three"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="sans-light"
android:maxLines="3"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="12sp"
tools:text="Third View"/>
</LinearLayout>
<TextView
android:id="@+id/four"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="4dp"
android:layout_marginLeft="4dp"
tools:text="Fourth view"/>
</RelativeLayout>
最初视图及其子项绘制得很好,在第一次单击时,每个视图都会重绘。任何进一步的点击只会导致id为“one”和“four”的视图被重绘。 “两个”和“三个”陷入困境。
如果我从onLayout中删除invalidate()
,则视图永远不会重绘。
如果我将removeViewInLayout
和addViewInLayout
换成detachViewFromParent
和attachViewToParent
,则会正确重新绘制视图。如果我删除了无效,则永远不会重新绘制它们。
任何人都可以了解正在发生的事情吗?是否应该在布局阶段删除并重新添加视图?为什么不是子视图无效的事实,虽然它是分离的,足以导致重绘?
我已将示例应用程序上传到https://github.com/SimonVT/add-in-layout - 单击屏幕上的任意位置以触发OnClickListener,它会递增计数变量并请求布局。