自定义ViewGroup

效果图

这里写图片描述

代码

public class CustomScrollView extends ViewGroup {

    private final int mMScreenHeight;
    private Scroller mScroller;
    private int mLastY;
    private int mStart;
    private int mEnd;
    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //获取屏幕高度
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        mMScreenHeight = metrics.heightPixels;
        //创建Scroller对象
        mScroller = new Scroller(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //测量子View
            measureChild(childView,widthMeasureSpec,heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        //设置ViewGroup的高度
        MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
        params.height = childCount*mMScreenHeight;
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            childView.layout(0,i*mMScreenHeight,r,(i+1)*mMScreenHeight);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int) event.getY();//当前点击的纵坐标位置
        int action = event.getAction();
        switch (action){
            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() - mMScreenHeight){//滑动到最底部
                    dy = 0;
                }
                scrollBy(0,dy);//跟随手指滑动对应距离
                mLastY = y;//把当前的位置赋值给上一次
                break;
            case MotionEvent.ACTION_UP:
                mEnd = getScrollY();//手指抬起时滑动的距离
                int dScrollY = mEnd - mStart;//一次滑动的距离
                if(dScrollY>0){//向下滑动
                    if(dScrollY > mMScreenHeight/3){
                        mScroller.startScroll(0,getScrollY(),0,mMScreenHeight - dScrollY);
                    }else{
                        mScroller.startScroll(0,getScrollY(),0,-dScrollY);
                    }
                }else{//向上滑动
                    if(-dScrollY>mMScreenHeight/3){
                        mScroller.startScroll(0,getScrollY(),0,-mMScreenHeight - dScrollY);
                    }else{
                        mScroller.startScroll(0,getScrollY(),0,-dScrollY);
                    }
                }
                invalidate();
                break;
        }
        return true;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mScroller.computeScrollOffset()){
            scrollTo(0,mScroller.getCurrY());
            postInvalidate();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android自定义ViewGroup是指在Android开发中,通过继承ViewGroup类来创建自定义的布局容器。自定义ViewGroup可以用于实现一些特殊的布局效果,比如侧滑菜单、滑动卡片等等。通过自定义ViewGroup,我们可以更灵活地控制子视图的布局和交互行为,以满足特定的需求。自定义ViewGroup的实现主要包括重写onMeasure()方法和onLayout()方法,来测量和布局子视图。同时,我们还可以通过重写onInterceptTouchEvent()方法和onTouchEvent()方法来处理触摸事件,实现自定义的交互效果。如果你对自定义ViewGroup还不是很了解,或者正想学习如何自定义,可以参考相关的教程和文档,如引用\[1\]和引用\[2\]所提到的博客和官方文档。 #### 引用[.reference_title] - *1* [Android 手把手教您自定义ViewGroup(一)](https://blog.csdn.net/iteye_563/article/details/82601716)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [使用LayoutParams自定义安卓ViewGroup](https://blog.csdn.net/lfq88/article/details/127268493)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Android自定义ViewGroup](https://blog.csdn.net/farsight2009/article/details/62046643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值