so I am trying to add loading item in the last index of my recycler view when fetching data from the internet, like Youtube when we keep scrolling and do pagination. something like this
now my recycler view extends ListAdapter
and not using RecyclerView.Adapter<RecyclerView.ViewHolder>
anymore
if using RecyclerView.Adapter<RecyclerView.ViewHolder>
(the old way) I will write code for my adapter like this:
public class PaginationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private static final String BASE_URL_IMG = "https://image.tmdb.org/t/p/w150";
private List<Movie> movieResults;
private Context context;
private boolean isLoadingAdded = false;
public PaginationAdapter(Context context) {
this.context = context;
movieResults = new ArrayList<>();
}
public List<Movie> getMovies() {
return movieResults;
}
public void setMovies(List<Movie> movieResults) {
this.movieResults = movieResults;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, inflater);
break;
case LOADING:
View v2 = inflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new LoadingVH(v2);
break;
}
return viewHolder;
}
@NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View v1 = inflater.inflate(R.layout.item_list, parent, false);
viewHolder = new MovieVH(v1);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Movie result = movieResults.get(position); // Movie
switch (getItemViewType(position)) {
case ITEM:
// some code here
break;
case LOADING:
// Do nothing
break;
}
}
@Override
public int getItemCount() {
return movieResults == null ? 0 : movieResults.size();
}
@Override
public int getItemViewType(int position) {
return (position == movieResults.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
public void addLoadingFooter() {
isLoadingAdded = true;
movieResults.add(new Moview());
notifyItemInserted(movieResults.size() - 1);
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = movieResults.size() - 1;
Movie result = getItem(position);
if (result != null) {
movieResults.remove(position);
notifyItemRemoved(position);
}
}
}
but now I am trying to use ListAdapter for my Recycler View. here is my code if my recycler view using ListAdapter
class GeneralEventRecyclerViewAdapter(val mContext: Context): ListAdapter<Event, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
lateinit var mOnEventKMListener : OnEventKMListener
private val ITEM = 0
private val LOADING = 1
private var isLoadingAdded = false
fun setOnItemClickListener(listener: OnEventKMListener) {
mOnEventKMListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == ITEM) {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_general_event, parent, false)
return GeneralEventViewHolder(itemView, mOnEventKMListener)
} else {
val loadingView = LayoutInflater.from(parent.context).inflate(R.layout.item_progress, parent, false)
return LoadingViewHolder(loadingView)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (getItemViewType(position) == ITEM) {
// some code here
}
}
override fun getItemViewType(position: Int): Int {
if (position == currentList.size - 1 && isLoadingAdded) {
return LOADING
} else {
return ITEM
}
}
fun addLoadingFooter() {
isLoadingAdded = true
currentList.add(Event())
notifyItemInserted(currentList.size - 1)
}
fun removeLoadingFooter() {
isLoadingAdded = false
val position: Int = currentList.size - 1
val result: Event? = getItem(position)
if (result != null) {
currentList.removeAt(position)
notifyItemRemoved(position)
}
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Event>() {
override fun areItemsTheSame(oldItem: Event, newItem: Event): Boolean {
return oldItem.eventID == newItem.eventID
}
override fun areContentsTheSame(oldItem: Event, newItem: Event): Boolean {
return oldItem == newItem
}
}
}
}
here is my problem.....
I am trying to imitate these 2 methods (using RecyclerView.Adapter) when adding and removing loading item in my recycler:
public void addLoadingFooter() {
isLoadingAdded = true;
movieResults.add(new Moview());
notifyItemInserted(movieResults.size() - 1);
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = movieResults.size() - 1;
Movie result = getItem(position);
if (result != null) {
movieResults.remove(position);
notifyItemRemoved(position);
}
}
I assume that those 2 methods above will be the same as my 2 methods below if using ListAdapter
fun addLoadingFooter() {
isLoadingAdded = true
currentList.add(Event())
notifyItemInserted(currentList.size - 1)
}
fun removeLoadingFooter() {
isLoadingAdded = false
val position: Int = currentList.size - 1
val result: Event? = getItem(position)
if (result != null) {
currentList.removeAt(position)
notifyItemRemoved(position)
}
}
but when I run the app I get crash
java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:148) at java.util.AbstractList.add(AbstractList.java:108)
on line currentList.add(Event())
it seems I can't add new item on the list if using ListAdapter
. so how to modify list in recycler view using List Adapter ?
I don't know how to access the existing list if using ListAdapter
, it seems the currentList
can't be modified
java or kotlin is ok