当前位置:网站首页>One line of code can quickly realize the automatic circular rotation effect of today's headlines and Netease News focus map

One line of code can quickly realize the automatic circular rotation effect of today's headlines and Netease News focus map

2021-08-08 15:43:40 Programming small stone

Sometimes we need the top focus map to rotate automatically and rotate when sliding left and right , The following is a self-defined control to implement , It's very easy to use
Realization function
1, Automatic round robin , You can set the time
2, Cyclic sliding can be realized manually
3, You can customize the size and color of dots during rotation

Look at the renderings first


It's also very easy to use , Directly copy the following custom controls to your project , You can quickly realize the automatic infinite rotation effect with one line of code .


One , Customize controls that can rotate automatically

package com.qclautocycleview;


import android.app.Activity;
import android.content.Context;
import android.os.SystemClock;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;


import java.util.ArrayList;
import java.util.List;


/** *  It can automatically rotate viewpager Control  *  Realization function  * 1, Automatic round robin , You can set the time  * 2, Cyclic sliding can be realized manually  */
public class AutoCycleView extends RelativeLayout {
    private final static String CYCLE_VIEW = "AtuoCycleView";// Print log With 


    private List<String> mViewList;
    private ViewPager mViewpage;
    private Activity mContext;
    private CyclePagerAdapter mAdapter;
    private CycleRunable mCycleRunable = new CycleRunable();


    private CycleIndexView mCycleIdxView;// Dot 




    public AutoCycleView(Context context) {
        super(context);
        init(context);
    }


