手机界面加载单个fragment,平板加载两个,列表和内容fragment,是最常见的布局分化情形。
首先要聪明地加载不同的布局文件
解决方案一:
实现一个activity基类,修改传入布局文件方式
setContentView(getLayoutResId());
@LayoutRes
//这个标记表明该方法必须返回有效的布局资源ID
protected int getLayoutResId() {
return R.layout.activity_fragment;
}
通过不同的activity加载不同的布局资源,fragment就通过fragmengManager寻找layout中合适的容器进行加载。
解决方案二:
通过资源修饰符来区分不同屏幕的layout,缺点就是需要复制多份layout资源分别导入不同的文件夹,实际做法就是将不同fragment资源放到不同layout文件中。
解决方案三:使用别名文件
代码中统一引用layoutA,通过values文件夹中的xml配置,根据设备屏幕实际加载不同的layout
values/refs.xml
<item name="activity_masterdetail" type="layout">@layout/activity_fragment</item>
values-sw600dp/refs.xml
<item name="activity_masterdetail" type="layout">@layout/activity_twopane</item>
sw是smallest width的缩写,指高度或者宽度中最小的那个。
这一步做好了,我们需要在代码中适配不同的布局
当同一界面上出现多个的fragment时候,如果采用getActivity.getSupportFragmentManager();再开启事务的方式,可行但需要fragment知道托管activity的实现细节,fragment是一个独立的组件,它没有义务关心其他组件的细节
所以,常见的做法是在fragment中设置回调接口。
public interface Callbacks {
void onCrimeSelected(Crime crime);
}
在fragment生命周期中将callback实例化
private Callbacks mCallbacks;
public void onAttach(Context context) {
super.onAttach(context);
mCallbacks = (Callbacks) context;
}
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
托管activity必须实现相应接口,这很正常,activity有义务实现管理者的功能
@Override
public void onCrimeSelected(Crime crime) {
if (findViewById(R.id.detail_fragment_container) == null) {
Intent intent = CrimePagerActivity.newIntent(this, crime.getId());
startActivity(intent);
} else {
Fragment newDetail = CrimeFragment.newInstance(crime.getId());
getSupportFragmentManager().beginTransaction()
.replace(R.id.detail_fragment_container, newDetail)
.commit();
}
}
核心就是fragment需要与其他组件通信的部分使用接口进行调用。
网友评论