写点什么

ConstraintLayout 1,flutterrow 换行

用户头像
Android架构
关注
发布于: 刚刚

Circular Position

涉及到三个属性


示例:


<Buttonandroid:id="@+id/btn_invoke"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="24dp"android:onClick="invoke"android:text="执行"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"/>


<Buttonandroid:id="@+id/btn_2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="51dp"android:layout_marginTop="31dp"android:text="2"app:layout_constraintCircle="@id/btn_invoke"app:layout_constraintCirc


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


leRadius="100dp"app:layout_constraintCircleAngle="80"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent"/>


效果图:



  1. 使用环形定位会导致之前的约束坐标失效

  2. 角度和半径默认为零, 所以不设置角度和半径只指定圆形就会完全重叠

强制约束

在 1.1 之前如果布局属性是wrap_content将无法遵守约束, 这一问题现在可以通过以下属性修复了;


app:layout_constrainedWidth=”true”

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%。


<TextViewandroid:id="@+id/textView6"android:layout_width="0dp"android:layout_height="0dp"


app:layout_constraintHeight_default="percent"app:layout_constraintHeight_percent="0.5"


app:layout_constraintWidth_default="percent"app:layout_constraintWidth_percent="0.5" />

布局属性

除了布局编辑器写布局也应该要了解布局的属性, 不然有些问题你看不出来的.

编辑器属性

该属性并不会在 Android 上有任何影响, 只会影响 AS 的布局编辑器坐标


tools:layout_editor_absoluteY="246dp"tools:layout_editor_absoluteX="36dp"


布局编辑器



真机上


约束

一个控件有四个约束点/ 十二个约束属性(左和右有各有两个属性 start 和 end 以及 right 和 left)



约束只能是同一水平下才能相互约束, 例如左和右之间能约束, 左不能和上下约束点关联.


约束并不是相互关联的关系. 而是


// 和父布局关联约束 app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"


// 和其他控件关联约束 app:layout_constraintLeft_toRightOf="@+id/button3"app:layout_constraintRight_toLeftOf="@+id/button3"app:layout_constraintTop_toBottomOf="@id/button3"app:layout_constraintBottom_toTopOf="@id/button3"


layout_constraintStart_toEndOflayout_constraintStart_toStartOflayout_constraintEnd_toStartOflayout_constraintEnd_toEndOf

文字基准线

有些控件是包含文字内容的, 所以约束布局的控件有一个文字基准线约束. 默认是隐藏,需要点击开关显示.


layout_constraintBaseline_toBaselineOf


注意: 使用了文字基准线对齐就不需要使用上下约束了

百分比偏移

通过小数点(百分比)控制控件在屏幕垂直/水平的百分比位置.


注意: 只有水平位置(上下/左右约束点都添加了约束)都添加约束, 该控件才支持百分比偏移


app:layout_constraintHorizontal_bias="0.0"app:layout_constraintVertical_bias="0.69"


注意: 如果是约束的 ConstraintLayout, 不需要这两个属性也可以设置百分比偏移



边距

一般的边距没什么好讲的. 和以前一样.


android:layout_marginStartandroid:layout_marginEndandroid:layout_marginLeftandroid:layout_marginTopandroid:layout_marginRightandroid:layout_marginBottom


因为约束布局控件之前的关联性太强, 如果一个布局隐藏(gone)就可能导致整个布局的位置移动. 所以 ConstraintLayout 拥有隐藏边距属性


ConstraintLayout 中使用 Gone 属性值



根据官方图可以看出 Constraintlayout 如果控件被隐藏并不会像其他布局一样坐标变成 0,0 点. 只是 margin 和宽高变成 0.


layout_goneMarginStartlayout_goneMarginEndlayout_goneMarginLeftlayout_goneMarginToplayout_goneMarginRightlayout_goneMarginBottom


以上边距属性会根据其约束的控件是否是隐藏(invisible 不算)来生效, 同时 margin 失效.

宽高比

通过设置宽或者高中的一个为 match_constraint(0dp), 就可以设置控件的宽高比


matc_constraint 的宽或高会根据另一边的尺寸变化来符合比例



宽高比分两种:


宽:高


app:layout_constraintDimensionRatio="2:1"


很简单就是宽比高, 默认受约束的就是match_constraint(0dp)的一边.


受约束的会根据另一边发生尺寸比例的变化(如果是 match_constraint 和 wrap_content 时 1:1 比例会发生尺寸变化成正方形)


自定义


app:layout_constraintDimensionRatio="w,2:1"


