将Android RecycleView 转换为 LazyColumn - Jetpack Compose

20 篇文章 1 订阅
2 篇文章 0 订阅

这个适合初学者的教程提供了一个如何将这个简单的 RecycleView 应用程序转换为 Jetpack Compose 的示例。

在迁移到 Jetpack Compose 后,我还采取了一些额外的步骤来清理未使用的代码或 xml。

1.删​​除RecycleView、Layout、Fragment和Library文件

除了RecycleView,您还可以删除片段和布局文件,因为 Jetpack Compose 不需要它们。

删除不需要的源代码

  • MainFragment.kt
  • RecyceViewAdapter.kt
  • ItemViewHolder.kt
  • ItemDiffCallback.kt

删除不需要的布局文件

  • main_activity.xml
  • main_fragment.xml
  • item.xml

删除不需要的构建功能和库

在app\build.gradle中,删除数据绑定,因为这不再适用于 Jetpack Compose。

buildFeatures {
    dataBinding true
}

也删除这些依赖项。

dependencies {
    implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
    implementation 'androidx.fragment:fragment-ktx:1.4.0'
}

修复 MainActivity.kt 中的编译问题

删除此代码,MainActivity::onCreate()因为您不再需要片段。

setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
    supportFragmentManager.beginTransaction()
        .replace(R.id.container, MainFragment.newInstance())
        .commitNow()
}

您现在应该能够成功构建。

2 设置 Jetpack Compose 库

更新 build.gradle(项目级别)

在内部添加compose_version扩展名,buildScript{ }以便以后可以引用撰写版本。

buildscript {
    ext {
        compose_version = '1.0.5'
    }
    ...
}

更新 app\build.gradle(应用级别)

添加compose构建功能和kotlinCompilerExtensionVersion组合选项。

android {
    ....
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
    }
    ....
}

替换implementation 'androidx.appcompat:appcompat:1.4.0’为implementation 'androidx.activity:activity-compose:1.4.0’并添加以下 Jetpack Compose 依赖项。

dependencies {
    ...
    implementation 'androidx.activity:activity-compose:1.4.0'
    ...
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
    ...
}

为撰写更新 MainActivity

在 Jetpack Compose 中,你不再需要AppCompatActivity了,你可以直接继承自ComponentActivity

修改MainActivity为直接继承ComponentActivity,覆盖onCreate()和调用SetContent{},允许@composable内部调用任何函数。

class MainActivity : ComponentActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContent {
            // Implement composable function here.  
        }  
    }
}

3. 在 Jetpack Compose 中添加主题

在 Jetpack Compose 中添加主题之前,让我们清理一下colors.xml和themes.xml.

您只需要themes.xml为 提供颜色android:statusBarColor。所以你保留它并删除其他任何东西。

清理colors.xml 和themes.xml

这些应该是自定义状态栏颜色所需的最少代码。

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_700">#FF3700B3</color>
</resources>

themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.RecycleViewDemo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
    </style>
</resources>

themes.xml(夜间)

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.RecycleViewDemo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
    </style>
</resources>

添加撰写主题

创建ui.theme包文件夹,将Colors.kt, Shape.kt,Type.kt放入该文件夹。

Colors.kt

val Purple200 = Color(0xFFBB86FC)
val Purple500 = Color(0xFF6200EE)
val Purple700 = Color(0xFF3700B3)
val Teal200 = Color(0xFF03DAC5)

Shape.kt

val Shapes = Shapes(
    small = RoundedCornerShape(4.dp),
    medium = RoundedCornerShape(4.dp),
    large = RoundedCornerShape(0.dp)
)

Type.kt

val Typography = Typography(
    body1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp
    )
)

Theme.kt

private val DarkColorPalette = darkColors(
    primary = Purple200,
    primaryVariant = Purple700,
    secondary = Teal200
)

private val LightColorPalette = lightColors(
    primary = Purple500,
    primaryVariant = Purple700,
    secondary = Teal200
)

@Composable
fun RecycleViewDemoTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable() () -> Unit
) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}

这些文件允许您自定义 Jetpack Compose 的主题。

要为您的应用程序设置主题,请MainContent()从RecycleViewDemoTheme. 代码如下所示:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MainScreen()
        }
    }
}

@Composable
fun MainScreen() {
    RecycleViewDemoTheme {
        MainContent()
    }
}

