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) } }