    public AutoCycleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }


    public AutoCycleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }


    /* *  initialization  * */
    public void init(Context context) {


        mViewList = new ArrayList<String>();


        /* *  hold viewpager And dots are added to the layout  * */
        mViewpage = new ViewPager(context);
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mViewpage.setLayoutParams(layoutParams);
        addView(mViewpage);
        mViewpage.setAdapter(mAdapter = new CyclePagerAdapter());
        mViewpage.addOnPageChangeListener(new CycleViewChangeListener());


        // Custom sliding dots 
        mCycleIdxView = new CycleIndexView(context);
        addView(mCycleIdxView);


    }


    /* *  Pass in the required data  * */
    public void setViewList(List<String> viewList, Activity mainActivity) {
        mContext = mainActivity;
        mViewList = viewList;
        // Add loop item 


        mViewpage.setCurrentItem(1);
        mAdapter.notifyDataSetChanged();


        createIdxView(viewList.size() - 2);// Create and viewpager The dot corresponding to the data 


    }


    /* *  Create the desired dot  * */
    public void createIdxView(int size) {
        if (null != mCycleIdxView) {
            mCycleIdxView.setViewCount(size);// Set the number of dots 
            LayoutParams layoutParams = new LayoutParams(mCycleIdxView.getCycleIdxViewWidth(), mCycleIdxView.getCycleIdxViewHeight());
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);// At the bottom 
            layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);// Horizontal center 
            mCycleIdxView.setLayoutParams(layoutParams);
        }
    }


    /* *  Set the automatic rotation interval  * */
    public void startCycle(long time) {
        mCycleRunable.setCycleTime(time);
        mCycleRunable.startCycle();
    }


    /* *  Turn on the cycle  * */
    public void startCycle() {
        mCycleRunable.startCycle();
    }




    /* * viewpager Corresponding adapter  * */
    public class CyclePagerAdapter extends PagerAdapter {


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


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


        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }


        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            LayoutInflater inflater = mContext.getLayoutInflater();
            View view = inflater.inflate(R.layout.pager_item, null);
            TextView tv = (TextView) view.findViewById(R.id.text);
            tv.setText(mViewList.get(position));
            container.addView(view);


            tv.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(mContext, " Click. " + mViewList.get(position), Toast.LENGTH_SHORT).show();
                }
            });
            return view;
        }


        @Override
        public int getItemPosition(Object object) {
            return super.getItemPosition(object);
        }


    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            // Pause auto scroll 
            mCycleRunable.puaseCycle();


        } else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Start automatic scrolling 
            mCycleRunable.startCycle();
        }
        return super.dispatchTouchEvent(ev);
    }


    /* *  Rotate to achieve  * */
    public void changePager() {
        if (mViewList.isEmpty()) {
            Log.e(CYCLE_VIEW, "data is empty!");
            throw new IllegalStateException("data is empty!");
        }
        int item = Math.min(mViewpage.getCurrentItem(), mViewList.size() - 1);
        //mViewpage.setCurrentItem(++item);




        if (item == mViewList.size() - 1) {
            mViewpage.setCurrentItem(0);
        } else {
            mViewpage.setCurrentItem(++item);
        }


    }


    /* * * */
    class CycleRunable implements Runnable {
        private boolean isAnimotion = false;
        private long mDefaultCycleTime = 1000L;// Set the default rotation time   Unit millisecond 
        private long mLastTime;


        public void setCycleTime(long time) {
            mDefaultCycleTime = time;
        }


        @Override
        public void run() {
            if (isAnimotion) {
                long now = SystemClock.currentThreadTimeMillis();
                if (now - this.mLastTime >= this.mDefaultCycleTime) {
                    changePager();// When it is greater than the specified time interval, the next 
                    this.mLastTime = now;
                }


                AutoCycleView.this.post(this);
            }
        }


        public void startCycle() {// Turn on the automatic cycle 
            if (this.isAnimotion) {
                return;
            }
            this.mLastTime = SystemClock.currentThreadTimeMillis();
            this.isAnimotion = true;
            AutoCycleView.this.post(this);
        }


        public void puaseCycle() {// Pause automatic rotation 
            this.isAnimotion = false;
        }
    }




    class CycleViewChangeListener implements ViewPager.OnPageChangeListener {
        // The users themselves 
        private boolean needJumpToRealPager = true;


        public void setNeedJumpFlag(boolean isNeedJump) {
            needJumpToRealPager = isNeedJump;
        }


        public boolean getNeedJumpFlag() {
            return needJumpToRealPager;
        }


        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {


        }


        @Override
        public void onPageSelected(int position) {
            // Log.d(CYCLE_VIEW, "onPageSelected position is "+position);


            if (null != mCycleIdxView && mViewpage.getCurrentItem() != 0 && mViewpage.getCurrentItem() != mViewList.size() - 1) {
                mCycleIdxView.setCurIndex(position - 1);// Bind dots and viewpager The entry of 
            }
            // If it's a head or tail , Equal sliding 
            if (mViewpage.getCurrentItem() == 0 && getNeedJumpFlag()) {
                setNeedJumpFlag(false);
                mViewpage.setCurrentItem(mViewList.size() - 1, false);
                mViewpage.setCurrentItem(mViewList.size() - 2);
            } else if (mViewpage.getCurrentItem() == mViewList.size() - 1 && getNeedJumpFlag()) {
                setNeedJumpFlag(false);
                mViewpage.setCurrentItem(0, false);
                mViewpage.setCurrentItem(1);
            } else {
                setNeedJumpFlag(true);
            }
            // mViewpage


        }


        @Override
        public void onPageScrollStateChanged(int state) {
            // Log.d(CYCLE_VIEW, "onPageScrollStateChanged state is "+state);


        }
    }
}

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.




The simple layout used above pager_item.xml Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ffff" android:orientation="vertical">
  
    <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="pager1"/>
</LinearLayout>


     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.




Two , Customize the dots used with the above

package com.qclautocycleview;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;


/** *  Custom dots  */
public class CycleIndexView extends View {
    private int mViewCount = 5;
    private IdxCircle mIdxCircle;
    private int mCurViewIndex = 0;




    public CycleIndexView(Context context) {
        this(context, null);


    }


