适应手机和平板屏幕

2019-08-16  本文已影响0人  LeoFranz

手机界面加载单个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需要与其他组件通信的部分使用接口进行调用。

上一篇 下一篇

猜你喜欢

热点阅读