2

다른 간단한보기 중에 ViewPager를 포함하는 레이아웃이 있습니다. 이 레이아웃을 ListView에 대한 목록 항목으로 사용하고 있으며 정상적으로 작동합니다. 그러나 ViewHolder 패턴을 구현하려고하면 아래로 스크롤 할 때 응용 프로그램이 충돌합니다. 뷰 페이저에 어댑터를 설정하면 오류가 발생합니다.없이ViewPager가 포함 된 ListView에서 ViewHolder 패턴 구현

어댑터 ViewHolder 구현 :

public class FaceInSandAdapter extends ArrayAdapter<Gem> { 
private Context mContext; 

    public FaceInSandAdapter(Context c, ArrayList<Gem> gems) { 
    super(c, 0, gems); 
    mContext = c; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
    final Gem gem = getItem(position); 

    convertView = ((Activity) mContext).getLayoutInflater().inflate(
      R.layout.list_item_gem, null); 
    final ViewPager pager = (ViewPager) convertView 
      .findViewById(R.id.list_item_gem_photosViewPager); 
    pager.setId(gem.getId()); 

    pager.setAdapter(new PhotoSliderPagerAdapter(((FragmentActivity) parent 
     .getContext()).getSupportFragmentManager(), gem.getImageUrls())); 

    TextView address = (TextView) convertView 
     .findViewById(R.id.list_item_gem_addressTextView); 

    address.setText(gem.getAddress()); 
    return convertView; 

    } 
} 

가 어떻게 올바르게 ViewPager를 포함하는 레이아웃을 팽창 어댑터에 대한 ViewHolder 패턴을 구현합니까?

FATAL EXCEPTION: main 
Process: xx.yyy.zzzzzz, PID: 5010 
android.content.res.Resources$NotFoundException: Unable to find resource ID #0x3fe1 
at android.content.res.Resources.getResourceName(Resources.java:1776) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:919) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) 
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472) 
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:1068) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:914) 
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:442) 
at xxx.xxx.xxx.FaceInSandAdapter.getView(FaceInSandAdapter.java:89) 
at android.widget.AbsListView.obtainView(AbsListView.java:2240) 
at android.widget.ListView.makeAndAddView(ListView.java:1790) 
at android.widget.ListView.fillDown(ListView.java:691) 
at android.widget.ListView.fillGap(ListView.java:655) 
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5136) 
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4247) 
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) 
at android.view.Choreographer.doCallbacks(Choreographer.java:574) 
at android.view.Choreographer.doFrame(Choreographer.java:543) 
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) 
at android.os.Handler.handleCallback(Handler.java:733) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5102) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
at dalvik.system.NativeStart.main(Native Method) 
: 나는 ViewHolder 패턴의 내 구현을 얻을 오류에 대한

스택 트레이스를

public class FaceInSandAdapter extends ArrayAdapter<Gem> { 
private Context mContext; 

public FaceInSandAdapter(Context c, ArrayList<Gem> gems) { 
    super(c, 0, ads); 
    mContext = c; 
} 

static class ViewHolder { 
    ViewPager pager; 
    TextView address; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 

    final Gem gem = getItem(position); 

    if (convertView == null) { 
     convertView = ((Activity) mContext).getLayoutInflater().inflate(
       R.layout.list_item_gem, null); 

     holder = new ViewHolder(); 
     holder.pager = (ViewPager) convertView 
       .findViewById(R.id.list_item_gem_photosViewPager); 


     holder.address = (TextView) convertView 
       .findViewById(R.id.list_item_gem_addressTextView); 

     convertView.setTag(holder); 

    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    FragmentManager fm = ((FragmentActivity) convertView.getContext()) 
      .getSupportFragmentManager(); 
    holder.pager.setId(gem.getId()); 
    holder.pager.setAdapter(new PhotoSliderPagerAdapter(fm, gem 
      .getImageUrls())); 

    holder.address.setText(gem.getAddress()); 

    return convertView; 

    } 
} 

편집 : 다음은 위에서 언급 한 오류를 제공 구현 같은 어댑터에서 내 시도이다

** 편집 2 **

이제 viepager가 목록보기 항목으로 작업 할 때 남아있는 문제 PagerAdapter의 베어 본 구현 (저장 상태 없음, 오프 스크린 뷰 제한 없음)이있는 ImageViews를 인스턴스화하고 있으므로 목록이 많은 양의 메모리를 사용하게됩니다.

android.content.res.Resources$NotFoundException: Unable to find resource ID #0x3fe1 

당신이 존재하지 않는 참조하는 ID가있는 것으로 보인다 :

+0

이 뷰 홀더 패턴이 실제로 필요합니까? 뚜껑에 얼마나 많은 물건이 있습니까? – pskink

+0

최대 10 개의보기가 있습니다. 여기서는 간략하게 생략했습니다. –

+1

예외 스택 트레이스를 게시 할 수 있습니까? – curtisLoew

답변

2

HorizontalScrollView 또는 일부 외부 라이브러리와 같은 몇 가지 대안을 시도한 후에도 처음부터 어떻게 구현했는지 다시 돌아 왔습니다. FragmentStatePagerAdapter 대신 PagerAdapter를 직접 확장하고 instantiateItem을 재정 의하여이 문제를 해결했습니다. 문제는 조각을 사용하는 것이 었습니다. 이제 FragmentStatePagerAdapter를 사용하는 것은 정말 불필요했습니다. 단, 사진 슬라이더를 만들려고 했으므로 조각을 사용하지 않아도됩니다.

public class PhotoPagerAdapter extends PagerAdapter { 
private Context mContext; 
private List<String> mUrls; 

public PhotoPagerAdapter(Context context, List<String> urls) { 
    mContext = context; 
    mUrls = urls; 
} 

@Override 
public int getCount() { 
    return mUrls.size(); 
} 

@Override 
public boolean isViewFromObject(View view, Object object) { 
    return view == ((RelativeLayout) object); 
} 

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    ImageView imgDisplay; 

    LayoutInflater inflater = (LayoutInflater) mContext 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View v = inflater.inflate(R.layout.fragment_gem_photo, container, false); 

    imgDisplay = (ImageView) v 
      .findViewById(R.id.fragment_gem_photo_imageView); 
    Picasso.with(mContext).load(mUrls.get(position)) 
      .placeholder(R.drawable.wait_image).into(imgDisplay); 
    ((ViewPager) container).addView(v); 

    return v; 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    ((ViewPager) container).removeView((RelativeLayout) object); 

} 
} 

편집 나는 문제가 전혀 ViewHolder 패턴의 잘못된 구현하지 않습니다 알아 냈

:

여기에 새로운 PhotoPagerAdapter 내 코드입니다. 대신, FragmentStatePagerAdapter가있는 뷰 페이지가 포함되어있을 때 이미 확장 된 convertView를 다시 사용합니다.

0

는 게시 된 스택 추적을 참조하십시오. 이로 인해 앱이 정지되는 것이 아니라 홀더 패턴이 손상됩니다.

+0

존재하지 않는 ID를 참조하고 있음을 어떻게 설명합니까? –

+0

그리고 왜 ViewHolder없이 동일한 오류가 발생하지 않습니까? –

+0

downvote를 설명해 주시겠습니까? 첫 번째 의견에 대한 답변이 제 답변에서 분명히 드러납니다. 홀더 버전에서'setId()'메서드가 빠져있는 것 같아서 리소스를 찾을 수없는 이유를 설명 할 수 있습니다. – curtisLoew

관련 문제