关于onTouchEvent跟OnClickListener冲突的问题

原创 2015年07月09日 14:49:50

最近在做一个app项目,自己学习android只有半年,做起来还是很吃力的。很多东西感觉有映像,真正用到的时候还是有很多细节不了解,又要查找资料、问大神什么的。算是自我鼓励吧,跟自己说加油!


说回正题,项目有个这样的需求。就像微信 “我” 那一栏,每项点击的时候背景改了,直到你松开手指背景才改回来并且跳到一个界面去。我按照自己的方法去做,遇到onTouchEvent跟OnClickListener冲突的问题。说白了就是只会触发onTouchEvent()方法,不会执行OnClickListener的onClick()方法。经过查找资料解决了顺便分享出来,希望大家遇到类似问题可以顺利解决。


上代码前先讲下逻辑,这样看起来比较方便。我在自定义控件类中覆写onTouchEvent()方法来跟换控件背景。点击控件时会触发MotionEvent.ACTION_DOWN事件,在这里将背景改为点击时的背景。松开手指时触发MotionEvent.ACTION_UP事件,在这里将背景改回来。最后在主界面中给组合控件设置点击监听(也就是设置OnClickListener),点击时跳到某个界面中


首先上MainActivity的代码,代码还算简单:

package com.example.test;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity implements OnClickListener{
private PersonalCustomView personal_edit_personaldata;  

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

personal_edit_personaldata = (PersonalCustomView) findViewById(R.id.personal_edit_personaldata);
personal_edit_personaldata.setOnClickListener(this);

}

@Override
public void onClick(View v) {

switch (v.getId()) {
//用户点击修改资料,跳刀修改资料界面
case R.id.personal_edit_personaldata:
Intent intent = new Intent(this, PersonalDataEditActivity.class);
startActivity(intent);

break;
}
}

接着上主界面的布局文件代码,也很简单,就是用到了自定义组合控件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:personal="http://schemas.android.com/apk/res/com.example.test"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

    <!-- 修改资料的布局 -->
    <com.example.test.PersonalCustomView
        android:id="@+id/personal_edit_personaldata"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        personal:personal_item_icon="@drawable/ic_launcher"
        personal:personal_item_text="修改资料" >
    </com.example.test.PersonalCustomView>


</LinearLayout>


代码很简单吧!


结下了就是自定义组合控件的代码。关于自定义组合控件这里就不说了。我有些过一篇关于自定义自定义组合控件的文章,有兴趣可以看一下<自定义组合控件>。

先上自定义组合控件的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/personal_root"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:gravity="center_vertical"
    android:background="#ffffff"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/personal_item_icon"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_gravity="center"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="10dp"/>

    <TextView
        android:id="@+id/personal_item_text"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:gravity="center_vertical"
        android:textSize="16sp" />
</LinearLayout>


自定义属性代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="PersonalCustomView">
        <attr name="personal_item_icon" format="reference" />
        <attr name="personal_item_text" format="string" />
    </declare-styleable>
</resources>

 

接下来就是代码了,先上代码,在详解具体问题:

package com.example.test;

import com.example.test.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.View.OnTouchListener;

public class PersonalCustomView extends LinearLayout implements OnTouchListener {
private ImageView personal_item_icon;
private TextView personal_item_text;
private LinearLayout personal_root;

@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();


switch (action) {
// 当用户点击了该自定义组合控件时,跟换背景
case MotionEvent.ACTION_DOWN:
personal_root.setBackgroundColor(Color.rgb(64, 161, 255));
break;
// 当用户松开手时将背景设置回原来的样子
case MotionEvent.ACTION_UP:
personal_root.setBackgroundColor(Color.rgb(255, 255, 255));
break;
}
return false;
}

public void initView(Context context) {
View.inflate(context, R.layout.customview_personal, this).setOnTouchListener(this); //.....
personal_item_icon = (ImageView) this
.findViewById(R.id.personal_item_icon);
personal_item_text = (TextView) this
.findViewById(R.id.personal_item_text);
personal_root = (LinearLayout) this.findViewById(R.id.personal_root);
}
public PersonalCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.PersonalCustomView);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.PersonalCustomView_personal_item_icon:
int resource = a.getResourceId(i, 0);
personal_item_icon.setImageResource(resource);
break;
case R.styleable.PersonalCustomView_personal_item_text:
// 默认颜色设置为黑色
String title = a.getString(i);
personal_item_text.setText(title);
break;
}
}
}
}


红色部分代码是问题的关键,点击事件触发顺序:

