Sök…


Introduktion

ViewPager är en layouthanterare som låter användaren bläddra åt vänster och höger genom datasidor. Det används oftast tillsammans med Fragment, vilket är ett bekvämt sätt att leverera och hantera livscykeln på varje sida.

Anmärkningar

En viktig sak att notera om ViewPager-användning är att det finns två olika versioner av både FragmentPagerAdapter och FragmentStatePagerAdapter .

Om du använder android.app.Fragment ursprungliga fragment med en FragmentPagerAdapter eller FragmentStatePagerAdapter, måste du använda v13-supportbibliotekets versioner av adaptern, dvs. android.support.v13.app.FragmentStatePagerAdapter .

Om du använder android.support.v4.app.Fragment supportbibliotekfragment med en FragmentPagerAdapter eller FragmentStatePagerAdapter, måste du använda versionerna för v4 supportbibliotek av adaptern, dvs android.support.v4.app.FragmentStatePagerAdapter .

Grundläggande ViewPager-användning med fragment

En ViewPager tillåter att visa flera fragment i en aktivitet som kan navigeras genom att antingen vända till vänster eller höger. En ViewPager måste matas antingen av Visningar eller fragment med hjälp av en PagerAdapter .

Det finns dock två mer specifika implementationer som du kommer att hitta mest användbara om du använder Fragment som är FragmentPagerAdapter och FragmentStatePagerAdapter . När ett fragment måste instanseras för första gången, kommer getItem(position) att kallas för varje position som behöver inställas. getCount() returnerar det totala antalet sidor så att ViewPager vet hur många fragment som måste visas.

Både FragmentPagerAdapter och FragmentStatePagerAdapter behåller en cache av de fragment som ViewPager behöver visa. Som standard kommer ViewPager att försöka lagra maximalt 3 fragment som motsvarar det för närvarande synliga fragmentet och de bredvid höger och vänster. Även FragmentStatePagerAdapter behåller tillståndet för vart och ett av dina fragment.

Var medveten om att båda implementeringarna antar att dina fragment kommer att behålla sina positioner, så om du behåller en lista över fragmenten istället för att ha ett statiskt antal av dem som du kan se i getItem() måste du skapa en underklass av PagerAdapter och åsidosätta åtminstone instantiateItem() , destroyItem() och getItemPosition() metoder.

Lägg bara till en ViewPager i din layout som beskrivs i grundexemplet :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout> 
    <android.support.v4.view.ViewPager
        android:id="@+id/vpPager"> 
    </android.support.v4.view.ViewPager>
</LinearLayout>

Definiera sedan adaptern som kommer att avgöra hur många sidor som finns och vilket fragment som ska visas för varje sida i adaptern.

public class MyViewPagerActivity extends AppCompatActivity {
    private static final String TAG = MyViewPagerActivity.class.getName();

    private MyPagerAdapter mFragmentAdapter;
    private ViewPager mViewPager;

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

        //Apply the Adapter
        mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());    
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(mFragmentAdapter);
    }

    private class MyPagerAdapter extends FragmentPagerAdapter{

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

        // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new Fragment1();

                case 1:
                    return new Fragment2();

                case 2:
                    return new Fragment3();

                default:
                    return null;
            }
        }

        // Returns total number of pages    
        @Override
        public int getCount() {
            return 3;
        }

    }
}
3.2.x

Om du använder android.app.Fragment måste du lägga till detta beroende:

compile 'com.android.support:support-v13:25.3.1'

Om du använder android.support.v4.app.Fragment måste du lägga till detta beroende:

compile 'com.android.support:support-fragment:25.3.1'

ViewPager med TabLayout

En TabLayout kan användas för enklare navigering.
Du kan ställa in flikarna för varje fragment i din adapter med hjälp av TabLayout.newTab() men det finns en annan bekvämare och enklare metod för den här uppgiften som är TabLayout.setupWithViewPager() .

Den här metoden synkroniseras genom att skapa och ta bort flikar enligt innehållet i adaptern som är associerad med din ViewPager varje gång du ringer den.
Dessutom ställer den in en återuppringning så att varje gång användaren vänder på sidan kommer motsvarande flik att väljas.

Definiera bara en layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabMode="scrollable" />

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

</LinearLayout>

Implementera sedan FragmentPagerAdapter och applicera den på ViewPager :

public class MyViewPagerActivity extends AppCompatActivity {
    private static final String TAG = MyViewPagerActivity.class.getName();

    private MyPagerAdapter mFragmentAdapter;
    private ViewPager mViewPager;
    private TabLayout mTabLayout;

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

        // Get the ViewPager and apply the PagerAdapter
        mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());    
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(mFragmentAdapter);

        // link the tabLayout and the viewpager together
        mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
        mTabLayout.setupWithViewPager(mViewPager);
    }

    private class MyPagerAdapter extends FragmentPagerAdapter{

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

         // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new Fragment1();

                case 1:
                    return new Fragment2();

                case 2:
                    return new Fragment3();

                default:
                    return null;
            }
        }
        
        // Will be displayed as the tab's label
        @Override
        public CharSequence getPageTitle(int position) {
            switch(position) {
                case 0:
                    return "Fragment 1 title";

                case 1:
                    return "Fragment 2 title";

                case 2:
                    return "Fragment 3 title";

                default:
                    return null;
            }
        }

        // Returns total number of pages 
        @Override
        public int getCount() {
            return 3;
        }

    }
}

