Android ViewPager usage summary, androidviewpager

Source: Internet
Author: User

Android ViewPager usage summary, androidviewpager

Android-support-v4.jar is a software package provided by Google to us that is compatible with Android devices of lower versions, which contains only available APIs in Android 3.0 and above. ViewPager is one of them. With it, we can do a lot of things, from the simplest navigation, to the page menu and so on.

Preparation

Before using ViewPager, add the following statement to build. gradle:

compile 'com.android.support:support-v4:25.3.0'compile 'com.github.hackware1993:MagicIndicator:1.5.0'

The first line is the android-support-v4 software package, ViewPager is inside; the second line is an open source navigator, through which we can achieve a variety of navigation effects.

ViewPager-basic usage

The basic usage of ViewPager can be divided into the following steps:

The last two steps are optional, but without the last two steps, our ViewPager is just an ordinary ViewPager.

The following is a simple example. Some images are prefixed in the drawable folder, and they all start with 'page:

<?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.zzw.activity.PageActivity">    <android.support.v4.view.ViewPager        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/view_pager"        android:background="@android:color/black" /></RelativeLayout>

We define a ViewPager component in the layout file, and then we need to set it in Activity:

pager=(ViewPager) findViewById(R.id.view_pager);PagerAdapter adapter=new ViewAdapter(pages);pager.setAdapter(adapter);class ViewAdapter extends PagerAdapter {    private List<View> datas;    public ViewAdapter(List<View> list) {        datas=list;    }    @Override    public int getCount() {        return datas.size();    }    @Override    public boolean isViewFromObject(View view, Object object) {        return view==object;    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        View view=datas.get(position);        container.addView(view);        return view;    }    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        container.removeView(datas.get(position));    }}

Well, now we have completed an "image browser" with similar effects:

PS: You may have noticed that there is a navigator at the bottom. This is because of the effect after adding the Navigator (I am too lazy to go back and change it again ).
Then you may ask, how is this navigator implemented? Why is it not in the above Code? Don't worry, because this open-source navigator is really awesome, so I want to introduce it in a special section. If you can't wait, you can also go to the introduction of the navigator first.


Now we are familiar with the basic usage of ViewPager,! The effect of ViewPager is far more than that. Let's look at it later.

ViewPager -- Special Effects

Well, now we need to add some special effects on the "image browser" (otherwise, the user will be tired of aesthetics ). Imagine it would be great if we could slide the image from behind it! Now, let's try to add this special effect.

But where should we start? Haha, in fact, Google has provided us with the corresponding API, that is, android. support. v4.view. viewPager. any class that implements the PageTransformer interface can provide a special effect for ViewPager.

We found that this interface only has one public void transformPage (View page, float position) method. Let's look at its two parameters. 'page' indicates a page in ViewPager, 'position' indicates the current position of 'page', [-1, 0) indicates 'page' on the left of the screen (partially visible), [0, 0] indicates the 'page' (completely visible) on the screen, and (0, 1] indicates the 'page' (partially visible) on the right of the screen. For details, see:


When 'page' slides to the left, 'position' changes from 0 to-1, and 'position =-1' is completely invisible. When 'page' slides to the right, the 'position' changes from 0 to 1 and is completely invisible when 'position = 1.

