Viewpager takes you hand in hand to achieve gallary effect, plus infinite loop, automatic rotation

Effect picture: the picture is very ugly, you see and change as needed.

Main functions:

1) Gallary style

② Infinite rotation

③ Conflict resolution between automatic rotation and gesture operation

Note ahead of time: you can forget about the provided connections; the overall code is provided at the end of the article.

1. General idea:

After looking up online information, personal feel viewPager implementation is the most reliable, save time and effort. Let’s address each of these requirements one by one:

1) Gallary style: use the ViewPager. PageTransformer solve sliding animation.

With reference to:

Developer.android.com/training/an…

www.jianshu.com/p/722ece163…

GetCount () returns a large enough value in the PagerAdapter.

Refer to: method 2 blog.csdn.net/Just_Sanpar…

③ Conflict resolution between automatic rotation and cleaning operation:

Automatic multicast uses handler to send delayed messages. The viewPager receives the Touch event in the dispatchTouchEvent method of the ViewPager.

2. Create a normal ViewPager:

1) activity_main. XML

<? xml version="1.0" encoding="utf-8"? > <android.support.constraint.ConstraintLayout 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.tongtong.tiny.loopviewpagergallary.MainActivity"> <! The ViewPager here would be better off wrapping a layer of parent layout and giving it android:clipChildren="false"Properties --> <FrameLayout Android :id="@+id/fl_vp_parent"
        android:layout_width="match_parent"
        android:layout_height="160dp"
        android:layout_centerInParent="true"
        android:background="#aadc71ff"
        android:clipChildren="false"> <! -- The width should not fill the screen setting Android :clipChildren="false"Properties - > <. Android support. The v4. The ViewPager android: id ="@+id/id_viewpager"
            android:layout_width="250dp"
            android:layout_height="120dp"
            android:layout_gravity="center"
            android:clipChildren="false"
            >
        </android.support.v4.view.ViewPager>

    </FrameLayout>

</android.support.constraint.ConstraintLayout>
Copy the code

ViewPager:

public class PageTransformerAdapter extends PagerAdapter {
    private Context context;
    private List<TextView> list;

    public PageTransformerAdapter(Context context, List<TextView> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(list.get(position));
        return list.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        TextView iv = (TextView) object;
        container.removeView(iv);
    }
}
Copy the code

MainActivity code:

public class MainActivity extends AppCompatActivity { public static final String TAG = MainActivity.class.getSimpleName(); Public static final int LIST_SIZE = 10; FrameLayout flVpParent; ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); flVpParent = findViewById(R.id.fl_vp_parent); mViewPager = findViewById(R.id.id_viewpager); List<TextView> viewList = getViewLists(); PageTransformerAdapter mAdapter = new PageTransformerAdapter(MainActivity.this, viewList); mViewPager.setAdapter(mAdapter); } /** * generate List<TextView> data ** @return
     */
    private List<TextView> getViewLists() {
        List<TextView> list = new ArrayList<>();
        for (int j = 0; j < LIST_SIZE; j++) {
            TextView tv = generateTextView(j);
            list.add(tv);
        }
        returnlist; } /** * generate a single TextView object ** @param j * @return
     */
    private TextView generateTextView(final int j) {
        TextView tv = new TextView(this);
        tv.setBackgroundColor(Color.parseColor("#2371e9"));
        String str = "This is number one." + (j + 1) + "A View";
        tv.setTag(str);
        tv.setText(str);
        tv.setTextColor(Color.parseColor("#f0523c"));
        tv.setTextSize(30);
        tv.setGravity(Gravity.CENTER);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "The first" + (j + 1) + "All views are clicked."); }});returntv; }}Copy the code

The effect is shown below:

Ok, the shelf is set up and you can start implementing the requirements step by step.

3, Gallary view effect: using the ViewPager. PageTransformer implementation

① The layout file of viewpager has been set before

(2) new ScaleDownPageTransformer, realizes the ViewPager. PageTransformer interface

/** * PageTransformer * Created by tiny on 2018/1/19. * Time: 17:04 * Version: */ public class ScaleDownPageTransformer implements ViewPager.PageTransformer { private static finalfloatDEFAULT_MIN_SCALE = 0.9 f; privatefloat mMinScale = DEFAULT_MIN_SCALE;

    /**
     * Apply a property transformation to the given page.
     *
     * @param view     Apply the transformation to this page
     * @param position Position of page relative to the current front-and-center
     *                 position of the pager. 0 is front and center. 1 is one full
     *                 page position to the right, and -1 is one page position to the left.
     */
    @Override
    public void transformPage(View view, float position) {
        float limitLow = -1;
        float limitMid = 0;
        float limitHigh = 1;

        if (position < limitLow) {
            view.setScaleX(mMinScale);
            view.setScaleY(mMinScale);
        } else if (position <= limitHigh) { // [-1,1]

            if (position < limitMid) / / [- 1, 0) {float factor = mMinScale + (1 - mMinScale) * (1 + position);
                view.setScaleX(factor);
                view.setScaleY(factor);
            } else/ / [0, 1] {float factor = mMinScale + (1 - mMinScale) * (1 - position); view.setScaleX(factor); view.setScaleY(factor); }}else { // (1,+Infinity]
            view.setScaleX(mMinScale);
            view.setScaleY(mMinScale); }}}Copy the code