    public CycleIndexView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public CycleIndexView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        float density = context.getResources().getDisplayMetrics().density;
        mIdxCircle = new IdxCircle(density);


    }


    /* *  Set the number of dots  * */
    public void setViewCount(int count) {
        mViewCount = count;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawIndexPoint(canvas);
    }


    public void drawIndexPoint(Canvas canvas) {
        final int saveCount = canvas.save();
        for (int i = 0; i < mViewCount; i++) {
            boolean isCurView = (i == mCurViewIndex);
            mIdxCircle.draw(canvas, i, isCurView);
        }
        canvas.restoreToCount(saveCount);


    }


    public int getCycleIdxViewHeight() {
        return mIdxCircle.getHeight();
    }


    public int getCycleIdxViewWidth() {
        return mIdxCircle.getRadius() * 2 * mViewCount + mIdxCircle.getSpace() * (mViewCount - 1);
    }


    // Bind dots and viewpager The entry of 
    public void setCurIndex(int idx) {
        mCurViewIndex = idx % mViewCount;
        invalidate();// Repaint 
    }


    private class IdxCircle {
        private int mAngle = 45;
        private Paint mPaint = new Paint();
        private int mCircleRadius = 2;// Set the dot radius 
        private int mSpace = 5;// Set dot spacing 
        private float mDensity = 1;


        public IdxCircle(float density) {
            mDensity = density;
            mCircleRadius = (int) (mCircleRadius * density);
            mSpace = (int) (mSpace * density);


            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setColor(Color.WHITE);
        }


        public void draw(Canvas canvas, int i, boolean isCurPosition) {
            final int saveCount = canvas.save();
            // final int alpha = isCurPosition ? 5 : 160;
            // mPaint.setAlpha(alpha);// Set transparency 
            if (!isCurPosition) {
                mPaint.setColor(0xffbfbfbf);// Set the color of unselected points 
            } else {
                mPaint.setColor(0xffffffff);// Set the color of the selected point 
            }


            canvas.translate(mCircleRadius + i * (mSpace + 2 * mCircleRadius), mCircleRadius);


            canvas.drawCircle(0, 0, mCircleRadius, mPaint);


            canvas.restoreToCount(saveCount);
        }


        public int getHeight() {
            return mCircleRadius * 4;// Set the height of the dot layout 
        }


        public int getRadius() {
            return mCircleRadius;
        }


        public int getSpace() {
            return mSpace;
        }
    }
}

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.



3、 ... and , When it's over , It depends on the use , It's very convenient to use

public class MainActivity extends AppCompatActivity {
    public AutoCycleView cycleView;


    List<String> mViewList = new ArrayList<String>();// The top layout collection for the loop 


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cycleView = (AutoCycleView) findViewById(R.id.cycle_view);
        initCycleViewPager();
        cycleView.setViewList(mViewList, this);
        cycleView.startCycle();// Start automatic sliding 
    }




    /* *  Add top loop sliding data  *  When adding data, you should pay attention to adding the last data to the first one on the basis of normal data , Add the first data to the last data , For recycling  *  Let's say there are 1,2,3 Three data , To implement the loop, you need to add two additional data , *  So the data becomes 3,1,2,3,1  In this way, the effect of circular sliding can be realized  * */
    public void initCycleViewPager() {
        mViewList = new ArrayList<String>();
        mViewList.add(" Page 5 ");
        mViewList.add(" first page ");
        mViewList.add(" The second page ");
        mViewList.add(" The third page ");
        mViewList.add(" Page four ");
        mViewList.add(" Page 5 ");
        mViewList.add(" first page ");
    }
}

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.



Let's take a look at activity_main Only need to AutoCycleView As a view Control can be used

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


    <com.qclautocycleview.AutoCycleView android:id="@+id/cycle_view" android:layout_width="match_parent" android:layout_height="300dp"/>
</RelativeLayout>

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.





So far, automatic wireless rotation can be realized viewpager The effect has been achieved. . Is it very simple

 

版权声明
本文为[Programming small stone]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/08/20210808153459171d.html

随机推荐