Поиск…


Вступление

ViewPager - это менеджер макетов, который позволяет пользователю листать страницы слева и справа. Он чаще всего используется совместно с Fragment, что является удобным способом обеспечения и управления жизненным циклом каждой страницы.

замечания

Важно отметить, что использование ViewPager состоит в том, что существуют две разные версии FragmentPagerAdapter и FragmentStatePagerAdapter .

Если вы используете android.app.Fragment native Fragments с помощью FragmentPagerAdapter или FragmentStatePagerAdapter, вам нужно использовать версии поддержки библиотеки v13 для адаптера, то есть android.support.v13.app.FragmentStatePagerAdapter .

Если вы используете android.support.v4.app.Fragment поддержки android.support.v4.app.Fragment с помощью FragmentPagerAdapter или FragmentStatePagerAdapter, вам нужно использовать версии библиотеки поддержки v4 для адаптера, то есть android.support.v4.app.FragmentStatePagerAdapter .

Использование Basic ViewPager с фрагментами

ViewPager позволяет отображать несколько фрагментов в активности, которые можно перемещать либо влево, либо вправо. ViewPager должен быть фидом либо Представлений, либо фрагментов с помощью PagerAdapter .

Есть, однако, еще две конкретные реализации, которые вы найдете наиболее полезными в случае использования фрагментов, которые являются FragmentPagerAdapter и FragmentStatePagerAdapter . Когда в первый раз необходимо создать экземпляр фрагмента, getItem(position) будет вызываться для каждой позиции, для которой требуется создание экземпляра. Метод getCount() вернет общее количество страниц, чтобы ViewPager знал, сколько фрагментов необходимо ViewPager .

И FragmentPagerAdapter и FragmentStatePagerAdapter хранят кеш фрагментов, которые должен показать ViewPager . По умолчанию ViewPager попытается сохранить максимум 3 фрагмента, соответствующих ViewPager видимому фрагменту, а также рядом с правой и левой. Также FragmentStatePagerAdapter сохранит состояние каждого из ваших фрагментов.

Имейте в виду, что обе реализации предполагают, что ваши фрагменты будут сохранять свои позиции, поэтому, если вы сохраните список фрагментов вместо статического числа из них, как вы можете видеть в методе getItem() , вам нужно будет создать подкласс PagerAdapter и переопределить, по крайней мере, destroyItem() instantiateItem() , destroyItem() и getItemPosition() .

Просто добавьте ViewPager в свой макет, как описано в основном примере :

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

Затем определите адаптер, который определит, сколько страниц существует и какой фрагмент будет отображаться для каждой страницы адаптера.

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

Если вы используете android.app.Fragment вы должны добавить эту зависимость:

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

Если вы используете android.support.v4.app.Fragment вы должны добавить эту зависимость:

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

ViewPager с TabLayout

TabLayout можно использовать для упрощения навигации.
Вы можете установить вкладки для каждого фрагмента в вашем адаптере, используя TabLayout.newTab() но есть еще один удобный и удобный метод для этой задачи, который является TabLayout.setupWithViewPager() .

Этот метод будет синхронизироваться, создавая и удаляя вкладки в соответствии с содержимым адаптера, связанного с вашим ViewPager каждый раз, когда вы его вызываете.
Кроме того, он будет устанавливать обратный вызов, чтобы каждый раз, когда пользователь переворачивает страницу, будет выбрана соответствующая вкладка.

Просто определите макет

<?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>

Затем выполните FragmentPagerAdapter и примените его к 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 с PreferenceFragment

До недавнего времени использование android.support.v4.app.FragmentPagerAdapter предотвратило бы использование PreferenceFragment как одного из фрагментов, используемых в FragmentPagerAdapter.

В последних версиях библиотеки поддержки v7 теперь есть класс PreferenceFragmentCompat , который будет работать с ViewPager и версией версии FragmentPagerAdapter версии v4.

Пример фрагмента, который расширяет 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) { 
 
    } 
}

Теперь вы можете использовать этот фрагмент в подклассе android.support.v4.app.FragmentPagerAdapter :

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

}

Добавление ViewPager

Убедитесь, что в файл build.gradle вашего приложения добавлена build.gradle зависимость:

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

Затем добавьте ViewPager в свой макет действий:

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

Затем определите свой 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;
    }    
}

Наконец, настройте ViewPager в своей деятельности:

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 с индикатором точек

ViewPager с индикатором точек

Все, что нам нужно: ViewPager , TabLayout и 2 чертежа для выбранных и стандартных точек.

Во-первых, мы должны добавить TabLayout в наш макет экрана и подключить его к ViewPager . Мы можем сделать это двумя способами:


Вложенная TabLayout в 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>

В этом случае TabLayout будет автоматически подключаться к ViewPager , но TabLayout будет рядом с ViewPager , а не над ним.


Отдельный 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"/>

В этом случае мы можем поместить TabLayout любом месте, но мы должны подключать TabLayout с помощью ViewPager программно

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

Как только мы создали наш макет, мы должны подготовить наши точки. Поэтому мы создаем три файла: selected_dot.xml , default_dot.xml и 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>

Теперь нам нужно добавить только 3 строки кода в TabLayout в наш макет xml, и все готово.

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

Настройка OnPageChangeListener

Если вам необходимо отслеживать изменения на странице выбранного вы можете реализовать ViewPager.OnPageChangeListener слушателя на 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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow