自定义Layout

经常写自定义滚动的Layout ,总是出问题,这次备份一下刚写的可以滑动的Layout,让新手看一下也让自己忘记的时候翻阅一下。这是一个完整的自定义类,可以替换activity中的主视图 使用。

package com.yp.customscrollerview;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.Toast;

public class CustomView extends RelativeLayout {
    private Context context;
    private FrameLayout leftView;
    private FrameLayout midView;
    private FrameLayout rightView;
    Toast toast;

    public CustomView(Context context) {
        super(context);
        init(context);
    }

    private void showToast(Context contxt, String text, int len) {
        if (toast == null)
            toast = new Toast(contxt);
        toast.setDuration(len);
        toast.setText(text);
        toast.show();

    }

    private void show(String text) {
        Log.i("test", text);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    Scroller mScroller;

    private void init(Context context) {
        mScroller = new Scroller(context, new DecelerateInterpolator());
        this.context = context;
        leftView = new FrameLayout(context);
        leftView.setBackgroundColor(Color.RED);
        midView = new FrameLayout(context);
        midView.setBackgroundColor(Color.GREEN);
        rightView = new FrameLayout(context);
        rightView.setBackgroundColor(Color.RED);
        leftView.setId(0x123);
        addView(leftView);
        addView(midView);
        addView(rightView);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        midView.measure(widthMeasureSpec, heightMeasureSpec);
        int realWidth = MeasureSpec.getSize(widthMeasureSpec);
        int tempWidthMeasure = MeasureSpec.makeMeasureSpec(
                (int) (realWidth * 0.8f), MeasureSpec.EXACTLY);
        leftView.measure(tempWidthMeasure, heightMeasureSpec);
        rightView.measure(tempWidthMeasure, heightMeasureSpec);
        show("width:" + leftView.getMeasuredWidth() + "rightvieww:"
                + rightView.getMeasuredWidth());
    }

    //
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        midView.layout(l, t, r, b);
        leftView.layout(l - leftView.getMeasuredWidth(), t, l, b);
        rightView.layout(l + midView.getMeasuredWidth(), t,
                r + rightView.getMeasuredWidth(), b);
        show("___width:" + leftView.getMeasuredWidth() + "rightvieww:"
                + rightView.getMeasuredWidth());

    }

    //
    private boolean isTestCompete = false;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (!isTestCompete) {
            getEventType(ev);
            return true;
        }
        if (is_event) {
            show("++++++++++++++++++++++++++");
            switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                // int curScrollX = getScrollX();
                // show(curScrollX+"");//
                // // showToast(context, "__" + curScrollX + "", 0);
                // int dis_x = (int) (ev.getX() - point.x);
                // int xx = -dis_x + curScrollX;
                // int finalX = 0;
                // show("dis_x: "+dis_x+"xx: "+xx+"scroll :"+curScrollX);
                // if (xx < 0) {
                // finalX = Math.max(xx, -leftView.getMeasuredWidth());
                // } else {
                // finalX = Math.min(xx, rightView.getMeasuredWidth());
                //
                // }
                // show("finalX:  "+finalX+"");
                // scrollTo(-200, 0);
                // point.x = (int) ev.getX();
                int curScrollX = getScrollX();
                show("scroll" + curScrollX);
                int dis_x = (int) (ev.getX() - point.x);
                int expectX = -dis_x + curScrollX;
                int finalX = 0;
                show("dis_x: " + dis_x + "expectX: " + expectX + "  "
                        + leftView.getMeasuredWidth());
                if (expectX < 0) {
                    finalX = Math.max(expectX, -leftView.getMeasuredWidth());
                } else {
                    finalX = Math.min(expectX, rightView.getMeasuredWidth());
                }
                show("finalX: " + finalX);
                scrollTo(finalX, 0);
                point.x = (int) ev.getX();
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                curScrollX = getScrollX();
                if (Math.abs(curScrollX) > leftView.getMeasuredWidth() >> 1) {
                    if (curScrollX < 0) {
                        mScroller.startScroll(curScrollX, 0,
                                -leftView.getMeasuredWidth() - curScrollX, 0,
                                200);
                    } else {
                        mScroller.startScroll(curScrollX, 0,
                                leftView.getMeasuredWidth() - curScrollX, 0,
                                200);
                    }

                } else {
                    mScroller.startScroll(curScrollX, 0, -curScrollX, 0, 200);
                }
                invalidate();
                is_event = false;
                isTestCompete = false;
                break;
            }

        } else {
            is_event = false;
            isTestCompete = false;
        }
        return super.dispatchTouchEvent(ev);
    }

    private Point point = new Point();
    final int TEST_DIS = 20;
    boolean is_event;

    private void getEventType(MotionEvent ev) {
        show("+++++++++++getEventType+++++++++++++++");
        switch (ev.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            point.x = (int) ev.getX();
            point.y = (int) ev.getY();
            super.dispatchTouchEvent(ev);
            break;
        case MotionEvent.ACTION_MOVE:
            int dX = (int) Math.abs(ev.getX() - point.x);
            int dY = (int) Math.abs(ev.getY() - point.y);
            if (dX >= TEST_DIS && dX > dY) {
                // 左右滑动
                is_event = true;
                isTestCompete = true;
                point.x = (int) ev.getX();
                point.y = (int) ev.getY();
            } else if (dY >= TEST_DIS && dY > dX) {
                // 上下滑动
                is_event = false;
                isTestCompete = true;
                point.x = (int) ev.getX();
                point.y = (int) ev.getY();
            }

            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            super.dispatchTouchEvent(ev);
            is_event = false;
            isTestCompete = false;
            break;

        }

    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (!mScroller.computeScrollOffset()) {
            return;
        }
        int tempX = mScroller.getCurrX();
        scrollTo(tempX, 0);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        return super.onTouchEvent(event);
    }
    // class Point{
    // public int x;
    // public int y;
    // }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值