ConstraintLayout是Android Studio2.2新增的主要功能之一,它使用约束的方式来指定控件的位置和大小。虽然使用起来还不能和IOS开发中StoryBoard中直接拖放控件那样方便,但也极大的方便了android的布局。它有效的解决了布局嵌套过多的问题,我们知道布局嵌套越多,性能越差,因此,使用ConstraintLayout布局复杂的界面能够极大的提高性能。
这里不介绍ConstraintLayout的使用,不清楚如何使用的建议百度学习一下,毕竟它实在是好用,一个复杂的布局使用它能够轻松搞定。
需要布局一个UI界面,实现的效果就是每一个列表项中平均分配有三个图片,图片的宽高相等。我们知道,ConstraintLayout布局中使用constraintDimensionRatio能够限制控件的宽高比。于是飞快的撸除了以下的代码:
列表Item布局代码:item_content.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"/>
<ImageView
android:id="@+id/image1"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="5dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/image2"
app:layout_constraintTop_toBottomOf="@id/item_title" />
<ImageView
android:id="@+id/image2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintLeft_toRightOf="@id/image1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/image1"
android:src="@mipmap/ic_launcher"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</android.support.constraint.ConstraintLayout>
代码中有三个控件,我们主要关注两个ImageView,两个ImageView宽度平分屏幕宽度,高度和宽度相等,即
app:layout_constraintDimensionRatio="1:1"
预期结果应该是这样的:
然而然而,运行结果竟然是这样的,什么都没有,对的,不是显示代码有问题,就是两个ImageView都没有宽度和高度。
此时心理一万只草泥马正在飞奔,没办法,调试调试,将
android:layout_width="0dp"
改成
android:layout_width="100dp"
运行结果显示正常。然而这并不能解决我的问题,我需要的是平分屏幕宽度啊,于是百度到了GuideLine这个控件。这个是一个参考线,我可以设置多个参考线位于屏幕的不同位置,这样我的ImageView也可以得到占据屏幕一半的宽度了。修改代码如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.Guideline
android:id="@+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"/>
<ImageView
android:id="@+id/image1"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="5dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/guideline1"
app:layout_constraintTop_toBottomOf="@id/item_title" />
<ImageView
android:id="@+id/image2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintLeft_toRightOf="@id/guideline1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/image1"
android:src="@mipmap/ic_launcher"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</android.support.constraint.ConstraintLayout>
代码其实就是在原来的代码上增加了一条位于屏幕50%的参考线。然后两个ImageView分别约束到它,于是就可以实现了需要的UI了。
总结
出现在ListView,ScrollView中无法显示控件的问题主要还是无法准确计算出控件的宽度和高度,导致他们的宽高为0.因此只要保证控件的宽度能够准确获取,就可以正常显示了。上述中直接设置宽度为100dp也好,或者设置参考线的方式也好,都是从这个思路进行解决的。
然而知道了如何解决这个问题,但还是不知道为什么在ListView,ScrollView中会出现这个问题,在Activity的布局中就不会出现这个问题。
最后附上MainActivity的布局文件和类文件。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="com.qcymall.demotest.MainActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#ff778899"/>
</android.support.constraint.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val listView = findViewById<ListView>(R.id.listview)
val datas = ArrayList<HashMap<String, Any>>()
val data = HashMap<String, Any>()
data.put("title", "Hello")
datas.add(data)
val adapter = SimpleAdapter(this, datas, R.layout.item_content, arrayOf("title"), intArrayOf(R.id.item_title))
listView.setAdapter(adapter)
}
}