DirectionControlView 一个方向控制自定义View

这是一个可识别上滑,下滑,左滑,右滑,方向识别与控制的自定义View


Demo下载:我的Github DirectionControlView

DirectionControlView它是一个控制面板之类的View,可以处理在这个View上面,左滑,右滑,上滑,下滑,单击,双击事件。

这个自定义View设计起来非常简单,使用的核心就是:GestureDetector,手势识别器,我只是把它用到了这个View里,然后对外提供接口。

下面要说设计思路了。

1,在自定义View里创建GestureDetector对象,设置监听器 OnGestureListener,OnDoubleTapListener。

2,让GestureDetector对象接管这个View的Event事件。

3,声明一个包含所有状态的接口,供外面使用。

4,处理单击,长按,双击事件。

5,处理上下左右滑动事件。

DirectionControlView设计思路就是酱子。


接下来看代码详细的分析上述所说的步骤。

1,在自定义View里创建GestureDetector对象,设置监听器 OnGestureListener,OnDoubleTapListener。


    public class DirectionControlView extends View implements
            GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

        private static final String TAG = DirectionControlView.class.getSimpleName();
        private static final int MIN_OFFSET_VALUE = 20;
        private GestureDetector mGestureDetector;
        private DirectionControlListener mDirectionControlListener;

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

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

        public DirectionControlView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }

        private void init() {
            mGestureDetector = new GestureDetector(this);
            mGestureDetector.setOnDoubleTapListener(this);
        }

2,让GestureDetector对象接管这个View的Event事件。


        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return mGestureDetector.onTouchEvent(event);
        }

3,声明一个包含所有状态的接口,供外面使用。


        public interface DirectionControlListener {
            void singleClick();

            void longClick();

            void doubleClick();

            void leftSlide();

            void rightSlide();

            void upSlide();

            void downSlide();
        }

        public void setControlStateListener(DirectionControlListener listener) {
            mDirectionControlListener = listener;
        }

4,处理单击,长按,双击事件。


        @Override
        public boolean onDown(MotionEvent motionEvent) {
            Log.i(TAG, "onDown");
            return true;
        }

        @Override
        public void onShowPress(MotionEvent motionEvent) {
            Log.i(TAG, "onShowPress");
        }

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            Log.i(TAG, "onSingleTapUp");

            if (mDirectionControlListener != null) {//单击事件
                mDirectionControlListener.singleClick();
            }
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.i(TAG, "onScroll");
            return false;
        }

        @Override
        public void onLongPress(MotionEvent motionEvent) {
            Log.i(TAG, "onLongPress");

            if (mDirectionControlListener != null) {//长按点击事件
                mDirectionControlListener.longClick();
            }
        }


        @Override
        public boolean onDoubleTap(MotionEvent motionEvent) {
            Log.i(TAG, "onDoubleTap");

            if (mDirectionControlListener != null) {//双击事件
                mDirectionControlListener.doubleClick();
            }
            return true;
        }

5,处理上下左右滑动事件。


        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            Log.i(TAG, "onFling");

            float offsetX = e1.getX() - e2.getX();//X方向偏移量
            float offsetY = e1.getY() - e2.getY();//Y方向偏移量

            if (Math.abs(offsetX) > Math.abs(offsetY)) {//左滑或者右滑
                if (e1.getX() - e2.getX() > MIN_OFFSET_VALUE) {
                    if (mDirectionControlListener != null) {//左滑
                        mDirectionControlListener.leftSlide();
                    }
                } else {
                    if (mDirectionControlListener != null) {//右滑
                        mDirectionControlListener.rightSlide();
                    }
                }
            } else {//上滑或者下滑
                if (e1.getY() - e2.getY() > MIN_OFFSET_VALUE) {
                    if (mDirectionControlListener != null) {//上滑
                        mDirectionControlListener.upSlide();
                    }
                } else {
                    if (mDirectionControlListener != null) {//下滑
                        mDirectionControlListener.downSlide();
                    }
                }
            }
            return true;
        }

处理上下左右滑动,我这里只做了简单的处理,其实可以做更细致一些,需要修改的可以自行修改业务逻辑。