Touch事件的ACTION_DOWN ->  ACTION_UP  ->  OnClick/OnLongClick
onTouchEvent()方法中,如果事件返回true,就会截断事件的下传,通俗点之后的ACTION_UP以及OnClick/OnLongClick就不会在触发了。如果返回false,应该是可以解决问题的,但是经测试,上面的红色代码实现应有的功能。有几种方法可以解决问题。

1、而onTouchEvent()中执行super.onTouchEvent(event)可以解决问题。

@Override
public boolean onTouchEvent(MotionEvent event) {

super.onTouchEvent(event);
int action = event.getAction();


switch (action) {
// 当用户点击了该自定义组合控件时,跟换背景
case MotionEvent.ACTION_DOWN:
personal_root.setBackgroundColor(Color.rgb(64, 161, 255));
break;
// 当用户松开手时将背景设置回原来的样子
case MotionEvent.ACTION_UP:
personal_root.setBackgroundColor(Color.rgb(255, 255, 255));
break;
}
return false;
}

2、不用onTouchEvent(),而用onTouch()

@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
// 当用户点击了该自定义组合控件时,跟换背景
case MotionEvent.ACTION_DOWN:
personal_root.setBackgroundColor(Color.rgb(64, 161, 255));
break;

// 当用户松开手时将背景设置回原来的样子
case MotionEvent.ACTION_UP:
personal_root.setBackgroundColor(Color.rgb(255, 255, 255));
break;
}

return false;
}

3、自定义组合控件提供调用接口,在接口中跳转界面

类中添加代码:

private PersonalActionUpListener listener;
//点击松开的监听器
public interface PersonalActionUpListener{

//松开手指的回调方法
public void personalCallBack(View v);
}

//设置监听器
public void setListener(PersonalActionUpListener listener){
this.listener = listener;

}

然后onTouchEvent中调用回调:

@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();


switch (action) {
// 当用户点击了该自定义组合控件时,跟换背景
case MotionEvent.ACTION_DOWN:
personal_root.setBackgroundColor(Color.rgb(64, 161, 255));
break;


// 当用户松开手时将背景设置回原来的样子

case MotionEvent.ACTION_UP:
personal_root.setBackgroundColor(Color.rgb(255, 255, 255));
listener.personalCallBack(this);
break;
}

return true;
}

最后在主界面中调用setListener()并实现PersonalActionUpListener接口:代码已经在上面给出


关于onTouchEvent跟OnClickListener冲突的问题就说到这里。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

解决onTouchListener和onClickListener冲突

package com.flrsdk.service; import com.flrsdk.activity.Activity_Community; import com.unionpay.upom...

Android关于OnTouch 和OnClick同时调用冲突的解决方案

Button的onTouch,onClick,onLongClick事件发生先后顺序和关联: 一,onTouch返回false 首先是onTouch事件的down事件发生,此时,如果长按,触发on...

Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法

今天在做项目的时候遇到一个问题,就是怎么让ListView中的item点击后其内部的内容跟着变色,比如现在我的item布局中有一个TextView,现在点击item的时候,让其背景色发生改变,这个我们...

Android中onClick事件和onTouchEvent事件冲突问题的解决方案

onClick事件和onTouchEvent 方法冲突的解决方案

Android系统中View的onTouchEvent和OnTouch区别

以自定义的TestButton为例。 我们可以通过重写onTouchEvent方法来处理诸如down move up的消息: ? 1 2 3 4 5 6 7 8 9 10 11 12 13...
  • DQ1005
  • DQ1005
  • 2016-06-04 20:35
  • 1185

解决ViewPager.OnPageChangeListener 和 OnClickListener 冲突的问题

如果这两种监听事件同时存在  那么直接让paperView 设置这两种监听  是不会响应点击事件的 那么想通过点击图片返回原页面 就成为泡影 其实只要把OnClick事件  加载到 paperV...

android使用GestureDetector实现手势下滑与ListView onTouchEvent 冲突问题 解决

在实际开发中你可能需要把ListView中的onTouchEvent写在Activity中进行操作,或者是同时存在对ListView或者Activity的不同向操作(例如向左右向上下滑动绑定不同事件)...

论onclicklistener、ontouchlistener、ontouchevent

本人新人写点自己的心得和

Android的事件分发onInterceptTouchEvent与onTouchEvent、OnClickListener、OnLongClick

onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截. ...

onTouchEvent事件冲突

做项目的时候需要用到两个效果,一个是仿建行圆形菜单效果,一个是侧滑菜单效果。但是添加后发现两个事件有冲突。盲目的修改一天之后突然醒悟,还是先学习一下事件及方法是怎么传递的,明白了里边的原理才能更好的解...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)