রিসাইক্লারভিউতে নির্বাচিত আইটেমটি কীভাবে সঠিকভাবে হাইলাইট করবেন?


146

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

এখানে আমার অনক্লিক ফাংশনটি রয়েছে:

@Override
public void onClick(View view) {

    if(selectedListItem!=null){
        Log.d(TAG, "selectedListItem " + getPosition() + " " + item);
        selectedListItem.setBackgroundColor(Color.RED);
    }
    Log.d(TAG, "onClick " + getPosition() + " " + item);
    viewHolderListener.onIndexChanged(getPosition());
    selectedPosition = getPosition();
    view.setBackgroundColor(Color.CYAN); 
    selectedListItem = view;
}

এখানে onBindViewHolder:

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {   
    viewHolder.setItem(fruitsData[position]);
    if(selectedPosition == position)
        viewHolder.itemView.setBackgroundColor(Color.CYAN);    
    else
        viewHolder.itemView.setBackgroundColor(Color.RED);

}

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

এই সাহায্য করতে পারে আপনি amolsawant88.blogspot.in/2015/08/…
আমল সাওয়ান্ত 96 কুলি

পুনর্ব্যবহারযোগ্য আইটেম নির্বাচন: stackoverflow.com/a/38501676/2648035
অলোক ওমকার

আপনার যদি ইতিমধ্যে কাজ করা কিছু না থাকে তবে এটি অনুসরণ করা শক্ত , যা উত্তর ট্যাগ বরাবর খারাপ এবং কোথায় কী চলে সে সম্পর্কে খুব বেশি নির্দিষ্ট করে না।
ফার্স্টওন

উত্তর:


61

আমি একটি পুনর্ব্যবহারযোগ্য ভিউ দিয়ে আইটেম নির্বাচন স্বয়ংক্রিয়ভাবে পরিচালনা করতে একটি বেস অ্যাডাপ্টার ক্লাস লিখেছি। কেবলমাত্র এটি থেকে আপনার অ্যাডাপ্টারটি বের করুন এবং রাজ্য_নির্বাচিত সাথে আঁকতে সক্ষম রাজ্য তালিকা ব্যবহার করুন, যেমন আপনি একটি তালিকার দৃশ্যের সাথে করেন।

এটি সম্পর্কে আমার এখানে একটি ব্লগ পোস্ট রয়েছে তবে কোডটি এখানে রয়েছে:

public abstract class TrackSelectionAdapter<VH extends TrackSelectionAdapter.ViewHolder> extends RecyclerView.Adapter<VH> {
    // Start with first item selected
    private int focusedItem = 0;

    @Override
    public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        // Handle key up and key down and attempt to move selection
        recyclerView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();

                // Return false if scrolled to the bounds and allow focus to move off the list
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
                        return tryMoveSelection(lm, 1);
                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
                        return tryMoveSelection(lm, -1);
                    }
                }

                return false;
            }
        });
    }

    private boolean tryMoveSelection(RecyclerView.LayoutManager lm, int direction) {
        int tryFocusItem = focusedItem + direction;

        // If still within valid bounds, move the selection, notify to redraw, and scroll
        if (tryFocusItem >= 0 && tryFocusItem < getItemCount()) {
            notifyItemChanged(focusedItem);
            focusedItem = tryFocusItem;
            notifyItemChanged(focusedItem);
            lm.scrollToPosition(focusedItem);
            return true;
        }

        return false;
    }

    @Override
    public void onBindViewHolder(VH viewHolder, int i) {
        // Set selected state; use a state list drawable to style the view
        viewHolder.itemView.setSelected(focusedItem == i);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);

            // Handle item click and set the selection
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // Redraw the old selection and the new
                    notifyItemChanged(focusedItem);
                    focusedItem = getLayoutPosition();
                    notifyItemChanged(focusedItem);
                }
            });
        }
    }
} 

mRecyclerViewকোথাও ঘোষণা করা হয় না। আমরা কি কেবল এটি কনস্ট্রাক্টরের প্যারামিটার হিসাবে পাস করে একটি ফিল্ডে সঞ্চয় করব?
পেড্রো

