So implementieren Sie einen ViewPager mit verschiedenen Fragmenten / Layouts


191

Wenn ich eine Aktivität starte, die Viewpager implementiert, hat der Viewpager verschiedene Fragmente erstellt. Ich möchte für jedes Fragment unterschiedliche Layouts verwenden, aber das Problem ist, dass der Viewpager maximal zwei Layouts anzeigt (zweites Layout für alle verbleibenden Fragmente nach 1).

Hier ist der Code für SwipeActivity, der den Viewpager implementiert:

public class SwipeActivity extends FragmentActivity
{

    MyPageAdapter pageAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_swipe);
        pageAdapter = new MyPageAdapter(getSupportFragmentManager());
        ViewPager pager=(ViewPager)findViewById(R.id.pager);
        pager.setAdapter(pageAdapter);
        ActionBar bar = getActionBar();
        bar.setDisplayHomeAsUpEnabled(true);
    }
    /**
    * Custom Page adapter
    */
    private class MyPageAdapter extends FragmentPagerAdapter
    {
        public MyPageAdapter(FragmentManager fm)
        {
            super(fm);
        }
        @Override
        public int getCount()
        {
            return 5;
        }
        @Override
        public Fragment getItem(int position)
        {
            switch(position)
            {
                case 0: return new MyFragment();
                case 1: return SecondFragment.newInstance("asdasd");
                default : return RamFragment.newInstance("s");
            }
        }
     }
}

Hier ist der Code für die Fragmente

public class MyFragment extends Fragment
{
   @Override
   public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup,    Bundle paramBundle)
   {
     return paramLayoutInflater.inflate(R.layout.processorlayout, paramViewGroup, false);
   }
}

Ich habe 5 Fragmente wie dieses verwendet, die alle unterschiedliche Layouts haben, aber der Viewpager zeigt maximal 2 an.

EDIT : Code für SecondFragment

public class SecondFragment extends Fragment
{
   public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE";

  public static final SecondFragment newInstance(String paramString)
  {
    SecondFragment f = new SecondFragment();
    Bundle localBundle = new Bundle(1);
    localBundle.putString("EXTRA_MESSAGE", paramString);
    f.setArguments(localBundle);
    return f;
  }

  @Override
  public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle)
  {
     return paramLayoutInflater.inflate(R.layout.motherboardlayout, paramViewGroup, false);
  }
}

Ich erhalte einen Typ-Mismatch-Fehler. Kannst du dir meinen Beitrag ansehen? stackoverflow.com/questions/28334800/…
Schardt12


Was ist das Problem Ihres Codes so?
user1510006

Hallo, Sie können diesen Beitrag sehr einfache Antwort mit vollständigem Code lesen .
Nirmal Dhara

Antworten:


516

Da dies eine sehr häufig gestellte Frage ist, wollte ich mir die Zeit und Mühe nehmen, den ViewPager mit mehreren Fragmenten und Layouts im Detail zu erklären. Bitte schön.

ViewPager mit mehreren Fragmenten und Layoutdateien - Gewusst wie

Das folgende Beispiel zeigt, wie Sie einen ViewPager mit verschiedenen Fragmenttypen und verschiedenen Layoutdateien implementieren.

In diesem Fall habe ich 3 Fragmentklassen und eine andere Layoutdatei für jede Klasse. Um die Dinge einfach zu halten, unterscheiden sich die Fragment-Layouts nur in ihrer Hintergrundfarbe . Natürlich kann jede Layoutdatei für die Fragmente verwendet werden.

FirstFragment.java hat ein orangefarbenes Hintergrundlayout, SecondFragment.java hat ein grünes Hintergrundlayout und ThirdFragment.java hat ein rotes Hintergrundlayout. Darüber hinaus zeigt jedes Fragment einen anderen Text an, je nachdem, aus welcher Klasse es stammt und aus welcher Instanz es stammt.

