关于onTouchEvent跟OnClickListener冲突的问题
来源:互联网 发布:绿色贸易壁垒的数据 编辑:程序博客网 时间:2024/06/05 10:22
最近在做一个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;
}
@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冲突的问题就说到这里。
- 关于onTouchEvent跟OnClickListener冲突的问题
- View OnclickListener与new DialogInterface.OnClickListener()冲突的问题
- onTouchListener和onClickListener的冲突问题
- 关于onTouchEvent跟onInterceptEvent的事件处理
- View.onClickListener和DialogInterface.onClickListener冲突问题
- listview与onTouchEvent的冲突问题
- 【Android开发】解决不同的OnClickListener冲突的问题
- 解决ViewPager.OnPageChangeListener 和 OnClickListener 冲突的问题
- 解决ViewPager.OnPageChangeListener 和 OnClickListener 冲突的有关问题
- 请教关于 View.OnClickListener() 的问题
- ontouchEvent,ontouchListener,onclickListener的执行顺序
- 关于VS跟IE冲突的解决方法
- OnClickListener导包冲突问题及其解决方案
- 导包View.OnClickListener和DialogInterface.OnClickListener冲突的解决方案
- 导包View.OnClickListener和DialogInterface.OnClickListener冲突的解决方案
- 导包View.OnClickListener和DialogInterface.OnClickListener冲突的解决方案
- 论onclicklistener、ontouchlistener、ontouchevent
- viewpager跟HorizontalScrollView,listview冲突的问题
- tomcat类加载器的层次及加载路径
- 汉诺塔求解
- Qt程序在windows 和 linux 下打包发布
- 云计算之路-阿里云上:Linux内核bug引起的“黑色10秒钟”
- TCP协议知识点总结
- 关于onTouchEvent跟OnClickListener冲突的问题
- 得到手机sim卡的相关信息
- 《统计学习方法》笔记(十一)--SMO
- qt学习笔记(一)之Hello world
- Dragon of Loowater
- Linux下JDK中文字体乱码
- UIButton UIEdgeInsetsMake
- LintCode 丑数
- Struts2 上传文件方法