我理解为颠倒了比例. w 即设置比例为高比宽, h 为宽比高. 实际操作体验吧

宽高

宽高属性值


  • Fixed 固定值

  • Wrap_Content 包裹值

  • Match_Constraint "0dp"

Match_Constraint

理论上 ConstraintLayout 的宽高不再使用match_parent这一属性值. 取而代之的是 0dp(称为 match_constraint).


**Important: **MATCH_PARENT is not supported for widgets contained in a ConstraintLayout, though similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent".


官方说明 match_parent 在 ConstraintLayout 中不被支持


match_constraint 只有在水平或者垂直拥有两条方向的约束时才有效, 即匹配剩余全部空间. 如果只有水平只存在一条或者没有约束相当于 wrap_content.


示例图:



如果你强行使用编辑器会自动帮你转换成固定 dp 值, 不过如果你仅仅是约束 ConstraintLayout 布局并没有问题.不能理解我说的什么自己动手试试.

链模式


两个空间相互约束就会产生一个锁链. (注意布局编辑器中是无法通过拖动约束点相互约束, 我认为是 bug)


只能通过多选居中的方式或者直接 XML 编辑.


app:layout_constraintHorizontal_chainStyle="packed"


链接在一起主要是可以设置不同的样式达到适配父容器宽度或者高度的效果. 注: 一个链还有第一个控件才需要设置(chainStyle)样式.


根据样式有三种参数值:


  • Spread 均布(默认样式)

  • Spread inside 头尾靠边, 其他中间均布

  • Packed 居中靠齐


官方有一张介绍图



虽然看着有五个,实际上属性还是那三个. 不过有加入权重和百分比偏移. Bias 是偏移, weighted 是权重.

权重

和 LinearLayout 的 wight 属性一样. 不过只支持 spread 和 spread_inside 有效.


layout_constraintHorizontal_weight


同样可以编辑属性也可以鼠标修改


宽高约束

wrap_content不受约束的限制 (这一问题在 ConstraintLayout1.1 被解决)


app:layout_constrainedWidth=”true|false”app:layout_constrainedHeight=”true|false”

Optimizer

需要知道的是,当我们使用 MATCH_CONSTRAINT 时,ConstraintLayout 将不得不对控件进行 2 次测量,而测量的操作是昂贵的。


而优化器(Optimizer)的作用就是对 ConstraintLayout 进行优化,对应设置给 ConstraintLauyout 的属性是:


  • layout_optimizationLevel。


可设置的值有:


  • none:不应用优化。

  • standard:仅优化直接约束和屏障约束(默认的)。

  • direct:优化直接约束。

  • barrier:优化屏障约束。

  • chain:优化链约束(实验)。

  • dimensions:优化尺寸测量(实验)。


在设置值时,可以设置多个,如:


app:layout_optimizationLevel="direct|barrier|dimensions"

ConstraintSet

修改 ConstraintLayout 官方不推荐使用ConstraintLayout.LayoutParams而是推荐使用 ConstraintSet


ConstraintSet可以直接通过代码创建或改变约束/改变 Margin 等操作, 并且都提供方法而非成员变量.


如果你想修改 ConstraintLayout 中任意一个控件的属性都需要进行以下三个步骤.


步骤:


  1. 克隆或者加载 XMl 布局

  2. 修改属性

  3. 应用到新的布局上


示例:


public class MainActivity extends AppCompatActivity {ConstraintSet mConstraintSet = new ConstraintSet(); // create a Constraint SetConstraintLayout mConstraintLayout; // cache the ConstraintLayout


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.state1);Context context = this;


mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);mConstraintSet.clone(mConstraintLayout); // 克隆一个布局到 ConstraintSet}


