糊UI记录

2021-05-07  本文已影响0人  Infinity_空

ConstraintLayout

1.Group的使用,统一控制一组View的隐藏与显示

<androidx.constraintlayout.widget.Group
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            app:constraint_referenced_ids="id1,id2,id3"
            tools:visibility="visible" />

其中app:constraint_referenced_ids就是我们要统一处理的id。
但是!!!只要View处于这个Group中,那么单独再对其进行视图状态的控制就失效了!!

2.在ConstraintLayout中使用Include标签
因为ConstraintLayout在计算布局的时候,需要所有tag的宽高,所以不仅需要设置约束,还需要设置layout_height和layout_width,这样约束布局才能生效

3.ConstraintLayout和HorizontalScrollView的神奇嵌套

<HorizontalScrollView 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="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/second_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="神奇神奇神奇神奇神奇神奇神奇神奇神奇神奇神奇神奇神奇神奇" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</HorizontalScrollView>

在如上的一个布局中,如果TextView的width是wrap_content的,那么可以正常显示。但是如果TextView的width是match_parent的话,就不能正常显示,TextView的宽度会被置为0,HorizontalScrollView 可以加一个android:fillViewport="true",让内部的元素都全部显示,但是就会有个神奇的bug,发现HorizontalScrollView 的height虽然是wrap_content,但是高度却会多了一段空白。这个应该是ConstraintLayout的bug,因为将ConstraintLayout换成RelativeLayout或者LinearLayout就没有这种问题

4.在ConstraintLayout中,如果左右有两个TextSize不同的TextView,左边的View比较小,右边的View比较大,并且有多行 。左边的View想要居中对齐右边的View的第一行,可以使用layout_constraintBaseline_toBaselineOf进行对齐。

微信截图_20211201092345.png

RecyclerView

1.RecyclerView嵌套缓存的问题
在RecyclverView中,每个item又是一个RecyclerVIew时,如果进行列表刷新,会发现布局异常,下面的item会跑到前几个item中去。具体原因未知,解决方案就是,在刷新父RecyclerView的item时,同时要对子RecyclerView进行notifyItemRangeChanged。(备注:如果用的是notifyDataSetChanged,会有比较大的闪烁)

PopupWindow

  1. 如果PopupWindow里面的TextView设置了DrawableStart或者DrawableEnd,那么measuredWidth在show之前和show之后会不一样,所以如果要根据PopupWindow的宽度计算它的显示位置的话,就不要使用CompoundDrawable。
  2. 使用ListPopupWindow点击外围或者重复点击anchorView消失的话,需要设置listPopupWindow.isModal = true
  3. 如果多个anchorView复用同一个ListPopupWindow,会出现“串行”。
    复现路径:
    1.点击第一个anchorView,不选择任何Item,点击外围弹框消失。
    2.点击第二个anchorView,选择item,发现第一个anchorView响应了选择,甚至会出现越界。
    原因:
    因为ListPopupWindowshow()的时候会执行buildDropDown(),此时如果mDropDownListnull就会重新设置onClickListener,如果mDropDownList不为null,则不会重新设置onClickListener。而mDropDownList设置为null的时候需要调用dismiss,但是【复现路径】中描述的操作,并不会调用ListPopupWindow的dismiss,而是直接调用了PopupWindowdismiss。所以ListPopupWindow的onClickListener没有被重置。
    方案:
    需要设置ListPopupWindow的OnDismissListener,这个Listener实际上监听的是PopupWindow的dismiss,所以每次消失都可以监听到。
    代码:
listPopupWindow.setOnDismissListener {
    listPopupWindow.dismiss()
}

Toolbar

  1. toolbar的navigationIcon的MenuItem的itemId是android.R.id.home,可以用onOptionsItemSelected中修改点击事件
  2. navigation icon的水波纹效果:
    2.1.对于简单的比如“+”的图标,如果toolbar的background是null,就不会出现点击效果。需要将background设置成TRANSPARENT,才会有效果(原因暂时未知)
    2.2.navigationIcon的点击效果是将background设置成"?attr/controlBackground",如果仿toolbar的view需要设置点击效果,可以使用这个。
    另外两种效果:
    ?attr/selectableItemBackgroundBorderless <!--无边界涟漪效果,最后阴影成圆形-->
    ?attr/selectableItemBackground <!--有边界涟漪效果,最后阴影成矩形-->
    
    这两种水波纹会比较大,应该是用于其他非标题栏的点击效果
  3. navigation icon的样式在原生目录中的values.xml中,Base.Widget.AppCompat.Toolbar.Button.Navigation,其中有设置navigation icon的背景和最小宽度
  4. contentInsetStart类似的属性是用来设置toolbar title的左右padding的

Dialog

  1. 如果使用DialogFragment,如果有输入框,键盘弹出Dialog会随着键盘的弹出收起而浮动,通过设置setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)是不生效的,需要通过修改style,将windowIsFloating设置成false, 不过设置之后,Diaolog的位置需要通过调整Layout,进行修改。最好是使用ConstraintLayout可以设置Dialog在竖直方向的百分比,比较动态

自定义View

1.如果自定义的View是一个单独继承原生View的View(比如TextView,ImageView等等),在init的时候修改LayoutParams时不生效。
原因:通过阅读源码,布局的inflate过程,主要是在LayoutInflater.java中的rInflate函数中执行,通过判断不同的tag,会执行不同的方案,如果是一个View的话,会先把这个View先new出来,此时就会先执行View的构造函数,new出来之后,在添加到ViewGroup时,会通过viewGroup.generateLayoutParams(attrs)给该View创建一个新的LayoutParams,所以之前在自定义View的构造函数中创建的LayoutParams就会被覆盖掉。另外其中的attrs就是自定义View在xml中设定的属性。所以如果要动态的改变自定义View的LayoutParams,只能在layout inflate完成之后再去修改。或者是在init中通过post(Runnable)去修改。

上一篇下一篇

猜你喜欢

热点阅读