与ViewPager合用的MyTitleLayout,可以设置滚动指示器
来源:互联网 发布:It 门槛 编辑:程序博客网 时间:2024/06/15 21:20
项目经理突然要求做一个有切换指向的标题头,开始想使用TabLayout,TabLayout的指示器只可以设置颜色,因此我就自己写了一个Layout,话不多说,先说下思路
- 可以设置多个、线性的标题,因此可以继承LinearLayout
- 指示图标可以使用onDraw绘制上去
- 根据ViewPager滑动进行设置指示图标的位置
- 可以手指滑动标题,进行切换ViewPager界面
思路就是这样,好了,话不多说,直接上代码
public class MyTitleLayout extends LinearLayout { private int mCount; private int mWidth; private int mHeight; private Paint mPaint; private int mStartWidth; private int mChildWidth; private Bitmap mBitmap; private int mStartX; private int mTouchSlop; //判断标题是否可以滑动,false:不可以 private boolean mCanScroll; //标题滑动监听 private OnTitleScroll mOnTitleScroll; private int mBitmapWidth; private int mBitmapHeight; public MyTitleLayout(Context context) { super(context); initData(); } public MyTitleLayout(Context context, AttributeSet attrs) { super(context, attrs); initData(); } public MyTitleLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initData(); } private void initData() { //不调用该方法不能进行绘制 setWillNotDraw(false); mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setAntiAlias(true); //初始化默认图标 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mark); mBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, mStartWidth + mChildWidth / 2 - mBitmapWidth / 2, mHeight - mBitmapHeight, mPaint); super.onDraw(canvas); } public interface OnTitleScroll { void onTitleScroll(int position); } /** * 设置标题是否可以滑动,设置标题滑动监听 * * @param onTitleScroll * @param canScroll */ public void setOnTitleScroll(OnTitleScroll onTitleScroll, boolean canScroll) { mCanScroll = canScroll; if (mCanScroll && onTitleScroll == null) { mCanScroll = false; } mOnTitleScroll = onTitleScroll; } /** * 滑动时调用该方法,参数为将要滑动到的position * * @param px */ public void onScrollTo(int px) { //viewPager会在position变化时突然传过来一个0,如果不进行判断,会重置 if (mStartWidth - px / 2 >= mWidth / (mCount + 1)) { return; } mStartWidth = px / 2; invalidate(); } /** * 滑动时调用该方法,参数为将要滑动的距离 * * @param px */ public void onScrollFor(int px) { //边界判定 if ((mStartWidth + px) > 0 && (mStartWidth + px) < mChildWidth * (mCount - 1)) { mStartWidth += px; invalidate(); } } /** * 滑动结束后调用,count为判定图标显示在第几个 * * @param count */ public void onFinishScroll(int count) { mStartWidth = mChildWidth * count; invalidate(); } /** * 滑动标题结束后调用该方法 */ private void onFinishScroll() { mStartWidth += mChildWidth / 2 - mBitmapWidth / 2; for (int i = 0; i < mCount; i++) { int startPosition = mChildWidth * i; int endPosition = mChildWidth * (i + 1); if (mStartWidth >= startPosition && mStartWidth < endPosition) { onFinishScroll(i); if (mOnTitleScroll != null) { mOnTitleScroll.onTitleScroll(i); } break; } } } /** * 使用外部拦截法 * * @param event * @return */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (!mCanScroll) { return false; } boolean intercept = false; int x = (int) getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: intercept = false; break; case MotionEvent.ACTION_MOVE: int moveX = (int) event.getX(); if (Math.abs(moveX - x) > mTouchSlop) { intercept = true; } else { intercept = false; } break; case MotionEvent.ACTION_UP: intercept = false; break; } return intercept; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mStartX = (int) event.getX(); break; case MotionEvent.ACTION_MOVE: int moveX = (int) event.getX(); onScrollFor(moveX - mStartX); mStartX = moveX; break; case MotionEvent.ACTION_UP: onFinishScroll(); break; } return true; } @Override protected void onFinishInflate() { super.onFinishInflate(); mCount = getChildCount(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = getMeasuredWidth(); mHeight = getMeasuredHeight(); mChildWidth = mWidth / mCount; mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); mBitmapWidth = mBitmap.getWidth(); mBitmapHeight = mBitmap.getHeight(); }
控件虽然很简单,但是提供更换指示图标,可以根据ViewPager滑动,或者根据手势滑动。事件分发采用外部拦截法进行,比较简单。
控件项目地址:https://git.oschina.net/qiangshen/commentview.git
这是我开始维护的一个控件地址,这里面的控件都是我自己学习时或工作时写的,可能控件还有各种bug,可能我的做法太复杂或代码规范有问题,我希望大家可以帮我提出并改正。
0 0
- 与ViewPager合用的MyTitleLayout,可以设置滚动指示器
- TabLayout与ViewPager和Fragment、FragmentPagerAdapter的合用
- TabLayout与ViewPager和Fragment、FragmentPagerAdapter的合用
- RecyclerViewer与ViewPager合用的NullPointer报错
- 设计ViewPager的指示器
- viewPager滚动速度的设置
- 一看就会的自定义指示器适用tab与viewpager
- android Fragment与ViewPager,自画指示器的一个应用
- viewpager的圆点指示器
- viewpager的下横线指示器
- Android简单的ViewPager指示器
- ViewPager滑动跟随的指示器
- Android简单的ViewPager指示器
- ViewPager+fragment实时滚动条的多屏滑动效果外加消息指示器
- ViewPager和Fragment结合,利用(HorizontalScrollView)实现指示器与ViewPager同时滑动的动态效果
- ViewPager 滚动速度设置
- ViewPager 指示器
- ViewPager指示器
- CPU卡程序设计实例(二十)8字节随机数读取
- CentOS7 删除乱码目录
- 电脑显示器vga和dvi
- cf 789c最大字段和
- 杨辉三角形
- 与ViewPager合用的MyTitleLayout,可以设置滚动指示器
- Android实现一个简单的自定义适配器
- Linux查看文件以及磁盘空间大小管理
- [ASIFT 0] ASIFT算法深入讲解
- 自定义控件之单点触摸监听
- CPU卡程序设计实例(二十一)4字节随机数读取
- ===============个人博客导航栏======================
- 抽象与计算机课程
- 显卡驱动