Beachten Sie auch, dass ich das Fragment der Support-Bibliothek verwende: android.support.v4.app.Fragment

MainActivity.java (Initialisiert den Viewpager und verfügt über den Adapter als innere Klasse). Schauen Sie sich noch einmal die Importe an . Ich benutze das android.support.v4Paket.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
    }

    private class MyPagerAdapter extends FragmentPagerAdapter {

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int pos) {
            switch(pos) {

            case 0: return FirstFragment.newInstance("FirstFragment, Instance 1");
            case 1: return SecondFragment.newInstance("SecondFragment, Instance 1");
            case 2: return ThirdFragment.newInstance("ThirdFragment, Instance 1");
            case 3: return ThirdFragment.newInstance("ThirdFragment, Instance 2");
            case 4: return ThirdFragment.newInstance("ThirdFragment, Instance 3");
            default: return ThirdFragment.newInstance("ThirdFragment, Default");
            }
        }

        @Override
        public int getCount() {
            return 5;
        }       
    }
}

activity_main.xml (Die .xml-Datei von MainActivitys) - eine einfache Layoutdatei, die nur den ViewPager enthält, der den gesamten Bildschirm ausfüllt.

<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />

Die Fragmentklassen FirstFragment.java importieren android.support.v4.app.Fragment;

public class FirstFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.first_frag, container, false);

        TextView tv = (TextView) v.findViewById(R.id.tvFragFirst);
        tv.setText(getArguments().getString("msg"));

        return v;
    }

    public static FirstFragment newInstance(String text) {

        FirstFragment f = new FirstFragment();
        Bundle b = new Bundle();
        b.putString("msg", text);

        f.setArguments(b);

        return f;
    }
}

first_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_orange_dark" >

    <TextView
        android:id="@+id/tvFragFirst"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="26dp"
        android:text="TextView" />
</RelativeLayout>

SecondFragment.java

public class SecondFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.second_frag, container, false);

    TextView tv = (TextView) v.findViewById(R.id.tvFragSecond);
    tv.setText(getArguments().getString("msg"));

    return v;
}

public static SecondFragment newInstance(String text) {

    SecondFragment f = new SecondFragment();
    Bundle b = new Bundle();
    b.putString("msg", text);

    f.setArguments(b);

    return f;
}
}

second_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_dark" >

    <TextView
        android:id="@+id/tvFragSecond"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="26dp"
        android:text="TextView" />

</RelativeLayout>

ThirdFragment.java

public class ThirdFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.third_frag, container, false);

    TextView tv = (TextView) v.findViewById(R.id.tvFragThird);      
    tv.setText(getArguments().getString("msg"));

    return v;
}

public static ThirdFragment newInstance(String text) {

    ThirdFragment f = new ThirdFragment();
    Bundle b = new Bundle();
    b.putString("msg", text);

    f.setArguments(b);

    return f;
}
}

Third_Frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_red_light" >

    <TextView
        android:id="@+id/tvFragThird"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="26dp"
        android:text="TextView" />

</RelativeLayout>

Das Endergebnis ist das Folgende:

Der Viewpager enthält 5 Fragmente, Fragmente 1 sind vom Typ FirstFragment und zeigen das Layout first_frag.xml an, Fragment 2 ist vom Typ SecondFragment und zeigt die zweite_frag.xml an, und Fragment 3-5 sind vom Typ ThirdFragment und alle zeigen die dritte_frag.xml an .

Geben Sie hier die Bildbeschreibung ein

Oben sehen Sie die 5 Fragmente, zwischen denen Sie durch Wischen nach links oder rechts wechseln können. Natürlich kann immer nur ein Fragment gleichzeitig angezeigt werden.

Zu guter Letzt:

Ich würde empfehlen, dass Sie in jeder Ihrer Fragmentklassen einen leeren Konstruktor verwenden.

Verwenden Sie die newInstance(...)Methode und die Bundlezur Übergabe von Parametern, anstatt potenzielle Parameter über den Konstruktor zu übergeben.

