কীভাবে পুনর্ব্যবহারযোগ্য ভিউতে নির্দিষ্ট আইটেম আপডেট / রিফ্রেশ করবেন


112

আমি নির্দিষ্ট আইটেমটি রিফ্রেশ করার চেষ্টা করছি RecyclerView

গল্প: ব্যবহারকারী যখনই আইটেমটিতে ক্লিক করেন, এটি প্রদর্শিত হয় AlertDialog। ব্যবহারকারী ওকে বোতামে ক্লিক করে কিছু পাঠ্য টাইপ করতে পারেন। আমি এই আইটেমটিতে এই পাঠ্যটি প্রদর্শন করতে এবং অদৃশ্য দেখাতে চাই ImageView- এক্সএমএল এবং অ্যাডাপ্টারে ঘোষিত ViewHolder-

AlertDialogআইটেমটি আপডেট করতে আমি এই ফাংশনটি ইতিবাচক বোতামটিতে ব্যবহার করেছি :

private void updateListItem(int position) {
  View view = layoutManager.findViewByPosition(position);
  ImageView medicineSelected = (ImageView) view.findViewById(R.id.medicine_selected);
  medicineSelected.setVisibility(View.VISIBLE);
  TextView orderQuantity = (TextView) view.findViewById(R.id.order_quantity);
  orderQuantity.setVisibility(View.VISIBLE);
  orderQuantity.setText(quantity + " packet added!");

  medicinesArrayAdapter.notifyItemChanged(position);
}

তবে এই কোডটি কেবল পাসকৃত অবস্থানে আইটেম ভিউকেই পরিবর্তন করে না, পাশাপাশি কিছু অন্যান্য আইটেম ভিউও পরিবর্তন করে!

আমি কীভাবে নির্দিষ্ট আইটেম ভিউতে এটি ক্লিক করে সঠিকভাবে পরিবর্তন করব?

উত্তর:


98

আপনি notifyItemChanged(int position)পদ্ধতিটি রিসাইক্লারভিউ.এডাপ্টার ক্লাস থেকে ব্যবহার করতে পারেন । ডকুমেন্টেশন থেকে:

কোনও নিবন্ধিত পর্যবেক্ষককে অবহিত করুন যে অবস্থানের আইটেমটি পরিবর্তিত হয়েছে। নোটিফাইম আইটেম চেঞ্জড (অবস্থান, নাল) কল করার সমতুল্য;।

এটি কোনও আইটেম পরিবর্তন ইভেন্ট, কাঠামোগত পরিবর্তন ইভেন্ট নয়। এটি সূচিত করে যে অবস্থানের ডেটাগুলির কোনও প্রতিচ্ছবি পুরানো এবং আপডেট হওয়া উচিত। অবস্থানের আইটেম একই পরিচয় ধরে রাখে।

আপনার যেমন ইতিমধ্যে অবস্থান রয়েছে তাই এটি আপনার পক্ষে কাজ করা উচিত।


9
আমি ইতিমধ্যে এটি ব্যবহার করেছি তবে যদি আমি 0 অবস্থান আপডেট করতে চাই তবে এটি 0, 9, 19, অবস্থান আপডেট করছে ...
এলিজেন্ডি

দুঃখিত, আপনার মন্তব্য বুঝতে পারে না। এটি কোন পজিশনে আপডেট হচ্ছে? 0, 9 বা 0 এবং 9 এর মধ্যে ব্যাপ্তি?
এডসন মেনেগাটি

না, এটি সীমাবদ্ধ নয়, যতবার আমি আইটেম আপডেট করি, এটি অযাচিত আইটেমগুলিকেও সতেজ করে
তোলে

@ শিখুন আপনি ভিউহোল্ডারটি 0 অবস্থানে আপডেট করলে এটি আপডেট থাকে। রিসাইক্লারভিউ সেই ভিউহোল্ডারটিকে পুনর্ব্যবহার করবে এবং এটি 9 নম্বরের জন্য ব্যবহার করবে, সুতরাং আপনি সেই পরিবর্তনগুলি দেখতে পাচ্ছেন। আমি পরিবর্তে অনবিন্দ ভিহোল্ডার () এ এই পাঠ্যটি সেট করার পরামর্শ দিচ্ছি - সেই উপায়ে, যখনই ভিউহোল্ডার পুনর্ব্যবহার করা হয় আপনি তার অবস্থানটি পরীক্ষা করতে পারেন এবং পাঠ্যটি সেট করতে পারেন বা চিত্রকে দৃশ্যমান বা যা সঠিকভাবে তৈরি করতে পারেন।
ক্লায়াভাচ

