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

2021-09-24 12:04:10 浏览数 (1)

参考自--> Android群英传

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


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

代码语言:javascript复制
    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 的位置

代码语言:javascript复制
    @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);
            }
        }
    }

粘性实现滑动

代码语言:javascript复制
    @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;
    }

完整代码如下:

代码语言:javascript复制
/**
 * 定义 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();
        }
    }
}

0 人点赞