300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 一行代码快速实现今日头条 网易新闻焦点图自动循环轮播效果

一行代码快速实现今日头条 网易新闻焦点图自动循环轮播效果

时间:2020-06-21 12:59:16

相关推荐

一行代码快速实现今日头条 网易新闻焦点图自动循环轮播效果

有时候我们需要顶部焦点图可以自动轮播并且左右滑动时可以循环轮播,下面就来自定义这样的控件来实现,使用起来特别简单

实现功能

1,自动循环轮播,可以设置时间

2,可以手动实现循环滑动

3,可以自定义轮播时圆点大小和颜色

GitHub源码地址:/qiushi123/QCLAutoCycleView 欢迎star

先看效果图

使用起来也特别简单,直接把下面的自定义控件复制到你的项目中,就可以一行代码快速实现自动无限轮播效果了。

一,自定义可以自动轮播的控件

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;/*** 可以自动循环轮播的viewpager控件* 实现功能* 1,自动循环轮播,可以设置时间* 2,可以手动实现循环滑动*/public class AutoCycleView extends RelativeLayout {private final static String CYCLE_VIEW = "AtuoCycleView";//打印log用的private List<String> mViewList;private ViewPager mViewpage;private Activity mContext;private CyclePagerAdapter mAdapter;private CycleRunable mCycleRunable = new CycleRunable();private CycleIndexView mCycleIdxView;//圆点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);}/** 初始化* */public void init(Context context) {mViewList = new ArrayList<String>();/** 把viewpager和圆点添加到布局中* */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());//自定义滑动时的圆点mCycleIdxView = new CycleIndexView(context);addView(mCycleIdxView);}/** 传入所需的数据* */public void setViewList(List<String> viewList, Activity mainActivity) {mContext = mainActivity;mViewList = viewList;//增加循环项mViewpage.setCurrentItem(1);mAdapter.notifyDataSetChanged();createIdxView(viewList.size() - 2);//创建和viewpager数据对应的圆点}/** 创建所需圆点* */public void createIdxView(int size) {if (null != mCycleIdxView) {mCycleIdxView.setViewCount(size);//设置圆点个数LayoutParams layoutParams = new LayoutParams(mCycleIdxView.getCycleIdxViewWidth(), mCycleIdxView.getCycleIdxViewHeight());layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);//居于底部layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);//水平居中mCycleIdxView.setLayoutParams(layoutParams);}}/** 设置自动轮播时间间隔* */public void startCycle(long time) {mCycleRunable.setCycleTime(time);mCycleRunable.startCycle();}/** 开启循环* */public void startCycle() {mCycleRunable.startCycle();}/** viewpager对应的适配器* */public class CyclePagerAdapter extends PagerAdapter {@Overridepublic int getCount() {return mViewList.size();}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);}@Overridepublic 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() {@Overridepublic void onClick(View view) {Toast.makeText(mContext, "点击了" + mViewList.get(position), Toast.LENGTH_SHORT).show();}});return view;}@Overridepublic int getItemPosition(Object object) {return super.getItemPosition(object);}}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {final int action = ev.getAction();if (action == MotionEvent.ACTION_DOWN) {//暂停自动滚动mCycleRunable.puaseCycle();} else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {//启动自动滚动mCycleRunable.startCycle();}return super.dispatchTouchEvent(ev);}/** 轮播实现* */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;//设置默认轮播时间 单位毫秒private long mLastTime;public void setCycleTime(long time) {mDefaultCycleTime = time;}@Overridepublic void run() {if (isAnimotion) {long now = SystemClock.currentThreadTimeMillis();if (now - this.mLastTime >= this.mDefaultCycleTime) {changePager();//大于指定时间间隔时就轮播下一个this.mLastTime = now;}AutoCycleView.this.post(this);}}public void startCycle() {//开启自动循环if (this.isAnimotion) {return;}this.mLastTime = SystemClock.currentThreadTimeMillis();this.isAnimotion = true;AutoCycleView.this.post(this);}public void puaseCycle() {//暂停自动轮播this.isAnimotion = false;}}class CycleViewChangeListener implements ViewPager.OnPageChangeListener {//用户自己private boolean needJumpToRealPager = true;public void setNeedJumpFlag(boolean isNeedJump) {needJumpToRealPager = isNeedJump;}public boolean getNeedJumpFlag() {return needJumpToRealPager;}@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic 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);//绑定圆点和viewpager的条目}//如果是头或者尾,等滑动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}@Overridepublic void onPageScrollStateChanged(int state) {// Log.d(CYCLE_VIEW, "onPageScrollStateChanged state is "+state);}}}

上面使用到的简单布局pager_item.xml布局

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

二,自定义和上面搭配使用的圆点

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;/*** 自定义圆点*/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);}/** 设置圆点个数* */public void setViewCount(int count) {mViewCount = count;}@Overrideprotected 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);}//绑定圆点和viewpager的条目public void setCurIndex(int idx) {mCurViewIndex = idx % mViewCount;invalidate();//重绘}private class IdxCircle {private int mAngle = 45;private Paint mPaint = new Paint();private int mCircleRadius = 2;//设置圆点半径private int mSpace = 5;//设置圆点间隔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);//设置透明度if (!isCurPosition) {mPaint.setColor(0xffbfbfbf);//设置未选中的点的颜色} else {mPaint.setColor(0xffffffff);//设置选中的点的颜色}canvas.translate(mCircleRadius + i * (mSpace + 2 * mCircleRadius), mCircleRadius);canvas.drawCircle(0, 0, mCircleRadius, mPaint);canvas.restoreToCount(saveCount);}public int getHeight() {return mCircleRadius * 4;//设置圆点布局的高度}public int getRadius() {return mCircleRadius;}public int getSpace() {return mSpace;}}}

三,上面完事以后,就看使用了,使用起来特别方便

public class MainActivity extends AppCompatActivity {public AutoCycleView cycleView;List<String> mViewList = new ArrayList<String>();//顶部用于循环的布局集合@Overrideprotected 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();//开始自动滑动}/** 添加顶部循环滑动数据* 添加数据的时候需要注意在正常数据的基础上把最后一个数据添加到第一个前面,把第一个数据添加到最后一个数据后面,用来循环* 比如一共有1,2,3三个数据,为了实现循环需要另外添加两个数据,* 这样数据就成了3,1,2,3,1 这样就可以实现循环滑动的效果了* */public void initCycleViewPager() {mViewList = new ArrayList<String>();mViewList.add("第五页");mViewList.add("第一页");mViewList.add("第二页");mViewList.add("第三页");mViewList.add("第四页");mViewList.add("第五页");mViewList.add("第一页");}}

再看下activity_main只需要把AutoCycleView作为一个view控件使用就可以了

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.qclautocycleview.AutoCycleViewandroid:id="@+id/cycle_view"android:layout_width="match_parent"android:layout_height="300dp"/></RelativeLayout>

至此就可以实现自动无线轮播viewpager的效果了。是不是特别简单

如有疑问可以微信我2501902696(备注安卓)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。