这是一个可识别上滑,下滑,左滑,右滑,方向识别与控制的自定义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