1
এর জন্যে দুঃখিত. আমার অ্যাডাপ্টারটি আমার খণ্ডের একটি অভ্যন্তর শ্রেণি তাই এটির পুনর্ব্যবহারযোগ্য দৃশ্যের ক্ষেত্রে অ্যাক্সেস রয়েছে। অন্যথায় হ্যাঁ আপনি এটি প্যারামিটার হিসাবে পাস করতে পারেন। বা আরও ভাল, হ্যান্ডেল onRecyclerViewAttachedএবং সেখানে সদস্য ভেরিয়েবল এ এটি সংরক্ষণ করুন।
গ্রেগ এনিস

1
উত্তম উত্তর, তবে কেন getChildPosition () ব্যবহার করবেন? আর একটি পদ্ধতি বিকাশকারী রয়েছে
and অ্যান্ড্রয়েড.com

আমি দুঃখিত, আপনি কি বলতে চান যে আমার কেবল আপনার TrackSelectionAdapterক্লাসটি আমদানি করা উচিত এবং এটি আমার তালিকায় ব্যবহার করা উচিত? আমি কীভাবে "আপনার ক্লাস থেকে আমার অ্যাডাপ্টারটি সংগ্রহ করব"? আপনি আমার প্রশ্নের উত্তর দিতে পারেন? : আমি এত গভীরভাবে আটকে আছি stackoverflow.com/questions/29695811/...
ক্রিস্টিয়ানো Colacillo

2
আমি এটি চেষ্টা করে দেখেছি নোটিফাইম আইটেম চেঞ্জড () -এর দুটি ব্যাক-টু-ব্যাক কল ধীর হার্ডওয়্যারে মসৃণ স্ক্রোলিংয়ের যেকোন চিহ্নকে হত্যা করেছে। ললিপপ আপডেটের আগে ফায়ার টিভিতে বিশেষত খারাপ ছিল
রেডশার্ট

157

এটি এটি করার অনেক সহজ উপায়।

private int selectedPos = RecyclerView.NO_POSITION;পুনর্ব্যবহারযোগ্য অ্যাডাপ্টার শ্রেণিতে একটি করুন এবং অনব্যান্ডভিউহোল্ডার পদ্ধতির অধীনে চেষ্টা করুন:

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {   
    viewHolder.itemView.setSelected(selectedPos == position);

}

এবং আপনার অনক্লিক ইভেন্টে পরিবর্তন করুন:

@Override
public void onClick(View view) {
     notifyItemChanged(selectedPos);
     selectedPos = getLayoutPosition();
     notifyItemChanged(selectedPos); 
}

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

দ্রষ্টব্য: আপনার লেআউটে একটি ব্যাকগ্রাউন্ড রঙ অবশ্যই নিশ্চিত করেছেন যেমন কোলাবগের মতো একটি নির্বাচক ব্যবহার করেছেন:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@color/pressed_color" android:state_pressed="true"/>
  <item android:drawable="@color/selected_color" android:state_selected="true"/>
  <item android:drawable="@color/focused_color" android:state_focused="true"/>
</selector>

অন্যথায় সেটসলেক্টেড (..) কিছুই করবে না, এই সমাধানটিকে অকেজো করে।


12
আমি আমার সারি ভিউতে ব্যাকগ্রাউন্ড ড্রয়যোগ্য / নির্বাচক সেট করে এই সমাধানটি ব্যবহার করেছি: <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/pressed_color" android:state_pressed="true"/> <item android:drawable="@color/selected_color" android:state_selected="true"/> <item android:drawable="@color/focused_color" android:state_focused="true"/> </selector>
কোলাব্যাগ

1
@ZIronManBox: দুর্দান্ত, সহজ উপায়! অনিক্লিক পদ্ধতিতে "নির্বাচিতপোজিশন" কি "নির্বাচিতপস" হিসাবে বিবেচিত?
এজেডাব্লু

3
getLayoutPosition () আমার দ্বারা উপলব্ধ নেই।
ka3ak

3
শুধু -1 ব্যবহার করবেন না, রিসাইক্লারভিউ ব্যবহার করুন N (যা -1)
মার্টিন মার্কনকিনি

8
@ ka3ak: getLayoutPosition হল ভিউহোল্ডার শ্রেণীর পদ্ধতি যাঁর বস্তুটি বাইন্ড ভিউ পদ্ধতিতে প্রথম প্যারামিটার হিসাবে পাস করা হয়। সুতরাং এটি দ্বারা অ্যাক্সেস করা যেতে পারেvieHolder.getLayoutPosition
তুষার কাঠুরিয়া

129

আপডেট [26 / জুলাই / 2017]:

হিসাবে পবন স্থির অবস্থানের ব্যবহার সম্পর্কে না যে আইডিই সতর্কবার্তা সম্পর্কে মন্তব্যে উল্লেখ, আমি শুধু নীচের হিসাবে আমার কোড সংশোধন করেছেন। ক্লিক শ্রোত্রে সরানো হয়েছে ViewHolder, এবং সেখানে আমি getAdapterPosition()পদ্ধতি ব্যবহার করে পজিশন পাচ্ছি

int selected_position = 0; // You have to set this globally in the Adapter class

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Item item = items.get(position);

    // Here I am just highlighting the background
    holder.itemView.setBackgroundColor(selected_position == position ? Color.GREEN : Color.TRANSPARENT);
}

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public ViewHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // Below line is just like a safety check, because sometimes holder could be null,
        // in that case, getAdapterPosition() will return RecyclerView.NO_POSITION
        if (getAdapterPosition() == RecyclerView.NO_POSITION) return;

        // Updating old as well as new positions
        notifyItemChanged(selected_position);
        selected_position = getAdapterPosition();
        notifyItemChanged(selected_position);

        // Do your another stuff for your onClick
    }
}

আশা করি এটি সাহায্য করবে


সেটা খুবই ভালো! যদিও আমি কিছুটা বিভ্রান্ত হয়েছি, আপনি কি আমাকে এই উত্তরটি প্রসারিত করে কোনও উপায় বাস্তবায়নে সহায়তা করতে পারবেন, ইতিমধ্যে নির্বাচিত কোনও আইটেমটিতে ক্লিক করার পরে আপনি অন্য বিবৃতিতে যা কিছু করছেন তা কীভাবে করবেন, যাতে আপনি এটি নির্বাচন থেকে অনির্বাচিত হন: অন্য { holder.itemView.setBackgroundColor (Color.TRANSPARENT); }
আইববব

অবশ্যই হ্যাঁ. @iBobb। নির্বাচিত আইটেমের জন্য, যার অবস্থান আমাদের 'নির্বাচিত_পরিষ্কার' ভেরিয়েবলের সমান নয়, কোনও পটভূমিতে থাকতে হবে না। আমি এটি ব্যবহার করেছি কারণ নাম অনুসারে রিসাইক্লারভিউ প্রতিটি আইটেমকে পুনর্ব্যবহার করে, তাই এটি এসসিআরএল করার সময় এলোমেলো সারিগুলির জন্য গ্রীন ব্যাকগ্রাউন্ড সেট করে, এজন্যই আমি সেই এলএসই অংশ রেখেছি। (আপনি কেবল ELSE অংশটি মন্তব্য করে চেষ্টা করে দেখতে পারেন এবং তারপরে আপনার রিসাইক্লার-ভিউ স্ক্রোল করুন)
সাথে দেখা করুন

আপনি আমার প্রশ্নটি বুঝতে পেরেছেন বলে আমি মনে করি না। আপনি যে কোনও অ্যাপ্লিকেশনটিতে জানেন, যখন আপনি কোনও কিছু নির্বাচন করেন এটি হাইলাইট হয়। যদি আপনি এটি আবার ধরে রাখেন তবে এটি অনির্বাচিত হয়ে যায়। আমরা কীভাবে এটি বাস্তবায়ন করব? এই মুহূর্তে আমরা কেবল আপনার কোড ব্যবহার করে নির্বাচন করতে পারি এবং একই আইটেমটিকে স্পর্শ করা এবং ধরে রাখা কিছুই করে না।
আইববব

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

কিছু কারণে ক্লিকের পরে হাইলাইট করতে সময় লাগে, প্রায় 100 থেকে 200 মিলিসেকেন্ড। কোন ধারণা কেন? আমি এটি একটি এমুলেটর এবং আমার ললিপপ ফোনে
দেখেছি

14

আপনার বাস্তবায়ন সম্ভবত কাজ করে যদি আপনি বিষয়বস্তুটিকে বাইরে রেখে স্ক্রোল করে আবার দেখুন। আমি যখন আপনার প্রশ্নটি নিয়ে আসি তখন আমারও তেমন সমস্যা ছিল।

নিম্নলিখিত ফাইল স্নিপেট আমার জন্য কাজ করছে। আমার বাস্তবায়ন একাধিক নির্বাচনের লক্ষ্য ছিল, তবে আমি একক নির্বাচনকে বাধ্য করার জন্য সেখানে একটি হ্যাক ছুড়েছি * (* 1)