If you want to learn more about the law of 'position' (maybe I didn't express it clearly ), for details, refer to the article "How to Implement personalized ViewPager switching animation for Android in PageTransformer (compatible with Android3.0 and below)" by the great god of Hong Yang.

Well, after the above instructions, we found that we only need to process the 'position' in the range [-1, 1:

public class ScalePageTransformer implements ViewPager.PageTransformer {    private static final float MIN_SCALE=0.75f;    @Override    public void transformPage(View page, float position) {        //Log.d("TAG", "<"+page.hashCode()+", "+position+">");        // out of left screen        if(position<-1.0f) {            page.setScaleX(MIN_SCALE);            page.setScaleY(MIN_SCALE);        }        // slide left        else if(position<=0.0f) {            page.setAlpha(1.0f);            page.setTranslationX(0.0f);            page.setScaleX(1.0f);            page.setScaleY(1.0f);        }        // slide right        else if(position<=1.0f) {            page.setAlpha(1.0f-position);            page.setTranslationX(-page.getWidth()*position);            float scale=MIN_SCALE+(1.0f-MIN_SCALE)*(1.0f-position);            page.setScaleX(scale);            page.setScaleY(scale);        }        // out of right screen        else {            page.setScaleX(MIN_SCALE);            page.setScaleY(MIN_SCALE);        }    }}

Then add the special effect to ViewPager:

pager.setPageTransformer(true, new ScalePageTransformer());

The effect is as follows:


Haha, isn't our "image browser" Very nice. However, don't rush. We can also implement more special effects.

ViewPager -- rotation effect

With the above foundation, let's create a special rotation effect:

public class RotatePageTransformer implements ViewPager.PageTransformer {    private static final float MAX_ROTATION=20.0f;    @Override    public void transformPage(View page, float position) {        if(position<-1)            rotate(page, -MAX_ROTATION);        else if(position<=1)            rotate(page, MAX_ROTATION*position);        else            rotate(page, MAX_ROTATION);    }    private void rotate(View view, float rotation) {        view.setPivotX(view.getWidth()*0.5f);        view.setPivotY(view.getHeight());        view.setRotation(rotation);    }}

This is simpler. You only need to determine the Rotation Angle Based on 'position. The effect is as follows:

ViewPager-3D Gallery

Next we will implement another special effect, but this effect is a little complicated, but the effect is really amazing! Let's first look at the effect:

Is it like you are in a 3D gallery. Now, let's implement this special effect.

First, PageTransformer:

public class GalleryPageTransformer implements ViewPager.PageTransformer {    private static final float MAX_ROTATION=20.0f;    private static final float MIN_SCALE=0.75f;    private static final float MAX_TRANSLATE=20.0f;    @Override    public void transformPage(View page, float position) {        if(position<-1) {            page.setTranslationX(MAX_TRANSLATE);            page.setScaleX(MIN_SCALE);            page.setScaleY(MIN_SCALE);            page.setRotationY(-MAX_ROTATION);        }        else if(position<=0) {            page.setTranslationX(-MAX_TRANSLATE*position);            float scale=MIN_SCALE+(1-MIN_SCALE)*(1.0f+position);            page.setScaleX(scale);            page.setScaleY(scale);            page.setRotationY(MAX_ROTATION*position);        }        else if(position<=1) {            page.setTranslationX(-MAX_TRANSLATE*position);            float scale=MIN_SCALE+(1-MIN_SCALE)*(1.0f-position);            page.setScaleX(scale);            page.setScaleY(scale);            page.setRotationY(MAX_ROTATION*position);        }        else {            page.setTranslationX(-MAX_TRANSLATE);            page.setScaleX(MIN_SCALE);            page.setScaleY(MIN_SCALE);            page.setRotationY(MAX_ROTATION);        }    }}

Here, the "3D" effect mainly depends on the View. setRotationY (float rotation) method is implemented. The function of this method is to make the View rotate around the Y axis for a certain angle (Please query the Android 3D Coordinate System by yourself ).

When you see this, you may ask, where is the reflection? Don't worry, we don't implement reflection in PageTransformer, but we did it at the beginning. When we set an adapter for ViewPager, we directly encapsulate the image with reflection into the adapter.

The following method generates images with reflections:

public static Bitmap getReverseBitmapById(Context context, int resId, float percent) {    // get the source bitmap    Bitmap srcBitmap=BitmapFactory.decodeResource(context.getResources(), resId);    // get the tow third segment of the reverse bitmap    Matrix matrix=new Matrix();    matrix.setScale(1, -1);    Bitmap rvsBitmap=Bitmap.createBitmap(srcBitmap, 0, (int) (srcBitmap.getHeight()*(1-percent)),            srcBitmap.getWidth(), (int) (srcBitmap.getHeight()*percent), matrix, false);    // combine the source bitmap and the reverse bitmap    Bitmap comBitmap=Bitmap.createBitmap(srcBitmap.getWidth(),            srcBitmap.getHeight()+rvsBitmap.getHeight()+20, srcBitmap.getConfig());    Canvas gCanvas=new Canvas(comBitmap);    gCanvas.drawBitmap(srcBitmap, 0, 0, null);    gCanvas.drawBitmap(rvsBitmap, 0, srcBitmap.getHeight()+20, null);    Paint paint=new Paint();    LinearGradient shader=new LinearGradient(0, srcBitmap.getHeight()+20, 0, comBitmap.getHeight(),            Color.BLACK, Color.TRANSPARENT, Shader.TileMode.CLAMP);    paint.setShader(shader);    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));    gCanvas.drawRect(0, srcBitmap.getHeight()+20, srcBitmap.getWidth(), comBitmap.getHeight(), paint);    return comBitmap;}

The 'percent 'parameter specifies the percentage of reflection to the source image.

Then process the source image:

private List<View> getPages() {    List<View> pages=new ArrayList<>();    Field[] fields=R.drawable.class.getDeclaredFields();    try {        for (Field field : fields) {            if (field.getName().startsWith("page")) {                ImageView view = new ImageView(this);                view.setImageBitmap(ImageUtils.getReverseBitmapById(this, field.getInt(null), 0.5f));                pages.add(view);            }        }    } catch (IllegalAccessException e) {        e.printStackTrace();    }    return pages;}

Now we have a beautiful "3D Gallery:

MagicIndicator -- MAGIC !!!

So far, the introduction to ViewPager has come to an end. However, have you found that when we slide an image, we do not know the number of current images (we still have very few images, if there are too many images, there will be this problem )!!!

To solve this problem, we also need an indicator/navigator to specify the current position. However, the idea of implementing an indicator from the ground up is big (of course, a simple indicator is easy ). Fortunately, MagicIndicator will help you.

MagicIndicator, the name of a person is MAGIC "!!! Let's just look at it first:


I just got down! For more information about MagicIndicator, see the following articles:

MagicIndicator's GitHub address is.

 

ViewPager and Fragment

ViewPager often works with Fragment to implement various page switches, such as the page menu we mentioned at the beginning. Since the Fragment used in ViewPager is slightly different from the method described above, we will introduce it here separately.

Think about it. Our previous ViewPager pages are all views, but now we want to change to Fragment. Do we need to replace the adapter? That's right. But we don't have to write an adapter from scratch. Google provides two abstract classes: FragmentPagerAdapter and FragmentStatePagerAdapter.

Whether inheriting FragmentPagerAdapter or FragmentStatePagerAdapter, you must implement the constructor, int getCount (), and Fragment getItem (int position) methods. The following is an example:

public class FragmentAdapter extends FragmentPagerAdapter {    private List<Fragment> datas;    public FragmentAdapter(FragmentManager fm, List<Fragment> list) {        super(fm);        datas=list;    }    @Override    public int getCount() {        return datas.size();    }    @Override    public Fragment getItem(int position) {        return datas.get(position);    }}

Each Fragment in the FragmentPagerAdapter will be stored in the memory, so it is applicable to relatively static and small numbers. If you need to process many pages, fragmentStatePagerAdapter should be used when the data is dynamic and the memory usage is large.

Same as FragmentStatePagerAdapter, FragmentPagerAdapter inherits from PagerAdapter. However, unlike the FragmentPagerAdapter, it only retains the current page, just as the "State" in its class name indicates. When the page is out of sight, it is recycled and its resources are released. When the page needs to be displayed, a new page is generated. The advantage is that when there are a large number of pages, it will not occupy a large amount of memory in the memory.

With the Fragment adapter, you also need to set the adapter for ViewPager:

FragmentAdapter adapter=new FragmentAdapter(getSupportFragmentManager(), frags);pager.setAdapter(adapter);

The final effect is as follows:

 

Source code

All the above source code has been uploaded to GitHub:
Https://github.com/jzyhywxz/ViewPager

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.