一行代码快速实现今日头条 网易新闻焦点图自动循环轮播效果
2017-02-07 10:57
886 查看
有时候我们需要顶部焦点图可以自动轮播并且左右滑动时可以循环轮播,下面就来自定义这样的控件来实现,使用起来特别简单
实现功能
1,自动循环轮播,可以设置时间
2,可以手动实现循环滑动
3,可以自定义轮播时圆点大小和颜色
GitHub源码地址:https://github.com/qiushi123/QCLAutoCycleView 欢迎star
先看效果图
使用起来也特别简单,直接把下面的自定义控件复制到你的项目中,就可以一行代码快速实现自动无限轮播效果了。
一,自定义可以自动轮播的控件
上面使用到的简单布局pager_item.xml布局
二,自定义和上面搭配使用的圆点
三,上面完事以后,就看使用了,使用起来特别方便
再看下activity_main只需要把AutoCycleView作为一个view控件使用就可以了
至此就可以实现自动无线轮播viewpager的效果了。是不是特别简单
如有疑问可以微信我2501902696(备注安卓)
实现功能
1,自动循环轮播,可以设置时间
2,可以手动实现循环滑动
3,可以自定义轮播时圆点大小和颜色
GitHub源码地址:https://github.com/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 { @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, "点击了" + 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) { //暂停自动滚动 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; } @Override public 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; } @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);//绑定圆点和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 } @Override public 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="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>
二,自定义和上面搭配使用的圆点
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; } @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); } //绑定圆点和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>();//顶部用于循环的布局集合 @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();//开始自动滑动 } /* * 添加顶部循环滑动数据 * 添加数据的时候需要注意在正常数据的基础上把最后一个数据添加到第一个前面,把第一个数据添加到最后一个数据后面,用来循环 * 比如一共有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"?> <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>
至此就可以实现自动无线轮播viewpager的效果了。是不是特别简单
如有疑问可以微信我2501902696(备注安卓)
相关文章推荐
- swiper实现今日头条导航效果,在官方demo实现全部代码
- Android广告条效果--使用Volley实现网络图片的自动轮播(仿淘宝、网易广告页轮播效果)
- [转]jQuery实现图片轮播效果,jQuery实现焦点新闻
- Android 仿今日头条视频播放控件JieCaoVideoPlayer(几行代码快速实现)
- jQuery实现图片轮播效果,jQuery实现焦点新闻
- Android之ViewPager自动循环播放(轮播)效果实现(超简单)
- Android实现带指示点的自动轮播无限循环效果
- iOS UIScrollView自动轮播图片效果(只需一行代码就可集成到自己的项目中)
- 轮播banner,实现旋转木马效果,Galler 效果,可无限循环自动播放、拖拽
- jquery实现jQuery实现图片轮播效果,jQuery实现焦点新闻
- 安卓视频播放器 一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,仿今日头条 Android视频播放器
- 一行代码集成今日头条效果
- 使用ItemTouchHelper高效地实现 今日头条 、网易新闻 的频道排序、移动
- 一行代码集成今日头条效果
- jQuery实现公告新闻自动滚屏效果实例代码
- jQuery实现图片轮播效果,jQuery实现焦点新闻
- CSS3 animation实现图片轮播效果 自动显示 无需使用js 含代码(图片轮播效果一)
- 牛刀小试:使用Reactive Extensions(Rx),一行代码实现多线程任务执行规定时间后自动停止
- asp.net导出excel-一行代码实现excel、xml、pdf、word、html、csv等7种格式文件导出功能而且美观-SNF快速开发平台
- 一行代码实现多线程任务执行规定时间后自动停止