滑动控件自定义使用

1,安卓自定义View总体来说有三种方式 

  1,继承自View

  2,继承自ViewGroup

  3,继承自ViewGroup子类 

  需要重写三个方法onMeasure   onLayout   onDraw

2,安卓View坐标

http://android.jobbole.com/83276/

3,继承ViewGroup子类实例

 1,实例背景

   产品设计,要滑动,可点击,点击后可弹出车辆信息(原始控件无法实现)

 2,实现思想

   继承RelativeLayout,背景,拖动车辆都事先写进layout文件中,自行控制onTouch事件

 3,实现效果

public class SlideThreeSelectView extends RelativeLayout {

    @InjectView(R.id.cartype_background)
    ImageView mBackgroundView;

    @InjectView(R.id.cartype_car)
    ImageView mCarTypeView;

    private DisplayMetrics mdDisplayMetrics;

    private int mHalfScreenWidth;


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

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

    private void init() {
        initView();
        initListener();
    }



    private void initView() {
        View view = View.inflate(getContext(), R.layout.select_three_cartype_view, this);
        ButterKnife.inject(view);
        mdDisplayMetrics = new DisplayMetrics();
        mdDisplayMetrics = getResources().getDisplayMetrics();
        mHalfScreenWidth = mdDisplayMetrics.widthPixels / 2;  //获取一般屏幕宽度
    }


    private void initListener() {
        //为本就添加onTouch事件是为了响应点击车出现popupwindow显示车辆详情
        mBackgroundView.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                int backgroundWidth = mBackgroundView.getWidth();

                int offSetLength = backgroundWidth / 4;

                int carTypeViewHalfLength = mCarTypeView.getWidth() / 2;

                int carTypeViewHigh = mCarTypeView.getHeight();

                switch (event.getAction()) {
                    case MotionEvent.ACTION_UP:
                        int upX = (int) event.getRawX();
                        updateCarTypeStatus(offSetLength, carTypeViewHalfLength, carTypeViewHigh, upX);
                        break;

                    default:
                        break;
                }
                return true;
            }
        });

        mCarTypeView.setOnTouchListener(new OnTouchListener() {

            private int mStartX = 0; //x记录起始位置

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                int backgroundLeft = mBackgroundView.getLeft();  //背景左边坐标

                int backgroundWidth = mBackgroundView.getWidth();  //背景宽度

                int offSetLength = backgroundWidth / 4;   //背景1/4宽度

                int carTypeViewHalfLength = mCarTypeView.getWidth() / 2;  //车辆宽度  1/2

                int carTypeViewHigh = mCarTypeView.getHeight(); //车辆高度

                int upX;   //为了在松开手时车辆弹回使用

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mStartX = (int) event.getRawX();    //按下时的x轴坐标
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int newX = (int) event.getRawX(); //移动时 x坐标
                        int dX = newX - mStartX;    //移动坐标 - 按下坐标  记录偏移量
                        int newl = mCarTypeView.getLeft() + dX;  //车辆图片加入left right添加偏移量
                        int newr = mCarTypeView.getRight() + dX;
                        if (newl <= backgroundLeft || newr > (backgroundLeft + backgroundWidth)) {  // 左侧坐标偏移过背景左侧,右侧坐标偏移过背景右侧,不处理
                            break;
                        }
                        mCarTypeView.layout(
                                mCarTypeView.getLeft() + dX,
                                mCarTypeView.getTop(),
                                mCarTypeView.getRight() + dX,
                                mCarTypeView.getBottom());     //将坐标设置进去 实现车辆跟随手指移动,只是移动了x轴,top bottom不变
                        mStartX = (int) event.getRawX();   //记录x新的起始位置
                        break;
                    case MotionEvent.ACTION_CANCEL://个人理解这个状态是 甩手的 状态跟 up类似
                        upX = (int) event.getRawX();
                        updateCarTypeStatus(offSetLength, carTypeViewHalfLength, carTypeViewHigh, upX);
                        break;
                    case MotionEvent.ACTION_UP:
                        upX = (int) event.getRawX();  //手指抬起时记录 抬起时x轴的位置
                        updateCarTypeStatus(offSetLength, carTypeViewHalfLength, carTypeViewHigh, upX);
                        break;

                    default:
                        break;
                }
                return true;  //如果让车子响应onclick方法这个要返回false
            }

        });

    }


    /**
     * 手指抬起后,实现车辆回弹。不能你拖到哪里就在哪里,那样有点太尴尬了 --- 这里的定位方式是要画图说明的
     * @param offSetLength
     * @param carTypeViewHalfLength
     * @param carTypeViewHigh
     * @param upX
     */
    private void updateCarTypeStatus(int offSetLength, int carTypeViewHalfLength, int carTypeViewHigh, int upX) {
        if (upX < mHalfScreenWidth - offSetLength) {  //如果在中间偏左,那就定位在左边
            mCarTypeView.layout(
                    mBackgroundView.getLeft(),
                    mBackgroundView.getTop(),
                    mBackgroundView.getLeft() + (2 * carTypeViewHalfLength),
                    mBackgroundView.getTop() + carTypeViewHigh);
        } else if (upX >= (mHalfScreenWidth - offSetLength) && upX <= (mHalfScreenWidth + offSetLength)) {  //如果在中间,那就定位在中间
            mCarTypeView.layout(
                    mBackgroundView.getLeft() + (2 * offSetLength) - carTypeViewHalfLength,
                    mBackgroundView.getTop(),
                    mBackgroundView.getLeft() + (2 * offSetLength) + carTypeViewHalfLength,
                    mBackgroundView.getTop() + carTypeViewHigh);

        } else if (upX > (mHalfScreenWidth + offSetLength)) {  //如果在中间偏右,那就定位在右边
            mCarTypeView.layout(
                    mBackgroundView.getLeft() + (4 * offSetLength) - (2 * carTypeViewHalfLength),
                    mBackgroundView.getTop(),
                    mBackgroundView.getLeft() + (4 * offSetLength),
                    mBackgroundView.getTop() + carTypeViewHigh);
        }
    }
}


绘制view思路




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值