// an array of selected items (Integer indices) 
private final ArrayList<Integer> selected = new ArrayList<>();

// items coming into view
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    // each time an item comes into view, its position is checked
    // against "selected" indices
    if (!selected.contains(position)){
        // view not selected
        holder.parent.setBackgroundColor(Color.LTGRAY);
    }
    else
        // view is selected
        holder.parent.setBackgroundColor(Color.CYAN);
}

// selecting items
@Override
public boolean onLongClick(View v) {

        // set color immediately.
        v.setBackgroundColor(Color.CYAN);

        // (*1)
        // forcing single selection here
        if (selected.isEmpty()){
            selected.add(position);
        }else {
            int oldSelected = selected.get(0);
            selected.clear();
            selected.add(position);
            // we do not notify that an item has been selected
            // because that work is done here.  we instead send
            // notifications for items to be deselected
            notifyItemChanged(oldSelected);
        }
        return false;
}

এই লিঙ্কযুক্ত প্রশ্নে উল্লিখিত হিসাবে , ভিউহোল্ডারদের জন্য শ্রোতাদের সেট করা অনক্রিটভিউহোল্ডারটিতে করা উচিত। আমি এর আগে উল্লেখ করতে ভুলে গেছি।


6

আমি মনে করি, আমাদের প্রয়োজনীয় সমস্ত বেসিক ফাংশনগুলি (সিঙ্গল + মাল্টিলেশন, হাইলাইট, রিপল, মাল্টিলেকশন এ ক্লিক করুন এবং মুছুন ইত্যাদি ইত্যাদি) কীভাবে পুনর্ব্যবহারযোগ্য ভিউটি ব্যবহার করতে হবে তার সেরা টিউটোরিয়ালটি আমি পেয়েছি।

এটি এখানে -> http://enoent.fr/blog/2015/01/18/recyclerview-basics/

তার ভিত্তিতে, আমি একটি "লাইব্রেরি অ্যাডাপ্টার" একটি লাইব্রেরি তৈরি করতে সক্ষম হয়েছি, যা একটি নির্বাচনযোগ্যআডাপ্টার প্রসারিত করে। আমি মনে করি এটি অবশ্যই অ্যাডাপ্টারের একটি দায়িত্ব হতে হবে, আসলে আপনাকে প্রতিবার অ্যাডাপ্টারের মৌলিক কার্যকারিতা পুনরায় লেখার দরকার নেই, একটি লাইব্রেরি এটি করতে দেয়, যাতে আপনি ঠিক একই প্রয়োগটি পুনরায় ব্যবহার করতে পারেন।

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

আপনার প্রকল্পে এটি বাস্তবায়নের জন্য দয়া করে দেখুন এবং নির্দ্বিধায় দয়া করে।

https://github.com/davideas/FlexibleAdapter

একটি উইকিও পাওয়া যায়।


দুর্দান্ত কাজ যে অ্যাডাপ্টারের, এটি খুব দরকারী বলে মনে হচ্ছে। কেবলমাত্র এটি হ'ল এর সত্যিকারের কয়েকটি বুনিয়াদি উদাহরণ এবং ডকুমেন্টেশন প্রয়োজন, এটি এটিকে চালিয়ে নেওয়া এবং চালিয়ে যাওয়াতে আমি কিছুটা বিভ্রান্তি বোধ করি। সম্ভাব্য যদিও দুর্দান্ত!
ভয়ে

হ্যাঁ, শুরু করার জন্য আমি সেখানে পর্যাপ্ত তথ্য পাইনি। কোডটিকে মনে মনে রেখে মন্তব্য করা হলেও এপিআই রেফারেন্সটি খুঁজে পেল না। নমুনা অ্যাপ্লিকেশনটি মনে হয় - যদিও বিস্তৃত এবং তথ্যবহুল - গ্রন্থাগারের পূর্বের জ্ঞান ছাড়াই বোঝা খুব কঠিন। সমস্ত ব্যবহারের কেসগুলি একত্রে আবদ্ধ, এতে কী বোঝা যায় তার খুব কম ইঙ্গিত পাওয়া যায় না, শ্রেণিগুলি বিভিন্ন পরিস্থিতি জুড়ে পুনরায় ব্যবহার করা হয় যার ফলস্বরূপ তারা তথ্যের সাথে অতিরিক্ত লোড হয়। আমি এই পরামর্শগুলি সহ এখানে একটি নতুন সমস্যা তৈরি করেছি: github.com/davideas/FlexibleAdapter/issues/120
Voy