@ ক্লিয়াভাচ এখনও একই পরিবর্তন করে onBindViewHolder()
যাচ্ছেন

39

একক আইটেম আপডেট করুন

  1. ডেটা আইটেম আপডেট করুন
  2. এর সাথে পরিবর্তনের অ্যাডাপ্টারকে অবহিত করুন notifyItemChanged(updateIndex)

উদাহরণ

"ভেড়া" আইটেমটি পরিবর্তন করুন যাতে এটিতে "আমি মেষগুলি পছন্দ করি।"

একক আইটেম আপডেট করুন

String newValue = "I like sheep.";
int updateIndex = 3;
data.set(updateIndex, newValue);
adapter.notifyItemChanged(updateIndex);

আরও উদাহরণ সহ আমার পূর্ণ উত্তর এখানে


আমি কীভাবে কীভাবে আপডেট করতে চাই যদি উপরে ডেটা পরিবর্তন করা যায়
ছয়ে

@ ছাই, আপনি ডেটা আপডেট করার পরে আপনি এটি সূচক 0 এ স্থানান্তর করতে পারেন এই আইটেমের
সুরগাচ

11

আপনার মডেল ডেটা তালিকায় পরিবর্তিত পাঠ্য যুক্ত করুন

mdata.get(position).setSuborderStatusId("5");
mdata.get(position).setSuborderStatus("cancelled");
notifyItemChanged(position);

10

আমি মনে করি এটি মোকাবেলা করার জন্য আমার একটি ধারণা রয়েছে। আপডেট করা হ'ল মুছে ফেলা এবং সঠিক অবস্থানে প্রতিস্থাপনের সমান। সুতরাং আমি প্রথমে নীচে কোড ব্যবহার করে সেই অবস্থান থেকে আইটেমটি সরিয়েছি:

public void removeItem(int position){
    mData.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, mData.size());
}

এবং তারপরে আমি নীচে প্রদর্শিত হিসাবে সেই নির্দিষ্ট অবস্থানে আইটেমটি যুক্ত করব:

public void addItem(int position, Landscape landscape){
    mData.add(position, landscape);
    notifyItemInserted(position);
    notifyItemRangeChanged(position, mData.size());
}

আমি এখন এটি বাস্তবায়নের চেষ্টা করছি। আমি যখন যাব তখন আপনাকে একটি প্রতিক্রিয়া জানাব!


2
আপনি একটি অতিরিক্ত পদক্ষেপ করছেন। কেবলমাত্র অবস্থানটিতে উপাদানটি প্রতিস্থাপন করুন এবং আইটেমটি পরিবর্তন করুন আইটেমচেনজড (অবস্থান);
toshkinl

@ টসকিনেল আপনি কীভাবে জানতে পারবেন যখন জেএসএনওজেক্ট থেকে ডেটা আসছে? কোন পদ নেই?
olajide

7

আমি যে আইটেমটি সংশোধন করতে হবে তার অবস্থান এবং তারপরে অ্যাডাপ্টারে কল করে এই সমস্যাটি সমাধান করেছি

public void refreshBlockOverlay(int position) {
    notifyItemChanged(position);
}

, এটি এই নির্দিষ্ট অবস্থানে এই নির্দিষ্ট আইটেমটির জন্য বাইন্ড ভিউহোল্ডারকে (ভিউহোল্ডারধারক, ইন পজিশন) কল করবে।


2

নীচের সমাধানটি আমার জন্য কাজ করেছে:

একটি পুনর্ব্যবহারযোগ্য আইটেমটিতে, ব্যবহারকারী একটি বোতাম ক্লিক করবে তবে টেক্সটভিউয়ের মতো অন্য ভিউটি সরাসরি অ্যাডাপ্টারকে না জানিয়ে আপডেট হবে:

আমি notifyDataSetChanged () পদ্ধতিটি ব্যবহার না করেই এর জন্য একটি ভাল সমাধান পেয়েছি, এই পদ্ধতিটি পুনর্ব্যবহারযোগ্য ভিউয়ের সমস্ত ডেটা পুনরায় লোড করে তাই যদি আপনার আইটেমের ভিতরে চিত্র বা ভিডিও থাকে তবে তারা পুনরায় লোড করবে এবং ব্যবহারকারীর অভিজ্ঞতা ভাল হবে না:

আইকনের মতো ইমেজভিউতে ক্লিক করার উদাহরণ এখানে রয়েছে এবং +1 যোগ করার পরে গণনা আপডেটের মতো দেখানোর জন্য কেবল একটি একক টেক্সটভিউ (একই আইটেমের একইভাবে আরও ভিউ আপডেট করার সম্ভাবনা) আপডেট করুন:

// View holder class inside adapter class
public class MyViewHolder extends RecyclerView.ViewHolder{

    ImageView imageViewLike;

    public MyViewHolder(View itemView) {
         super(itemView);

        imageViewLike = itemView.findViewById(R.id.imageViewLike);
        imageViewLike.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = getAdapterPosition(); // Get clicked item position
                TextView tv = v.getRootView().findViewById(R.id.textViewLikeCount); // Find textView of recyclerView item
                resultList.get(pos).setLike(resultList.get(pos).getLike() + 1); // Need to change data list to show updated data again after scrolling
                tv.setText(String.valueOf(resultList.get(pos).getLike())); // Set data to TextView from updated list
            }
        });
    }

1

একটি উপায় যা ব্যক্তিগতভাবে আমার জন্য কাজ করেছে, তার আইটেমগুলির পরিবর্তনগুলি মোকাবেলায় পুনর্ব্যবহারযোগ্য অ্যাডাপ্টার পদ্ধতি ব্যবহার করছে is

এটি এর অনুরূপ উপায়ে চলে যেতে পারে, আপনার কাস্টম পুনর্ব্যবহারকারীটির দৃষ্টিতে কিছুটা এমন পদ্ধতি তৈরি করুন:

public void modifyItem(final int position, final Model model) {
    mainModel.set(position, model);
    notifyItemChanged(position);
}

0

আপনার অ্যাডাপ্টার শ্রেণিতে, অনবিন্দ ভিউহোল্ডার পদ্ধতিতে, ভিউহোল্ডারকে নীচের কোড হিসাবে সেটআইসাইক্রাইক্লেবল (মিথ্যা) এ সেট করুন।

@Override
public void onBindViewHolder(RecyclerViewAdapter.ViewHolder p1, int p2)
{
    // TODO: Implement this method
    p1.setIsRecyclable(false);

    // Then your other codes
}

0

আপনি কেবল সংরক্ষণ ক্লিকের উপর সতর্কতা ডায়ালগ বক্সে নিম্নলিখিত কোড যুক্ত করতে হবে

          recyclerData.add(position, updateText.getText().toString());
          recyclerAdapter.notifyItemChanged(position);

0

সমস্যাটি এমন RecyclerView.Adatperকোনও পদ্ধতি সরবরাহ করে না যা উপাদানটির সূচক ফেরত দেয়

public abstract static class Adapter<VH extends ViewHolder> {
  /**
   * returns index of the given element in adapter, return -1 if not exist
   */
  public int indexOf(Object elem);
}

আমার কাজটি হ'ল (উপাদান, অবস্থান) এর জন্য মানচিত্রের উদাহরণ তৈরি করা

public class FriendAdapter extends RecyclerView.Adapter<MyViewHolder> {
  private Map<Friend, Integer> posMap ;
  private List<Friend> friends;

  public FriendAdapter(List<Friend> friends ) {
    this.friends = new ArrayList<>(friends);
    this.posMap = new HashMap<>();
    for(int i = 0; i < this.friends.size(); i++) {
      posMap.put(this.friends.get(i), i);
    }
  }

  public int indexOf(Friend friend) {
    Integer position = this.posMap.get(elem);
    return position == null ? -1 : position;
  }
  // skip other methods in class Adapter
}
  • উপাদান ধরণের (এখানে শ্রেণি Friend) প্রয়োগ করা উচিত hashCode()এবং equals()কারণ এটি হ্যাশম্যাপে মূল।

