Cara menerapkan ViewPager dengan Fragmen / Tata Letak yang berbeda

191

Ketika saya memulai aktivitas yang mengimplementasikan viewpager, viewpager membuat berbagai fragmen. Saya ingin menggunakan tata letak yang berbeda untuk setiap fragmen, tetapi masalahnya adalah viewpager hanya menampilkan dua tata letak di max (tata letak kedua pada semua fragmen yang tersisa setelah 1).

Ini adalah kode untuk SwipeActivity yang mengimplementasikan viewpager:

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

Ini adalah kode untuk fragmen

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

Saya menggunakan 5 fragmen seperti ini, semuanya memiliki tata letak yang berbeda, tetapi viewpager hanya menampilkan 2 pada maks.

EDIT : kode untuk 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);
  }
}
Haxor
sumber
Saya mendapatkan kesalahan ketik ketidakcocokan. Bisakah Anda melihat posting saya? stackoverflow.com/questions/28334800/…
Schardt12
Apa masalah kode Anda?
user1510006
Hai Anda dapat membaca posting ini jawaban yang sangat sederhana dengan kode lengkap yang disediakan.
Nirmal Dhara

Jawaban:

516

Karena ini adalah pertanyaan yang sangat sering diajukan, saya ingin meluangkan waktu dan upaya untuk menjelaskan ViewPager dengan beberapa Fragmen dan Tata Letak secara terperinci. Ini dia

ViewPager dengan beberapa file Fragmen dan Tata Letak - Cara

Berikut ini adalah contoh lengkap tentang bagaimana menerapkan ViewPager dengan Jenis fragmen yang berbeda dan file tata letak yang berbeda.

Dalam hal ini, saya memiliki 3 kelas Fragmen, dan file tata letak yang berbeda untuk setiap kelas. Agar hal-hal sederhana, tata letak fragmen-hanya berbeda dalam warna latar belakang mereka . Tentu saja, setiap file layout dapat digunakan untuk Fragmen.

FirstFragment.java memiliki tata letak latar belakang oranye , SecondFragment.java memiliki tata letak latar belakang hijau dan ThirdFragment.java memiliki tata letak latar belakang merah . Selanjutnya, setiap Fragmen menampilkan teks yang berbeda, tergantung dari kelas mana dan dari mana itu.

Perlu diketahui juga bahwa saya menggunakan fragmen dukungan-perpustakaan: android.support.v4.app.Fragment

MainActivity.java (Menginisialisasi Viewpager dan memiliki adaptor untuknya sebagai kelas dalam). Sekali lagi lihat impor . Saya menggunakan 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 (File MainActivitys .xml) - file tata letak sederhana, hanya berisi ViewPager yang memenuhi seluruh layar.

<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"
    />

Kelas Fragmen, FirstFragment.java mengimpor 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>

Hasil akhirnya adalah sebagai berikut:

Viewpager memegang 5 Fragmen, Fragmen 1 bertipe FirstFragment, dan menampilkan tata letak first_frag.xml, Fragmen 2 bertipe SecondFragment dan menampilkan second_frag.xml, dan Fragmen 3-5 bertipe ThirdFragment dan semua menampilkan third_frag.xml .

masukkan deskripsi gambar di sini

Di atas Anda dapat melihat 5 Fragmen di antaranya dapat diaktifkan melalui gesek ke kiri atau kanan. Hanya satu Fragmen yang bisa ditampilkan pada saat yang bersamaan tentunya.

Terakhir tapi bukan yang akhir:

Saya akan merekomendasikan agar Anda menggunakan konstruktor kosong di setiap kelas Fragmen Anda.

Alih-alih menyerahkan parameter potensial melalui konstruktor, gunakan newInstance(...)metode dan Bundleuntuk menyerahkan parameter.

Dengan cara ini jika terlepas dan dilampirkan kembali keadaan objek dapat disimpan melalui argumen. Sangat mirip Bundlesdengan Intents.

Philipp Jahoda
sumber
7
@ PhilippJahoda jawaban yang bagus, terima kasih. Saya ingin menyebutkan satu hal, jika ViewPager didefinisikan dalam Fragmen daripada getSupportChildFragmentManager () harus digunakan daripada getSupportFragmentManager () saat membuat adaptor. Kalau tidak, kode rusak ketika perubahan orientasi terjadi.
guy.gc
5
Ya itu benar. Tetapi dalam contoh saya, ViewPager didefinisikan dalam suatu Kegiatan, dan karenanya, getSupportFragmentManager () sesuai. Lebih lanjut metode getSupportChildFragmentManager () tidak ada, saya menganggap Anda merujuk ke getChildFragmentManager ().
Philipp Jahoda
1
Anda dapat menggunakan ViewPager dengan fragmen asli saat menggunakan paket dukungan v13. developer.android.com/reference/android/support/v13/app/…
Philipp Jahoda
1
pada Android Lollipop 5.0, apakah ini masih valid?
Orkun Ozen
5
Dalam metode MyPagerAdapter -> getItem (int pos) Anda selalu mendapatkan instance fragmen target baru (berdasarkan nilai pos). Jadi setiap kali Anda memutar perangkat Anda (perubahan orientasi), metode getItem dipanggil dan fragmen dibuat berulang-ulang. Tetapi mereka disimpan di manajer fragmen setelah penciptaan. Saya pikir Anda harus memeriksa apakah mereka sudah ada di manajer fragmen karena jika Anda tidak membuang-buang memori. Lihat pastebin.com/0bJc9mHA
rekt0x
8

Buat larik Tampilan dan terapkan ke: 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);
    }

}
akash ingle
sumber
Kita dapat mengembang tata letak di ViewPager dengan membuat berbagai tampilan.
akash ingle
6

Kode untuk menambahkan fragmen

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

Buat file xml untuk setiap fragmen katakanlah untuk Fragment1, gunakan fragment_one.xml sebagai file layout, gunakan kode di bawah ini dalam file java 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;

    }
}

Kemudian Anda dapat melakukan koreksi yang diperlukan .. Ini berhasil untuk saya.

sushh
sumber
4

Contoh Tampilan Dasar

Jawaban ini adalah penyederhanaan dokumentasi , tutorial ini , dan jawaban yang diterima . Tujuannya adalah untuk mendapatkan kerja ViewPagerdan berlari secepat mungkin. Pengeditan lebih lanjut dapat dilakukan setelah itu.

masukkan deskripsi gambar di sini

XML

Tambahkan tata letak xml untuk aktivitas utama dan untuk setiap halaman (fragmen). Dalam kasus kami, kami hanya menggunakan satu tata letak fragmen, tetapi jika Anda memiliki tata letak yang berbeda pada halaman yang berbeda maka cukup buat satu untuk masing-masing.

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>

Kode

Ini adalah kode untuk aktivitas utama. Ini termasuk PagerAdapterdan FragmentOnesebagai kelas batin. Jika ini terlalu besar atau Anda menggunakannya kembali di tempat lain, maka Anda dapat memindahkannya ke kelas masing-masing.

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

Jadi

Jika Anda menyalin dan menempelkan ketiga file di atas ke proyek Anda, Anda harus dapat menjalankan aplikasi dan melihat hasilnya dalam animasi di atas.

Sedang terjadi

Ada beberapa hal yang dapat Anda lakukan dengan ViewPagers. Lihat tautan berikut untuk memulai:

Suragch
sumber
3

Ini juga baik:

<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>
Ashutoshg
sumber
0

Buat instance baru di fragmen Anda dan lakukan seperti itu di Aktivitas Anda

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