Auf diese Weise kann der Objektstatus über die Argumente gespeichert werden, wenn er getrennt und erneut angehängt wird. Ähnlich wie Bundlesan Intents.


7
@PhilippJahoda tolle Antwort, danke. Ich möchte eine Sache , wenn auch erwähnen, wenn die ViewPager in einem Fragment als definiert ist getSupportChildFragmentManager () sollte statt getSupportFragmentManager () verwendet werden , wenn der Adapter zu schaffen. Andernfalls wird der Code unterbrochen, wenn die Ausrichtung geändert wird.
guy.gc

5
Ja, das ist richtig. In meinem Beispiel ist der ViewPager jedoch in einer Aktivität definiert, und daher ist getSupportFragmentManager () geeignet. Außerdem existiert die Methode getSupportChildFragmentManager () nicht. Ich gehe davon aus, dass Sie sich auf getChildFragmentManager () beziehen.
Philipp Jahoda

1
Sie können den ViewPager mit nativen Fragmenten verwenden, wenn Sie das v13-Support Package verwenden. developer.android.com/reference/android/support/v13/app/…
Philipp Jahoda

1
Ist dies ab Android Lollipop 5.0 noch gültig?
Orkun Ozen

5
In Ihrer MyPagerAdapter -> getItem (int pos) -Methode erhalten Sie immer eine neue Instanz des Zielfragments (basierend auf dem pos-Wert). Jedes Mal, wenn Sie Ihr Gerät drehen (Orientierungsänderung), wird die Methode getItem aufgerufen und es werden immer wieder Fragmente erstellt. Sie werden jedoch bei der Erstellung im Fragment-Manager gespeichert. Ich denke, Sie sollten überprüfen, ob sie bereits im Fragment-Manager vorhanden sind, denn wenn Sie dies nicht tun, verschwenden Sie Speicher. Siehe pastebin.com/0bJc9mHA
rekt0x

8

Erstellen Sie ein Array von Ansichten und wenden Sie es an: container.addView(viewarr[position]);

public class Layoutes extends PagerAdapter {

    private Context context;
    private LayoutInflater layoutInflater;
    Layoutes(Context context){
        this.context=context;
    }
    int layoutes[]={R.layout.one,R.layout.two,R.layout.three};
    @Override
    public int getCount() {
        return layoutes.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return (view==(LinearLayout)object);
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position){
        layoutInflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View one=layoutInflater.inflate(R.layout.one,container,false);
        View two=layoutInflater.inflate(R.layout.two,container,false);
        View three=layoutInflater.inflate(R.layout.three,container,false);
        View viewarr[]={one,two,three};
        container.addView(viewarr[position]);
        return viewarr[position];
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object){
        container.removeView((LinearLayout) object);
    }

}

Wir können Layouts in ViewPager aufblasen, indem wir ein Array von Ansichten erstellen.
Akash Ingle

6

Code zum Hinzufügen eines Fragments

public Fragment getItem(int position) {

    switch (position){
        case 0:
            return new Fragment1();

        case 1:
            return new Fragment2();

        case 2:
            return new Fragment3();

        case 3:
            return new Fragment4();

        default:
            break;
    }

    return null;
}

Erstellen Sie eine XML-Datei für jedes Fragment, z. B. für Fragment1, verwenden Sie fragment_one.xml als Layoutdatei und verwenden Sie den folgenden Code in der Java-Datei Fragment1.

public class Fragment1 extends Fragment {

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_one, container, false);

        return view;

    }
}

Später können Sie notwendige Korrekturen vornehmen. Es hat bei mir funktioniert.


4

Grundlegendes ViewPager-Beispiel

Diese Antwort ist eine Vereinfachung der Dokumentation , dieses Tutorials und der akzeptierten Antwort . Ziel ist es, die Arbeit ViewPagerso schnell wie möglich zum Laufen zu bringen . Danach können weitere Änderungen vorgenommen werden.

