Android kotlin的 Views-DSL的看法

2023-05-11  本文已影响0人  海龙lv
伴随着时间的流逝,公司项目的功能也基本上趋于稳定,所以空闲的时间也就多了起来,就想着写写安卓原生,来将自己负责的公司项目的相关的功能用安卓来写一下,因为之前是写过Jetpack Compose的,但是现在看来,还是不太和当前的现实契合。比如版本,比如很多公司用的还是安卓原先的框架,甚至很多是用Java的,所以Jetpack Compose虽然更加的优秀,奈何现实如此,只能从头研究先前的框架了
因为自己主攻iOS,一般的来说UI布局用的也是代码来实现,现在安卓要用XML,倒不是感觉难,因为自己也会Vue,只是感觉和iOS的开发有点突兀,并且布局如果和数据相关的话,就感觉很呆,还有Views DSL vs xml layouts
所以我就学习了一种代码布局的框架——Views DSL,这样一来,就能和写iOS一样了,用代码进行布局。这个框架还是谷歌官方推荐的(当然最推荐的还是Jetpack Compose...)。
最蛋疼的一个问题是,网上相关的中尉教程我没有找到,顶多是将官网的英文翻译一下,而且,官网的文档写的也是言简意赅,让人味同嚼蜡,苦不堪言,所以我自己总结了下使用的经验,共同学习。
和iOS一样,因为主要使用的Masonry框架,相对于安卓来讲,布局就很多,什么FrameLayout、LinearLayout... 也感觉有点乱套,还是觉得ConstraintLayout感觉更加的顺手。这个框架可以用代码进行创建常用的UI控件,比如TextView、Button、ImageView、EditTextView等,可以方便的进行创建UI,结合Views DSL ConstraintLayout可以很顺利的进行UI的创建、布局。
例子:下面的是DSL创建的ImageView,并且用的ConstraintLayout进行的布局
       // 放大镜
        val glass = imageView {
            imageResource = R.drawable.searchggla
            scaleType = ImageView.ScaleType.CENTER_CROP

        }
        searchBg.add(glass, glass.constraintLayout().lParams {
            width = 20.sp2px()
            height = 20.sp2px()
            centerVertically()
            startOfParent(20.sp2px())
        })
但是如果说遇到一些三方的,比如一个三方的轮播图,那怎么办呢?我现在的办法是用XML进行创建对象,然后再代码布局。就是相互结合使用,如果看官姥爷们有更好的办法,可以教我😄
例子:下面的是一个三方的轮播图:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <com.youth.banner.Banner
        android:id="@+id/bannerLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:banner_indicator_normal_color="@color/clear"
        app:banner_indicator_selected_color="@color/clear"
        app:banner_radius="15sp"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>
  // 轮播图
    let constraintLayout = requireContext().inflate<ConstraintLayout>(R.layout.banner)
    let banner =
            constraintLayout.findViewById<Banner<String, BannerImageAdapter<String>>>(R.id.bannerLayout1)
        // 轮播图设置
        banner.apply {
            addBannerLifecycleObserver(activity)
            indicator = CircleIndicator(activity)
        }

      constraintLayout.add(banner, banner.lParams {
            width = 0
            height = 102.sp2px()
            topOfParent(60.sp2px())
            leftOfParent(16.sp2px())
            rightOfParent(16.sp2px())
        })
还有一些比较特殊的不是三方的UI组件如ShapeableImageView这些,Views-DSL没有提供代码的对象创建方法,可以如此:
例子:下面的是一个圆形的网络图片(用Glide进行网络图片的赋值)
// 图片(加载网络图片的,需要剪圆角的,需要ShapeableImageView)
            val shapeModel = ShapeAppearanceModel.builder()
                .setAllCorners(RoundedCornerTreatment())
                .setAllCornerSizes(28.dp2pxFloat())
                .build()

            val imageV = ShapeableImageView(ctx).apply {

                shapeAppearanceModel = shapeModel

            }

            supView.add(imageV, imageV.constraintLayout().lParams {
                width = 56.sp2px()
                height = 56.sp2px()
                centerHorizontally()
                topOfParent(22.sp2px())
            })

            Glide.with(ctx)
                .load(hotRoom[index].icon)
                .into(imageV)
如果布局在Activity中的话,可以直接进行在onCreate中进行创建,然后setContentView,但是在fragement中的话,那就需要如此(继承Ui的一个类进行布局):
// 消息
class MessageFragment: Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val ui = MessageUi(requireContext())
        return ui.root
    }
}

class MessageUi(override val ctx: Context) : Ui {

    override val root = constraintLayout {
        setBackgroundResource(R.color.purple_700)
        lParams {
            width = matchParent
            height = matchParent
        }
    }

}
将来遇到棘手问题,继续更新...
上一篇下一篇

猜你喜欢

热点阅读