DataSetObserver使用——自定义View之二
来源:互联网 发布:seo网络推广专员 编辑:程序博客网 时间:2024/06/06 17:35
这是一个开源项目:https://github.com/Jude95/RollViewPager图片轮播控件,写的特别好,有必要好好总结一下。
RollViewPager 是一个ViewGroup,里面封装了ViewPager和指示器(HintView)。里面有很多东西值得我们学习:
1.间隔时间自己滑动
2.手动点击就不自动滑动(事件处理)
3.可以动态设置和更新页面和指示器
我这篇文章主要想研究里面的观察者,怎么样通过DataSetObserver,实现no动态设置页面个数和指示器个数。
package lib.util.open.rollviewpage;import android.content.Context;import android.content.res.TypedArray;import android.database.DataSetObserver;import android.graphics.Color;import android.graphics.drawable.GradientDrawable;import android.os.Handler;import android.os.Message;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.Interpolator;import android.widget.RelativeLayout;import android.widget.Scroller;import lib.util.open.R;import lib.util.open.rollviewpage.adapter.LoopPagerAdapter;import lib.util.open.rollviewpage.hintview.ColorPointHintView;import java.lang.ref.WeakReference;import java.lang.reflect.Field;import java.util.Timer;import java.util.TimerTask;/** * 支持轮播和提示的的viewpager * https://github.com/Jude95/RollViewPager */public class RollPagerView extends RelativeLayout implements OnPageChangeListener {private ViewPager mViewPager;private PagerAdapter mAdapter;private OnItemClickListener mOnItemClickListener; private GestureDetector mGestureDetector;private long mRecentTouchTime;//播放延迟private int delay;//hint位置private int gravity;//hint颜色private int color;//hint透明度private int alpha;private int paddingLeft;private int paddingTop;private int paddingRight;private int paddingBottom;private View mHintView;private Timer timer;public interface HintViewDelegate{ void setCurrentPosition(int position, HintView hintView); void initView(int length, int gravity, HintView hintView); } private HintViewDelegate mHintViewDelegate = new HintViewDelegate() { @Override public void setCurrentPosition(int position,HintView hintView) { if(hintView!=null) hintView.setCurrent(position); } @Override public void initView(int length, int gravity,HintView hintView) { if (hintView!=null) hintView.initView(length,gravity); } };public RollPagerView(Context context){this(context,null);}public RollPagerView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RollPagerView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initView(attrs);}/** * 读取提示形式 和 提示位置 和 播放延迟 * @param attrs */private void initView(AttributeSet attrs){if(mViewPager!=null){removeView(mViewPager);}TypedArray type = getContext().obtainStyledAttributes(attrs, R.styleable.RollViewPager);gravity = type.getInteger(R.styleable.RollViewPager_rollviewpager_hint_gravity, 1);delay = type.getInt(R.styleable.RollViewPager_rollviewpager_play_delay, 0);color = type.getColor(R.styleable.RollViewPager_rollviewpager_hint_color, Color.BLACK);alpha = type.getInt(R.styleable.RollViewPager_rollviewpager_hint_alpha, 0);paddingLeft = (int) type.getDimension(R.styleable.RollViewPager_rollviewpager_hint_paddingLeft, 0);paddingRight = (int) type.getDimension(R.styleable.RollViewPager_rollviewpager_hint_paddingRight, 0);paddingTop = (int) type.getDimension(R.styleable.RollViewPager_rollviewpager_hint_paddingTop, 0);paddingBottom = (int) type.getDimension(R.styleable.RollViewPager_rollviewpager_hint_paddingBottom, Util.dip2px(getContext(),4));mViewPager = new ViewPager(getContext());mViewPager.setId(R.id.rollViewpager_inner);mViewPager.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));addView(mViewPager);type.recycle();initHint(new ColorPointHintView(getContext(),Color.parseColor("#E3AC42"),Color.parseColor("#88ffffff"))); //手势处理 mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onSingleTapUp(MotionEvent e) { if (mOnItemClickListener!=null){ if (mAdapter instanceof LoopPagerAdapter){//原谅我写了这么丑的代码 mOnItemClickListener.onItemClick(mViewPager.getCurrentItem()%((LoopPagerAdapter) mAdapter).getRealCount()); }else { mOnItemClickListener.onItemClick(mViewPager.getCurrentItem()); } } return super.onSingleTapUp(e); } });} private final static class TimeTaskHandler extends Handler{ private WeakReference<RollPagerView> mRollPagerViewWeakReference; public TimeTaskHandler(RollPagerView rollPagerView) { this.mRollPagerViewWeakReference = new WeakReference<>(rollPagerView); } @Override public void handleMessage(Message msg) { RollPagerView rollPagerView = mRollPagerViewWeakReference.get(); int cur = rollPagerView.getViewPager().getCurrentItem()+1; if(cur>=rollPagerView.mAdapter.getCount()){ cur=0; } rollPagerView.getViewPager().setCurrentItem(cur); rollPagerView.mHintViewDelegate.setCurrentPosition(cur, (HintView) rollPagerView.mHintView);if (rollPagerView.mAdapter.getCount()<=1)rollPagerView.stopPlay(); } } private TimeTaskHandler mHandler = new TimeTaskHandler(this); private static class WeakTimerTask extends TimerTask{ private WeakReference<RollPagerView> mRollPagerViewWeakReference; public WeakTimerTask(RollPagerView mRollPagerView) { this.mRollPagerViewWeakReference = new WeakReference<>(mRollPagerView); } @Override public void run() { RollPagerView rollPagerView = mRollPagerViewWeakReference.get(); if (rollPagerView!=null){ if(rollPagerView.isShown() && System.currentTimeMillis()-rollPagerView.mRecentTouchTime>rollPagerView.delay){ rollPagerView.mHandler.sendEmptyMessage(0); } }else{ cancel(); } } }/** * 开始播放 * 仅当view正在显示 且 触摸等待时间过后 播放 */private void startPlay(){if(delay<=0||mAdapter==null||mAdapter.getCount()<=1){return;}if (timer!=null){timer.cancel();}timer = new Timer();//用一个timer定时设置当前项为下一项timer.schedule(new WeakTimerTask(this), delay, delay);} private void stopPlay(){ if (timer!=null){ timer.cancel(); timer = null; } } public void setHintViewDelegate(HintViewDelegate delegate){ this.mHintViewDelegate = delegate; }private void initHint(HintView hintview){if(mHintView!=null){removeView(mHintView);}if(hintview == null||!(hintview instanceof HintView)){return;}mHintView = (View) hintview;loadHintView();}/** * 加载hintview的容器 */private void loadHintView(){addView(mHintView);mHintView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);((View) mHintView).setLayoutParams(lp);GradientDrawable gd = new GradientDrawable();gd.setColor(color);gd.setAlpha(alpha);mHintView.setBackgroundDrawable(gd); mHintViewDelegate.initView(mAdapter == null ? 0 : mAdapter.getCount(), gravity, (HintView) mHintView);}/** * 设置viewager滑动动画持续时间 * @param during */public void setAnimationDurtion(final int during){try {// viePager平移动画事件(反射)Field mField = ViewPager.class.getDeclaredField("mScroller");mField.setAccessible(true);Scroller mScroller = new Scroller(getContext(),// 动画效果与ViewPager的一致 new Interpolator() { public float getInterpolation(float t) { t -= 1.0f; return t * t * t * t * t + 1.0f; } }) { @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { // 如果手工滚动,则加速滚动 if (System.currentTimeMillis() - mRecentTouchTime > delay) { duration = during; } else { duration /= 2; } super.startScroll(startX, startY, dx, dy, duration); }@Overridepublic void startScroll(int startX, int startY, int dx,int dy) {super.startScroll(startX, startY, dx, dy,during);}};mField.set(mViewPager, mScroller);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}} public void setPlayDelay(int delay){ this.delay = delay; startPlay(); } public void pause(){ stopPlay(); } public void resume(){ startPlay(); } public boolean isPlaying(){ return timer!=null; } public void setOnItemClickListener(OnItemClickListener listener){ this.mOnItemClickListener = listener; }/** * 设置提示view的位置 * */public void setHintPadding(int left,int top,int right,int bottom){paddingLeft = left;paddingTop = top;paddingRight = right;paddingBottom = bottom;mHintView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);}/** * 设置提示view的透明度 * @param alpha 0为全透明 255为实心 */public void setHintAlpha(int alpha){this.alpha = alpha;initHint((HintView)mHintView);}/** * 支持自定义hintview * 只需new一个实现HintView的View传进来 * 会自动将你的view添加到本View里面。重新设置LayoutParams。 * @param hintview */public void setHintView(HintView hintview){if (mHintView != null) {removeView(mHintView);}this.mHintView = (View) hintview;if (hintview!=null&&hintview instanceof View){initHint(hintview);}}/** * 取真正的Viewpager * @return */public ViewPager getViewPager() {return mViewPager;}/** * 设置Adapter * @param adapter */public void setAdapter(PagerAdapter adapter){ mViewPager.setAdapter(adapter); mViewPager.addOnPageChangeListener(this);mAdapter = adapter;dataSetChanged();//关键的一步adapter.registerDataSetObserver(new JPagerObserver()); }/** * 用来实现adapter的notifyDataSetChanged通知HintView变化 */private class JPagerObserver extends DataSetObserver {@Overridepublic void onChanged() {dataSetChanged();}@Overridepublic void onInvalidated() {dataSetChanged();}}private void dataSetChanged(){if(mHintView!=null) {mHintViewDelegate.initView(mAdapter.getCount(), gravity, (HintView) mHintView);mHintViewDelegate.setCurrentPosition(mViewPager.getCurrentItem(), (HintView) mHintView);} startPlay(); }/** * 为了实现触摸时和过后一定时间内不滑动,这里拦截 * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent ev) {mRecentTouchTime = System.currentTimeMillis(); mGestureDetector.onTouchEvent(ev); return super.dispatchTouchEvent(ev); } @Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onPageSelected(int arg0) { mHintViewDelegate.setCurrentPosition(arg0, (HintView) mHintView);}}
0 0
- DataSetObserver使用——自定义View之二
- DataSetObserver使用——自定义View之一
- 安卓复习之旅—自定义view(二)
- Android 自定义view(二) —— attr 使用
- 自定义view-二,使用枚举
- Android自定义控件之自定义View(二)
- 自定义View(二)之自定义属性
- Android自定义View(二)——常用工具
- Android自定义View探索(二)—常用工具
- android 自定义view——自定义属性(二)
- android 自定义View研究(二) — 自定义控件添加属性
- 【Android应用实例之二】跟随手指的小球——自定义View应用
- 自定义View之大风车系列demo(二)
- Android学习之自定义view(二)
- 自定义View之文字游乐场(二)
- Android进阶之自定义view(二)
- 【Android进阶之自定义View(二)】
- 自定义View(二)之折线图
- solr搭建一
- 多版本python切换
- java 归并
- ztree实例
- spring boot ant风格路径表达式的采坑记录
- DataSetObserver使用——自定义View之二
- 【招行】软件开发工程师实习生面试
- 事务及事务的隔离级别
- Hadoop深入学习:Combiner
- spark.mllib源码阅读-聚类算法1-KMeans
- HTML标签使用
- Gitlab Omnibus
- Syrotek Course -ROS_CPP
- 简述时间复杂度和空间复杂度