ViewPager med PreferenceFragment

Tills nyligen skulle android.support.v4.app.FragmentPagerAdapter förhindra användning av ett PreferenceFragment som ett av de fragment som används i FragmentPagerAdapter.

De senaste versionerna av support v7-biblioteket inkluderar nu klassen PreferenceFragmentCompat , som fungerar med en ViewPager och v4-versionen av FragmentPagerAdapter.

Exempel Fragment som utvidgar PreferenceFragmentCompat :

import android.os.Bundle; 
import android.support.v7.preference.PreferenceFragmentCompat; 
import android.view.View; 
 
public class MySettingsPrefFragment extends PreferenceFragmentCompat { 
  
    public MySettingsPrefFragment() { 
        // Required empty public constructor 
    } 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        addPreferencesFromResource(R.xml.fragment_settings_pref); 
    } 
 
    @Override 
    public void onCreatePreferences(Bundle bundle, String s) { 
 
    } 
}

Du kan nu använda detta fragment i en android.support.v4.app.FragmentPagerAdapter underklass:

private class PagerAdapterWithSettings extends FragmentPagerAdapter {

    public PagerAdapterWithSettings(FragmentManager supportFragmentManager) {
        super(supportFragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0:
                return new FragmentOne();

            case 1:
                return new FragmentTwo();

            case 2:
                return new MySettingsPrefFragment();

            default:
                return null;
        }
    }
    
    // .......

}

Lägga till en ViewPager

Se till att följande beroende läggs till i appens build.gradle fil under beroenden:

compile 'com.android.support:support-core-ui:25.3.0'

Lägg sedan till ViewPager i din aktivitetslayout:

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

Definiera sedan din PagerAdapter :

public class MyPagerAdapter extends PagerAdapter {

    private Context mContext;

    public CustomPagerAdapter(Context context) {
        mContext = context;
    }

    @Override
    public Object instantiateItem(ViewGroup collection, int position) {
 
        // Create the page for the given position. For example:
        LayoutInflater inflater = LayoutInflater.from(mContext);
        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.xxxx, collection, false);
        collection.addView(layout);
        return layout;
    }

    @Override
    public void destroyItem(ViewGroup collection, int position, Object view) {
        // Remove a page for the given position. For example:
        collection.removeView((View) view);
    }

    @Override
    public int getCount() {
        //Return the number of views available.
        return numberOfPages;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        // Determines whether a page View is associated with a specific key object
        // as returned by instantiateItem(ViewGroup, int). For example:
        return view == object;
    }    
}

Slutligen konfigurera ViewPager i din aktivitet:

public class MainActivity extends AppCompatActivity {

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

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new MyPagerAdapter(this));
    }
}

ViewPager med en prickindikator

ViewPager med en prickindikator

Allt vi behöver är: ViewPager , TabLayout och 2 rader för utvalda och standardprickar.

Först måste vi lägga till TabLayout i vår skärmlayout och ansluta den till ViewPager . Vi kan göra detta på två sätt:


Nested TabLayout i ViewPager

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

    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</android.support.v4.view.ViewPager>

I detta fall TabLayout automatiskt till ViewPager , men TabLayout kommer bredvid ViewPager , inte över honom.


Separera TabLayout

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

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

I det här fallet kan vi placera TabLayout helst, men vi måste ansluta TabLayout till ViewPager programmatiskt

ViewPager pager = (ViewPager) view.findViewById(R.id.photos_viewpager);
PagerAdapter adapter = new PhotosAdapter(getChildFragmentManager(), photosUrl);
pager.setAdapter(adapter);

TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(pager, true);

När vi skapat vår layout måste vi förbereda våra prickar. Så vi skapar tre filer: selected_dot.xml , default_dot.xml och tab_selector.xml .


selected_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@color/colorAccent"/>
        </shape>    
    </item>
</layer-list>

default_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@android:color/darker_gray"/>
        </shape>    
    </item>
</layer-list>

tab_selector.xml

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

    <item android:drawable="@drawable/selected_dot"
          android:state_selected="true"/>

    <item android:drawable="@drawable/default_dot"/>
</selector>

Nu måste vi lägga till bara TabLayout rader med kod till TabLayout i vår xml-layout och du är klar.

app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"

Konfigurera OnPageChangeListener

Om du behöver lyssna efter ändringar på den valda sidan kan du implementera ViewPager.OnPageChangeListener lyssnaren på ViewPager:

viewPager.addOnPageChangeListener(new OnPageChangeListener() {
    
    // This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
    @Override
    public void onPageSelected(int position) {
         // Your code
    }
    
    // This method will be invoked when the current page is scrolled, either as part of 
    // a programmatically initiated smooth scroll or a user initiated touch scroll.
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
         // Your code
    }
    
    // Called when the scroll state changes. Useful for discovering when the user begins
    // dragging, when the pager is automatically settling to the current page, 
    // or when it is fully stopped/idle.
    @Override
    public void onPageScrollStateChanged(int state) {
         // Your code
    }
});


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow