【问题标题】:how to modify list in recycler view using List Adapter?如何使用列表适配器修改回收站视图中的列表?
【发布时间】:2019-12-22 05:28:29
【问题描述】:

所以当我们从互联网上获取数据时,我试图在我的回收站视图的最后一个索引中添加加载项,比如当我们继续滚动并进行分页时的 Youtube。像这样的

现在我的回收站视图扩展了ListAdapter,不再使用RecyclerView.Adapter<RecyclerView.ViewHolder>

如果使用RecyclerView.Adapter<RecyclerView.ViewHolder>(旧方式),我将为我的适配器编写如下代码:

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);
        }
    }



}

但现在我正在尝试将 ListAdapter 用于我的回收站视图。如果我的回收站视图使用 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
            }


        }
    }


}

这是我的问题.....

在我的回收器中添加和删除加载项时,我试图模仿这两种方法(使用 RecyclerView.Adapter):

        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);
            }
        }

如果使用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)
        }
    }  

但是当我运行应用程序时我会崩溃

    java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)

在线currentList.add(Event())

如果使用ListAdapter,我似乎无法在列表中添加新项目。那么如何使用 List Adapter 修改回收站视图中的列表呢?

如果使用ListAdapter,我不知道如何访问现有列表,似乎currentList无法修改

java 或者 kotlin 都可以

【问题讨论】:

  • 你应该使用 mAdapter.submitList(newlist) 方法来更新列表。

标签: android kotlin android-recyclerview listadapter


【解决方案1】:

最终找到解决方案

override fun getItemViewType(position: Int): Int {
        if ( position == currentList.lastIndex && isLoadingAdded) {
            return LOADING
        } else {
            return ITEM
        }
    }

    fun addLoadingFooter(currentList: ArrayList<Event>) {
        isLoadingAdded = true
        currentList.add(Event())
        submitList(currentList)
        notifyItemInserted(currentList.lastIndex)


    }

    fun removeLoadingFooter(currentList: ArrayList<Event>) {
        isLoadingAdded = false

        val result = currentList[currentList.lastIndex]
        currentList.remove(result)
        submitList(currentList)
        notifyItemRemoved(currentList.size)

    }

【讨论】:

    【解决方案2】:

    聚会迟到了,但您当前的回答并未充分发挥ListAdapter 的作用。您应该改用ListAdapter.submitList,它可以完成大部分notifyItemXXXXXX 工作。

    val newList = ArrayList(listAdapter.currentList)
    newList.add(Event()) // or to remove / update / ... etc.
    listAdapter.submitList(newList)
    

    还有一件重要的事情要知道:submitList 必须使用原始对象的新对象(列表)

    val objList = mutableListOf(myObjects)
    listAdapter.submitList(objList)
    
    objList.add(newObject)
    listAdapter.submitList(objList) // will NOT do updates.
    listAdapter.submitList(ArrayList(objList)) // will do updates.
    

    在另一个Stack Overflow question中提到过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多