উইকির সম্পূর্ণ পুনর্লিখন হয়েছে এবং সমাপ্তির পথে রয়েছে।
ডেভিডাস

6

আমার সমাধান দেখুন। আমি মনে করি আপনার ধারক হিসাবে নির্বাচিত অবস্থান নির্ধারণ করা উচিত এবং এটিকে ভিউ ট্যাগ হিসাবে পাস করুন। ভিউটি অনক্রিটভিউহোল্ডার (...) পদ্ধতিতে সেট করা উচিত। শ্রোতাদের অনক্লিকলিস্টনার বা লং ক্লিকলিস্টনার হিসাবে দেখার জন্য সেট করার সঠিক জায়গাও রয়েছে।

নীচের উদাহরণটি দেখুন এবং কোড মন্তব্য পড়ুন।

public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ViewHolder> {
    //Here is current selection position
    private int mSelectedPosition = 0;
    private OnMyListItemClick mOnMainMenuClickListener = OnMyListItemClick.NULL;

    ...

    // constructor, method which allow to set list yourObjectList

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //here you prepare your view 
        // inflate it
        // set listener for it
        final ViewHolder result = new ViewHolder(view);
        final View view =  LayoutInflater.from(parent.getContext()).inflate(R.layout.your_view_layout, parent, false);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //here you set your current position from holder of clicked view
                mSelectedPosition = result.getAdapterPosition();

                //here you pass object from your list - item value which you clicked
                mOnMainMenuClickListener.onMyListItemClick(yourObjectList.get(mSelectedPosition));

                //here you inform view that something was change - view will be invalidated
                notifyDataSetChanged();
            }
        });
        return result;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        final YourObject yourObject = yourObjectList.get(position);

        holder.bind(yourObject);
        if(mSelectedPosition == position)
            holder.itemView.setBackgroundColor(Color.CYAN);
        else
            holder.itemView.setBackgroundColor(Color.RED);
    }

    // you can create your own listener which you set for adapter
    public void setOnMainMenuClickListener(OnMyListItemClick onMyListItemClick) {
        mOnMainMenuClickListener = onMyListItemClick == null ? OnMyListItemClick.NULL : onMyListItemClick;
    }

    static class ViewHolder extends RecyclerView.ViewHolder {


        ViewHolder(View view) {
            super(view);
        }

        private void bind(YourObject object){
            //bind view with yourObject
        }
    }

    public interface OnMyListItemClick {
        OnMyListItemClick NULL = new OnMyListItemClick() {
            @Override
            public void onMyListItemClick(YourObject item) {

            }
        };

        void onMyListItemClick(YourObject item);
    }
}

আপনি কি মনে করেন যে কনফিগারেশনের পরিবর্তনগুলি বজায় রাখার জন্য এম-সিলেক্টড পজিশনটিকে স্থির হিসাবে ঘোষণা করা যেতে পারে?
সত্যেশ

না! এটিকে স্থির হিসাবে তৈরি করা খুব ভুল এটি
কনরাড ক্রাকওইক

হ্যাঁ। এটা বিপদজনক. তবে কনফিগার চেঞ্জ (যেমন, স্ক্রিন রোটেশন) বজায় রাখতে আমরা এই পরিবর্তনশীলটিকে ক্রিয়াকলাপে ঘোষণা করতে এবং সেখান থেকে পেতে পারি, তাই না?
সত্যেশ

অনেকগুলি সমাধান রয়েছে ... আপনি গিটার এবং সেটার ব্যবহার করতে পারেন, আপনি অ্যাডাপ্টারের জন্য আপনার নিজস্ব পদ্ধতি সেভইনস্ট্যান্সস্টেট তৈরি করতে এবং এটিকে ক্রিয়াকলাপ / টুকরা থেকে সেভ ইনস্ট্যান্সস্টেটে কল করতে পারেন
কনরাড ক্রাকওইয়াক

4

রিসাইক্লারভিউতে লিস্টভিউ এবং গ্রিডভিউয়ের মতো কোনও নির্বাচক নেই তবে আপনি এটি আমার পক্ষে কাজ করেছেন এমন নীচে চেষ্টা করে দেখুন

