我有一个ListView,其自定义子视图作为其行布局。我的要求是仅在滚动ListView时使行的子视图无效。现在我通过从子视图的onDraw()方法调用ChildView.invalidate()来实现这一点,并且事情按照我的预期很好地工作,但是即使ListView没有滚动,这种方法也会使子视图无效,所以我观察到它在应用程序运行时消耗大量CPU。我正在寻找一个廉价的解决方案。 滚动ListView时是否有回调?我看不到任何东西。 请回答,谢谢。
protected void onDraw (Canvas canvas) {
drawBackground(canvas);
drawContent(canvas);
this.invalidate();//Recursive calling...? But no error or warnings issued.
//super.onDraw(canvas);
}
答案 0 :(得分:0)
@pskink谢谢它有效!但是并没有解决这个问题"用廉价的方法做到这一点"。请参考代码中的注释并回答如何处理onScroll()的参数,以便仅使屏幕上可见的视图无效。 View.getChildAt(int).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);
}
}
}