@Composable
fun MainContent() {
    //Todo: Implement LazyColumn
}

4.添加顶部应用栏

由于您已删除AppCompatActivity,因此不再创建顶部应用栏。您需要使用 Jetpack Compose 创建它。

添加 Scaffold() 可组合函数

要创建顶部应用栏,请使用ScaffoldI()可组合功能。代码如下所示:

@Composable
fun MainScreen() {
    RecycleViewDemoTheme {
        Scaffold(
            topBar = { TopAppBar (title = {Text(stringResource(R.string.app_name))})
            }
        ) {
            MainContent()
        }
    }
}

预览可组合函数

为了预览可组合函数,您添加以下代码:

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MainScreen()
}

编译后,您应该会在右侧看到类似的内容。如果您运行您的应用程序,您应该会看到与预览版相同的 UI。

现在,该应用程序已完全使用 Jetpack Compose 代码实现。此时,UI 与没有回收视图内容的基于视图的 UI 方法完全相同。

5.实现LazyColumn可组合功能

RecycleViewJetpack compose 中的等价物是LazyColumn可组合函数。

严格来说,它们并不相同。LazyColumn并没有真正回收项目 UI。它只是重新创建整个项目 UI。所以理论上RecycleView性能应该比LazyColumn.

它的好处是LazyColumn使用更少的代码,因为RecycleView它有很多样板代码。

创建 MainViewModel 并传入 MainContent

由于数据即将到来,您可以在将其作为参数传递给可组合函数时使用委托属性MainViewModel创建它。by viewModels MainActivityMainContent()

MainActivity.kt

class MainActivity : ComponentActivity() {  
    val viewModel by viewModels<MainViewModel>()  

    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContent {  
            MainScreen(viewModel)  
        }  
    }  
}

by viewModels使用,以便在销毁和重新创建MainViewModel实例时不会重新创建实例。

MainScreen.kt

@Composable
fun MainScreen(viewModel: MainViewModel) {
    RecycleViewDemoTheme {
        Scaffold(
            topBar = { TopAppBar (title = {Text(stringResource(R.string.app_name))})
            }
        ) {
            MainContent(viewModel)
        }
    }
}

将 LiveData 转换为状态

在 Jetpack Compose 中,您需要将其转换为LiveData,State以便在数据更改或更新时能够正确重组。要转换它,请使用observeAsState() LiveData函数。

在此之前,您需要添加此库依赖项:

implementation "androidx.compose.runtime:runtime-livedata:$compose_version"

转换为 后State,您将值(即List)作为ListContent()可组合函数的参数。

@Composable
fun MainContent(viewModel: MainViewModel) {
    val itemsState = viewModel.items.observeAsState()

    itemsState.value?.let { items ->
        ListContent(items)
    }
}

实现 LazyColumn

由于RecycleViewitem 原始实现填充了整个屏幕宽度并居中对齐,因此您需要执行相同的操作。这可以通过modifer和horizontalAlignment参数来完成LazyColumn

在最后一个参数LazyColumn是Function Literal (Lambda Function) with Receiver。是LazyListScope接收器。

要添加项目(即List),请调用LazyListSciope.items()可组合函数。要添加项目内容,您需要实现ShowItem()仅显示文本的可组合功能。

为了匹配原始RecycleView实现,我们将字体大小设置为34.sp和FontWeight.Bold。

代码如下所示:

@Composable
fun ListContent(items: List<ItemData>) {
    LazyColumn (
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        items(items = items) { item ->
            ShowItem(item)
        }
    }
}

@Composable
fun ShowItem(item: ItemData) {
    Text(
        text = item.id.toString(),
        fontSize = 34.sp,
        fontWeight = FontWeight.Bold
    )
}

更新预览以包括 MainViewModel 创建

由于MainScreen()接受MainViewModel为参数,因此您需要创建它并传递它。

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    val viewModel = MainViewModel()
    MainScreen(viewModel)
}

6. 完成

终于完成了!。RecycleView该应用程序看起来像这样,这与基于视图的 UI 方法完全相同。


如果需要,您还可以通过将MainContent()可组合函数移出到一个更简洁的单独文件来重构代码。

最后

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

最后针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

需要资料的朋友可以点击下方微信卡片即可免费领取
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值