নীচে হিসাবে একটি নির্বাচনযোগ্য অঙ্কনযোগ্য তৈরি করুন

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:state_pressed="true">
   <shape>
         <solid android:color="@color/blue" />
   </shape>
</item>

<item android:state_pressed="false">
    <shape>
       <solid android:color="@android:color/transparent" />
    </shape>
</item>
</selector>

তারপরে আপনার পুনর্ব্যবহারযোগ্য সারি বিন্যাসের পটভূমি হিসাবে এই অঙ্কনযোগ্যকে সেট করুন

android:background="@drawable/selector"

2
এটি দরকারী কিছু করে না। এটি প্রেসের সময় করে রঙ পরিবর্তন করবে।
লিও ড্রয়েডকোডার

4

ইন্টারফেস এবং কলব্যাকস নিয়ে সিদ্ধান্ত। নির্বাচন এবং অনির্বাচিত রাজ্যগুলির সাথে ইন্টারফেস তৈরি করুন:

public interface ItemTouchHelperViewHolder {
    /**
     * Called when the {@link ItemTouchHelper} first registers an item as being moved or swiped.
     * Implementations should update the item view to indicate it's active state.
     */
    void onItemSelected();


    /**
     * Called when the {@link ItemTouchHelper} has completed the move or swipe, and the active item
     * state should be cleared.
     */
    void onItemClear();
}

ভিউহোল্ডারটিতে ইন্টারফেস প্রয়োগ করুন:

   public static class ItemViewHolder extends RecyclerView.ViewHolder implements
            ItemTouchHelperViewHolder {

        public LinearLayout container;
        public PositionCardView content;

        public ItemViewHolder(View itemView) {
            super(itemView);
            container = (LinearLayout) itemView;
            content = (PositionCardView) itemView.findViewById(R.id.content);

        }

               @Override
    public void onItemSelected() {
        /**
         * Here change of item
         */
        container.setBackgroundColor(Color.LTGRAY);
    }

    @Override
    public void onItemClear() {
        /**
         * Here change of item
         */
        container.setBackgroundColor(Color.WHITE);
    }
}

কলব্যাকে রাষ্ট্র পরিবর্তন চালনা করুন:

public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private final ItemTouchHelperAdapter mAdapter;

    public ItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
        this.mAdapter = adapter;
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        int swipeFlags = ItemTouchHelper.END;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        ...
    }

    @Override
    public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
        ...
    }

    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            if (viewHolder instanceof ItemTouchHelperViewHolder) {
                ItemTouchHelperViewHolder itemViewHolder =
                        (ItemTouchHelperViewHolder) viewHolder;
                itemViewHolder.onItemSelected();
            }
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        if (viewHolder instanceof ItemTouchHelperViewHolder) {
            ItemTouchHelperViewHolder itemViewHolder =
                    (ItemTouchHelperViewHolder) viewHolder;
            itemViewHolder.onItemClear();
        }
    }   
}

কলব্যাকের সাহায্যে রিসাইক্লারভিউ তৈরি করুন (উদাহরণ):

mAdapter = new BuyItemsRecyclerListAdapter(MainActivity.this, positionsList, new ArrayList<BuyItem>());
positionsList.setAdapter(mAdapter);
positionsList.setLayoutManager(new LinearLayoutManager(this));
ItemTouchHelper.Callback callback = new ItemTouchHelperCallback(mAdapter);
mItemTouchHelper = new ItemTouchHelper(callback);
mItemTouchHelper.attachToRecyclerView(positionsList);

আইপলপ্রোতে নিবন্ধে আরও দেখুন: https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd#.6gh29uaaz


3

এটি আমার সমাধান, আপনি একটি আইটেম সেট করতে পারেন (বা একটি গোষ্ঠী) এবং অন্য ক্লিকের মাধ্যমে এটি নির্বাচন থেকে অনির্বাচিত:

 private final ArrayList<Integer> seleccionados = new ArrayList<>();
@Override
    public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
        viewHolder.san.setText(android_versions.get(i).getAndroid_version_name());
        if (!seleccionados.contains(i)){ 
            viewHolder.inside.setCardBackgroundColor(Color.LTGRAY);
        }
        else {
            viewHolder.inside.setCardBackgroundColor(Color.BLUE);
        }
        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (seleccionados.contains(i)){
                    seleccionados.remove(seleccionados.indexOf(i)); 
                    viewHolder.inside.setCardBackgroundColor(Color.LTGRAY);
                } else { 
                    seleccionados.add(i);
                    viewHolder.inside.setCardBackgroundColor(Color.BLUE);
                }
            }
        });
    }

