DirectionControlView 一个方向控制自定义View

来源:互联网 发布:js实现文件的上传下载 编辑:程序博客网 时间:2024/04/29 17:18
这是一个可识别上滑,下滑,左滑,右滑,方向识别与控制的自定义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 0