1

Ich habe begonnen, Android Studio zu verwenden und Java vor nicht allzu langer Zeit zu lernen, und stachelte jetzt auf das Anwenden von Adaptern auf different ViewPager. Ich habe nicht genug Kenntnisse, um das Verhaltensproblem solcher Komponenten selbst zu lösen, und werde Ihnen für Ihre Hilfe dankbar sein. (Sorry für mein Englisch)FragmentPagerAdapter zu ViewPager

Die Idee ist:

1) Eine Spalte von Datensätzen (wie in Instagram), die nach oben nach unten gescrollt werden kann;

2) Jeder Datensatz enthält einen Bildblock, der von links nach rechts gescrollt werden kann, und einen Textblock;

Wie es organisiert ist (siehe Screenshot auch):

1) (main.xml) Auf dem Haupt Layout (ConstraintLayout) gibt es nestedScrollView, in dem ich Linearlayout enthalten (records.xml). Dies ist die Spalte der Datensätze.

2) LinearLayout ist mit Datensätzen in Zyklus gefüllt (record.xml). Jeder Datensatz ist ConstraintLayout, das ViewPager und TextView enthält.

3) In jedem neu hinzugefügten Datensatz versuche ich ViewPager zu finden, den ich mit setAdapter (new MyFragmentPagerAdapter (getSupportFragmentManager())) adapter setze.

4) MyFragmentPagerAdapter, wenn getItem kommt, ruft RecordImageFragment.newInstance auf und erstellt ein neues Fragment (RecordImageFragment.java).

5) Jedes RecordImageFragment platziert FrameLayout (record_images_pager.xml), findet ImageView darin und speichert das Bild dort.

Screenshots:

app running

project structure

Das Problem ist:

Alle Arbeiten, aber Bilder werden nur in der ersten Aufzeichnung gesehen. Wenn der Datensatz erstellt wird, finde ich dort auch TextView (record.xml) und setze Text darauf. Texte unterscheiden sich von Datensatz zu Datensatz (das ist gut), aber nur der erste ViewPager im ersten Datensatz hat Bilder. Obwohl Adapter (MyFragmentPagerAdapter) in jedem ViewPager funktioniert, ruft OnPageChangeListener auf, Tracing-Position: 0-2. Nach Recherchen stellte sich heraus, dass RecordImageFragment denkt, dass der erste Datensatz seine ViewGroup.getRootView(). GetRootView() ist (nicht der Datensatz, auf den der Adapter gesetzt wurde). Bis jetzt versuche ich herauszufinden, warum der Inhalt (record_images_pager.xml) des Fragments (RecordImageFragment.java) nicht zum ViewPager hinzugefügt wurde, auf den der Adapter gesetzt wurde, sondern zum ersten.

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; 
 
    } 
 
}

Antwort

1

Endlich, nach Stunden des Suchens und versuchen. Ich habe eine Antwort gefunden. Das Problem ist sehr subtil. Das Problem liegt bei Ihrem Adapter, Sie verwenden einen FragmentManager in Ihrem Adapter, um die Fragmente zu verwalten. In der folgenden (zweiten oder dritten Zeile) denke ich, dass die FragmentPagerAdapter die von der getItem()-Methode zurückgegebenen Elemente nicht als neue Fragmente betrachtet. Sie sehen sie also überhaupt nicht. Dies könnte möglicherweise daran liegen, dass Sie denselben FragmentManager verwenden, um den Adapter zu verwalten.

Die Lösung wäre, den FragmentManager komplett zu beseitigen, indem Sie die Basis PagerAdapter verwenden und instantiateItem() und destroyItem() selbst implementieren. Dies eliminiert die Notwendigkeit von Fragmenten und Sie können die Bildansichten einfach selbst aufblasen.

Hier ist die neue MyPagerAdapter müssen Sie anstelle der MyFragmentPagerAdapter setzen.

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); 
     } 
    } 

Am Ende stellen Sie sicher, pager.setAdapter(new MyFragmentPagerAdapter()); von pager.setAdapter(new MyPagerAdapter());

Sie RecordImageFragment auch nicht ersetzen müssen.

Getestet in Android Studio.

Ich lese this als Referenz.

Tipp - Verwenden Sie ListView mit einem benutzerdefinierten Adapter anstelle eines einfachen LinearLayout, um alle Ihre Viewpager für reibungsloses Scrollen zu platzieren.

Verwandte Themen