这可能有点难以解释,所以我能想到的最佳方式是为您提供一个显示问题的视频。
在视频中我自己滚动列表视图,5秒后,创建一个视图并添加到底部的持有者中。在那一刻,listview被刷新。
http://tinypic.com/player.php?v=vpz0k8%3E&s=8#.U0VrIvl_t8E
问题如下:
我的活动布局包含:
片段显示一个ListView,其中包含每行的动画。
如果我在“RelativeLayout”上添加一个View,它会使片段重新调整为新的大小,因为它设置在此RelativeLayout之上,因此每个Row都会重新重建。
你们想以任何方式避免这种情况吗?
编辑:源代码: https://bitbucket.org/sergicast/listview-animated-buggy
答案 0 :(得分:5)
如果添加的页脚视图的布局过程正在运行,请不要启动动画。可以使用ViewTreeObserver确定布局过程的结束(开始显然从添加页脚视图开始):
hand.postDelayed(new Runnable() {
@Override
public void run() {
ViewTreeObserver viewTreeObserver = holder.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
holder.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mIgnoreAnimation = false;
}
});
mIgnoreAnimation = true;
holder.addView(viewToAdd);
}
}, 5000);
将此方法添加到您的活动:
public boolean ignoreAnimation() {
return mIgnoreAnimation;
}
并在片段中查看:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Context context = FragmentTest.this.getActivity();
TextView tv = new TextView(context);
tv.setText("Pos: " + position);
tv.setTextSize(35f);
if (runAnimation()) {
Animation anim = AnimationUtils.loadAnimation(context, R.anim.animation);
tv.startAnimation(anim);
}
return tv;
}
private boolean runAnimation() {
Activity activity = getActivity();
if (activity != null && activity instanceof MainActivity) {
return ! ((MainActivity)activity).ignoreAnimation();
}
return true;
}
当然整个Activity - Fragment通信可以大大改进,但是这个例子让你了解如何解决这个问题。
虽然它阻止动画启动,但它并不会阻止ListView刷新,尽管用户不会注意到。如果您担心性能,可以通过重新使用视图来改进适配器代码:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Context context = FragmentTest.this.getActivity();
TextView tv = null;
if (convertView != null && convertView instanceof TextView) {
tv = (TextView) convertView;
}
else {
tv = new TextView(context);
}
答案 1 :(得分:0)
是的,我可以想出解决这个问题的可行方法。
你的问题是:
holder
的布局参数设置为wrap_content。默认情况下,当它没有内容时,它是"零大小的"在底部的某个地方,对你来说是不可见的(就Android来说,不是不可见的,不过,sic!)holder
添加视图时,框架会理解,holder
容器的大小现在不同了。但是这个容器是另一个容器的孩子 - 你的 root RelativeLayout
,反过来又包含另一个孩子 - 你的<fragment>
。要修复列表获取无效并重新绘制的问题,只需为holder
指定一些固定的布局参数即可。例如:
<RelativeLayout
android:id="@+id/holder"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" >
</RelativeLayout>
这将阻止重新绘制列表。但在这种情况下,您将从一开始就显示holder
。
答案 2 :(得分:-1)
是。这是 RelativeLayout
的预期行为您正在将 ListView Fragment 和TextView添加到RelativeLayout中,因此,只要子视图维度发生更改,就会影响RelativeLayout中的其他子项。
因此,当您添加新的TexView时,即使其高度为match_parent,另一个子Fragment也会受到影响。
您只能通过将父版面更改为 LinearLayout 来解决此问题。