| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.paging |
| |
| import android.view.ViewGroup |
| import androidx.recyclerview.widget.RecyclerView |
| |
| /** |
| * Adapter for displaying a RecyclerView item based on [LoadState], such as a loading spinner, or |
| * a retry error button. |
| * |
| * By default will use one shared [view type][RecyclerView.Adapter.getItemViewType] for all |
| * items. |
| * |
| * By default, both [LoadState.Loading] and [LoadState.Error] are presented as adapter items, |
| * other states are not. To configure this, override [displayLoadStateAsItem]. |
| * |
| * To present this Adapter as a header and or footer alongside your [PagingDataAdapter], see |
| * [PagingDataAdapter.withLoadStateHeaderAndFooter], or use |
| * [MergeAdapter][androidx.recyclerview.widget.MergeAdapter] directly to concatenate Adapters. |
| * |
| * @see PagingDataAdapter.withLoadStateHeaderAndFooter |
| * @see PagingDataAdapter.withLoadStateHeader |
| * @see PagingDataAdapter.withLoadStateFooter |
| * |
| * @sample androidx.paging.samples.loadStateAdapterSample |
| */ |
| abstract class LoadStateAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() { |
| /** |
| * LoadState to present in the adapter. |
| * |
| * Changing this property will immediately notify the Adapter to change the item it's |
| * presenting. |
| */ |
| var loadState: LoadState = LoadState.Idle |
| set(loadState) { |
| if (field != loadState) { |
| val oldItem = displayLoadStateAsItem(field) |
| val newItem = displayLoadStateAsItem(loadState) |
| |
| if (oldItem && !newItem) { |
| notifyItemRemoved(0) |
| } else if (newItem && !oldItem) { |
| notifyItemInserted(0) |
| } else if (oldItem && newItem) { |
| notifyItemChanged(0) |
| } |
| field = loadState |
| } |
| } |
| |
| final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH { |
| return onCreateViewHolder(parent, loadState) |
| } |
| |
| final override fun onBindViewHolder(holder: VH, position: Int) { |
| onBindViewHolder(holder, loadState) |
| } |
| |
| final override fun getItemViewType(position: Int): Int = getStateViewType(loadState) |
| |
| final override fun getItemCount(): Int = if (displayLoadStateAsItem(loadState)) 1 else 0 |
| |
| /** |
| * Called to create a ViewHolder for the given LoadState. |
| * |
| * @param parent The ViewGroup into which the new View will be added after it is bound to |
| * an adapter position. |
| * @param loadState The LoadState to be initially presented by the new ViewHolder. |
| * |
| * @see [getItemViewType] |
| * @see [displayLoadStateAsItem] |
| */ |
| abstract fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): VH |
| |
| /** |
| * Called to bind the passed LoadState to the ViewHolder. |
| * |
| * @param loadState LoadState to display. |
| * |
| * @see [getItemViewType] |
| * @see [displayLoadStateAsItem] |
| */ |
| abstract fun onBindViewHolder(holder: VH, loadState: LoadState) |
| |
| /** |
| * Override this method to use different view types per LoadState. |
| * |
| * By default, this LoadStateAdapter only uses a single view type. |
| */ |
| open fun getStateViewType(loadState: LoadState): Int = 0 |
| |
| /** |
| * Returns true if the LoadState should be displayed as a list item when active. |
| * |
| * By default, [LoadState.Loading] and [LoadState.Error] present as list items, others do not. |
| */ |
| open fun displayLoadStateAsItem(loadState: LoadState): Boolean { |
| return loadState is LoadState.Loading || loadState is LoadState.Error |
| } |
| } |