ViewPager에서 notify DataSetChanged 호출 실패 문제

3247 단어

가장 기본적인 방법:


childview가 비교적 간단한 상황(예를 들어 TextView, ImageView 등만,ListView 등 전시 데이터가 없는 경우)에 대해 자신의 어댑터에 코드를 추가할 수 있다.
@Override 
public int getItemPosition(Object object) { 
return POSITION_NONE; 
} 

이렇게 하면 일반적인 상황에서 요구하는 효과에 도달할 수 있다.

문제점:


이것은 Pager Adapter의 Bug이 아닙니다. 보통 notify DataSetChanged 방법을 사용하면 ViewPager가 Adapter의 getItem Position 방법을 통해 모든 child view를 조회할 수 있습니다. 이 경우 모든 child view 위치는 POSITIONNONE, 모든 child view가 존재하지 않는다는 뜻입니다. ViewPager는destroy Item 방법을 호출하여 삭제하고 다시 생성하여 시스템 비용을 증가시키고 복잡한 상황에서 논리적인 문제를 초래합니다.특히 childview 콘텐츠만 업데이트하고 싶을 때 전혀 불필요한 비용이 든다.

보다 효과적인 방법:


ViewPger는 notify DataSetChanged () 를 호출할 때 Pager Adapter의 getItem Position () 방법을 반복해서 호출하여 페이지마다 옮겨다니게 합니다.
instantiateItem () 에서 setTag () 를 통해 모든 페이지 페이지를 기억합니다.getItem Position () 에서 Object의 getTag () 를 가져옵니다. 바꿀 페이지의 아래 표시가 이 tag와 같으면 POSITIONNONE;그렇지 않으면 POSITION으로 돌아갑니다.UNCHANGED.
이 방법은 POSITION으로 돌아가는NONE; ,이 페이지가 바뀌었음을 나타냅니다.destroy Item () 방법으로 삭제하고instantiate Item () 방법으로 만들 것입니다.POSITION으로 돌아가기UNCHANGED, 안 바꿨다고 아무것도 안 했어요.
private List mViewCache = new ArrayList();  
private ViewPager viewPager;  
private int curUpdatePager;  
  
//      
class MyPagerAdapter extends PagerAdapter {  
  
  
    public void destroyItem(View arg0, int arg1, Object arg2) {  
        View view = (View)arg2;  
        ((ViewPager) arg0).removeView((View)arg2);  
    }  
  
  
    public void finishUpdate(View arg0) {  
    }  
  
  
    public int getCount() {  
        return mViewCache.size();  
    }  
  
  
    public Object instantiateItem(View arg0, int arg1) {  
        mViewCache.get(arg1).setTag(arg1);  
        ((ViewPager) arg0).addView(mViewCache.get(arg1));  
  
  
        return mViewCache.get(arg1);  
    }  
  
  
    public boolean isViewFromObject(View arg0, Object arg1) {  
        return arg0 == (arg1);  
    }  
  
  
    public void restoreState(Parcelable arg0, ClassLoader arg1) {  
    }  
  
  
    public Parcelable saveState() {  
        return null;  
    }  
  
  
    @Override  
    public void startUpdate(View arg0) {  
    }  
  
    @Override  
    public int getItemPosition(Object object) {  
        View view = (View)object;  
        if(curUpdatePager == (Integer)view.getTag()){  
            return POSITION_NONE;    
        }else{  
            return POSITION_UNCHANGED;  
        }  
        // return super.getItemPosition(object);  
    }  
}  
  
/** 
 *   pager    
 * @param view     pager 
 * @param index      
 *  
 *   :updateViewPagerItem(fragment2_parentctrl_changepwd,1); 
 */  
private void updateViewPagerItem(View view,int index){  
    curUpdatePager = index;  
    mViewCache.remove(index);  
    mViewCache.add(index, view);  
    viewPager.getAdapter().notifyDataSetChanged();  
    // findViewById(getResources().getIdentifier("sysset_button"+(index+1), "id", "com.jzbyapp.suzhou")).requestFocus();  
}  

Fragment State Pager Adapter 종류의destroy Item 방법에서remove가 되었을 때 Fragment의 onDestroy 방법과 onDetach 방법이 모두 호출되었습니다.Fragment가dd에 다시 호출되었을 때 Fragment의 생명주기는 모두 다시 호출되지만savedInstanceState 파라미터는 이전에 저장된 데이터를 보존하고 있습니다.

좋은 웹페이지 즐겨찾기