2

আমার একই সমস্যা ছিল এবং আমি এটি নিম্নলিখিত উপায়ে সমাধান করি:

এক্সএমএল ফাইল যা তৈরি ভিউহোল্ডারের ভিতরে সারি তৈরি করার জন্য ব্যবহার করছে, কেবল নীচের লাইনের সাথে যুক্ত করুন:

 android:clickable="true"
 android:focusableInTouchMode="true"
 android:background="?attr/selectableItemBackgroundBorderless"

বা যদি আপনি সারি আইটেমের পিতামাতা হিসাবে ফ্রেমলআউট ব্যবহার করেন তবে:

android:clickable="true"
android:focusableInTouchMode="true"
android:foreground="?attr/selectableItemBackgroundBorderless"

জাভা কোডটিতে ভিউ হোল্ডারের অভ্যন্তরে যেখানে আপনি ক্লিক শ্রোতার সাথে যুক্ত করেছেন:

@Override
   public void onClick(View v) {

    //ur other code here
    v.setPressed(true);
 }

1

এই সমস্যার জন্য ওয়েবে আমি কোনও ভাল সমাধান খুঁজে পেলাম না এবং এটি নিজেই সমাধান করেছি। এই সমস্যায় ভুগছেন প্রচুর মানুষ। এইভাবে আমি আমার সমাধানটি এখানে ভাগ করতে চাই।

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

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

https://www.dropbox.com/s/ssm58w62gw32i29/recyclerView_checkbox_highlight.zip?dl=0

    public class RV_Adapter extends RecyclerView.Adapter<RV_Adapter.ViewHolder> {
        public ArrayList<String> list;
        boolean[] checkBoxState;
        MainActivity mainActivity;
        MyFragment myFragment;
        View firstview;

        private Context context;

        FrameLayout framelayout;

        public RV_Adapter() {

      }

        public RV_Adapter(Context context, MyFragment m, ArrayList<String> list ) {
          this.list = list;
          myFragment = m;
          this.context = context;
          mainActivity = (MainActivity) context;
          checkBoxState = new boolean[list.size()];
          // relativeLayoutState = new boolean[list.size()];
        }

        public class ViewHolder extends RecyclerView.ViewHolder  {
            public TextView textView;
            public CheckBox checkBox;
            RelativeLayout relativeLayout;
            MainActivity mainActivity;
            MyFragment myFragment;
            public ViewHolder(View v,MainActivity mainActivity,MyFragment m) {
                super(v);
                textView = (TextView) v.findViewById(R.id.tv_foodname);
                /**/
                checkBox= (CheckBox) v.findViewById(R.id.checkBox);
                relativeLayout = (RelativeLayout)v.findViewById(R.id.relativelayout);
                this.mainActivity = mainActivity;
                this.myFragment = m;
                framelayout = (FrameLayout) v.findViewById(R.id.framelayout);
                framelayout.setOnLongClickListener(m);
            }

        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            firstview = inflater.inflate(R.layout.row, parent, false);
            return new ViewHolder(firstview,mainActivity, myFragment);
        }

        @Override
        public void onBindViewHolder( final ViewHolder holder,  final int position) {

            holder.textView.setText(list.get(position));

            holder.itemView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {

              }
            });

            // When action mode is active, checkboxes are displayed on each row, handle views(move icons) on each row are disappered.
            if(!myFragment.is_in_action_mode)
            {

              holder.checkBox.setVisibility(View.GONE);
            }
            else
            {
              holder.checkBox.setVisibility(View.VISIBLE);
              holder.checkBox.setChecked(false);
            }

              holder.checkBox.setTag(position);

              holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                  if(compoundButton.isPressed()) // ekrandan kaybolan checkbox'lar otomatik olarak state degistiriyordu ve bu listener method cagiriliyordu, bunu onlemek icin isPressed() method'u ile kullanici mi basmis diye kontrol ediyorum.
                  {
                    int getPosition = (Integer) compoundButton.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                    checkBoxState[getPosition] = compoundButton.isChecked(); // Set the value of checkbox to maintain its state.
                    //relativeLayoutState[getPosition] = compoundButton.isChecked();

                  if(checkBoxState[getPosition] && getPosition == position )
                    holder.relativeLayout.setBackgroundResource(R.color.food_selected); /** Change background color of the selected items in list view  **/
                  else
                    holder.relativeLayout.setBackgroundResource(R.color.food_unselected); /** Change background color of the selected items in list view  **/
                    myFragment.prepareselection(compoundButton, getPosition, holder.relativeLayout);

                  }
                }
              });
              holder.checkBox.setChecked(checkBoxState[position]);

              if(checkBoxState[position]  )
                holder.relativeLayout.setBackgroundResource(R.color.food_selected); /** Change background color of the selected items in list view  **/
              else
                holder.relativeLayout.setBackgroundResource(R.color.food_unselected);
        }



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

        public void updateList(ArrayList<String> newList){
          this.list = newList;
          checkBoxState = new boolean[list.size()+1];
        }

      public void resetCheckBoxState(){
        checkBoxState = null;
        checkBoxState = new boolean[list.size()];
      }

    }

