Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 滚动其父ListView时使子视图无效的有效方法?_Android_Listview_Ondraw_Invalidation - Fatal编程技术网

Android 滚动其父ListView时使子视图无效的有效方法?

Android 滚动其父ListView时使子视图无效的有效方法?,android,listview,ondraw,invalidation,Android,Listview,Ondraw,Invalidation,我有一个ListView,它的行布局是自定义子视图。我的要求是仅在滚动ListView时使行的子视图无效。现在,我通过从子视图的onDraw方法调用ChildView.invalidate来实现这一点,事情正如我所期望的那样工作得很好,但是这种方法也会使子视图无效,即使在ListView没有滚动的情况下,因此我观察到,当应用程序运行时,它会消耗大量CPU。我正在寻找一个廉价的解决方案。 滚动ListView时是否发生回调?我什么也看不见。 请回答,谢谢 protected void onDraw

我有一个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);               
}  

@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值,您将看到它们是相同的