最后,就可以在外面直接使用了。


我的Demo里的布局中文使用情况:


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.zhan.directioncontrolview.widget.DirectionControlView
            android:id="@+id/main_dcv"
            android:layout_weight="1"
            android:background="#41E194"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/main_tv"
            android:gravity="center"
            android:textSize="25sp"
            android:text="Show"
            android:textColor="@android:color/white"
            android:background="#4164E1"
            android:layout_width="match_parent"
            android:layout_height="50dp" />

       </LinearLayout>

代码中使用:


    public class MainActivity extends AppCompatActivity 
            implements DirectionControlView.DirectionControlListener {

        private DirectionControlView mDirectionControlView;
        private TextView mTextView;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            mDirectionControlView.setControlStateListener(this);
        }

        private void initView() {
            mDirectionControlView = (DirectionControlView) findViewById(R.id.main_dcv);
            mTextView = (TextView) findViewById(R.id.main_tv);
        }

        private void showToast(String str) {
            mTextView.setText(str);
        }

        @Override
        public void singleClick() {
            showToast("单击");
        }

        @Override
        public void longClick() {
            showToast("长按");
        }

        @Override
        public void doubleClick() {
            showToast("双击");
        }

        @Override
        public void leftSlide() {
            showToast("左滑");
        }

        @Override
        public void rightSlide() {
            showToast("右滑");
        }

        @Override
        public void upSlide() {
            showToast("上滑");
        }

        @Override
        public void downSlide() {
            showToast("下滑");
        }
    }

DirectionControlView这个自定义View就这样分析完了。

再来看一次效果图:

让它做一个简单识别: 上下左右 并进行业务逻辑处理,我想还是不错的。

Demo下载:我的Github DirectionControlView

2016年7月03日 14:11:34

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的圆形进度条的自定义View实现: ```java public class CircleProgressBar extends View { private float mProgress = 0; // 当前进度值 private float mMax = 100; // 最大进度值 private int mCircleWidth = 10; // 圆环宽度 private int mCircleColor = Color.GRAY; // 圆环颜色 private int mProgressColor = Color.BLUE; // 进度条颜色 private Paint mPaint; public CircleProgressBar(Context context) { super(context); init(); } public CircleProgressBar(Context context, AttributeSet attrs) { super(context, attrs); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar); mCircleWidth = ta.getDimensionPixelSize(R.styleable.CircleProgressBar_circleWidth, 10); mCircleColor = ta.getColor(R.styleable.CircleProgressBar_circleColor, Color.GRAY); mProgressColor = ta.getColor(R.styleable.CircleProgressBar_progressColor, Color.BLUE); ta.recycle(); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centerX = getWidth() / 2; int centerY = getHeight() / 2; int radius = getWidth() / 2 - mCircleWidth / 2; // 画圆环 mPaint.setColor(mCircleColor); mPaint.setStrokeWidth(mCircleWidth); mPaint.setStyle(Paint.Style.STROKE); canvas.drawCircle(centerX, centerY, radius, mPaint); // 画进度条 mPaint.setColor(mProgressColor); mPaint.setStrokeWidth(mCircleWidth); mPaint.setStyle(Paint.Style.STROKE); RectF rectF = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius); canvas.drawArc(rectF, -90, 360 * mProgress / mMax, false, mPaint); } public void setProgress(float progress) { mProgress = progress; invalidate(); } public void setMax(float max) { mMax = max; invalidate(); } } ``` 其中,我们可以设置圆环的宽度、圆环颜色、进度条颜色等属性。在onDraw()方法中,我们先画出圆环,然后再画出进度条,进度条的弧度根据当前进度值和最大进度值计算得出。 使用时,可以在布局文件中添加如下代码: ```xml <com.example.customview.CircleProgressBar android:id="@+id/circle_progress_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" app:circleColor="#FFA500" app:circleWidth="20dp" app:progressColor="#00BFFF" /> ``` 然后在代码中设置进度值即可: ```java CircleProgressBar circleProgressBar = findViewById(R.id.circle_progress_bar); circleProgressBar.setMax(100); circleProgressBar.setProgress(50); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值