Litho的使用–基本使用及加载网络图片
Litho是Facebook推出的一套高效构建Android UI的声明式框架,主要目的是提升RecyclerView复杂列表的滑动性能和降低内存占用。详见Litho的原理
以及Litho官网,这里记录下我自己对Litho的基本使用。
Litho的配置
apply plugin: 'kotlin-kapt'
dependencies { // ... // Litho implementation 'com.facebook.litho:litho-core:0.21.0' implementation 'com.facebook.litho:litho-widget:0.21.0' compileOnly 'com.facebook.litho:litho-annotations:0.21.0' kapt 'com.facebook.litho:litho-processor:0.21.0' // SoLoader implementation 'com.facebook.soloader:soloader:0.5.1' // For integration with Fresco implementation 'com.facebook.litho:litho-fresco:0.21.0' // For testing testImplementation 'com.facebook.litho:litho-testing:0.21.0' //下面是可选的库 // Sections implementation 'com.facebook.litho:litho-sections-core:0.21.0' implementation 'com.facebook.litho:litho-sections-widget:0.21.0' compileOnly 'com.facebook.litho:litho-sections-annotations:0.21.0' kapt 'com.facebook.litho:litho-sections-processor:0.21.0' }
project的build.gradle添加
repositories { jcenter() }
Litho的Hello World
首先在自定义的Application的onCreate方法中添加
SoLoader.init(this, false)
然后就可以使用Litho了
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val cc = ComponentContext(this) setContentView(LithoView.create(this,getTextView(cc))) } / * 获取TextView */ private fun getTextView(cc: ComponentContext): Component? { return Text.create(cc) .textColorRes(R.color.colorPrimary) .text("Hello World!") .textSizeDip(50f) .build() } }
明显看出来是React的UI风格,与kotlin、flutter写界面有异曲同工之处。由于kotlin的简洁性,可以将抽出一个工具Litho.kt,网上已经有轮子,拿来直接用,这里就不贴出来了,详见demo。简化后的代码,如下:
/ * 获取TextView */ private fun getTextView(cc: ComponentContext): Component? { return text(cc) { textColorRes(R.color.colorPrimary) text("Hello World!") textSizeDip(50f) }.build() }
当然Litho并不是这样用的,Litho类似dragger2一样,可以通过注解apt的形式生成我们需要的布局,两种方式:@LayoutSpec和@MountSpec,首先看一下@LayoutSpec
LayoutSpec
话不多说,直接上代码:
@LayoutSpec object LayoutComponentSpec { @OnCreateLayout fun onCreateLayout(c: ComponentContext): Component { return column(c) { paddingDip(YogaEdge.ALL, 8f) children { text { text("title") textColorRes(R.color.colorPrimary) textSizeDip(28f) } text { text("content") textColorRes(R.color.colorAccent) textSizeDip(16f) } } } } }
Build之后就会生成一个LayoutComponent类,和之前的Text一样使用
val layoutComponent = LayoutComponent.create(cc).build() setContentView(LithoView.create(this,layoutComponent))
MountSpec
- 在布局计算之前运行 @OnPrepare 一次。
- 在布局计算期间选择性运行 @OnMeasure 。
- 在布局计算之后运行 @OnBoundsDefined 一次。
- 在组件挂接到宿主 View 之前运行 @OnCreateMountContent 。
- 在组件挂接到宿主 View 之前运行 @OnMount 。
- 在组件挂接到宿主 View 后运行 @OnBind 。
- 在将组件从宿主 View 分离之前运行 @OnUnbind 。
- 在组件从宿主 View 分离后,选择性运行 @OnUnmount 。
还是以例子为主:
@MountSpec(poolSize = 12, canPreallocate = true) object GlideImageSpec { private val TAG = "GlideImageSpec" / * 在组件挂接到宿主 View 之前运行 */ @OnCreateMountContent internal fun onCreateMountContent(c: Context): ImageView { val imageView = ImageView(c) imageView.scaleType = ImageView.ScaleType.CENTER_CROP return imageView } / * 在布局计算之前运行 */ @OnPrepare internal fun onPrepare(context: ComponentContext, @Prop imageUrl: String, load: Output
>) { Log.d(TAG, "onPrepare: $imageUrl") val requestBuilder = Glide.with(context.androidContext).load(imageUrl) val apply = requestBuilder.apply(RequestOptions()) load.set(apply) } / * 在组件挂接到宿主 View 之前运行 */ @OnMount internal fun onMount(context: ComponentContext, imageView: ImageView, @FromPrepare load: RequestBuilder
) { Log.d(TAG, "onMount: load:$load") load.into(imageView) } }
主要是一个以Glide加载网络图片的组件,下面我们看一下使用,并对Component添加点击事件:
@LayoutSpec object ImageViewComponentSpec { @OnCreateLayout fun onCreateLayout(c: ComponentContext, @Prop title: String, @Prop content: String,@Prop imgUrl: String, @Prop click: String): Component { return column(c){ paddingDip(YogaEdge.ALL, 16f) backgroundColor(Color.WHITE) child(text(c){ text(title) textSizeSp(40f) }) child(text(c){ text(content) textSizeSp(20f) }) //GlideImage加载网络图片 child(GlideImage.create(c) .widthDip(200f) .heightDip(200f) .imageUrl(imgUrl) .build()) //添加点击事件 clickHandler(ImageViewComponent.onClick(c, click)) } } / * 注解点击事件的回调 */ @OnEvent(ClickEvent::class) fun onClick(c: ComponentContext, @FromEvent view: View, @Param someProp: String) { Toast.makeText(c.applicationContext, "click:$someProp", Toast.LENGTH_SHORT).show() } }
//内容+图片(加载网络)的Component,并添加点击事件 val imageViewComponent = ImageViewComponent.create(cc) .title("title") .content("content") .click("here") .imgUrl("http://pic37.nipic.com//_0_2.png") .build() setContentView(LithoView.create(this,imageViewComponent))
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215822.html原文链接:https://javaforall.net
