Compose中使用paging3进行列表分页加载Room中的数据

一、前言

本文简要记录下流程,代码需要修改后才可以运行。
另外使用paging进行数据加载可以做到数据变动感知,只要数据库数据变动,页面就会自动刷新,无需额外操作。

二、相关依赖

<project>/build.gradle

buildscript {
    ext {
        compose_version = '1.5.4'
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '8.2.1' apply false
    id 'com.android.library' version '8.2.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.9.22' apply false
}

app/build.gradle

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    compileSdk 34

    defaultConfig {
        applicationId "com.design.compose"
        minSdk 21
        targetSdk 34
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary true
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_18
        targetCompatibility JavaVersion.VERSION_18
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_18
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion "1.5.8"
        kotlinCompilerVersion "1.9.22"
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }

    namespace 'com.design.compose'
}

dependencies {

    implementation 'androidx.core:core-ktx:1.12.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.material3:material3"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")

    implementation("androidx.activity:activity-compose:1.8.1")
    implementation(platform("androidx.compose:compose-bom:2023.03.00"))
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.ui:ui-graphics")
    implementation("androidx.compose.ui:ui-tooling-preview")

    implementation "androidx.paging:paging-compose:3.2.1"
//    该依赖需要target为34,可以使用androidx.paging:paging-compose进行替代
//    implementation "androidx.paging:paging-compose-android:3.3.0-alpha02"
    implementation "androidx.paging:paging-runtime-ktx:3.2.1"
    implementation "androidx.paging:paging-common-ktx:3.2.1"
    implementation "androidx.room:room-paging:2.6.1"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
    implementation 'androidx.activity:activity-compose:1.8.1'
    kapt("androidx.room:room-compiler:2.6.1")
    implementation("androidx.room:room-runtime:2.6.1")
    implementation("androidx.room:room-ktx:2.6.1")
    implementation("androidx.room:room-paging:2.4.2")
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
}

三、具体代码

@Parcelize
@Entity(tableName = "user_table")
data class UserInfo(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    var id: Long = 0L,

    @ColumnInfo(name = "name")
    var name: String = "",
): Parcelable

@Dao
interface UserDao {
    @Query("SELECT * FROM user_table")
    fun getAllPagingSource(): PagingSource<Int, UserInfo>
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(list: List<UserInfo>)
    
    @Delete
    fun deleteAll(list: List<UserInfo>)
}
@Database(entities = [UserInfo::class,], version = 1, exportSchema = true)
abstract class DatabaseManager : RoomDatabase() {
    abstract fun getUserDao(): User

    companion object {
        private const val DATABASE_NAME = "user.db"

        private val instance by lazy {
            Room.databaseBuilder(App.getInstance(), DatabaseManager::class.java, DATABASE_NAME).build()
        }

        private fun getUserDao(): AlertDao {
            return instance.getUserDao()
        }
         fun getUserAllPagingSource(): PagingSource<Int,UserInfo>{
            return getAlertAreaDao().getAllPagingSource()
        }
    }
}

ViewModel

class UserModel : ViewModel(){
    val action = MutableLiveData<Action>()
    val singlePageSize = 10 //每页显示为10条

    fun loadRoomData(): PagingSource<Int, UserInfo> {
        return DatabaseManager.getUserAllPagingSource()
    }

    fun sendAction(action: Action) {
        this.action.value = action
    }

    sealed class Action {
        object BACK : Action()
        object ADD : Action()
        data class DETAILS(val info: UserInfo) : Action()
    }
}

UI

...
@Composable
    fun Center(modifier: Modifier = Modifier, viewModel: UserModel = viewModel()) {
        val pager = remember {
            Pager(
                PagingConfig(
                    pageSize = viewModel.singlePageSize,
                    enablePlaceholders = true,
//                    maxSize = 200
                )
            ) { viewModel.loadRoomData() }
        }

        val lazyPagingItems = pager.flow.map {
            it.map { info ->
              //  info.name = "${info.name}-->后缀"
                info.copy(name = "${info.name}-->后缀")
//                Log.e("YM--->", "--->区域时间:${info.areaCreateTime}")
            }
        }.collectAsLazyPagingItems()

        LazyColumn(modifier = modifier) {
            if (lazyPagingItems.itemCount == 0) {
                item(key = "defaultItem", contentType = "defaultItem") {
                    DefaultUserItem()
                }
            }

            items(count = lazyPagingItems.itemCount) { index ->
                val item = lazyPagingItems[index]
                if (item != null) {
                    UserItem(
                        modifier = Modifier.clickable(// 去除点击效果
                            indication = null,
                            interactionSource = remember {
                                MutableInteractionSource()
                            }) {
                            viewModel.sendAction(UserModel.Action.DETAILS(item))
                        },
                        info = item
                    )
                }
            }

            if (lazyPagingItems.loadState.append == LoadState.Loading) {
                item(key = "loadItem", contentType = "loadItem") {
                    CircularProgressIndicator(
                        modifier = Modifier
                            .fillMaxWidth()
                            .wrapContentWidth(Alignment.CenterHorizontally)
                    )
                }
            }

        }
    }

...

四、注意事项

以上代码在如果没有使用下述代码的话,默认的情况下paging3是从异步中加载数据库代码的

Room.databaseBuilder(App.getInstance(), DatabaseManager::class.java, DATABASE_NAME).setQueryExecutor {
	//这里设置数据库时候不要设置到主线程中去
  }.build()

五、参考链接

  1. androidx.paging.compose
  2. Paging 库概览
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Paging3 是一个用于在 Android 应用实现分页加载数据的开源库。它是 Google 官方发布的最新版本的 Paging 库,相较于以往的版本,Paging3 在实现简单、功能强大和性能优化方面有了很大的改进。 首先,Android Paging3 提供了强大的数据加载和显示机制。它通过将数据分割成固定大小的数据块 (page),并在需要时按需加载和展示数据,实现了无限滚动加载的效果。相较于传统的 RecyclerView 分页加载Paging3 更加灵活,可以自动处理数据加载和卸载,无需手动实现判断是否到底部、加载更多等繁琐逻辑。同时,Paging3 还支持局部刷新、数据源无缝替换等操作,让数据加载和显示更加简单和高效。 其次,Paging3 在性能方面进行了优化。它使用了异步数据加载和显示机制,可以在后台线程上进行数据加载,不会阻塞主线程。同时,Paging3 采用了数据加载和缓存策略,可以将下一页的数据提前加载到内存,从而提高用户体验和应用的响应速度。并且,Paging3 还支持数据的持久化存储,可以将加载数据缓存到本地数据库或文件,避免了重复加载数据的开销。 最后,Paging3 还提供了丰富的扩展功能和灵活的定制选项。开发者可以自定义数据加载策略、数据源类型、数据显示方式等,以满足不同的业务需求。同时,Paging3 还提供了相关的辅助类和工具方法,帮助开发者更加便捷地实现数据分页加载和显示。 总结来说,Android Paging3 是一个功能强大、性能优越的分页加载库,可以帮助开发者轻松实现数据分页加载和显示,提高应用的用户体验和性能表现。无论是处理大量数据列表页,还是实现无限滚动加载的功能,Paging3 都是一个值得推荐的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值