যখন একটি উপাদান পরিবর্তন,

  void someMethod() {
    Friend friend = ...;
    friend.setPhoneNumber('xxxxx');

    int position = friendAdapter.indexOf(friend);
    friendAdapter.notifyItemChanged(position);

  }

কোনও সহায়ক পদ্ধতির সংজ্ঞা দেওয়া ভাল is

public class FriendAdapter extends extends RecyclerView.Adapter<MyViewHolder> {

  public void friendUpdated(Friend friend) {
    int position = this.indexOf(friend);
    this.notifyItemChanged(position);
  }
}

মানচিত্রের উদাহরণ ( Map<Friend, Integer> posMap) অবশ্যই প্রয়োজন হয় না। যদি মানচিত্রটি ব্যবহার না করা হয় তবে তালিকার জুড়ে লুপিং কোনও উপাদানটির অবস্থান খুঁজে পেতে পারে।


-1

এটিও আমার শেষ সমস্যা। এখানে আমার সমাধানটি আমি আমার রিসাইক্লারভিউয়ের জন্য ডেটা মডেল এবং অ্যাডাপ্টার ব্যবহার করি

 /*Firstly, register your new data to your model*/
 DataModel detail = new DataModel(id, name, sat, image);

 /*after that, use set to replace old value with the new one*/
 int index = 4;
 mData.set(index, detail);

 /*finally, refresh your adapter*/
 if(adapter!=null)
    adapter.notifyItemChanged(index);

-1

যদি আপনি একটি অবজেক্ট তৈরি করে সেটি আপনার অ্যাডাপ্টারে যে তালিকার সাথে যুক্ত করেন, আপনি যখন অ্যাডাপ্টারে আপনার তালিকার একটি উপাদান পরিবর্তন করেন তখন আপনার সমস্ত আইটেমের সমস্ত শব্দ অন্য শব্দগুলিতে খুব বদলে যায় এটির উল্লেখগুলি এবং আপনার তালিকাটি এতে করে না যে একক বস্তুর পৃথক অনুলিপি রাখা।


-5

আপনার পুনর্ব্যবহারযোগ্য অ্যাডাপ্টারে আপনার অ্যারেলিস্ট এবং অ্যারেলিস্টে addItemsToList(items)তালিকা আইটেম যুক্ত করার জন্য একটি পদ্ধতি থাকা উচিত । তারপরে আপনি কল দিয়ে তালিকার আইটেমগুলিকে adapter.addItemsToList(items)গতিশীল যুক্ত করতে পারেন । আপনার সমস্ত তালিকা আইটেম অ্যারেলিস্টে যুক্ত হওয়ার পরে আপনি adapter.notifyDataSetChanged()নিজের তালিকা প্রদর্শন করতে কল করতে পারেন ।

আপনি notifyDataSetChangedরিসাইক্লার ভিউয়ের জন্য অ্যাডাপ্টারে ব্যবহার করতে পারেন


হ্যাঁ আমার কাছে ডেটার জন্য অ্যারেলিস্ট আছে, এটি কোনও সমস্যা ছাড়াই কাজ করে, এই তালিকার নির্দিষ্ট-বিদ্যমান-আইটেমটি আপডেট করার ক্ষেত্রে আমার সমস্যা
এলিজেন্ডি

আপনার আইটেমের অবস্থানটি আপডেট হওয়া উচিত তবে তারপরে আপনাকে কেবল নতুন আইটেমটি mList.add (পজিশন) .setName ("নতুন নাম") এর মতো তার সম্পর্কিত অবস্থানে রাখতে হবে; তারপরে mAdapter.notifyDataSetChanged () ব্যবহার করুন;
নূরউদ্দিন লাখানী

4
এই উত্তরটি একটি একক আইটেম আপডেট করার ইচ্ছা উপেক্ষা করে। NotifDataSetChanged () কলিং কেবল তখনই করা উচিত যখন সম্পূর্ণ ডেটা সেট পরিবর্তন হয়।
মার্ক ম্যাককেলল্যান্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.