Android View Focus详解

一、EditText监听焦点例子,setOnFocusChangeListener


焦点事件是对某一组件的状态的监听事件。比如说我们在注册页面输入自己的用户名时,这当光标点击到高文本框时,我们可以理解为该文本框获得了焦点;但是,当光标离开了该文本框,则可以理解为该文本框失去了焦点。
焦点事件常用来处理该组件的验证处理等功能,例如输入框内容的清空功能,文本框的验证、提示功能等等。
Android中的View类中专门提供了一个接口——View.OnFocusChangeListener,用于监听焦点改变(得到焦点和失去焦点)事件,而所有的组件上又存在都存在这监听焦点变化的方法:
public void setOnFocusChangeListener(View v, Boolean hasFocus){};
V        :  发生变化的视图
hasFocus  :  用来判断视图是否获得了焦点。true——获得了焦点;flash——没有获得焦点。

  • 范例:如图所示显示输入框组件焦点获得及失去情况,并用TextView显示出来的效果 
  • mail.xml代码如下:
  • [Java] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <font color= "#000000" ><?xml version= "1.0" encoding= "utf-8" ?>
    <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
         android:layout_width= "fill_parent"
         android:layout_height= "wrap_content"
         android:orientation= "vertical" >
     
         <!-- 输入框,提供给用户输入信息 -->
         <EditText
             android:id= "@+id/inputText"
             android:layout_width= "fill_parent"
             android:layout_height= "wrap_content"
             android:text= "请输入信息" />
         <EditText
             android:layout_width= "fill_parent"
             android:layout_height= "wrap_content"
             android:text= "焦点事件" />
         
         <!--文本显示框,用来显示组件焦点变换情况 -->
         <TextView
             android:id= "@+id/showText"
             android:layout_width= "fill_parent"
             android:layout_height= "wrap_content"
             android:text= "请输入信息" />
    </LinearLayout></font>

  • Activity——TestProActivity.java代码如下:

  • [Java] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    <font color= "#000000" > package com.heidie.demo;
     
    import java.security.PublicKey;
     
    import javax.security.auth.PrivateCredentialPermission;
     
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.DatePicker;
    import android.widget.DatePicker.OnDateChangedListener;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.TimePicker;
     
    public class TestProActivity extends Activity {
     
         private EditText inputEditText = null //输入框,用来提供给用户输入信息
         private TextView showTextView = null ;   //文本显示框,用来显示组件焦点变换情况
     
         public void onCreate(Bundle savedInstanceState) {
             super .onCreate(savedInstanceState);
             super .setContentView(R.layout.main);
     
             /*获得组件*/
             inputEditText = (EditText)findViewById(R.id.inputText);
             showTextView = (TextView)findViewById(R.id.showText);
             
             //绑定焦点事件
             inputEditText.setOnFocusChangeListener( new View.OnFocusChangeListener() {  
                 @Override
                 public void onFocusChange(View v, boolean hasFocus) {
                     // TODO Auto-generated method stub
                     if (hasFocus){ //如果组件获得焦点
                         showTextView.setText( "组件获得了焦点" );
                         
                     } else {
                         showTextView.setText( "组件失去了焦点" );
                     }
                 }
             });
             //绑定单击事件
             inputEditText.setOnClickListener( new View.OnClickListener() {
                 
                 @Override
                 public void onClick(View v) {
                     inputEditText.setText( " " ); //清空输入框内容
                 }
             });
         }
     
    }
    </font>
    v
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

(二)View的requestFocus()和requestFocusFromTouch()方法的区别


if(userNameEditText.isInTouchMode()){
userNameEditText.requestFocusFromTouch();
}else{
userNameEditText.requestFocus();
}
不理解这两个方法的意思,去看了下API。了解了:
首先,这两个方法都是获得焦点的方法。
其次,requestFocus()在两种情况下不能获得焦点:
1.对应的View不支持Focus
2.对应的View支持Focus,但是不支持在Touch模式下的Focus。
而requestFocusFromTouch()就是解决requestFocus()的第二种不能获得焦点的情况,也就是说即使在Touch模式下不支持焦点,也能够获得焦点。
/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

(三)setOnFocusChangeListener木有反应,因为Touch Mode下原本不存在focus,要增加一句代码:button.setFocusableInTouchMode(true)


今天试跑了"Google Android SDK开发范例大全源码里的EX04_02工程",发现mImageButton1.setOnFocusChangeListener这个监听器木有反应。查了很多资料发现原因是:在Android TouchMode模式下是不存在focus的。所谓的focus是指被选中的意思,类似于windows平台下单击一个文件夹后鼠标的焦点(focus)就在该文件夹上面。既然不存在focus,也就不存在FocusChange的问题,所以setOnFocusChangeListener监听器不起作用也就可以理解。如果想在TouchMode下面使用这个监听器可以使用如下两种方法:

         1.增加一句代码:mImageButton1.setFocusableInTouchMode(true)

         2.在main.xml中mImageButton标签中加入一个子标签:android:focusableInTouchMode="true"。这两种方法的作用都是使得focus在TouchMode下恢复作用。

       关于TouchMode可以参考下面两片文章:

       1.http://developer.android.com/resources/articles/touch-mode.html

       2.http://hi.baidu.com/qmiao128/blog/item/3bc40f54e0605144574e0048.html

         下面附上Google Android SDK开发范例大全源码里的EX04_02工程源代码

