0
点赞
收藏
分享

微信扫一扫

Android 系列 6.11以五种不同的方式处理事件监听器


6.11以五种不同的方式处理事件监听器
问题
你需要熟悉不同的方式来编写事件处理程序,既要知道什么时候使用哪种方法,因为你会在本手册和其他地方遇到各种方法。

当编写软件时,很少有只有一种方法来做事情。这在连接查看事件时是正确的;在这个配方中显示了六种技术。
讨论
当视图触发事件时,应用程序不会响应它,除非应用程序正在侦听它。为了检测事件,监听器被实例化并分配给视图。
例如,onClick事件,Android应用程序中使用最广泛的事件。
几乎每个可以添加到应用程序屏幕的视图将在用户用手指(触摸屏)按下时触发事件,或者在视图具有焦点时按下触控板/轨迹球。此事件由实现OnClickListener接口的类监听。然后,使用View的setOnClickListener方法将类实例分配给所需的视图。在下面的“技术1。
Member类“,在按下按钮(button1)时,HandleClick内部类设置TextView(textview1)的文本。
技术1. Member类
在示例6-12中,一个实现OnClickListener的嵌套类HandleClick被声明为Activity(main)的成员。当多个侦听器需要类似的处理,可以由单个类处理时,这是有用的。
实例6-12。 Member类

public class MainActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//attach an instance of HandleClick to the Button

findViewById(R.id.button1).setOnClickListener(new HandleClick());

}

private class HandleClick implements OnClickListener{

public void onClick(View arg0) {

Button btn = (Button)arg0; //cast view to a button

// get a reference to the TextView

TextView tv = (TextView) findViewById(R.id.textview1);

// update the TextView text

tv.setText("You pressed " + btn.getText());

}

}

}



技术2.接口类型
在Java中,接口可以用作类型。变量声明为OnClickListener,并使用新的OnClickListener(){...}分配,而幕后Java是创建一个实现OnClickListener的对象(一个匿名类)。这具有与第一种技术类似的益处(参见实施例6-13)。
实例6-13。接口类型

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//use the handleClick variable to attach the event listener
findViewById(R.id.button1).setOnClickListener(handleClick);
}
private OnClickListener handleClick = new OnClickListener(){
public void onClick(View arg0) {
Button btn = (Button)arg0;
TextView tv = (TextView) findViewById(R.id.textview1);
tv.setText("You pressed " + btn.getText());
}
};
}


技术3.匿名内部类


在调用setOnClickListener方法中声明OnClickListener是常见的。当每个侦听器没有可以与其他侦听器共享的功能时,此方法很有用。一些新手开发人员发现这种类型的代码很难理解。再次,在后面的新OnClickListener(){...} Java正在创建一个实现接口的对象(见例6-14)。


实例6-14。匿名内部类


public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
Button btn = (Button)arg0;
TextView tv = (TextView) findViewById(R.id.textview1);
tv.setText("You pressed " + btn.getText());
}
});
}
}


技术4.在活动中的实现


Activity本身可以实现OnClickListener。因为Activity对象(main)已经存在,所以通过不需要另一个对象托管onClick方法,这节省了少量内存。它确实使公共一个不太可能在别处使用的方法。实现多个事件将使声明为long long(见例6-15)。


实例6-15。在活动中的实现


public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.button1).setOnClickListener(this);
}
public void onClick(View arg0) {
Button btn = (Button)arg0;
TextView tv = (TextView) findViewById(R.id.textview1);
tv.setText("You pressed " + btn.getText());
}
}


技术5. Lambda表达式(需要Java 8工具链)


在Android 7和更高版本中,使用Java 8工具链(见配方1.16),您可以使用lambda表达式来缩短代码。 Lambdas可以通过“→”语法识别,使用Java SE版本8引入Java语言。示例6-16中显示了Lambda的使用示例。


实例6-16。 Lambda表达式

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View v = findViewById(R.id.button1);
v.setOnClickListener(v->{
Button btn = (Button)arg0;
TextView tv = (TextView) findViewById(R.id.textview1);
tv.setText("You pressed " + btn.getText());
});
}
}

一个限制是,Lambda表达式只能用于实现一个“功能接口”,即一个只有一个抽象方法的接口,因为方法的名称(以及接口本身的名称)由编译器推断。


技术6. OnClick事件的视图布局中的属性


Activity中定义的方法的名称可以分配给布局文件中的android:onClick属性(参见示例6-17)。这可以避免您编写大量样板代码。


实例6-17。在manifest中命名的类



public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void handleClick(View arg0) {
Button btn = (Button)arg0;
TextView tv = (TextView) findViewById(R.id.textview1);
tv.setText("You pressed " + btn.getText());
}
}

在布局文件中,Button将使用android:onClick属性声明。


<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
android:onClick="handleClick"/>




前五种处理事件的技术可以与其他事件类型(onLongClick,onKey,onTouch,onCreateContextMenu,onFocusChange)一起使用。本小节中描述的技术仅适用于onClick事件。例6-18中的布局文件声明了另外两个按钮;使用android:onClick属性,不需要额外的代码;也就是说,不需要为每个按钮添加额外的findViewById和setOnClickListener。这应该如图6-8所示。


实例6-18。 android:onClick的多个用途

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/textview1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Click a button."
android:textSize="20dp"/>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
android:onClick="HandleClick"/>
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
android:onClick="HandleClick"/>
<Button android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
android:onClick="HandleClick"/>
</LinearLayout>
</LinearLayout>



图6-8。来自android:onClick的OnClick事件


决定使用哪种技术来连接侦听器将取决于所需的功能,多个代码可以在多个视图中重复使用,以及代码如何容易被未来的维护者理解。理想情况下,代码应该简洁易懂。



举报

相关推荐

事件监听器

0 条评论