Android 滚动其父ListView时使子视图无效的有效方法?
我有一个ListView,它的行布局是自定义子视图。我的要求是仅在滚动ListView时使行的子视图无效。现在,我通过从子视图的onDraw方法调用ChildView.invalidate来实现这一点,事情正如我所期望的那样工作得很好,但是这种方法也会使子视图无效,即使在ListView没有滚动的情况下,因此我观察到,当应用程序运行时,它会消耗大量CPU。我正在寻找一个廉价的解决方案。 滚动ListView时是否发生回调?我什么也看不见。 请回答,谢谢Android 滚动其父ListView时使子视图无效的有效方法?,android,listview,ondraw,invalidation,Android,Listview,Ondraw,Invalidation,我有一个ListView,它的行布局是自定义子视图。我的要求是仅在滚动ListView时使行的子视图无效。现在,我通过从子视图的onDraw方法调用ChildView.invalidate来实现这一点,事情正如我所期望的那样工作得很好,但是这种方法也会使子视图无效,即使在ListView没有滚动的情况下,因此我观察到,当应用程序运行时,它会消耗大量CPU。我正在寻找一个廉价的解决方案。 滚动ListView时是否发生回调?我什么也看不见。 请回答,谢谢 protected void onDraw
protected void onDraw (Canvas canvas) {
drawBackground(canvas);
drawContent(canvas);
this.invalidate();//Recursive calling...? But no error or warnings issued.
//super.onDraw(canvas);
}
@pskink谢谢,它很有效!但并没有用廉价的方法解决这个问题。请参考代码中的注释,并回答如何处理onScroll的参数,以仅使屏幕上可见的视图无效。View.GetChildStatint.invalidate不起作用
import android.app.ListActivity;
import android.widget.ListView;
import android.widget.AbsListView;
public class MyListActivity extends ListActivity implements ListView.OnScrollListener {
...
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.list_activity_layout);
getListView().setOnScrollListener(this);
}
....
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.e("MyListActivity", "onScrollStateChanged()");
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.e("MyListActivity", "onScroll()");
Log.e("view.getId():", "" + view.getId());
//view.invalidateViews();//Calling this method does the job, but it seems that It might re-measure
// and redraw each and every views of each and every rows in the ListView..!
// So, still it is an expensive approach. is it?, but better than doing
// recursive calling of invalidate(); am I right?
// I am not satisfied with this approach.
// At least it should be possible to invalidate the views which are visible on the screen, as we expect from -
// the arguments of this method.
// Let me attempt to do it, shown below..
if(visibleItemCount != 0){
int lastVisibleItemCount = firstVisibleItem + visibleItemCount;
for(int i=firstVisibleItem; i<lastVisibleItemCount; i++){
if(view.getChildAt(i) != null){
view.getChildAt(i).invalidate();// Not works.
}
Log.e("view.getItemIdAtPosition(i):", "" + view.getItemIdAtPosition(i));
}
}
}
}
@这里的pskink正是我想要的解决方案。它仅使可见性范围内的单个子视图无效。它的工作没有任何问题
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//view.invalidateViews();//It does.., but still being expensive...!
//The following only invalidates a single child view of the Row view in the visibility range.
//Initializing i=0 may seem unnecessary, but it resolves many unexpected behavior of
//the ListView when it is initialized to i=firstVisibleItem.
if(visibleItemCount != 0){
int lastVisibleItemCount = firstVisibleItem + visibleItemCount;;
for(int i=0; i<lastVisibleItemCount; i++){
mRowView = mListView.getChildAt(i);//returns the row view.
if(mRowView != null){
mChildView = (CustomChildView) mRowView.findViewById(R.id.custom_child_view);//Single child of the Row View.
if(mChildView != null){
mChildView.invalidate();//only invalidates the required Child view of the row view.
}
}
Log.e("Row view pos: ", "" + i);
}
}
}
@pskink谢谢,它很有效!但并没有用廉价的方法解决这个问题。请参考代码中的注释,并回答如何处理onScroll的参数,以仅使屏幕上可见的视图无效。View.getChildAtint.invalidate不起作用..使ListView的所有视图无效,有什么问题吗?@pskink可以吗?正如文档所说,它会导致所有视图都被重建和重画,这是一种好的做法吗?如果我对此有错误或误解,请道歉。@pskink这是我正在寻找的确切解决方案。请参考最近的答案。它仅使可见性范围内的单个子视图无效。现在尝试记录.d lastVisibleItemCount和view.getChildCount并比较这些rwo值,您将看到它们是相同的