Android ImageButton的使用 及长按Button的实现

本文介绍如何使用Android自定义ImageButton实现长按事件。通过创建RepeatButton类并重写相关方法,实现不同间隔时间的长按回调。同时提供了一个示例项目供下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我自己用Photoshop画了2种按钮图片,每种有3种状态,分为:normal、focus、press等。
放在工程的“res/drawable/”目录下。
ImageButton要使用这些图片做出漂亮的效果,可以在Java代码中使用setImageResource(int)方法,我采用xml文件中设置android:src属性。

在工程目录“res/drawable/”下新建“imgbt1.xml”,文件内容为:
[html]   view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.   
  4.     <item android:state_pressed="true"  
  5.            android:drawable="@drawable/bt1_press" /> <!-- pressed -->  
  6.     <item android:state_focused="true"  
  7.            android:drawable="@drawable/bt1_focus" /> <!-- focused -->  
  8.     <item android:drawable="@drawable/bt1_normal" /> <!-- default -->  
  9.   
  10. </selector>  

新建“imgbt2.xml”,文件内容为:
[html]   view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.   
  4.     <item android:state_pressed="true"  
  5.            android:drawable="@drawable/bt2_press" /> <!-- pressed -->  
  6.     <item android:state_focused="true"  
  7.            android:drawable="@drawable/bt2_focus" /> <!-- focused -->  
  8.     <item android:drawable="@drawable/bt2_normal" /> <!-- default -->  
  9.   
  10. </selector>  

使用方法:
[html]   view plain copy
  1. <ImageButton  
  2.     android:id="@+id/imgbt1"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="#a000ff00"  
  6.     android:src="@drawable/imgbt1"  
  7.     />  
android:background="#a000ff00" 可设置Button或者ImageButton的背景为透明
表达式顺序是“aabbggrr”,其中“aa=alpha”(00-ff)、“bb=blue”(00-ff)、“gg=green”(00-ff)、“rr=red”(00-ff)。值以十六进制表示,对于alpha值,0表示完全透明,255表示完全不透明。
看文档,可在Java代码中使用方法onSetAlpha (int alpha)来设置透明度。


Button长按事件的实现
我在网上查看资料的时候,看到一篇游戏开发的长按Button实现,关键代码有给出,但都是抄来抄去,且并不完全,决定实现它。
增加个接口,用来实现监听事件。
[java]   view plain copy
  1. public interface RepeatListener  
  2. {  
  3.     /** manpeng 
  4.      * @param v 用户传入的Button对象 
  5.      * @param duration 延迟的毫秒数 
  6.      * @param repeatcount 重复次数回调 
  7.      */  
  8.     void onRepeat(View v, long duration, int repeatcount);  
  9. }  

既然要实现ImageButton类的长按事件,首先自定义RepeatButton类,当然这个类要继承ImageButton。
需要增加RepeatButton类的成员变量mInterval,用来记录长按的时间,也就是说press这个按钮的时候,多久时间算一次长按。
例:mInterval=5000;//mInterval设为5秒钟,假设用户长按Button了12秒,那么用户长按了该按钮2次。

当长按时,会执行performLongClick(),我们override该方法,并启动一个线程。
这是一个Runnable线程mThread,在线程实现中,每隔mInterval时间,判断按键是否还在按下,以及回调监听事件,是实现长按Button的关键。
postDelayed(this, mInterval);//这句实现了长按事件中,线程mThread不断的循环判断

