欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android-自定义控件-自定义ViewGroup

程序员文章站 2022-06-08 17:15:48
...

参考自--> Android群英传

项目地址-->书中自定义 view 汇总:https://github.com/FishInWater-1999/DesighViewText


确定 ViewGroup 的高度,并生成 Scroller 对象

    private void initView(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        mScreenHeight = dm.heightPixels;
        mScroller = new Scroller(context);
    }

确定子 View 的位置

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        // 设置 ViewGroup 的高度
        MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
        mlp.height = mScreenHeight * childCount;
        setLayoutParams(mlp);
        for (int i = 0 ; i < childCount ; i++ ){
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE){
                child.layout(1, i * mScreenHeight,
                        r, (i + 1) * mScreenHeight);
            }
        }
    }

粘性实现滑动

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int)event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastY = y;
                mStart = getScrollY();
                break;

            case MotionEvent.ACTION_MOVE:
                if (!mScroller.isFinished()){
                    mScroller.abortAnimation();
                }
                int dy = mLastY - y;
                if (getScrollY() < 0){
                    dy = 0;
                }
                if (getScrollY() > getHeight() - mScreenHeight){
                    dy = 0;
                }
                scrollBy(0, dy);
                mLastY = y;
                break;
            case MotionEvent.ACTION_UP:
                mEnd = getScrollY();
                int dScrollY = mEnd - mStart;
                if (dScrollY > 0){
                    if (dScrollY < mScreenHeight / 3){
                        mScroller.startScroll(
                                0 , getScrollY(),
                                0, -dScrollY
                        );
                    }else {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, mScreenHeight - dScrollY
                        );
                    }
                }else {
                    if (-dScrollY < mScreenHeight / 3){
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, -dScrollY
                        );
                    }else {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, -mScreenHeight - dScrollY
                        );
                    }
                }
                break;
        }
        postInvalidate();
        return true;
    }

完整代码如下:

/**
 * 定义 ViewGroup 实现类似:ScrollView 的功能
 */
public class ViewGroup_3_7 extends ViewGroup {
    /*
    数据成员
     */
    private int mScreenHeight = 0;
    private int childCount = 0;
    private int mLastY = 0;
    private int mStart = 0;
    private int mEnd = 0;
    private Scroller mScroller ;


    /*
    构造方法
     */
    public ViewGroup_3_7(Context context) {
        this(context, null);
    }

    public ViewGroup_3_7(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ViewGroup_3_7(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    /*
    确定 ViewGroup 的高度
     */
    private void initView(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        mScreenHeight = dm.heightPixels;
        mScroller = new Scroller(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int count = getChildCount();
        for ( int i = 0 ; i < count ; i++ ){
            View childViews = getChildAt(i);
            measureChild(childViews, widthMeasureSpec, heightMeasureSpec);
        }
    }

    /*
    确定子 View 的位置
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        // 设置 ViewGroup 的高度
        MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
        mlp.height = mScreenHeight * childCount;
        setLayoutParams(mlp);
        for (int i = 0 ; i < childCount ; i++ ){
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE){
                child.layout(1, i * mScreenHeight,
                        r, (i + 1) * mScreenHeight);
            }
        }
    }

    /*
    粘性实现滑动
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int)event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastY = y;
                mStart = getScrollY();
                break;

            case MotionEvent.ACTION_MOVE:
                if (!mScroller.isFinished()){
                    mScroller.abortAnimation();
                }
                int dy = mLastY - y;
                if (getScrollY() < 0){
                    dy = 0;
                }
                if (getScrollY() > getHeight() - mScreenHeight){
                    dy = 0;
                }
                scrollBy(0, dy);
                mLastY = y;
                break;
            case MotionEvent.ACTION_UP:
                mEnd = getScrollY();
                int dScrollY = mEnd - mStart;
                if (dScrollY > 0){
                    if (dScrollY < mScreenHeight / 3){
                        mScroller.startScroll(
                                0 , getScrollY(),
                                0, -dScrollY
                        );
                    }else {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, mScreenHeight - dScrollY
                        );
                    }
                }else {
                    if (-dScrollY < mScreenHeight / 3){
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, -dScrollY
                        );
                    }else {
                        mScroller.startScroll(
                                0, getScrollY(),
                                0, -mScreenHeight - dScrollY
                        );
                    }
                }
                break;
        }
        postInvalidate();
        return true;
    }

    /*

     */
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()){
            scrollTo(0, mScroller.getCurrY());
            postInvalidate();
        }
    }
}