1.Fragment+限定符适配屏幕(平板与手机适配)
解决平板与手机的屏幕适配问题。由于平板的屏幕比较大,可以放更多的内容,这样就不能根据手机来设计了,要充分利用屏幕。这里使用android.support.v4.app.Fragment,兼容性较好,如果直接用 android.app.Fragment,4.2版本之前,Fragment嵌套Fragment会崩溃。
我们有两种布局,一个是手机的,另一个是平板的,为了能让程序在运行时自动选择合适的布局,我们这里用到了最小宽度限定符layout-sw600dp,当屏幕大于600dp时(600dp不是分辨率),会加载layout-sw600dp文件中的布局,当屏幕小于600dp时,会加载layout文件中的布局。怎么用,在res文件中创建名为layout-sw600dp的文件夹,将平板所使用到的布局放进去。在android目录方式下看不到layout-sw600dp文件,切换到project目录方式下就能看见了。
举个例子,说明一下适配过程,有MainActivity、FragmentA、FragmentB,MainActivity有两种布局,一种是只显示FragmentA,另一种都显示(FragmentA、FragmentB),由于布局是系统自动选的,所以我们要知道选择的是哪个布局。在FragmentA中进行检测,代码如下:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//R.id.fragment_b在layout-sw600dp的布局文件中,是FragmentB的id
//只要检测R.id.fragment_b就可判断加载了哪个布局
if(getActivity().findViewById(R.id.fragment_b) != null){
Log.i("123123","找到");
}else{
Log.i("123123","没有找到");
}
}
明确了所加载的布局,接下来要执行的动作就很明了了。比如在FragmentA中有个button,点击button,向FragmentB传值,FragmentB来显示。如果加载是只有FragmentA的布局,那就需要跳转到一个只有FragmentB的activity。如果加载的是FragmentA、FragmentB都在的布局,在FragmentA获取到FragmentB的实例,用来传值。
2.广播
标准广播:完全异步执行的广播,在广播发出的一瞬间所有的广播接收器都会接收到。这种广播无法被拦截。
有序广播:同步执行的广播,在广播发出的同一时刻只有一个广播接收器会收到。这种广播是可以被拦截的。
在代码中注册的广播是动态注册,在AndroidManifest.xml注册的广播是静态注册。动态注册只能在程序启动的时候接收广播,而静态注册可以在没有启动程序的时候接收广播。
动态注册基本用法
1. 创建一个类并继承BroadcastReceiver,重写onReceive()。
2.intentFilter用来设置要接收的广播
3.注册
//广播接收器
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"网络改变",Toast.LENGTH_SHORT).show();
}
}
//设置要接收的广播,注册广播
myReceiver = new MyReceiver();
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(myReceiver, intentFilter);
取消注册
unregisterReceiver(myReceiver);
静态注册基本用法
android studio提供了能够直接创建广播接收器的功能。右键→New→Other→Broadcast Receiver。创建过程中有两个属性,exported属性表示是否允许广播接收器接收本程序以外的广播,Enabled属性表示是否启用广播接收器。
创建成功后,AndroidManifest.xml中会自动生成相应的receiver。
<receiver
android:name=".test.StaticReceiver"
android:enabled="true"
android:exported="true">
<!--与动态注册类似,设置接收什么广播-->
<intent-filter>
<action android:name="android.intent......."></action>
</intent-filter>
</receiver>
发送自定义广播
Intent intent = new Intent("自定义action");
//标准广播
sendBroadcast(intent);
sendBroadcast()为标准广播, sendOrderedBroadcast(,null)为有序广播。使用有序广播需要设置广播接收器的优先级,在静态注册中添加android:priority属性到intent-filter。
<intent-filter android:priority="100">
<action android:name="cn.xd......."></action>
</intent-filter>
在有序广播中需要拦截时,使用abortBroadcast()方法。
public class StaticReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"提示信息",Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
本地广播
本地广播只能在应用程序的内部进行传递,本地广播接收器只能接收来自本应用的广播。与动态注册的广播非常相似,只不过多了LocalBroadcastManager,导致几处稍有变动。如下:
manager = LocalBroadcastManager.getInstance(this);
manager.registerReceiver(myReceiver, intentFilter);
manager.sendBroadcast(intent);
manager.unregisterReceiver(myReceiver);
本地广播无法通过静态注册的方式来接收。