android - রিসাইক্লারভিউ অ্যাডাপ্টার ডেটা কীভাবে আপডেট করবেন?




android-recyclerview (8)

RecyclerView অ্যাডাপ্টার আপডেট করার ক্ষেত্রে সমস্যাটি কী তা বোঝার চেষ্টা করছেন।

আমি পণ্যের নতুন তালিকা পাওয়ার পরে, আমি চেষ্টা করেছিলাম:

  1. recyclerView তৈরি করা হয়েছে সেই খণ্ড থেকে ArrayList আপডেট করুন, অ্যাডাপ্টারে নতুন ডেটা সেট করুন, তারপরে অ্যাডাপ্টারকে কল করুন adapter.notifyDataSetChanged() ; এটা কাজ করে না.

  2. অন্যরা যেমন করেছে তেমন একটি নতুন অ্যাডাপ্টার তৈরি করুন এবং এটি তাদের জন্য কাজ করেছে, তবে আমার জন্য কোনও পরিবর্তন হয়নি: recyclerView.setAdapter(new RecyclerViewAdapter(newArrayList)) অ্যাডাপ্টার recyclerView.setAdapter(new RecyclerViewAdapter(newArrayList))

  3. Adapter একটি পদ্ধতি তৈরি করুন যা ডেটা আপডেট করে:

    public void updateData(ArrayList<ViewModel> viewModels) {
       items.clear();
       items.addAll(viewModels);
       notifyDataSetChanged();
    }

    তারপরে আমি যখনই ডেটা তালিকা আপডেট করতে চাই তখন এই পদ্ধতিটি কল করি; এটা কাজ করে না.

  4. আমি যে কোনও উপায়ে পুনর্ব্যবহারযোগ্য ভিউ সংশোধন করতে পারি কিনা তা যাচাই করতে এবং আমি কমপক্ষে একটি আইটেম সরানোর চেষ্টা করেছি:

     public void removeItem(int position) {
        items.remove(position);
        notifyItemRemoved(position);
    }

    সবকিছু যেমন ছিল তেমন রয়ে গেছে।

আমার অ্যাডাপ্টারটি এখানে:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements View.OnClickListener {

    private ArrayList<ViewModel> items;
    private OnItemClickListener onItemClickListener;

    public RecyclerViewAdapter(ArrayList<ViewModel> items) {
        this.items = items;
    }


    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false);
        v.setOnClickListener(this);
        return new ViewHolder(v);
    }

    public void updateData(ArrayList<ViewModel> viewModels) {
        items.clear();
        items.addAll(viewModels);
        notifyDataSetChanged();
    }
    public void addItem(int position, ViewModel viewModel) {
        items.add(position, viewModel);
        notifyItemInserted(position);
    }

    public void removeItem(int position) {
        items.remove(position);
        notifyItemRemoved(position);
    }



    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        ViewModel item = items.get(position);
        holder.title.setText(item.getTitle());
        Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image);
        holder.price.setText(item.getPrice());
        holder.credit.setText(item.getCredit());
        holder.description.setText(item.getDescription());

        holder.itemView.setTag(item);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    @Override
    public void onClick(final View v) {
        // Give some time to the ripple to finish the effect
        if (onItemClickListener != null) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    onItemClickListener.onItemClick(v, (ViewModel) v.getTag());
                }
            }, 0);
        }
    }

    protected static class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView image;
        public TextView price, credit, title, description;

        public ViewHolder(View itemView) {
            super(itemView);
            image = (ImageView) itemView.findViewById(R.id.image);
            price = (TextView) itemView.findViewById(R.id.price);
            credit = (TextView) itemView.findViewById(R.id.credit);
            title = (TextView) itemView.findViewById(R.id.title);
            description = (TextView) itemView.findViewById(R.id.description);
        }
    }

    public interface OnItemClickListener {

        void onItemClick(View view, ViewModel viewModel);

    }
}

এবং আমি নীচে RecyclerView শুরু করি:

recyclerView = (RecyclerView) view.findViewById(R.id.recycler);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 5));
adapter = new RecyclerViewAdapter(items);
adapter.setOnItemClickListener(this);
recyclerView.setAdapter(adapter);

সুতরাং, নতুন প্রাপ্ত আইটেমগুলি প্রদর্শনের জন্য আমি কীভাবে আসলে অ্যাডাপ্টার ডেটা আপডেট করব?

আপডেট: সমস্যাটি হ'ল গ্রিডভিউয়ের লেআউটটি নীচে দেখানো হয়েছিল:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:tag="catalog_fragment"
    android:layout_height="match_parent">

    <FrameLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"/>

        <ImageButton
            android:id="@+id/fab"
            android:layout_gravity="top|end"
            style="@style/FabStyle"/>

    </FrameLayout>
</LinearLayout>

তারপরে আমি সবেমাত্র LinearLayout সরিয়ে LinearLayout প্যারেন্ট লেআউট হিসাবে তৈরি করেছি।


অন্য বিকল্প হ'ল DiffUtil ব্যবহার করা। এটি নতুন তালিকার সাথে মূল তালিকার তুলনা করবে এবং কোনও পরিবর্তন হলে নতুন তালিকাটিকে আপডেট হিসাবে ব্যবহার করবে।

মূলত, আমরা পুরানো ডেটা বনাম নতুন ডেটার তুলনা করতে ডিফুটিল ব্যবহার করতে পারি এবং এটি আপনার পক্ষে বিজ্ঞপ্তি আইটেমরঞ্জারভেস্ট করুন এবং বিজ্ঞপ্তি আইটেমরঞ্জ চ্যাঞ্জড এবং নোটিফাই আইটেমরেঞ্জইন্ট করা যাক।

নোটিফাইড ডেটাসেট পরিবর্তিত পরিবর্তে ডিফুটিল ব্যবহারের একটি দ্রুত উদাহরণ:

DiffResult diffResult = DiffUtil
                .calculateDiff(new MyDiffUtilCB(getItems(), items));

//any clear up on memory here and then
diffResult.dispatchUpdatesTo(this);

//and then, if necessary
items.clear()
items.addAll(newItems)

আমি ক্যালকুলেট ডিফটি একটি বড় তালিকা তৈরির ক্ষেত্রে মূল থ্রেডের কাজ করি।


আমি একই সমস্যাটিকে অন্যভাবে সমাধান করেছি। ব্যাকগ্রাউন্ড থ্রেড থেকে আমি অপেক্ষা করছি এমন ডেটা আমার কাছে নেই সুতরাং একটি এমিটি তালিকা দিয়ে শুরু করুন।

        mAdapter = new ModelAdapter(getContext(),new ArrayList<Model>());
   // then when i get data

        mAdapter.update(response.getModelList());
  //  and update is in my adapter

        public void update(ArrayList<Model> modelList){
            adapterModelList.clear(); 
            for (Product model: modelList) {
                adapterModelList.add(model); 
            }
           mAdapter.notifyDataSetChanged();
        }

এটাই.


আমি দীর্ঘ সময় পরে উত্তর পেয়েছি

  SELECTEDROW.add(dt);
                notifyItemInserted(position);
                SELECTEDROW.remove(position);
                notifyItemRemoved(position);

আমি রিসাইক্লারভিউয়ের সাথে কাজ করছি এবং অপসারণ এবং আপডেট উভয়ই ভাল কাজ করে।

1) সরান: একটি পুনর্ব্যবহারযোগ্য ভিউ থেকে একটি আইটেম অপসারণ 4 টি পদক্ষেপ আছে

list.remove(position);
recycler.removeViewAt(position);
mAdapter.notifyItemRemoved(position);                 
mAdapter.notifyItemRangeChanged(position, list.size());

কোডগুলির এই লাইনটি আমার পক্ষে কাজ করে।

2) ডেটা আপডেট করুন: আমার একমাত্র কাজ করতে হবে

mAdapter.notifyDataSetChanged();

আপনাকে এ্যাকটিভিটি / ফ্রেগমেন্ট কোডে রিসাইক্লারভিউ অ্যাডাপ্টার কোডে নয় এগুলি করতে হয়েছিল।


একটি বেসিক RecyclerView ব্যবহার শুরু করার জন্য এই পদ্ধতিগুলি দক্ষ এবং ভাল।

private List<YourItem> items;

public void setItems(List<YourItem> newItems)
{
    clearItems();
    addItems(newItems);
}

public void addItem(YourItem item, int position)
{
    if (position > items.size()) return;

    items.add(item);
    notifyItemInserted(position);
}

public void addMoreItems(List<YourItem> newItems)
{
    int position = items.size() + 1;
    newItems.addAll(newItems);
    notifyItemChanged(position, newItems);
}

public void addItems(List<YourItem> newItems)
{
    items.addAll(newItems);
    notifyDataSetChanged();
}

public void clearItems()
{
    items.clear();
    notifyDataSetChanged();
}

public void addLoader()
{
    items.add(null);
    notifyItemInserted(items.size() - 1);
}

public void removeLoader()
{
    items.remove(items.size() - 1);
    notifyItemRemoved(items.size());
}

public void removeItem(int position)
{
    if (position >= items.size()) return;

    items.remove(position);
    notifyItemRemoved(position);
}

public void swapItems(int positionA, int positionB)
{
    if (positionA > items.size()) return;
    if (positionB > items.size()) return;

    YourItem firstItem = items.get(positionA);

    videoList.set(positionA, items.get(positionB));
    videoList.set(positionB, firstItem);

    notifyDataSetChanged();
}

আপনি এগুলি অ্যাডাপ্টারের ক্লাসের ভিতরে বা আপনার খণ্ড বা ক্রিয়াকলাপের মধ্যে প্রয়োগ করতে পারেন তবে সেক্ষেত্রে আপনাকে বিজ্ঞপ্তি পদ্ধতিগুলিতে কল করতে অ্যাডাপ্টারটি ইনস্ট্যান্ট করতে হবে। আমার ক্ষেত্রে আমি সাধারণত এটি অ্যাডাপ্টারে প্রয়োগ করি।


এটি করার জন্য আপনার কাছে দুটি বিকল্প রয়েছে: অ্যাডাপ্টার থেকে ইউআই রিফ্রেশ করুন:

mAdapter.notifyDataSetChanged();

অথবা রিসাইক্লার ভিউ থেকে এটিকে রিফ্রেশ করুন:

recyclerView.invalidate();

এটিই আমার পক্ষে কাজ করেছে:

recyclerView.setAdapter(new RecyclerViewAdapter(newList));
recyclerView.invalidate();

একটি নতুন অ্যাডাপ্টার তৈরির পরে আপডেট হওয়া তালিকা রয়েছে (আমার ক্ষেত্রে এটি একটি অ্যারেলিস্টে রূপান্তরিত একটি ডেটাবেস ছিল) এবং এটি অ্যাডাপ্টারের হিসাবে সেট করার পরে, আমি recyclerView.invalidate() চেষ্টা করেছি recyclerView.invalidate() এবং এটি কার্যকর recyclerView.invalidate()


তালিকাভিউ, গ্রিডভিউ এবং পুনর্ব্যবহারযোগ্য দর্শন আপডেট করুন

mAdapter.notifyDataSetChanged();

অথবা

mAdapter.notifyItemRangeChanged(0, itemList.size());




android-recyclerview