动态加载布局,就是根据屏幕的大小分辨率来决定加载哪个xml 布局文件。
5.4.1 使用限定符
我们知道平板的屏幕是非常大的,在布局上我们可以采用双页展示的形式(就是展示两页内容),但是手机只能展示一页,我们要怎样才能区分程序应该使用双页还是单页呢?这时候就要借助限定符(英文:qualifier)来实现了。
首先来讲解一下 large 限定符 ,正常的项目下都会有一个res/layout 文件夹,但是文件夹是可以携带限定符的 我们还可以创建另一个文件夹为 layout-large ,这个文件夹后面的 large 就是限定符,系统会根据large 设备自动选用 layout-large 目录下的文件,而不是layout 下的,如果不是那么就使用默认的 layout。
我们来演示一下,还是FragmentTest 项目,修改一下MainActivity 的代码,注释掉 replaceFragment 函数的调用。然后在res 目录下创建layout-large 文件夹,可以去手动创建也可以通过Android Studio 创建 ,右键res -- New -- Android Resource Directory 弹出的界面如下选择
点击OK 创建完毕,然后我们把之前的平板设备activity_main.xml copy 一份到这个目录中把FrameLayout 换个背景色
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/leftFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_weight="1"
/>
<FrameLayout
android:id="@+id/rightLayout"
android:background="#000"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
再把原目录的 activity_main.xml 中的右侧 FrameLayout 删除。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/leftFrag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.fragmenttest.LeftFragment"
/>
</LinearLayout>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
// replaceFragment(AnotherRightFragment())
}
// replaceFragment(RightFragment())
}
private fun replaceFragment(fragment: Fragment){
val supportFragmentManager = supportFragmentManager
val beginTransaction = supportFragmentManager.beginTransaction()
beginTransaction.addToBackStack(null)
beginTransaction.replace(R.id.rightLayout,fragment)
beginTransaction.commit()
}
}
Ok 运行程序!
运行看效果:
平板电脑
手机:
最后在发一次限定符这个表格:
5.4.2 使用最小宽度限定符
前面解决了 large 限定符的单页双页判断问题,large 具体是多大我们其实并不知道,也就不够灵活,如果我们想要灵活地为不同设备加载布局不管是不是会被系统认定为large ,我们这时可以使用最小宽度限定符(small-width qualifier 简化后为sw)。
最小宽度限定符允许我们对屏幕的宽度指定一个最小值(dp单位),然后以这个值为临界点,屏幕大于这个值的设备就加载这个布局,屏幕小于这个值的设备就加载另一个布局。创建layout 的方式上面已经说过了,只是最后的选择我们要选择 small 然后自己定义名字即可 layout-sw600dp,然后我们再创建一个activity_main.xml 在layout-sw600dp 目录下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/leftFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.fragmenttest.LeftFragment"
/>
<fragment
android:id="@+id/rightFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.fragmenttest.RightFragment"
/>
</LinearLayout>
我们运行程序,平板的界面改变成了我们设置的设个布局。也就是说small 优先级高于 large 。