安卓成长记(五)
磨磨蹭蹭的重要到了第三章了
安卓的两种事件处理的方式:基于回调和基于监听的事件处理。
ps:一句,如果是在xml文件中为其制定OnClick属性,那在java文件中设计对应的函数的时候,一般是传入一个View类型的参数。
比如:
public haha(View source){}
基于回调的方法就就简单多了,是直接重写特定的回调方法就行了,是不是一般都有@Override这个单词呢?
OnCreate()函数就是一个回调函数。
监听器共有如下几种形式:
- 内部类形式:将监听器定义为内部类
- 外部类形式:将监听器定义为一个外部类
- Activity本身实现监听器接口,并实现时间处理方法
- 匿名内部类。其实这个使用的最多。
下面看一下外部类的实现方式:
//这个是写在外部的类当中的,实现一个监听接口。
public class SendSmsListener implements OnLongClickListener
{
private Activity act;
private EditText address;
private EditText content;
//为什么之前没看到过有构造函数呢?
//因为那都是在内部,内部类可以使用内部的成员变量,所以不需要构造函数将组件传过去。
public SendSmsListener(Activity act, EditText address
, EditText content)
{
this.act = act;
this.address = address;
this.content = content;
}
@Override
public boolean onLongClick(View source)
{
String addressStr = address.getText().toString();
String contentStr = content.getText().toString();
//下面是发送短信的几步
// 首先获取短信管理器,一般这种管理器都是干些边角活
SmsManager smsManager = SmsManager.getDefault();
// 创建发送短信的PendingIntent
//这个pendingIntent不知道是干什么用的,但是很多有这个
PendingIntent sentIntent = PendingIntent.getBroadcast(act
, 0, new Intent(), 0);
// 发送文本短信
smsManager.sendTextMessage(addressStr, null, contentStr
, sentIntent, null);
Toast.makeText(act, "短信发送完成", Toast.LENGTH_LONG).show();
return false;
}
}
Activity本身实现监听器类:
//activity本身实现监听器接口的做法其实是比较怪异的。
public class MainActivity extends Activity
implements View.OnClickListener
{
EditText show;
Button bn;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (EditText) findViewById(R.id.show);
bn = (Button) findViewById(R.id.bn);
// 直接使用Activity作为事件监听器
bn.setOnClickListener(this);
}
// 实现事件处理方法
//原来这个类的格式是这样的:
//new OnclickListener(){}
//写在大括号里面的,现在因为自己结成了接口,于是直接写在Activity类体中了。
@Override
public void onClick(View v)
{
show.setText("bn按钮被单击了!");
}
}
还是匿名内部类的实现方式顺眼啊:
public class MainActivity extends Activity
{
EditText show;
Button bn;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (EditText) findViewById(R.id.show);
bn = (Button) findViewById(R.id.bn);
// 使用匿名内部类的实例作为事件监听器
//内聚性很好,new OnClickListener(){}是在一个函数里面。
bn.setOnClickListener(new OnClickListener()
{
// 实现事件处理方法
@Override
public void onClick(View v)
{
show.setText("bn按钮被单击了!");
}
});
}
}
响应系统的事件
首先我们来看一下如何获取系统的事件。
系统的信息其实都包裹成了一个对象,你通过系统的方法获得到系统的这个对象
将里面的东西读出来就完了,要多简单有多简单。
获取这个东西连权限都不用配置
public class MainActivity extends Activity
{
EditText ori;
EditText navigation;
EditText touch;
EditText mnc;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取应用界面中的界面组件
ori = (EditText)findViewById(R.id.ori);
navigation = (EditText)findViewById(R.id.navigation);
touch = (EditText)findViewById(R.id.touch);
mnc = (EditText)findViewById(R.id.mnc);
Button bn = (Button)findViewById(R.id.bn);
bn.setOnClickListener(new OnClickListener()
{
// 为按钮绑定事件监听器
@Override
public void onClick(View source)
{
// 获取系统的Configuration对象
//你看他也真有意思,你弄成在OnCreate()不就行了,还弄个点击事件里面,不点击没反应的。
//通过getResources().getConfiguration();获取到系统的这个对象。
//注意getResources()这个函数,它是Context里面的资源,可以获取很多系统的对象
Configuration cfg = getResources().getConfiguration();
String screen = cfg.orientation ==
Configuration.ORIENTATION_LANDSCAPE
? "横向屏幕": "竖向屏幕";
String mncCode = cfg.mnc + "";
String naviName = cfg.orientation ==
Configuration.NAVIGATION_NONAV
? "没有方向控制" :
cfg.orientation == Configuration.NAVIGATION_WHEEL
? "滚轮控制方向" :
cfg.orientation == Configuration.NAVIGATION_DPAD
? "方向键控制方向" : "轨迹球控制方向";
navigation.setText(naviName);
String touchName = cfg.touchscreen ==
Configuration.TOUCHSCREEN_NOTOUCH
? "无触摸屏" : "支持触摸屏";
ori.setText(screen);
mnc.setText(mncCode);
touch.setText(touchName);
}
});
}
}
主要是这一点:Configuration cfg = getResources().getConfiguration();
这个cfg里就包含了系统的信息。
但是如果要监听的话怎么弄呢?
这就又碰到Activity给提供分方法了。
真的应该看看Activity里面共有多少方法可以重写啊。
public class MainActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
// 为按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View source) {
//这里getResources().getConfiguration();获取系统提供的那个cfg地址
Configuration config = getResources().getConfiguration();
// 如果当前是横屏
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 设为竖屏
//手动设置为横竖屏也是可以的。也是用的activity提供的方法
//setRequestedOrientation()
MainActivity.this.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
// 如果当前是竖屏
if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
// 设为横屏
MainActivity.this.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//尼玛为啥竖屏是这个东西?
//ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}
}
});
}
// 重写该方法,用于监听系统设置的更改,主要是监控屏幕方向的更改
//这个是系统提供的监听系统变化的回调函数
//Configuration newConfig这里面这个参数也是系统提供的吧。系统包裹好
//一个变化之后的参数传给这个函数
//因为config里面的参数如果不变化的话也不会触发这个回调方法
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
String screen = newConfig.orientation ==
Configuration.ORIENTATION_LANDSCAPE ? "横向屏幕" : "竖向屏幕";
Toast.makeText(this, "系统的屏幕方向发生改变" + "\n修改后的屏幕方向为:"
+ screen, Toast.LENGTH_LONG).show();
}
}
到这里还没完呢
要想监听到系统参数的更改,在manifest文件中还要配置属性
在activity里面配置configChanges属性。
这个属性支持很多参数见209页。
不过这个在文档怎么找?
“orientation|screenSize”指定可以监听屏幕方向改变的事件
另外的属性还支持mcc,mnc,local地点变化等属性。
这个参数可以获取当前的用户地点,在后边的LBS会有讲解。
<activity
android:configChanges="orientation|screenSize"
android:name="com.example.testlistensystem.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
这里ps一句,使用Handler消息机制其实是处理了进程之间的通信。
UI线程才能修改UI线程。