public void onClick(View view) {TransitionManager.beginDelayedTransition(mConstraintLayout); // 一行代码添加动画 mConstraintSet1.applyTo(mConstraintLayout); // 应用到新的布局}}


官方示例, 但是我发现我是无效.

克隆

复制一个 ConstraintLayout 布局到 ConstraintSet 中. 后面可以对 ConstraintSet 进行修改(即对复制的布局修改).


void clone (ConstraintSet set)


void clone (ConstraintLayout constraintLayout)


void clone (Context context,int constraintLayoutId)

创建约束

这仅仅指的是创建一条约束, 一个控件可以存在 n 条约束. 最少两条才能确定位置.


需要注意的是STARTLEFT本身是可以并存的. 不要混用


void connect(int startID, int startSide, int endID, int endSide)


void connect(int startID, int startSide, int endID, int endSide, int margin)


示例:


// 克隆布局 mConstraintSet = new ConstraintSet();mConstraintSet.clone(mBinding.root);


// 用三条约束连接两个控件 mConstraintSet.connect(R.id.btn_3, ConstraintSet.LEFT, R.id.btn, ConstraintSet.RIGHT, 100);mConstraintSet.connect(R.id.btn_3, ConstraintSet.TOP, R.id.btn, ConstraintSet.TOP);mConstraintSet.connect(R.id.btn_3, ConstraintSet.BOTTOM, R.id.btn, ConstraintSet.BOTTOM);


// 应用布局 mConstraintSet.applyTo(mBinding.root);

垂直居中

void centerVertically(int viewId, int toView)


void centerVertically(int centerID,int topId,


int topSide,


int topMargin,int bottomId,int bottomSide,int bottomMargin,float bias)


示例: 相对父布局垂直居中


mConstraintSet.centerVertically(R.id.btn_3, ConstraintSet.PARENT_ID);


相对其他控件垂直居中


mConstraintSet.centerVertically(R.id.btn_3, R.id.btn);


错误示例: 如果你使用 TOP 或者 BOTTOM 之类的属性, 只会贴靠顶部.. 并不会居中


mConstraintSet.centerVertically(R.id.btn_3, ConstraintSet.TOP);


注意如果你在第二种方法垂直居中使用了 LEFT 或 RIGHT 会导致程序停止

水平居中

水平居中同样不能使用 TOP 或者 BOTTOM, 并且 Rtl 和不包含 Rtl 有使用上的区别


void centerHorizontally(int centerID,int leftId,int leftSide,int leftMargin,int rightId,int rightSide,int rightMargin,float bias)


void centerHorizontally(int viewId,int toView)// 只能使用 LEFT/RIGHT 否者 Crash


void centerHorizontallyRtl(int viewId,int toView)


void centerHorizontallyRtl(int centerID,int startId,int startSide,int startMargin,int endId,int endSide,int endMargin,float bias)// 只能使用 START/END


示例:


// 居中父布局 mConstraintSet.centerHorizontallyRtl(R.id.btn_3, ConstraintSet.PARENT_ID);


mConstraintSet.centerHorizontallyRtl(R.id.btn_3, R.id.btn, ConstraintSet.START, 0, R.id.btn_2, ConstraintSet.END, 0, 0.5f);

居中

该方法不仅支持水平居中还支持垂直居中.


void center (int centerID,int firstID,int firstSide,int firstMargin,int secondId,int secondSide,int secondMargin,float bias)

宽高

可以是一个像素值尺寸或者 WRAP_CONTENTMATCH_CONSTRAINT


void constrainHeight (int viewId,int height) // 像素单位


void constrainWidth (int viewId,int width)


最大和最小宽高只在MATCH_CONSTRAINT情况下才有效果


void constrainMaxHeight (int viewId,int height)


void constrainMinHeight (int viewId,int height)


void constrainMaxWidth (int viewId,int width)


void constrainMinWidth (int viewId,int width)


默认宽高: 即均布排列的时候宽度(例如 weight 模式下)


void constrainDefaultWidth (int viewId,int width)


void constrainDefaultWidth (int viewId,int width)

GuidLine

创建 Guideline


void create (int guidelineID, // 给创建的 guideline 指定 idint orientation) // guidline 方向


设置 Guideline 边距


void setGuidelineEnd (int guidelineID,int margin)


void setGuidelineBegin (int guidelineID,int margin)


void setGuidelinePercent (int guidelineID,float ratio)

Barrier

void createBarrier (int id, // idint direction, // 方向 int... referenced) // 组 id


设置类型


void setBarrierType (int id,int type)

删除约束

void clear (int viewId,int anchor)// 删除该空间某一约束


void clear (int viewId)// 删除该控件全部约束


示例: 删除顶部约束


mConstraintSet.clear(R.id.btn, ConstraintSet.TOP);

透明度

void setAlpha (int viewId,float alpha)

旋转

旋转中心是控件的中心


void setRotation (int viewId,float rotation)// 以控件的左上角为中心旋转


void setRotationX (int viewId,float rotationX)


// 以控件的 x 轴翻转


void setRotationY (int viewId,float rotationY)// 以控件的 y 轴翻转

缩放

以控件为中心, 百分比浮点数


void setScaleX (int viewId,float scaleX) // 倍数关系


void setScaleY (int viewId,float scaleY)

偏移

以控件中心偏移

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
ConstraintLayout 1,flutterrow换行