[java]  view plain copy
  1. public class EX04_02 extends Activity     
  2. {    
  3.   /*声明三个对象变量(图片按钮,按钮,与TextView)*/    
  4.   private ImageButton mImageButton1;    
  5.   private Button mButton1;    
  6.   private TextView mTextView1;    
  7.       
  8.   /** Called when the activity is first created. */    
  9.   @Override    
  10.   public void onCreate(Bundle savedInstanceState)    
  11.   {    
  12.     super.onCreate(savedInstanceState);    
  13.     setContentView(R.layout.main);    
  14.         
  15.     /*通过findViewById构造三个对象*/    
  16.     mImageButton1 =(ImageButton) findViewById(R.id.myImageButton1);    
  17.     mButton1=(Button)findViewById(R.id.myButton1);    
  18.     mTextView1 = (TextView) findViewById(R.id.myTextView1);    
  19.         
  20.     /*通过OnFocusChangeListener来响应ImageButton的onFous事件*/    
  21.     mImageButton1.setOnFocusChangeListener(new OnFocusChangeListener()    
  22.     {    
  23.       public void onFocusChange(View arg0, boolean isFocused)    
  24.       {    
  25.         // TODO Auto-generated method stub    
  26.             
  27.         /*若ImageButton状态为onFocus改变ImageButton的图片  
  28.          * 并改变textView的文字*/    
  29.         if (isFocused==true)    
  30.         {    
  31.           mTextView1.setText("图片按钮状态为:Got Focus");    
  32.           mImageButton1.setImageResource(R.drawable.iconfull);    
  33.         }    
  34.         /*若ImageButton状态为offFocus改变ImageButton的图片  
  35.          *并改变textView的文字*/    
  36.         else     
  37.         {    
  38.           mTextView1.setText("图片按钮状态为:Lost Focus");    
  39.           mImageButton1.setImageResource(R.drawable.iconempty);    
  40.         }    
  41.       }    
  42.     });    
  43.            
  44.     /*通过onClickListener来响应ImageButton的onClick事件*/    
  45.     mImageButton1.setOnClickListener(new OnClickListener()    
  46.     {    
  47.       public void onClick(View v)    
  48.       {    
  49.         // TODO Auto-generated method stub    
  50.         /*若ImageButton状态为onClick改变ImageButton的图片  
  51.          * 并改变textView的文字*/    
  52.         mTextView1.setText("图片按钮状态为:Got Click");    
  53.         mImageButton1.setImageResource(R.drawable.iconfull);    
  54.       }       
  55.     });    
  56.           
  57.     /*通过onClickListener来响应Button的onClick事件*/    
  58.     mButton1.setOnClickListener(new OnClickListener()    
  59.     {    
  60.       public void onClick(View v)    
  61.       {    
  62.         // TODO Auto-generated method stub    
  63.         /*若Button状态为onClick改变ImageButton的图片  
  64.          * 并改变textView的文字*/    
  65.         mTextView1.setText("图片按钮状态为:Lost Focus");    
  66.         mImageButton1.setImageResource(R.drawable.iconempty);    
  67.       }     
  68.     });     
  69.   }    
  70. }    
####################################################################################################################
(四)判断View在TouchMode下是否有接收焦点资格
+XML里设置焦点属性
1、通过isFocusable()这个方法我们可以知道view是否具有接受焦点的资格
2、也可以通过setFocusable()来设置view接受焦点的资格
3、对应在触摸模式(TouchMode)下,你可以调用isFocusableInTouchMode()来获知是否有焦点来响应触摸,也可以通过setFocusableInTouchMode()来设置是否有焦点来响应触摸的资格——前面说过,默认TouchMode下是不存在focus的,需要调用setFocusableInTouchMode(true)
Framework控制焦点移动到另一个组件的算法是在某一方向上邻近的组件,在极个别情况下,默认的算法可能不符合开发者的预想要求,在这种情况下,你可以覆写下列XML属性的布局文件:nextFocusDown ,nextFocusLeft ,nextFocusRight ,和nextFocusUp 设置他们的值来明确 
        焦点从当前界面移动下个界面的Id。例如: 
<LinearLayout 
android:orientation="vertical" 
... > 
<Button android:id="@+id/top" 
android:nextFocusUp="@+id/bottom" 
... /> 
<Button android:id="@+id/bottom" 
android:nextFocusDown="@+id/top" 
... /> 
</LinearLayout> 
一般来说,在这个垂直布局,浏览的焦点会从第一个按钮开始,不会是从第二个或者其他的,现在topButtont已经通过nextFocusUp (反之亦然)确定了bottom. 

      通常如果你想宣布用户界面具有焦点的资格 (如果这个界面在传统上是没有的),可以在xml布局里去加上的android:focusable的属性,并设置它的值,您也可以宣布在触摸模式下具有焦点的资格,同样也只在xml里添android:focusableInTouchMode.的属性,并设置它的值. 当用户请求在某个界面聚集焦点时,会调用requestFocus().这个方法。监听到焦点活动(获得焦点或失去焦点都会被通知),会调用onFocusChange(),这个方法。虽然帖子比较短,但是我感觉这个例子还是非常有用的,希望对开发者有一些帮助。想继续交流的可以回帖。

[java]  view plain copy print ?
  1. //监听焦点事件  
[java]  view plain copy print ?
  1. et_search.setOnFocusChangeListener(new OnFocusChangeListener() {  
  2.                   
  3.                 @Override  
  4.                 public void onFocusChange(View v, boolean isFocused) {  
  5.                     // TODO Auto-generated method stub  
  6.                     System.out.println(isFocused);  
  7.                     if(!isFocused){  
  8.                         et_search.setVisibility(View.GONE);  
  9.                     }  
  10.                 }  

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值