• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Using ViewPager for Screen Slides
2trainingnavtop=true
3
4@jd:body
5
6  <div id="tb-wrapper">
7    <div id="tb">
8      <h2>This lesson teaches you to</h2>
9         <ol>
10            <li><a href="#views">Create the Views</a></li>
11            <li><a href="#fragment">Create the Fragment</a></li>
12            <li><a href="#viewpager">Add a ViewPager</a></li>
13            <li><a href="#pagetransformer">Customize the Animation with PageTransformer</a></li>
14        </ol>
15        <h2>
16          Try it out
17        </h2>
18        <div class="download-box">
19          <a href="{@docRoot}shareables/training/Animations.zip" class=
20          "button">Download the sample app</a>
21          <p class="filename">
22            Animations.zip
23          </p>
24        </div>
25    </div>
26  </div>
27  <p>
28      Screen slides are transitions between one entire screen to another and are common with UIs
29      like setup wizards or slideshows. This lesson shows you how to do screen slides with
30      a {@link android.support.v4.view.ViewPager} provided by the <a href=
31      "{@docRoot}tools/extras/support-library.html">support library</a>.
32      {@link android.support.v4.view.ViewPager}s can animate screen slides
33      automatically. Here's what a screen slide looks like that transitions from
34      one screen of content to the next:
35    </p>
36
37    <div class="framed-galaxynexus-land-span-8">
38      <video class="play-on-hover" autoplay>
39        <source src="anim_screenslide.mp4" type="video/mp4">
40        <source src="anim_screenslide.webm" type="video/webm">
41        <source src="anim_screenslide.ogv" type="video/ogg">
42      </video>
43    </div>
44
45    <div class="figure-caption">
46      Screen slide animation
47      <div class="video-instructions">&nbsp;</div>
48    </div>
49
50<p>If you want to jump ahead and see a full working example,
51<a href="{@docRoot}shareables/training/Animations.zip">download</a>
52and run the sample app and select the Screen Slide example. See the
53following files for the code implementation:</p>
54<ul>
55  <li><code>src/ScreenSlidePageFragment.java</code></li>
56  <li><code>src/ScreenSlideActivity.java</code></li>
57  <li><code>layout/activity_screen_slide.xml</code></li>
58  <li><code>layout/fragment_screen_slide_page.xml</code></li>
59</ul>
60
61<h2 id="views">Create the Views</h2>
62  <p>Create a layout file that you'll later use for the content of a fragment. The following example
63    contains a text view to display some text:
64
65<pre>
66&lt;com.example.android.animationsdemo.ScrollView
67    xmlns:android="http://schemas.android.com/apk/res/android"
68    android:id="@+id/content"
69    android:layout_width="match_parent"
70    android:layout_height="match_parent"&gt;
71
72        &lt;TextView style="?android:textAppearanceMedium"
73            android:padding="16dp"
74            android:lineSpacingMultiplier="1.2"
75            android:layout_width="match_parent"
76            android:layout_height="wrap_content"
77            android:text="@string/lorem_ipsum" /&gt;
78
79&lt;/com.example.android.animationsdemo.ScrollView&gt;
80</pre>
81
82<h2 id="fragment">Create the Fragment</h2>
83<p>Create a {@link android.support.v4.app.Fragment} class that returns the layout
84that you just created in the {@link android.app.Fragment#onCreateView onCreateView()}
85  method. You can then create instances of this fragment in the parent activity whenever you need a new page to
86  display to the user:</p>
87
88
89<pre>
90public class ScreenSlidePageFragment extends Fragment {
91
92    &#64;Override
93    public View onCreateView(LayoutInflater inflater, ViewGroup container,
94            Bundle savedInstanceState) {
95        ViewGroup rootView = (ViewGroup) inflater.inflate(
96                R.layout.fragment_screen_slide_page, container, false);
97
98        return rootView;
99    }
100}
101</pre>
102
103<h2 id="viewpager">Add a ViewPager</h2>
104
105<p>{@link android.support.v4.view.ViewPager}s have built-in swipe gestures to transition
106  through pages, and they display screen slide animations by default, so you don't need to create any. {@link android.support.v4.view.ViewPager}s use
107{@link android.support.v4.view.PagerAdapter}s as a supply for new pages to display, so the {@link android.support.v4.view.PagerAdapter} will use the
108fragment class that you created earlier.
109  </p>
110
111<p>To begin, create a layout that contains a {@link android.support.v4.view.ViewPager}:</p>
112
113<pre>
114&lt;android.support.v4.view.ViewPager
115    xmlns:android="http://schemas.android.com/apk/res/android"
116    android:id="@+id/pager"
117    android:layout_width="match_parent"
118    android:layout_height="match_parent" /&gt;
119</pre>
120
121<p>Create an activity that does the following things:
122</p>
123
124<ul>
125  <li>Sets the content view to be the layout with the {@link android.support.v4.view.ViewPager}.</li>
126  <li>Creates a class that extends the {@link android.support.v13.app.FragmentStatePagerAdapter} abstract class and implements
127  the {@link android.support.v4.app.FragmentStatePagerAdapter#getItem getItem()} method to supply
128    instances of <code>ScreenSlidePageFragment</code> as new pages. The pager adapter also requires that you implement the
129    {@link android.support.v4.view.PagerAdapter#getCount getCount()} method, which returns the amount of pages the adapter will create (five in the example).
130  <li>Hooks up the {@link android.support.v4.view.PagerAdapter} to the {@link android.support.v4.view.ViewPager}</code>.</li>
131  <li>Handles the device's back button by moving backwards in the virtual stack of fragments.
132    If the user is already on the first page, go back on the activity back stack.</li>
133</ul>
134
135<pre>
136public class ScreenSlidePagerActivity extends FragmentActivity {
137    /**
138     * The number of pages (wizard steps) to show in this demo.
139     */
140    private static final int NUM_PAGES = 5;
141
142    /**
143     * The pager widget, which handles animation and allows swiping horizontally to access previous
144     * and next wizard steps.
145     */
146    private ViewPager mPager;
147
148    /**
149     * The pager adapter, which provides the pages to the view pager widget.
150     */
151    private PagerAdapter mPagerAdapter;
152
153    &#64;Override
154    protected void onCreate(Bundle savedInstanceState) {
155        super.onCreate(savedInstanceState);
156        setContentView(R.layout.activity_screen_slide_pager);
157
158        // Instantiate a ViewPager and a PagerAdapter.
159        mPager = (ViewPager) findViewById(R.id.pager);
160        mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
161        mPager.setAdapter(mPagerAdapter);
162    }
163
164    &#64;Override
165    public void onBackPressed() {
166        if (mPager.getCurrentItem() == 0) {
167            // If the user is currently looking at the first step, allow the system to handle the
168            // Back button. This calls finish() on this activity and pops the back stack.
169            super.onBackPressed();
170        } else {
171            // Otherwise, select the previous step.
172            mPager.setCurrentItem(mPager.getCurrentItem() - 1);
173        }
174    }
175
176    /**
177     * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
178     * sequence.
179     */
180    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
181        public ScreenSlidePagerAdapter(FragmentManager fm) {
182            super(fm);
183        }
184
185        &#64;Override
186        public Fragment getItem(int position) {
187            return new ScreenSlidePageFragment();
188        }
189
190        &#64;Override
191        public int getCount() {
192            return NUM_PAGES;
193        }
194    }
195}
196</pre>
197
198
199<h2 id="pagetransformer">Customize the Animation with PageTransformer</h2>
200
201<p>To display a different animation from the default screen slide animation, implement the
202  {@link android.support.v4.view.ViewPager.PageTransformer} interface and supply it to
203  the view pager. The interface exposes a single method, {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()}. At each point in the screen's transition, this method is called once for each visible page (generally there's only one visible page) and for adjacent pages just off the screen.
204  For example, if page three is visible and the user drags towards page four,
205  {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()} is called
206  for pages two, three, and four at each step of the gesture.</p>
207
208  <p>
209  In your implementation of {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()},
210  you can then create custom slide animations by determining which pages need to be transformed based on the
211  position of the page on the screen, which is obtained from the <code>position</code> parameter
212  of the {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()} method.</p>
213
214<p>The <code>position</code> parameter indicates where a given page is located relative to the center of the screen.
215It is a dynamic property that changes as the user scrolls through the pages. When a page fills the screen, its position value is <code>0</code>.
216When a page is drawn just off the right side of the screen, its position value is <code>1</code>. If the user scrolls halfway between pages one and two, page one has a position of -0.5 and page two has a position of 0.5. Based on the position of the pages on the screen, you can create custom slide animations by setting page properties with methods such as {@link android.view.View#setAlpha setAlpha()}, {@link android.view.View#setTranslationX setTranslationX()}, or
217  {@link android.view.View#setScaleY setScaleY()}.</p>
218
219
220<p>When you have an implementation of a {@link android.support.v4.view.ViewPager.PageTransformer PageTransformer},
221call {@link android.support.v4.view.ViewPager#setPageTransformer setPageTransformer()} with
222  your implementation to apply your custom animations. For example, if you have a
223  {@link android.support.v4.view.ViewPager.PageTransformer PageTransformer} named
224  <code>ZoomOutPageTransformer</code>, you can set your custom animations
225  like this:</p>
226<pre>
227ViewPager pager = (ViewPager) findViewById(R.id.pager);
228...
229pager.setPageTransformer(true, new ZoomOutPageTransformer());
230</pre>
231
232
233<p>See the <a href="#zoom-out">Zoom-out page transformer</a> and <a href="#depth-page">Depth page transformer</a>
234sections for examples and videos of a {@link android.support.v4.view.ViewPager.PageTransformer PageTransformer}.</p>
235
236
237<h3 id="zoom-out">Zoom-out page transformer</h3>
238<p>
239 This page transformer shrinks and fades pages when scrolling between
240 adjacent pages. As a page gets closer to the center, it grows back to
241 its normal size and fades in.
242</p>
243
244<div class="framed-galaxynexus-land-span-8">
245  <video class="play-on-hover" autoplay>
246    <source src="anim_page_transformer_zoomout.mp4" type="video/mp4">
247    <source src="anim_page_transformer_zoomout.webm" type="video/webm">
248    <source src="anim_page_transformer_zoomout.ogv" type="video/ogg">
249  </video>
250</div>
251
252<div class="figure-caption">
253  <code>ZoomOutPageTransformer</code> example
254  <div class="video-instructions">&nbsp;</div>
255</div>
256
257
258<pre>
259public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
260    private static float MIN_SCALE = 0.85f;
261    private static float MIN_ALPHA = 0.5f;
262
263    public void transformPage(View view, float position) {
264        int pageWidth = view.getWidth();
265        int pageHeight = view.getHeight();
266
267        if (position &lt; -1) { // [-Infinity,-1)
268            // This page is way off-screen to the left.
269            view.setAlpha(0);
270
271        } else if (position &lt;= 1) { // [-1,1]
272            // Modify the default slide transition to shrink the page as well
273            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
274            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
275            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
276            if (position &lt; 0) {
277                view.setTranslationX(horzMargin - vertMargin / 2);
278            } else {
279                view.setTranslationX(-horzMargin + vertMargin / 2);
280            }
281
282            // Scale the page down (between MIN_SCALE and 1)
283            view.setScaleX(scaleFactor);
284            view.setScaleY(scaleFactor);
285
286            // Fade the page relative to its size.
287            view.setAlpha(MIN_ALPHA +
288                    (scaleFactor - MIN_SCALE) /
289                    (1 - MIN_SCALE) * (1 - MIN_ALPHA));
290
291        } else { // (1,+Infinity]
292            // This page is way off-screen to the right.
293            view.setAlpha(0);
294        }
295    }
296}
297</pre>
298
299<h3 id="depth-page">Depth page transformer</h3>
300<p>
301This page transformer uses the default slide animation for sliding pages
302to the left, while using a "depth" animation for sliding pages to the
303right. This depth animation fades the page out, and scales it down linearly.
304</p>
305
306<div class="framed-galaxynexus-land-span-8">
307  <video class="play-on-hover" autoplay>
308    <source src="anim_page_transformer_depth.mp4" type="video/mp4">
309    <source src="anim_page_transformer_depth.webm" type="video/webm">
310    <source src="anim_page_transformer_depth.ogv" type="video/ogg">
311  </video>
312</div>
313
314<div class="figure-caption">
315  <code>DepthPageTransformer</code> example
316  <div class="video-instructions">&nbsp;</div>
317</div>
318
319<p class="note"><strong>Note:</strong> During the depth animation, the default animation (a screen slide) still
320takes place, so you must counteract the screen slide with a negative X translation.
321
322For example:
323
324<pre>
325view.setTranslationX(-1 * view.getWidth() * position);
326</pre>
327
328The following example shows how to counteract the default screen slide animation
329in a working page transformer:
330</p>
331
332<pre>
333
334public class DepthPageTransformer implements ViewPager.PageTransformer {
335    private static float MIN_SCALE = 0.75f;
336
337    public void transformPage(View view, float position) {
338        int pageWidth = view.getWidth();
339
340        if (position &lt; -1) { // [-Infinity,-1)
341            // This page is way off-screen to the left.
342            view.setAlpha(0);
343
344        } else if (position &lt;= 0) { // [-1,0]
345            // Use the default slide transition when moving to the left page
346            view.setAlpha(1);
347            view.setTranslationX(0);
348            view.setScaleX(1);
349            view.setScaleY(1);
350
351        } else if (position &lt;= 1) { // (0,1]
352            // Fade the page out.
353            view.setAlpha(1 - position);
354
355            // Counteract the default slide transition
356            view.setTranslationX(pageWidth * -position);
357
358            // Scale the page down (between MIN_SCALE and 1)
359            float scaleFactor = MIN_SCALE
360                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
361            view.setScaleX(scaleFactor);
362            view.setScaleY(scaleFactor);
363
364        } else { // (1,+Infinity]
365            // This page is way off-screen to the right.
366            view.setAlpha(0);
367        }
368    }
369}
370</pre>
371
372