1

J'ai commencé à utiliser Android Studio et à apprendre le Java il n'y a pas si longtemps et je suis maintenant bloqué sur l'application d'adaptateurs à différents ViewPager. Je n'ai pas assez de connaissances pour résoudre moi-même le problème de comportement de ces composants et serai reconnaissant de votre aide. (Désolé pour mon anglais)FragmentPagerAdapter à ViewPager

L'idée est:

1) Une colonne d'enregistrements (comme dans Instagram), qui peut être défilée up-down; 2) Chaque enregistrement comporte un bloc d'images pouvant être défilées de gauche à droite et un bloc de texte;

Comment est organisé (voir capture d'écran aussi):

1) (main.xml) Sur la mise en page principale (ConstraintLayout) il y a nestedScrollView, dans lequel je LinearLayout inclus (records.xml). C'est la colonne des enregistrements.

2) LinearLayout est rempli d'enregistrements en cycle (record.xml). Chaque enregistrement est ConstraintLayout, qui contient ViewPager et TextView.

3) Dans chaque nouvel enregistrement ajouté, j'essaie de trouver ViewPager, à qui j'ai assigné l'adaptateur avec setAdapter (new MyFragmentPagerAdapter (getSupportFragmentManager())).

4) MyFragmentPagerAdapter lorsqu'il s'agit d'appels getItem RecordImageFragment.newInstance, créant un nouveau fragment (RecordImageFragment.java).

5) Chaque RecordImageFragment place FrameLayout (record_images_pager.xml), y trouve ImageView et y place une image.

Captures d'écran:

app running

project structure

Le problème est:

Toutes les oeuvres, mais les images sont visibles que dans le premier enregistrement. Lorsque l'enregistrement est créé, je trouve également TextView ici (record.xml) et y définir le texte. Les textes diffèrent d'un enregistrement à l'autre (c'est bien), mais seulement le premier ViewPager dans le premier enregistrement a des images. Bien que l'adaptateur (MyFragmentPagerAdapter) fonctionne dans tous les appels ViewPager, OnPageChangeListener, position de suivi: 0-2. Après recherche, il s'est avéré que RecordImageFragment pense que le premier enregistrement est son ViewGroup.getRootView(). GetRootView() (pas l'enregistrement auquel l'adaptateur a été défini). Jusqu'à présent, j'essaie de comprendre pourquoi le contenu (record_images_pager.xml) du fragment (RecordImageFragment.java) n'est pas ajouté au ViewPager, auquel l'adaptateur a été défini, mais au premier.

MainActivity.java

package example; 
 

 
import android.os.*; 
 
import android.support.v4.app.*; 
 
import android.support.v4.view.*; 
 
import android.support.v7.app.AppCompatActivity; 
 
import android.util.*; 
 
import android.view.*; 
 
import android.widget.*; 
 

 
public class MainActivity extends AppCompatActivity { 
 
\t @Override 
 
    protected void onCreate(Bundle savedInstanceState) 
 
\t { 
 
\t \t super.onCreate(savedInstanceState); 
 
\t \t setContentView(R.layout.main); 
 
\t \t addRecords(); 
 
\t } 
 
\t 
 
\t public void addRecords() 
 
\t { 
 
\t \t for (int j = 1; j <= 10; j++ ) 
 
\t \t { 
 
\t \t \t addNewRecord(j); 
 
\t \t } 
 
\t } 
 
\t public void addNewRecord(int id) 
 
\t { 
 
\t \t LinearLayout records = (LinearLayout) findViewById(R.id.records); 
 
\t \t // Add new record 
 
\t \t LayoutInflater inflater = getLayoutInflater(); 
 
\t \t View record = inflater.inflate(R.layout.record, null, false); 
 
\t \t records.addView(record); 
 
\t \t // Set text to text field 
 
\t \t TextView title_tv = (TextView) record.findViewById(R.id.title); 
 
\t \t title_tv.setText("Запись " + id); 
 
\t \t //Find ViewPager, add adapter and page change listener 
 
\t \t ViewPager pager = (ViewPager) record.findViewById(R.id.pager); 
 
\t \t pager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager())); 
 
\t \t pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() 
 
\t \t { 
 
\t \t \t @Override 
 
\t \t \t public void onPageSelected(int position) { Log.d("example", "Картинка сменилась на: " + position);} 
 
\t \t \t @Override 
 
\t \t \t public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} 
 
\t \t \t @Override 
 
\t \t \t public void onPageScrollStateChanged(int state) {} 
 
\t \t }); 
 
\t } 
 
\t 
 
\t private class MyFragmentPagerAdapter extends FragmentPagerAdapter 
 
\t { 
 
\t \t int[] internalPicts = {R.drawable.pict1, R.drawable.pict2, R.drawable.pict3}; 
 
\t \t public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } 
 
\t \t @Override 
 
\t \t public Fragment getItem(int pos) { return RecordImageFragment.newInstance(internalPicts[pos]); } 
 
\t \t @Override 
 
\t \t public int getCount() { 
 
\t \t \t return internalPicts.length; 
 
\t \t } 
 
\t } 
 
}

RecordImageFragment.java

package example; 
 

 
import android.os.Bundle; 
 
import android.support.v4.content.*; 
 
import android.view.LayoutInflater; 
 
import android.view.View; 
 
import android.view.ViewGroup; 
 
import android.widget.ImageView; 
 

 
public class RecordImageFragment extends android.support.v4.app.Fragment { 
 
    @Override 
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
 
     View layoutWithImage = inflater.inflate(R.layout.record_images_pager, container, false); 
 
\t \t //Find ImageView on layout and place drawable there 
 
\t \t ImageView image = (ImageView) layoutWithImage.findViewById(R.id.image); 
 
\t \t int imgId = getArguments().getInt("img"); 
 
\t \t image.setImageDrawable(ContextCompat.getDrawable(getActivity(), imgId)); 
 
    \t return layoutWithImage; 
 
    } 
 

 
    public static RecordImageFragment newInstance(int image) { 
 
\t \t RecordImageFragment f = new RecordImageFragment(); 
 
     Bundle b = new Bundle(); 
 
     b.putInt("img", image); 
 
\t \t f.setArguments(b); 
 
     return f; 
 
    } 
 
}

Répondre

1

Enfin, après des heures de recherche et d'essayer. J'ai trouvé une réponse. Le problème est très subtil. Le problème réside avec votre adaptateur, vous utilisez un FragmentManager dans votre adaptateur pour gérer les fragments. Dans la suite (deuxième ou troisième rangée) je pense que le FragmentPagerAdapter ne considère pas les éléments retournés par la méthode getItem() comme de nouveaux fragments. Donc vous ne les voyez pas du tout. Cela pourrait probablement être parce que vous utilisez le même FragmentManager pour gérer l'adaptateur.

La solution serait de supprimer complètement le FragmentManager en utilisant le PagerAdapter de base et en mettant en œuvre instantiateItem() et destroyItem() vous-même. Cela élimine les besoins de Fragments et vous pouvez simplement gonfler les vues de l'image vous-même.

Voici le nouveau MyPagerAdapter que vous devez mettre à la place du MyFragmentPagerAdapter.

private class MyPagerAdapter extends PagerAdapter { 
     int[] internalPicts = {R.drawable.dashboard, R.drawable.icon, R.drawable.mockup}; 

     public MyPagerAdapter() { 
      super(); 
     } 

     @Override 
     public int getCount() { 
      return internalPicts.length; 
     } 

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

     @Override 
     public Object instantiateItem(ViewGroup collection, int position) { 

      // Inflating layout 
      LayoutInflater inflater = (LayoutInflater) collection.getContext() 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

      View view = inflater.inflate(R.layout.record_images_pager, null); 

      ImageView image = (ImageView) view.findViewById(R.id.image); 

      image.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), internalPicts[position])); 

      collection.addView(view, 0); 
      return view; 

     } 

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

A la fin assurez-vous de remplacer pager.setAdapter(new MyFragmentPagerAdapter()); par pager.setAdapter(new MyPagerAdapter());

Vous n'avez pas besoin RecordImageFragment aussi.

Testé dans Android Studio. Je lis this pour référence. Astuce - Utilisez ListView avec un adaptateur personnalisé au lieu d'un simple LinearLayout pour placer tous vos viewpagers pour un défilement fluide.