Android——自定义滚动ViewGroup

27 篇文章 0 订阅

该自定义控件对外提供getAdapter和setAdapter接口,能够设置要滚动显示的View(每个View默认显示全屏幕宽高)

public class ScrollerViewGroup extends ViewGroup {

    private int screenHeight;//the phone screen height
    private int currentY;//记录当前当前的Y位置
    private int startScrollY;//记录手指按下触摸事件时的Y方向的滚动位置
    private int endScrollY;//记录手指抬起触摸事件时的Y方向的滚动位置

    private Adapter mAdapter;//显示适配器

    private Scroller mScroller;


    public ScrollerViewGroup(Context context, AttributeSet attrs) {
        this(context, null, attrs);
    }

    public ScrollerViewGroup(Context context) {
        this(context, null, null);
    }

    public ScrollerViewGroup(Context context, Adapter adapter) {
        this(context, adapter, null);
    }

    public ScrollerViewGroup(Context context, Adapter adapter, AttributeSet attrs) {
        this(context, adapter, attrs, 0);
    }

    public ScrollerViewGroup(Context context, Adapter adapter, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mAdapter = adapter;
        init(context);
    }

    //初始化mScroller和screenHeight
    private void init(Context context) {
        mScroller = new Scroller(context);
        DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
        screenHeight = metrics.heightPixels;

    }

    public Adapter getAdapter() {
        return mAdapter;
    }

    public void setAdapter(Adapter mAdapter) {
        this.mAdapter = mAdapter;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mAdapter == null) return;
        int count = mAdapter.getCount();
        for (int i = 0; i < count; i++) {
            View child = mAdapter.getView(i, null, this);
            addView(child);
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new MarginLayoutParams(p);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
        mlp.height = screenHeight * count;
        setLayoutParams(mlp);
        for (int i = 0, j = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == VISIBLE) {
                child.layout(l, j * screenHeight, r, (++j) * screenHeight);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                currentY = y;
                startScrollY = getScrollY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (!mScroller.isFinished())
                    mScroller.abortAnimation();
                int offset = currentY - y;
                if (getScrollY() < 0)
                    offset = 0;
                if (getScrollY() > getHeight() - screenHeight)
                    offset = 0;
                scrollBy(0, offset);
                currentY = y;
                break;
            case MotionEvent.ACTION_UP:
                endScrollY = getScrollY();
                int offsetY = endScrollY - startScrollY;
                if (offsetY > 0) {
                    if (offsetY > screenHeight / 3) {
                        mScroller.startScroll(0, endScrollY, 0, screenHeight - offsetY);
                    } else {
                        mScroller.startScroll(0, endScrollY, 0, -offsetY);
                    }
                } else {
                    if (-offsetY > screenHeight / 3) {
                        mScroller.startScroll(0, endScrollY, 0, -screenHeight - offsetY);
                    } else {
                        mScroller.startScroll(0, endScrollY, 0, -offsetY);
                    }
                }
                break;
        }
        postInvalidate();
        return true;
    }

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

使用时:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
        Adapter adapter = new ArrayAdapter<Integer>(this, 0, color) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                int color = getItem(position);
                if (convertView == null) {
                    convertView = new View(getContext());
                    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT
                    );
                    convertView.setLayoutParams(params);
                }
                convertView.setBackgroundColor(color);
                return convertView;
            }
        };
        svg = (ScrollerViewGroup) findViewById(R.id.svg);
        if(svg==null) Log.e("main","null");
        svg.setAdapter(adapter);
    }

    Integer[] color = new Integer[]{Color.RED, Color.BLUE, Color.YELLOW};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值