Android基础:listview的item点击事件会使里面的Button也出现按压的效果

本文介绍了解决 ListView 中 Button 的按下效果与点击监听冲突的问题。提供了两种解决方案:一是禁用 ListView 的点击监听;二是使用自定义 Button 判断并阻止事件传递。附带提供了一段实现自定义 Button 的代码。

给listview里面的button设置selector后,当给listview设置listview.setOnitemClickedListener()的时候,里面的button会有press的效果,有两个方案

1:放弃listview的onItemClickedListener()

listview.setOnItemClickedListener(null);

2:使用自定义的Button,判断他的父控件是否press,如果是就把这个事件消耗掉,不向下传递即可,

可用代码如下:


package com.audiocn.kalaok.widget;
 
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
 
public class FixedListButton extends Button {
 
    public FixedListButton(Context context) {
        super(context);
    }
 
    public FixedListButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    public FixedListButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
 
    @Override
    public void setPressed(boolean pressed) {
        if (pressed && getParent() instanceof View
                && ((View) getParent()).isPressed()) {
            return;
        }
        super.setPressed(pressed);
    }

}


原文地址:http://www.cnblogs.com/0616--ataozhijia/archive/2012/11/02/2751731.html

<think>首先,用户查询是:“我想查找在Android中动态设置按压事件的方法 请问Android动态设置按压事件的方法”。这表明用户想知道如何在Android应用中动态地为视图(如按钮)设置按压事件。 我有两个引用: - 引用[1]:讨论了在Android中动态设置button的Pressed态图片。它提到在创建Activity时传入nominal和press资源ID,然后在appBar中动态监测imageButton的pressed态并设置背景图片。 - 引用[2]:描述了使用GridView实现9宫格菜单,并实现item点击按压效果更改图片。它提到了使用GridView布局,设置水平和垂直间距。 这些引用都涉及按压事件的处理,特别是改变图片或背景以响应按压状态。 用户上一次的问题和我的回答:用户的问题是“我想查找在Android中动态设置按压事件的方法”,而我的系统指令要求我基于引用和用户查询回答。指令说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 这里是第一个交互,所以没有“上一次的问题和回答”。我应该专注于当前的查询。 系统级指令: - 回答使用中文。 - 行内数学表达式用$...$格式(但这里可能不相关)。 - 独立公式用$$...$$格式(不相关)。 - LaTeX语法正确(可能不适用)。 - 生成相关问题(在回答末尾)。 - 在回答中引用的段落末尾添加引用标识,例如[^1]。 回答结构:结构清晰,帮助用户逐步解决问题,保证真实可靠。 关键点:用户想知道“动态设置按压事件的方法”。在Android中,按压事件通常关联到触摸事件(如ACTION_DOWN和ACTION_UP),或者通过设置按压状态的监听器来实现按压效果。 从引用[1],它涉及动态设置Pressed态图片,这可以通过设置一个selector drawable来实现,但引用提到动态方式:传入资源ID并监测pressed态。 在Android中,动态设置按压事件的方法包括: 1. 使用Selector:创建一个XML drawable(如selector)定义不同状态的图片(normal, pressed, focused等),然后动态应用到视图的背景或src。 2. 编程方式设置监听器:使用setOnTouchListener来侦测按压事件(ACTION_DOWN和ACTION_UP),并在事件发生时改变视图的图片或背景。 3. 对于按钮等控件,可以使用setBackgroundDrawable或setImageResource动态设置状态列表。 引用[1]提到“动态监测imageButton的pressed态”,这暗示使用OnTouchListener或类似方法。 Android中,View有setOnTouchListener方法来处理触摸事件。用户可以覆盖onTouch方法,检查事件类型(如MotionEvent.ACTION_DOWN表示按压开始,MotionEvent.ACTION_UP表示按压结束)。 步骤概述: - 获取视图引用(如Button或ImageView)。 - 设置一个OnTouchListener。 - 在onTouch方法中,根据事件类型改变视图背景或图片。 例如: ```java button.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: v.setBackgroundResource(R.drawable.pressed_image); // 设置按压时的图片 break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: v.setBackgroundResource(R.drawable.normal_image); // 设置正常时的图片 break; } return false; // 返回false以允许其他事件处理 } }); ``` 另外,引用[2]提到GridView的item点击按压效果,这可以通过设置适配器中的视图状态来实现,或者使用selector。 在GridView中,为每个item设置按压效果,通常使用selector drawable定义在布局文件中。 但用户指定“动态设置”,意思是代码中动态配置,而不是XML中硬编码。 所以,我应该强调动态方式。 生成相关问题:在回答末尾,添加相关问题,基于主题。 引用标识:在回答中,如果引用引用内容,末尾加[^1]或[^2]。 我的回答应该包括: 1. 引言:解释动态设置按压事件的方法。 2. 步骤:逐步说明如何实现,使用OnTouchListener。 3. 代码示例:提供Java或Kotlin代码片段(用户引用中有Java代码,所以我用Java)。 4. 基于引用的内容:引用[1]提到动态监测pressed态,我可以引用它。 5. 相关问题。 确保中文回答。 最终回答结构: - 解释方法:动态设置按压事件通常通过OnTouchListener实现。 - 详细步骤。 - 代码示例。 - 结尾:添加相关问题。 </think>### Android动态设置按压事件的方法 在Android开发中,动态设置按压事件(press event)通常涉及为视图(如Button、ImageView或自定义View)编程方式添加触摸监听器(OnTouchListener),以响应按压状态(如按下和释放)。这种方法避免了硬编码XML选择器(selector),适用于运行时动态修改按压效果(如改变背景图片)。以下是详细的步骤说明和代码示例,基于您提供的引用内容并结合Android官方文档[^Android Docs]。 #### 步骤说明 1. **理解按压事件**:按压事件由触摸动作触发,包括: - `MotionEvent.ACTION_DOWN`:用户按下视图时触发。 - `MotionEvent.ACTION_UP`:用户释放视图时触发。 - `MotionEvent.ACTION_CANCEL`:事件被取消(如滑动出视图范围)时触发。 通过监听这些动作,可以动态设置按压态图片或背景[^1]。 2. **核心方法**:使用`View.setOnTouchListener()`动态设置监听器: - 在代码中获取视图引用(如findViewById)。 - 实现`OnTouchListener`接口,在`onTouch`方法中处理按压状态。 - 根据事件类型动态切换图片资源(如正常态和按压态)。 3. **优化建议**: - **资源管理**:引用[1]提到传入资源ID动态设置图片建议使用资源ID参数化,便于复用。 - **性能考虑**:避免在监听器中做耗时操作,确保UI响应流畅。 - **兼容性**:适用于所有View子类(如Button、ImageView),也支持GridView的item按压效果(如引用[2]的9宫格菜单)。 #### 代码示例 以下是一个完整的Java示例,展示如何为Button动态设置按压事件:当用户按下时切换按压态图片,释放时恢复正常态图片。 ```java // 假设在Activity或Fragment中 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取Button视图 Button myButton = findViewById(R.id.my_button); // 动态设置按压事件监听器 myButton.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下时设置按压态图片(动态传入资源ID) v.setBackgroundResource(R.drawable.button_pressed); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 释放或取消时设置正常态图片 v.setBackgroundResource(R.drawable.button_normal); break; } // 返回false以允许其他事件(如点击事件)继续处理 return false; } }); } } ``` #### 关键细节说明 - **资源准备**:提前在`res/drawable`文件夹添加图片资源(如`button_normal.png`和`button_pressed.png`)。 - **动态参数化**:如引用[1]所述,您可以在创建Activity时传递资源ID参数,实现更灵活的配置: ```java public void setupButtonPressEffect(Button button, int normalResId, int pressedResId) { button.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { v.setBackgroundResource(pressedResId); } else if (event.getAction() == MotionEvent.ACTION_UP) { v.setBackgroundResource(normalResId); } return false; }); } ``` - **GridView集成**:对于GridView的item(如9宫格菜单),在Adapter的`getView`方法中为每个item视图设置监听器。引用[2]的布局可复用,结合上述代码实现动态按压效果[^2]。 - **注意事项**: - 如果同时需要点击事件,使用`setOnClickListener`独立处理。 - 在`onTouch`方法中返回`false`确保事件传递给其他监听器。 #### 相关问题 1. 如何在Android中为自定义View实现按压状态反馈? 2. 动态设置按压事件与XML selector相比有哪些优缺点? 3. 如何处理ListView或RecyclerView中item按压效果优化性能?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值