Android Jetpack

Paging LV2 - 2 (Network Simple Ex)

----___<<<<< 2023. 3. 8. 09:51

// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

// paging
def paging_version = "3.1.1"
implementation "androidx.paging:paging-runtime:$paging_version"

// LifecycleScope
def lifecycle_version = "2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"

 

class GithubResponse : ArrayList<GithubResponseItem>()
data class GithubResponseItem(
val allow_forking: Boolean,
val archive_url: String,
val archived: Boolean,
val assignees_url: String,
val blobs_url: String,
val branches_url: String,
val clone_url: String,
val collaborators_url: String,
val comments_url: String,
val commits_url: String,
val compare_url: String,
val contents_url: String,
val contributors_url: String,
val created_at: String,
val default_branch: String,
val deployments_url: String,
val description: String,
val disabled: Boolean,
val downloads_url: String,
val events_url: String,
val fork: Boolean,
val forks: Int,
val forks_count: Int,
val forks_url: String,
val full_name: String,
val git_commits_url: String,
val git_refs_url: String,
val git_tags_url: String,
val git_url: String,
val has_discussions: Boolean,
val has_downloads: Boolean,
val has_issues: Boolean,
val has_pages: Boolean,
val has_projects: Boolean,
val has_wiki: Boolean,
val homepage: String,
val hooks_url: String,
val html_url: String,
val id: Int,
val is_template: Boolean,
val issue_comment_url: String,
val issue_events_url: String,
val issues_url: String,
val keys_url: String,
val labels_url: String,
val language: String,
val languages_url: String,
val license: License,
val merges_url: String,
val milestones_url: String,
val mirror_url: Any,
val name: String,
val node_id: String,
val notifications_url: String,
val open_issues: Int,
val open_issues_count: Int,
val owner: Owner,
val `private`: Boolean,
val pulls_url: String,
val pushed_at: String,
val releases_url: String,
val size: Int,
val ssh_url: String,
val stargazers_count: Int,
val stargazers_url: String,
val statuses_url: String,
val subscribers_url: String,
val subscription_url: String,
val svn_url: String,
val tags_url: String,
val teams_url: String,
val topics: List<Any>,
val trees_url: String,
val updated_at: String,
val url: String,
val visibility: String,
val watchers: Int,
val watchers_count: Int,
val web_commit_signoff_required: Boolean
)
data class License(
val key: String,
val name: String,
val node_id: String,
val spdx_id: String,
val url: String
)
data class Owner(
val avatar_url: String,
val events_url: String,
val followers_url: String,
val following_url: String,
val gists_url: String,
val gravatar_id: String,
val html_url: String,
val id: Int,
val login: String,
val node_id: String,
val organizations_url: String,
val received_events_url: String,
val repos_url: String,
val site_admin: Boolean,
val starred_url: String,
val subscriptions_url: String,
val type: String,
val url: String
)
view raw data.kt hosted with ❤ by GitHub
interface GitApi {
// https://api.github.com/users/google/repos?page=1&per_page=30
// https://api.github.com/users/google/repos?page=1&per_page=30
@GET("users/google/repos")
suspend fun getData(
@Query("page") page: Int,
@Query("per_page") prePage: Int
) : Response<GithubResponse>
}
view raw GitApi.kt hosted with ❤ by GitHub
object RetrofitInstance {
val BASE_URL = "https://api.github.com/"
val client = Retrofit
.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun getInstance() : Retrofit {
return client
}
}
class MyAdapter : PagingDataAdapter<GithubResponseItem, MyAdapter.MyViewHolder>(DIFF_CALLBACK) {
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<GithubResponseItem>() {
override fun areItemsTheSame(oldItem: GithubResponseItem, newItem: GithubResponseItem): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: GithubResponseItem, newItem: GithubResponseItem): Boolean {
return oldItem == newItem
}
}
}
class MyViewHolder(view : View) : RecyclerView.ViewHolder(view) {
val textArea = view.findViewById<TextView>(R.id.textArea)
fun bind(item : GithubResponseItem) {
textArea.text = item.name
}
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val item = getItem(position)
if(item != null) {
holder.bind(item)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.rv_item, parent, false)
return MyViewHolder(view)
}
}
view raw MyAdapter.kt hosted with ❤ by GitHub
private const val STARTING_KEY = 1
class MyPagingSource(
private val githubService : GitApi
) : PagingSource<Int, GithubResponseItem>() {
init {
Log.d("MyPagingSource", "init")
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, GithubResponseItem> {
Log.d("MyPagingSource", "load")
Log.d("MyPagingSource", "params.key : " + params.key.toString())
val page = params.key ?: STARTING_KEY
Log.d("MyPagingSource", "page : " + page.toString())
Log.d("MyPagingSource", "size : " + params.loadSize.toString())
val response = githubService.getData(page, params.loadSize)
Log.d("response", response.body().toString())
Log.d("response", response.body()?.size.toString())
val data = response.body()
Log.d("data", data?.size.toString())
if(page != 1) {
Log.d("MyPagingSource", "delay")
delay(3000)
}
Log.d("loadSize", params.loadSize.toString())
Log.d("loadSize", (params.loadSize / 30).toString())
Log.d("data", data?.size.toString())
// test
if (data != null) {
var count = 1
for(i in data) {
Log.d("data", i.toString())
Log.d("count", count.toString())
Log.d("name", i.name)
count++
}
}
if(data == null) {
return LoadResult.Page(
data = listOf(),
prevKey = null,
nextKey = null
)
} else {
return LoadResult.Page(
data = data,
prevKey = null,
nextKey = page + (params.loadSize / 30)
)
}
}
override fun getRefreshKey(state: PagingState<Int, GithubResponseItem>): Int? {
return null
}
}
class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
val rv = findViewById<RecyclerView>(R.id.rv)
val myAdapter = MyAdapter()
rv.layoutManager = LinearLayoutManager(this)
rv.adapter = myAdapter
lifecycleScope.launch {
viewModel.items.collect {
Log.d("MainActivity", it.toString())
myAdapter.submitData(it)
}
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub
class MainViewModel : ViewModel() {
init {
Log.d("MainViewModel", "init")
}
private val api = RetrofitInstance.getInstance().create(GitApi::class.java)
val items : Flow<PagingData<GithubResponseItem>> = Pager(
config = PagingConfig(pageSize = 30),
pagingSourceFactory = {
MyPagingSource(api)
}
)
.flow
.cachedIn(viewModelScope)
}

 

 

 

 

 

 

 

 

- 참조

 

https://github.com/MindorksOpenSource/Paging3-Android-Tutorial/tree/master/app/src/main/java/com/mindorks/example/paging3

 

GitHub - MindorksOpenSource/Paging3-Android-Tutorial: An example project to demonstrate how to use the Paging-3 in Android.

An example project to demonstrate how to use the Paging-3 in Android. - GitHub - MindorksOpenSource/Paging3-Android-Tutorial: An example project to demonstrate how to use the Paging-3 in Android.

github.com

 

'Android Jetpack' 카테고리의 다른 글

Paging LV3 - 2 (Loading)  (0) 2023.03.20
Paging LV3 - 1 (Simple Ex)  (0) 2023.03.18
Paging LV2 - 1 (Json To Kotlin Class)  (0) 2023.03.06
Paging LV1 - 3 (Simple Ex)  (0) 2023.03.05
Paging LV1 - 2 (Paging 소스 살펴보기)  (0) 2023.02.25