Geben Sie hier die Bildbeschreibung ein

XML

Fügen Sie die XML-Layouts für die Hauptaktivität und für jede Seite (Fragment) hinzu. In unserem Fall verwenden wir nur ein Fragmentlayout. Wenn Sie jedoch unterschiedliche Layouts auf den verschiedenen Seiten haben, erstellen Sie für jedes ein Layout.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.verticalviewpager.MainActivity">

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

</RelativeLayout>

fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textview"
        android:textSize="30sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

Code

Dies ist der Code für die Hauptaktivität. Es schließt die PagerAdapterund FragmentOneals innere Klassen ein. Wenn diese zu groß werden oder Sie sie an anderen Orten wiederverwenden, können Sie sie in ihre eigenen Klassen verschieben.

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class MainActivity extends AppCompatActivity {

    static final int NUMBER_OF_PAGES = 2;

    MyAdapter mAdapter;
    ViewPager mPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mAdapter = new MyAdapter(getSupportFragmentManager());
        mPager = findViewById(R.id.viewpager);
        mPager.setAdapter(mAdapter);
    }

    public static class MyAdapter extends FragmentPagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUMBER_OF_PAGES;
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    return FragmentOne.newInstance(0, Color.WHITE);
                case 1:
                    // return a different Fragment class here
                    // if you want want a completely different layout
                    return FragmentOne.newInstance(1, Color.CYAN);
                default:
                    return null;
            }
        }
    }

    public static class FragmentOne extends Fragment {

        private static final String MY_NUM_KEY = "num";
        private static final String MY_COLOR_KEY = "color";

        private int mNum;
        private int mColor;

        // You can modify the parameters to pass in whatever you want
        static FragmentOne newInstance(int num, int color) {
            FragmentOne f = new FragmentOne();
            Bundle args = new Bundle();
            args.putInt(MY_NUM_KEY, num);
            args.putInt(MY_COLOR_KEY, color);
            f.setArguments(args);
            return f;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mNum = getArguments() != null ? getArguments().getInt(MY_NUM_KEY) : 0;
            mColor = getArguments() != null ? getArguments().getInt(MY_COLOR_KEY) : Color.BLACK;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_one, container, false);
            v.setBackgroundColor(mColor);
            TextView textView = v.findViewById(R.id.textview);
            textView.setText("Page " + mNum);
            return v;
        }
    }
}

Fertig

Wenn Sie die drei oben genannten Dateien kopiert und in Ihr Projekt eingefügt haben, sollten Sie in der Lage sein, die App auszuführen und das Ergebnis in der obigen Animation zu sehen.

Weiter geht's

Mit ViewPagers können Sie einige Dinge tun. Weitere Informationen finden Sie unter den folgenden Links:


3

Das ist auch gut so:

<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));

    }
}


public class FragmentTab1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragmenttab1, container, false);
        return rootView;
    }
}

class MyPagerAdapter extends FragmentPagerAdapter{

    public MyPagerAdapter(FragmentManager fragmentManager){
        super(fragmentManager);

    }
    @Override
    public android.support.v4.app.Fragment getItem(int position) {
        switch(position){
            case 0:
                FragmentTab1 fm =   new FragmentTab1();
                return fm;
            case 1: return new FragmentTab2();
            case 2: return new FragmentTab3();
        }
        return null;
    }

    @Override
    public int getCount() {
        return 3;
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/Fragment1" />

</RelativeLayout>

0

Erstellen Sie neue Instanzen in Ihren Fragmenten und tun Sie dies in Ihrer Aktivität

 private class SlidePagerAdapter extends FragmentStatePagerAdapter {
    public SlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position){
            case 0:
                return Fragment1.newInstance();
            case 1:
                return Fragment2.newInstance();
            case 2:
                return Fragment3.newInstance();
            case 3:
                return Fragment4.newInstance();


            default: break;

        }
        return null;
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.