【安卓自定义控件】自定义ViewGroup实现透明背景的ViewPager效果

来源:互联网 发布:aop面向切面编程面试题 编辑:程序博客网 时间:2024/04/27 01:50

HelloWorld!

作为一名屌丝程序员,在博客园写第一篇技术博客内心是无比激动滴,其实作为一名忙成狗的Android开发人员,一直觉得自己永远都不会有时间去写博客,

因为我TM连找女朋友的时间都没用==

言归正传,今天自定义控件系列要实现的效果是自定义ViewGroup来实现ViewPager的效果,并且自带美女背景哟~

废话不多少,上布局代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                android:background="#ffffff"                android:layout_gravity="center"                android:layout_width="match_parent"                android:layout_height="match_parent">    <com.example.myview.HorizontalScrollViewGroup            android:layout_width="match_parent"            android:background="@drawable/mn"            android:layout_height="match_parent">        <TextView                android:layout_width="match_parent"                android:layout_height="match_parent"                android:background="#ccee342a"                android:textSize="20sp"                android:textColor="#000000"                android:gravity="center"                android:text="First Page"/>        <TextView                android:layout_width="match_parent"                android:layout_height="match_parent"                android:background="#ccadee40"                android:textSize="20sp"                android:textColor="#000000"                android:gravity="center"                android:text="Second Page"/>        <TextView                android:layout_width="match_parent"                android:layout_height="match_parent"                android:background="#cc347cee"                android:textSize="20sp"                android:textColor="#000000"                android:gravity="center"                android:text="Third Page"/>    </com.example.myview.HorizontalScrollViewGroup></RelativeLayout>
布局文件很简单,就是把自定义的HorizontalScrollViewGroup放进去
布局中设置了HorizontalScrollViewGroup的背景图片,这个大家随意设置,图片就不传上去了。
HorizontalScrollViewGroup的代码如下:
package com.example.myview;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewGroup;import android.widget.Scroller;/** * Created by WangChunLei on 15/10/29. * 横向移动的布局对象,类似于ViewPager的效果 */public class HorizontalScrollViewGroup extends ViewGroup {    private static final String TAG = "HorizontalScrollView";    /*布局的宽度*/    private int mScreenWidth;    /*布局高度*/    private int mScreenHeight;    int mLastX = 0;    private int x;    /*子View的个数*/    private int mChildCount;    /*ACTION_DOWN记录的手指坐标*/    private int mDownX;    private Scroller mScroller;    private VelocityTracker mVelocityTracker;    public HorizontalScrollViewGroup(Context context) {        this(context, null);    }    public HorizontalScrollViewGroup(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public HorizontalScrollViewGroup(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    private void init(Context context) {        mScroller = new Scroller(context);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mScreenWidth = MeasureSpec.getSize(widthMeasureSpec);        mScreenHeight = MeasureSpec.getSize(heightMeasureSpec);        mChildCount = getChildCount();        measureChildren(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        Log.e(TAG, "onLayout=====");        int childCount = getChildCount();        for (int i = 0; i < childCount; i++) {            View child = getChildAt(i);            child.layout(i * mScreenWidth, 0, (i + 1) * mScreenWidth, mScreenHeight);        }    }    @Override    protected void onAttachedToWindow() {        super.onAttachedToWindow();        mVelocityTracker = VelocityTracker.obtain();    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        if (mVelocityTracker != null) {            mVelocityTracker.recycle();        }    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), 0);            postInvalidate();        }    }    @Override    public boolean onTouchEvent(MotionEvent event) {        x = (int) event.getX();        mVelocityTracker.addMovement(event);        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                if (!mScroller.isFinished()) {                    return false;                }                mDownX = getScrollX();                mLastX = x;                break;            case MotionEvent.ACTION_MOVE:                int dx = x - mLastX;                float scrollX = getScrollX();                if (scrollX - dx <= 0) {                    scrollTo(0, 0);                } else if (scrollX - dx >= (mChildCount - 1) * mScreenWidth) {                    scrollTo((mChildCount - 1) * mScreenWidth, 0);                } else {                    scrollBy(-dx, 0);                }                mLastX = x;                break;            case MotionEvent.ACTION_UP:                int dScrollX = Math.abs(getScrollX() - mDownX);                if (mDownX - getScrollX() > 0) {//右划                    if (mDownX - getScrollX() > mScreenWidth / 2 || getXVelocity() > 600) {//下一页                        mScroller.startScroll(getScrollX(), 0, dScrollX - mScreenWidth, 0);                    } else {//当前页                        mScroller.startScroll(getScrollX(), 0, dScrollX, 0);                    }                } else if (getScrollX() - mDownX > 0) {//左划                    if (getScrollX() - mDownX > mScreenWidth / 2 || getXVelocity() > 600) {//上一页                        mScroller.startScroll(getScrollX(), 0, mScreenWidth - dScrollX, 0);                    } else {//当前页                        mScroller.startScroll(getScrollX(), 0, -dScrollX, 0);                    }                }                postInvalidate();                break;            default:                break;        }        return true;    }    private int getXVelocity() {        mVelocityTracker.computeCurrentVelocity(1000);        int xVelocity = (int) Math.abs(mVelocityTracker.getXVelocity());        return xVelocity;    }}

按照自定义控件的步骤,
1.新建HorizontalScrollViewGroup类并继承ViewGroup类,表问我为啥是ViewGroup而不是View,因为ViewGroup
才能包含其他的View对象
2.重写onMeasure方法,设置HorizontalScrollViewGroup的宽高和子View的宽高
@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mScreenWidth = MeasureSpec.getSize(widthMeasureSpec);        mScreenHeight = MeasureSpec.getSize(heightMeasureSpec);        mChildCount = getChildCount();        measureChildren(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);    }
这里通过measureChildren方法,直接把父ViewGroup的尺寸传递给了所有子View,因为每个View的尺寸都是跟父ViewGroup一样的填充布局。
3.onLayout中设置父ViewGroup的显示范围
@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {    Log.e(TAG, "onLayout=====");    int childCount = getChildCount();    for (int i = 0; i < childCount; i++) {        View child = getChildAt(i);        child.layout(i * mScreenWidth, 0, (i + 1) * mScreenWidth, mScreenHeight);    }}

4.最后,在onTouchEvent方法中处理触摸事件
不说了,老板来了,写不下去了==


0 0
原创粉丝点击