③ Set ScaleDownPageTransformer to the viewPager object.

// Set the spacing between pages mviewPager.setPagemargin (20); // Set the number of cached pages // If this is set to 1, or if the default value is 1, the zooming animation of the newly loaded view on the right is not displayed when it is first loaded when sliding left. mViewPager.setOffscreenPageLimit(2); mViewPager.setPageTransformer(true, new ScaleDownPageTransformer());
mViewPager.setAdapter(mAdapter);
Copy the code

Reference:

Website demo

www.jianshu.com/p/722ece163…

The effect is as follows:

4. Infinite loop

Next, let’s look at the requirements of wireless circulation. There are a lot of details and principles on the Internet. I choose the second method of this article.

portal

Some changes have been made to the PagerAdapter:

public class PageTransformerAdapter extends PagerAdapter {
    private Context context;
    private List<TextView> list;

    public PageTransformerAdapter(Context context, List<TextView> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int actualPos = position % list.size();
        if(list.get(actualPos).getParent() ! = null) { ((ViewPager) list.get(actualPos).getParent()).removeView(list.get(actualPos)); } container.addView(list.get(actualPos));return list.get(actualPos);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        TextView iv = (TextView) object;
        container.removeView(iv);
    }
}
Copy the code

Added code to MainActivity:

Int startPos = 1000 * viewlist.size () + 1; mViewPager.setCurrentItem(startPos);Copy the code

The effect is shown below:

5, automatic rotation, support gesture sliding

① The function of automatic round casting decides to use handler to send messages

(2) When the user performs a rotation operation, the automatic rotation message needs to be stopped, which is decided to operate in the ViewPager dispatchTouchEvent method.

Ps: The reason why it does not operate in onTouchEvent is that the ViewPager processes the events distributed, and it cannot intercept ACTION_DOWN events and long-press events in onTouchEvent.

① Custom LoopViewPager, inherit from ViewPager

/** * Created by tiny on 2018/1/23. * Time: 14:38 * Version: */ public class LoopViewPager extends ViewPager { public static final String TAG = LoopViewPager.class.getSimpleName(); public LoopViewPager(Context context) { super(context); init(); } public LoopViewPager(Context context, AttributeSet attrs) { super(context, attrs); init(); } private voidinit() { autoPollTask = new AutoPollTask(this); } private static final long TIME_AUTO_POLL = 2000; private static AutoPollTask autoPollTask; private static boolean running; Private static Boolean canRun; // Whether the flag can be automatically polling, can not be set when not neededfalsestatic class AutoPollTask implements Runnable { private final WeakReference<ViewPager> mReference; Public AutoPollTask(ViewPager reference) {this.mReference = new WeakReference<>(reference); } @Override public voidrun() {
            ViewPager viewPager = mReference.get();
            if(viewPager ! = null && running && canRun) { int currPos = viewPager.getCurrentItem(); viewPager.setCurrentItem(currPos + 1,true); viewPager.postDelayed(autoPollTask, TIME_AUTO_POLL); }}} // Enable: If running, stop -> then enable public voidstart() {
        if (running)
            stop();
        canRun = true;
        running = true;
        postDelayed(autoPollTask, TIME_AUTO_POLL);
    }

    public void stop() {
        running = false; removeCallbacks(autoPollTask); } /** * The onTouchEvent event is handled by viewPagerreturn*/ @override public Boolean dispatchTouchEvent(MotionEvent ev) {// Stop scrolling whenever an event is received.if(running) stop(); Switch (ev.getAction()) {// When fingers lift or underline the pagecase MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_OUTSIDE:
                if (canRun)
                    start();
                break;
        }
        returnsuper.dispatchTouchEvent(ev); }}Copy the code

(2) Replace the ViewPager in activity_main. XML with LoopViewPager and add the following code to the MainActivity:

mViewPager.start();
Copy the code

Finally, to save resources, add the following code to MainActivity.

@Override
protected void onStart() {
    super.onStart();
    if(mViewPager ! = null) { mViewPager.start(); } } @Override protected voidonStop() {
    super.onStop();
    if (mViewPager != null) {
        mViewPager.stop();
    }
}
Copy the code

Finally, attached benefits: source code address, for star. Github.com/tinyvampire…