当用户结束长按的时候,根据触摸或按键的不同,此时可能触发onTouchEvent或触发onKeyDown函数,我们override这2个函数后,在其中要停止线程。
因为是延迟一定的时间,才执行线程,所以在结束长按的时候要把没有执行的线程drop掉:
removeCallbacks(mThread);//删除队列当中未执行的线程对象,否则线程可能还会再执行一次。
下面给出RepeatButton类的代码:
[java]   view plain copy
  1. /* 
  2.  * Copyright (C) 2012 Manpeng 
  3.  * 
  4.  * http://blog.youkuaiyun.com/manp1212 
  5.  * 
  6.  */  
  7. package com.manpeng.example;  
  8.   
  9. import android.content.Context;  
  10. import android.os.SystemClock;  
  11. import android.util.AttributeSet;  
  12. import android.util.Log;  
  13. import android.view.KeyEvent;  
  14. import android.view.MotionEvent;  
  15. import android.widget.ImageButton;  
  16.   
  17. /** 
  18.  * @author manpeng 
  19.  */  
  20. public class RepeatButton extends ImageButton  
  21. {  
  22.     public static final String TAG = "RepeatButton";  
  23.     private long mStart;//长按开始时间  
  24.     private int mRepeatCount;//长按重复次数  
  25.     private RepeatListener mListener;//  
  26.     private long mInterval = 500;//长按一次持续时间   
  27.   
  28.     public RepeatButton(Context context)  
  29.     {  
  30.         super(context);  
  31.         Log.d(TAG, "RepeatButton1");  
  32.     }  
  33.   
  34.     public RepeatButton(Context context, AttributeSet attrs)  
  35.     {  
  36.         super(context, attrs);  
  37.         Log.d(TAG, "RepeatButton");  
  38.         setFocusable(true); //设置焦点  
  39.         setLongClickable(true); //启用长按事件,长按后会执行performLongClick()  
  40.     }  
  41.   
  42.     public RepeatButton(Context context, AttributeSet attrs, int defStyle)  
  43.     {  
  44.         super(context, attrs, defStyle);  
  45.         Log.d(TAG, "RepeatButton3");  
  46.     }  
  47.   
  48.     private Runnable mThread = new Runnable()  
  49.     {  
  50.         public void run()  
  51.         {  
  52.             Log.d(TAG, "mRepeaterThread run()");  
  53.             doRepeat(false);  
  54.             if (isPressed())  
  55.             {  
  56.                 Log.d(TAG, "mRepeaterThread run() press");  
  57.                 postDelayed(this, mInterval);//延迟mInterval后执行当前线程  
  58.             }  
  59.         }  
  60.     };  
  61.       
  62.     /** 
  63.      * @param end 表示最后一次长按,即结束长按事件 
  64.      */  
  65.     private void doRepeat(boolean end)  
  66.     {  
  67.         Log.d(TAG, "mRepeaterThread run() end=" + end);  
  68.         long now = SystemClock.elapsedRealtime();//获取当前时间  
  69.         if (mListener != null)  
  70.         {  
  71.             mListener.onRepeat(this, now - mStart, end ? -1 : mRepeatCount++);  
  72.         }  
  73.     }  
  74.       
  75.     /** 
  76.      * 长按结束 
  77.      */  
  78.     private void endRepeat()  
  79.     {  
  80.         doRepeat(true);  
  81.         mStart = 0;  
  82.     }  
  83.       
  84.     /** 
  85.      * 设置长按监听事件,初始化mInterval 
  86.      */  
  87.     public void setRepeatListener(RepeatListener listener, long interval)  
  88.     {  
  89.         Log.d(TAG, "setRepeatListener interval=" + interval);  
  90.         mListener = listener;  
  91.         mInterval = interval;  
  92.     }  
  93.       
  94.     @Override  
  95.     public boolean performLongClick()  
  96.     {  
  97.         Log.d(TAG, "performLongClick");  
  98.         mStart = SystemClock.elapsedRealtime();//获取系统当前时间  
  99.         mRepeatCount = 0;  
  100.         post(mThread);//调用post()方法,执行mThread  
  101.         return true;  
  102.     }  
  103.       
  104.     @Override  
  105.     public boolean onTouchEvent(MotionEvent event)  
  106.     {  
  107.         if (event.getAction() == MotionEvent.ACTION_UP)  
  108.         {  
  109.             Log.d(TAG, "onTouchEvent UP");  
  110.             removeCallbacks(mThread);//删除队列当中未执行的线程对象     
  111.             if (mStart != 0)  
  112.             {  
  113.                 endRepeat();  
  114.             }  
  115.         }  
  116.         return super.onTouchEvent(event);  
  117.     }  
  118.       
  119.     @Override  
  120.     public boolean onKeyDown(int keyCode, KeyEvent event)  
  121.     {  
  122.         //Log.d(TAG, "onKeyDown keyCode=" + keyCode);  
  123.         switch(keyCode)  
  124.         {  
  125.         case KeyEvent.KEYCODE_DPAD_CENTER:  
  126.         case KeyEvent.KEYCODE_ENTER:  
  127.             super.onKeyDown(keyCode, event);  
  128.             return true;  
  129.         }  
  130.         return super.onKeyDown(keyCode, event);  
  131.     }  
  132.       
  133.     @Override  
  134.     public boolean onKeyUp(int keyCode, KeyEvent event)  
  135.     {  
  136.         Log.d(TAG, "onKeyUp keyCode=" + keyCode);  
  137.         switch(keyCode)  
  138.         {  
  139.         case KeyEvent.KEYCODE_DPAD_CENTER:  
  140.         case KeyEvent.KEYCODE_ENTER:  
  141.             removeCallbacks(mThread);  
  142.             if (mStart != 0)  
  143.             {  
  144.                 Log.d(TAG, "onKeyUp mStart=" + mStart);  
  145.                 endRepeat();  
  146.             }  
  147.             super.onKeyUp(keyCode, event);  
  148.             return true;  
  149.         }  
  150.         return super.onKeyUp(keyCode, event);  
  151.     }  
  152.       
  153. }  

在布局xml文件中,添加RepeatButton,需要以下定义。
[html]   view plain copy
  1. <com.manpeng.example.RepeatButton  
  2.     android:id="@+id/rptbt3"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="#80000000"  
  6.     android:src="@drawable/imgbt2"  
  7.     />  
注意 :RepeatButton是我们自定义的类,所以引用的时候,要加上全名。

在Activity中,要使用的话,先要实现RepeatListener:
[java]   view plain copy
  1. public class MyRepeatListener implements RepeatListener  
  2. {  
  3.     public void onRepeat(View v, long duration, int repeatcount)  
  4.     {  
  5.         //加入处理代码  
  6.     }          
  7. }  

然后设置setRepeatListener,实现监听:
[java]   view plain copy
  1. RepeatButton rb = (RepeatButton)findViewById(R.id.rptbt3);  
  2. rb.setRepeatListener(new MyRepeatListener(), 5000);  

下面给出源码的下载地址: http://download.youkuaiyun.com/detail/manp1212/4400624
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值