Constraint Layout 1.1.x带来了哪些新东西?

 

泡在网上的日子 / 文 发表于2017-10-19 15:54 第10115次阅读 ConstraintLayout,转载作者原文地址http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/1019/8618.html

编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识、前端、后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过!

今年的Google I/O上谷歌发布了新版本的ConstraintLayout,但是我们并没有从中得到多少信息,只有一篇非常简陋的博客

那么到底是哪些新特性,它们的功能和用法又是怎么回事呢?

首先引入 ConstraintLayout 1.1.x,这里是beta3版本:


 
  1. repositories {
  2.     maven {
  3.         url 'https://maven.google.com'
  4.     }
  5. }
  6. dependencies {
  7.     ...
  8.     compile 'com.android.support.constraint:constraint-layout:1.1.0-beta3'
  9. }

Percent Dimensions

说到Percent Dimensions就不得不说ConstraintLayout中的0dp问题,当控件设置为0dp的时候(0dp的称呼又叫match_constraint),默认的行为是撑开(spread),占满可用空间,但是这个行为是可以用layout_constraintWidth_default 属性来设置的。在 ConstraintLayout 1.0.x中,这个属性还可以把它设置为wrap。而到了1.1.x,它又有了一个新的值:percent,允许我们设置控件占据可用空间的百分比。

下面的TextView控件将占据剩余宽度的50%和剩余高度的50%。


 
  1.     <TextView
  2.         android:id="@+id/textView6"
  3.         android:layout_width="0dp"
  4.         android:layout_height="0dp"
  5.         
  6.         app:layout_constraintHeight_default="percent"
  7.         app:layout_constraintHeight_percent="0.5"
  8.         
  9.         app:layout_constraintWidth_default="percent"
  10.         app:layout_constraintWidth_percent="0.5" />

Barrier

Barrier是一个虚拟的辅助控件,它可以阻止一个或者多个控件越过自己,就像一个屏障一样。当某个控件要越过自己的时候,Barrier会自动移动,避免自己被覆盖。

 ConstraintLayout.com上面有关于这个控件的文章,这里是翻译:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/1017/8601.html 。

在下面的例子中 ,不管text1 和 text2有多长,或者哪个更长,它们的end属性都不会越过Barrier。而text3因为约束在Barrier的后面,所以也就保证了text3总是在text1 和 text2后面。


 
  1. <android.support.constraint.ConstraintLayout...>
  2.   <TextView
  3.     android:id=”@+id/text1" ... />
  4.   <TextView
  5.     android:id=”@+id/text2" ... />
  6.   <android.support.constraint.Barrier
  7.     android:id=”@+id/barrier”
  8.     android:layout_width=”wrap_content”
  9.     android:layout_height=”wrap_content”
  10.     app:barrierDirection=”end” <!-- start, top, bottom, right... -->
  11.     app:constraint_referenced_ids=”text1,text2" />
  12.   <TextView
  13.     android:id=”@+id/text3"
  14.     ...
  15.     app:layout_constraintStart_toEndOf=”@+id/barrier” />
  16. </android.support.constraint.ConstraintLayout>

上面的代码在设计面板里大概是这样的:

barrier.png

中间偏左有点阴影的虚线就是Barrier,它是一个虚拟的辅助控件,不会显示到布局中。

Group

Group帮助你对一组控件进行设置。最常见的情况是控制一组控件的visibility。你只需把控件的id添加到Group,就能同时对里面的所有控件进行操作。


 
  1. <android.support.constraint.ConstraintLayout ...>
  2.   <TextView
  3.     android:id=”@+id/text1" ... />
  4.   <TextView
  5.     android:id=”@+id/text2" ... />
  6.   <android.support.constraint.Group
  7.     android:id=”@+id/group”
  8.     ...
  9.     app:constraint_referenced_ids=”text1,text2" />
  10. </android.support.constraint.ConstraintLayout>

此时如果我们调用


 
  1. group.setVisibility(View.GONE);

那么text1 和 text2 都将不可见。

Placeholder

Placeholder顾名思义,就是用来一个占位的东西,它可以把自己的内容设置为ConstraintLayout内的其它view。因此它用来写布局的模版,也可以用来动态修改UI的内容。

用作模版:

我们用Placeholder创建一个名为template.xml的模版:


 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <merge xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     xmlns:tools="http://schemas.android.com/tools"
  5.     android:layout_width="match_parent"
  6.     android:layout_height="match_parent"
  7.     tools:layout_editor_absoluteX="0dp"
  8.     tools:layout_editor_absoluteY="81dp"
  9.     tools:parentTag="android.support.constraint.ConstraintLayout">
  10.  
  11.     <android.support.constraint.Placeholder
  12.         android:id="@+id/template_main_image"
  13.         android:layout_width="0dp"
  14.         android:layout_height="0dp"
  15.         android:layout_marginTop="16dp"
  16.         app:content="@+id/top_image"
  17.         app:layout_constraintDimensionRatio="16:9"
  18.         app:layout_constraintLeft_toLeftOf="parent"
  19.         app:layout_constraintRight_toRightOf="parent" />
  20.  
  21.     <android.support.constraint.Placeholder
  22.         android:id="@+id/template_save"
  23.         android:layout_width="48dp"
  24.         android:layout_height="48dp"
  25.         app:content="@+id/save"
  26.         app:layout_constraintEnd_toStartOf="@+id/template_delete"
  27.         app:layout_constraintHorizontal_bias="0.5"
  28.         app:layout_constraintStart_toStartOf="parent"
  29.         tools:layout_editor_absoluteY="460dp" />
  30.  
  31.     <android.support.constraint.Placeholder
  32.         android:id="@+id/template_delete"
  33.         android:layout_width="48dp"
  34.         android:layout_height="48dp"
  35.         app:content="@+id/delete"
  36.         app:layout_constraintEnd_toStartOf="@+id/template_cancel"
  37.         app:layout_constraintHorizontal_bias="0.5"
  38.         app:layout_constraintStart_toEndOf="@+id/template_save"
  39.         tools:layout_editor_absoluteY="460dp" />
  40.  
  41.     <android.support.constraint.Placeholder
  42.         android:id="@+id/template_cancel"
  43.         android:layout_width="48dp"
  44.         android:layout_height="48dp"
  45.         app:content="@+id/cancel"
  46.         app:layout_constraintEnd_toStartOf="@+id/template_edit"
  47.         app:layout_constraintHorizontal_bias="0.5"
  48.         app:layout_constraintStart_toEndOf="@+id/template_delete"
  49.         tools:layout_editor_absoluteY="460dp" />
  50.  
  51.     <android.support.constraint.Placeholder
  52.         android:id="@+id/template_edit"
  53.         android:layout_width="48dp"
  54.         android:layout_height="48dp"
  55.         app:content="@+id/edit"
  56.         app:layout_constraintEnd_toEndOf="parent"
  57.         app:layout_constraintHorizontal_bias="0.5"
  58.         app:layout_constraintStart_toEndOf="@+id/template_cancel"
  59.         tools:layout_editor_absoluteY="460dp" />
  60.  
  61. </merge>

注意我们在这里使用了 tools:parentTag="android.support.constraint.ConstraintLayout",这样在编辑的时候就会让它按照ConstraintLayout来处理。

每个PlaceHolder都设置了自己的app:content属性,比如app:content="@+id/edit",表示用id为edit的控件来填充这个位置。

这个模版在设计视图中是这样的:

模版写好了我们来填充真正的东西。

我们把刚才定义的模版include到真正的布局文件中,并且在这个布局文件中添加真实的控件,注意这里的控件无需添加任何约束,因为它们的位置是由Placeholder决定的。

还有一点就是模版要放在被引用的所有控件之前:


 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     xmlns:tools="http://schemas.android.com/tools"
  5.     android:id="@+id/root"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent"
  8.     app:layout_behavior="@string/appbar_scrolling_view_behavior"
  9.     tools:context="com.app.androidkt.constraintlayoutb.MainActivity"
  10.     tools:showIn="@layout/activity_main">
  11.     <include layout="@layout/template" />
  12.     <ImageView
  13.         android:id="@+id/top_image"
  14.         android:layout_width="wrap_content"
  15.         android:layout_height="wrap_content"
  16.         android:scaleType="fitXY"
  17.         android:src="@drawable/place_holder_demo" />
  18.     
  19.     <ImageButton
  20.         android:id="@+id/save"
  21.         android:layout_width="wrap_content"
  22.         android:layout_height="wrap_content"
  23.         android:layout_marginBottom="16dp"
  24.         app:layout_constraintBottom_toBottomOf="parent"
  25.         app:srcCompat="@drawable/ic_save_black_24dp" />
  26.  
  27.     <ImageButton
  28.         android:id="@+id/edit"
  29.         android:layout_width="wrap_content"
  30.         android:layout_height="wrap_content"
  31.         app:srcCompat="@drawable/ic_edit_black_24dp" />
  32.  
  33.     <ImageButton
  34.         android:id="@+id/cancel"
  35.         android:layout_width="wrap_content"
  36.         android:layout_height="wrap_content"
  37.         android:layout_marginBottom="16dp"
  38.  
  39.         app:srcCompat="@drawable/ic_cancel_black_24dp" />
  40.  
  41.     <ImageButton
  42.         android:id="@+id/delete"
  43.         android:layout_width="wrap_content"
  44.         android:layout_height="wrap_content"
  45.         android:layout_marginBottom="16dp"
  46.  
  47.         app:srcCompat="@drawable/ic_delete_black_24dp" />
  48.  
  49.  
  50. </android.support.constraint.ConstraintLayout>

界面预览如下:

以上就是PlaceHolder的使用场景之一模版功能。

动态替换

PlaceHolder还可以在Java代码中动态替换自己的内容:


 
  1. public class MainActivity extends AppCompatActivity {
  2.   private Placeholder placeholder;
  3.   private ConstraintLayout root;
  4.   @Override
  5.   public void onCreate(Bundle savedInstanceState) {
  6.     super.onCreate(savedInstanceState);
  7.     setContentView(R.layout.activity_main);
  8.     ...
  9.   }
  10.   public void onClick(View view) {
  11.     placeholder.setContentId(view.getId());
  12.   }
  13. }

如果结合过渡动画的话,就可以实现一些比较有趣的效果:


 
  1. public class MainActivity extends AppCompatActivity {
  2.   private Placeholder placeholder;
  3.   private ConstraintLayout root;
  4.   @Override
  5.   public void onCreate(Bundle savedInstanceState) {
  6.     super.onCreate(savedInstanceState);
  7.     setContentView(R.layout.activity_main);
  8.     ...
  9.   }
  10.   public void onClick(View view) {
  11.     TransitionManager.beginDelayedTransition(root);
  12.     placeholder.setContentId(view.getId());
  13.   }
  14. }

下面是使用PlaceHolder结合过渡动画实现的效果:

Placeholder.gif

源码见:Download this project from GitHub

文章参考

http://androidkt.com/constraintlayout/ 

What's new in Constraint Layout 1.1.x 

阅读更多
换一批

没有更多推荐了,返回首页