অ্যাপ্লিকেশন এর স্ক্রিনশট:

screen1 screen2 screen3 screen4


-1

private int selected_position = -1;শুরুতে কোনও আইটেম নির্বাচন করা থেকে বিরত রাখতে সেট করুন।

 @Override
 public void onBindViewHolder(final OrdersHolder holder, final int position) {
    final Order order = orders.get(position);
    holder.bind(order);
    if(selected_position == position){
        //changes background color of selected item in RecyclerView
        holder.itemView.setBackgroundColor(Color.GREEN);
    } else {
        holder.itemView.setBackgroundColor(Color.TRANSPARENT);
        //this updated an order property by status in DB
        order.setProductStatus("0");
    }
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //status switch and DB update
            if (order.getProductStatus().equals("0")) {
                order.setProductStatus("1");
                notifyItemChanged(selected_position);
                selected_position = position;
                notifyItemChanged(selected_position);
             } else {
                if (order.getProductStatus().equals("1")){
                    //calls for interface implementation in
                    //MainActivity which opens a new fragment with 
                    //selected item details 
                    listener.onOrderSelected(order);
                }
             }
         }
     });
}

-1

android:background="?attr/selectableItemBackgroundBorderless"আপনার পটভূমির রঙ না থাকলে কেবল যোগ করার কাজ করা উচিত তবে সেটসলেক্টেড পদ্ধতিটি ব্যবহার করতে ভুলবেন না। আপনার যদি ভিন্ন পটভূমির রঙ থাকে তবে আমি কেবল এটি ব্যবহার করেছি (আমি ডেটা-বাইন্ডিং ব্যবহার করছি);

অনক্লিক ফাংশনে সেটটি নির্বাচন করা হয়েছে

b.setIsSelected(true);

এবং এটি এক্সএমএল যুক্ত করুন;

android:background="@{ isSelected ? @color/{color selected} : @color/{color not selected} }"

-1

নির্বাচক করুন:

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/Green_10" android:state_activated="true" />
    <item android:drawable="@color/Transparent" />
</selector>

আপনার তালিকা আইটেম বিন্যাস এ ব্যাকগ্রাউন্ড হিসাবে সেট করুন

   <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:background="@drawable/selector_attentions_list_item"
        android:layout_width="match_parent"
        android:layout_height="64dp">

আপনার অ্যাডাপ্টারে ভিউতে অনক্লিকলিস্টনার যুক্ত করুন (অনবিন্দ পদ্ধতি)

 @Suppress("UNCHECKED_CAST")
    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bindItems(item: T) {
            initItemView(itemView, item)
            itemView.tag = item
            if (isClickable) {
                itemView.setOnClickListener(onClickListener)
            }
        }
    }

অনক্লিক ইভেন্টে দৃশ্যটি সক্রিয় করুন:

 fun onItemClicked(view: View){
        view.isActivated = true
    }

2
এতে 2 টি সমস্যা রয়েছে: 1) আপনি পুনর্ব্যবহারকারীতে অন্যান্য আইটেমগুলির সক্রিয়করণ পূর্বাবস্থায় ফেলার কোনও উপায় সরবরাহ করেন নি। 2) দর্শন পুনরায় ব্যবহার করা হয়। সুতরাং এটি সম্ভব যে স্ক্রোল করা হলে একই অ্যাক্টিভেটেড ভিউটি ক্রমের নীচে দৃশ্যমান হবে।
অনুপ শর্মা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.