16

Provo ad utilizzare ViewPager come una riga in ListView ma ottengo un comportamento bizzarro - Solo la prima riga funziona, ma quando faccio scorrere l'elenco scompare. Quando faccio scorrere una riga vuota, improvvisamente viene visualizzata la riga sopra. Sembra che Android crei un singolo cercapersone e lo utilizzi per tutte le righe.Posizionare ViewPager come una riga in ListView

Questo è quello che vedo quando lancio l'applicazione:

screen shot

Questo è il mio layout di fila:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@android:color/white" 
    android:orientation="vertical" 
    android:paddingBottom="2dp" > 

    <TextView 
     android:id="@+id/textViewFriendName" 
     style="@style/TextStyle" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@color/myFriendsBg" 
     android:paddingBottom="5dp" 
     android:paddingTop="5dp" 
     android:text="TextView" /> 

    <View style="@style/DividerHorizontalStyle_gray" /> 

     <android.support.v4.view.ViewPager 
      android:id="@+id/pagerMyFriendHabits" 
      android:layout_width="match_parent" 
      android:layout_height="@dimen/DefaultImageHeight" /> 


    <View style="@style/DividerHorizontalStyle" /> 

</LinearLayout> 

Questo è il mio adattatore di listino:

public class MyFriendsAdapter extends BaseAdapter implements OnClickListener { 

    private ArrayList<UiD_UserFriend> mItems; 
    private Context mContext; 
    private FragmentManager mFragmentManager; 

    public MyFriendsAdapter(Context context, ArrayList<UiD_UserFriend> items, FragmentManager fragmentManager) { 
     mContext = context; 
     mItems = items; 
     mFragmentManager = fragmentManager; 
    } 

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

    @Override 
    public Object getItem(int position) { 
     return mItems.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View currentView, ViewGroup viewGroup) { 
     Holder holder = null; 
     if (currentView == null) { 
      currentView = View.inflate(mContext, R.layout.view_list_item_myfriends, null); 
      holder = new Holder(); 
      holder.textViewUserName = (TextView) currentView.findViewById(R.id.textViewFriendName); 
      holder.mMyFriendspager = (ViewPager) currentView.findViewById(R.id.pagerMyFriendHabits); 
      currentView.setTag(holder); 
     } else { 
      holder = (Holder) currentView.getTag(); 
     } 

     holder.textViewUserName.setText(mItems.get(position).getmName()); 
     MyFriendPagerAdapter tempMyFriendPagerAdapter = new MyFriendPagerAdapter(mFragmentManager, mItems.get(position).getFriendHabits()); 
     holder.mMyFriendspager.setAdapter(tempMyFriendPagerAdapter); 

     return currentView; 
    } 

    class Holder { 
     TextView textViewUserName; 
     ViewPager mMyFriendspager; 
    } 
} 

Questo è il mio adattatore per cercapersone:

public class MyFriendPagerAdapter extends FragmentPagerAdapter { 

    private ArrayList<UiD_Habit> mHabits; 

    public MyFriendPagerAdapter(FragmentManager fm, ArrayList<UiD_Habit> habits) { 
     super(fm); 
     mHabits = habits; 
    } 

    @Override 
    public Fragment getItem(int index) { 
     return new FragmentMyFriendPage(mHabits.get(index)); 
    } 

    @Override 
    public int getCount() { 
     return mHabits.size(); 
    } 
} 
+0

hey può u condividere il codice completo per questa implementazione. thnx –

+0

Come hai risolto il problema, sto affrontando lo stesso problema in recycler-view – Dory

risposta

27

Ogni volta che è necessario aggiungere in modo dinamico i cercapersone, è necessario impostare un ID per ciascun cercapersone utilizzando ViewPager.setId().

+1

Un buon modo per far rispettare gli ID univoci è dichiararli come numeri interi o altre risorse in un file xml e quindi avvolgerlo con un provider in Java. – greg7gkb

+1

Liren Peretz: dove setId() per viewPager? Sto facendo la stessa cosa e ho lo stesso problema. –

+1

Dove si creano i cercapersone, il problema è che si crea una visualizzazione dinamica dei cercapersone e che non hanno un ID. –

3

ho creato campione app

Esempio ViewPager con frammento: https://dl.dropboxusercontent.com/u/20178650/builds/listviewwithviewpager.zip

ma c'è un grande svantaggio. Tutte le cellule sono memorizzati nella memoria, e l'applicazione può bloccarsi con poca memoria, se si dispone di un sacco di cellule

EDIT:

Empiricamente è stato trovato. Se usi semplicemente visualizza invece il frammento in ViewPager. Posso scrivere un adattatore in modo corretto e non essere colpito con la memoria

Esempio ViewPager con vista: https://dl.dropboxusercontent.com/u/20178650/builds/listviewwithviewpager_v2.zip

Spero che qualcuno possa aiutare

+0

awesome esempio thanx ... può essere d'aiuto anche qui? http://stackoverflow.com/questions/27200546/mediaplayer-inside-viewpager-fragment –

+0

Grazie! Aiuta molto !! Ho votato per tutte le tue risposte. – Zikkoua

-3

ho affrontato esattamente lo stesso problema. Soluzioni:

  1. Usa Holder
  2. tag utilizza
  3. Generare ID univoco

ho risolto il problema. Se qualcuno ha bisogno di codice, per favore mandami un messaggio.

+0

Puoi dirci come è stato risolto con qualche codice di esempio. – Dory

+0

Per favore mostraci come hai fatto? –

+0

Aggiunto codice sorgente. Dory e Dr. aDRO si prega di consultare la risposta. –

0
/// <summary> 
    /// To Improve ListView Memory Optimization 
    /// </summary> 
    public class ViewPageHolder : Java.Lang.Object 
    { 
     public TextView _firstTextView{ get; set; } 
     public ViewPager _ViewPager { get; set; } 
     public CirclePageIndicator _CirclePageIndicator { get; set; } 
    } 
Queue<int> _pagerId= new Queue<int>(Enumerable.Range(10, 100));//To set a Unique Id to View Pager to avoid ListView Recycle memory issue 




public override View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent) 
     { 
      View view = convertView; 
      ViewPageHolder ViewPageHolder = null; 

     if (view != null) 
     { 
      ViewPageHolder = view.Tag as ViewPageHolder ; 
     } 
     if (ViewPageHolder == null) 
     { 
      ViewPageHolder = new ViewPageHolder(); 
      view = Context.LayoutInflater.Inflate(Resource.Layout.SystemListLayout, null); 
      ViewPageHolder .SystemNameTextView = view.FindViewById<TextView>(Resource.Id.SystemNameTextView); 
      //View Pager 
      ViewPageHolder._ViewPager = view.FindViewById<ViewPager>(Resource.Id.viewPager); 
      //Circle Pager Indicator 
      ViewPageHolder.CirclePageIndicator = view.FindViewById<CirclePageIndicator>(Resource.Id.viewPageIndicator); 
      ViewPageHolder._ViewPager.Id = _pagerId.Dequeue(); 
      ViewPageHolder._ViewPager.Adapter = new ZoneRenameViewPagerFragmentAdapter(fm, Context, List.ElementAt(position).Zones.ToList(), ((BaseActivity)Context).IsTablet); 
      ViewPageHolder.CirclePageIndicator.SetViewPager(ZoneRenameHolder.ZoneRenameViewPager); 
      view.Tag = ZoneRenameHolder; 
     } 
     return view; 
    } 
  1. Usa Holder
  2. tag utilizza
  3. generare ID univoco
Problemi correlati