android - ক্লিক করা আইটেম এবং পুনর্ব্যবহারযোগ্য ভিউতে এর অবস্থান পান




listview android-recyclerview (12)

এখানে ক্লিক করা আইটেমটির অবস্থান সন্ধান করার সবচেয়ে সহজ এবং সহজ উপায়:

আমিও একই সমস্যার মুখোমুখি হয়েছি।

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

getAdapterPosition () পদ্ধতি এই ধরণের স্টাফগুলির জন্য কবজির মতো কাজ করে। একদিন দীর্ঘ গবেষণার পরে এবং অন্যান্য অসংখ্য পদ্ধতির চেষ্টা করার পরে আমি এই পদ্ধতিটি পেয়েছি।

int position = getAdapterPosition();
Toast.makeText(this, "Position is: "+position, Toast.LENGTH_SHORT).show();

আপনাকে কোনও অতিরিক্ত পদ্ধতি ব্যবহার করতে হবে না। কেবলমাত্র 'পজিশন' নামের একটি বৈশ্বিক পরিবর্তনশীল তৈরি করুন এবং অ্যাডাপ্টারের (ক্লাস বা অনুরূপ) যেকোন বড় পদ্ধতিতে getAdapterPosition () দিয়ে এটি আরম্ভ করুন।

এই link থেকে একটি সংক্ষিপ্ত ডকুমেন্টেশন এখানে।

getAdapterP स्थिति 22.1.0 সংস্করণে যুক্ত হয়েছে getAdapterPosition () এই ভিউহোল্ডার দ্বারা প্রতিনিধিত্ব করা আইটেমটির অ্যাডাপ্টারের অবস্থান প্রদান করে। মনে রাখবেন যে অ্যাডাপ্টারের আপডেটগুলি মুলতুবি থাকলেও একটি নতুন লেআউট পাস এখনও ঘটে নি তবে এটি getLayoutPosition () এর চেয়ে আলাদা হতে পারে। রিসাইক্লারভিউ পরবর্তী লেআউট ট্র্যাভারসাল না হওয়া পর্যন্ত কোনও অ্যাডাপ্টার আপডেট পরিচালনা করে না। এটি স্ক্রিনে ব্যবহারকারী কী দেখেন এবং অ্যাডাপ্টারের সামগ্রীগুলির মধ্যে সাময়িক অসঙ্গতি তৈরি করতে পারে। এই অসঙ্গতিটি গুরুত্বপূর্ণ নয় যেহেতু এটি 16 এমএমের চেয়ে কম হবে তবে আপনি যদি অ্যাডাপ্টারে অ্যাক্সেস করতে ভিউহোল্ডার অবস্থান ব্যবহার করতে চান তবে এটি একটি সমস্যা হতে পারে। কখনও কখনও, ব্যবহারকারীর ইভেন্টগুলির প্রতিক্রিয়া হিসাবে কিছু ক্রিয়া করার জন্য আপনাকে সঠিক অ্যাডাপ্টারের অবস্থান পেতে হতে পারে। সেক্ষেত্রে আপনার এই পদ্ধতিটি ব্যবহার করা উচিত যা ভিউহোল্ডারের অ্যাডাপ্টারের অবস্থান গণনা করবে।

সাহায্য করতে পারলে খুশি. সন্দেহ জিজ্ঞাসা করুন নির্দ্বিধায়।

আমি আমার ListView RecyclerView ListView সাথে প্রতিস্থাপন করছি, তালিকাটি ঠিক আছে দেখছি, তবে আমি কীভাবে ক্লিক করা আইটেম এবং তার অবস্থান পেতে পারি তা জানতে OnItemClickListener.onItemClick(AdapterView parent, View v, int position, long id) মতো similar ListView

ধারণার জন্য ধন্যবাদ!


অনভিউহোল্ডারটিতে যে কোনও ভিউতে ক্লিকলিস্টাইনার অন ক্লিক করুন এবং সাইড ক্লিকে এই কোডটি ব্যবহার করুন:

টোস্ট.মেকটেক্সট (ড্রয়ার_বার.এই, "পজিশন" + পজিশন, টোস্ট। এলএনজিটিএসএইচআরটি)। শো ();

আপনার ক্রিয়াকলাপের নাম দিয়ে Drawer_Bar প্রতিস্থাপন করুন।


আপনি যদি অ্যাডাপ্টারের পরিবর্তে ক্রিয়াকলাপ / খণ্ড থেকে রিসাইকেল-ভিউয়ের ইভেন্ট ক্লিক করতে চান তবে নীচের শর্ট কাট উপায়টিও ব্যবহার করতে পারেন।

recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final TextView txtStatusChange = (TextView)v.findViewById(R.id.txt_key_status);
                txtStatusChange.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e(TAG, "hello text " + txtStatusChange.getText().toString() + " TAG " + txtStatusChange.getTag().toString());
                        Util.showToast(CampaignLiveActivity.this,"hello");
                    }
                });
                return false;
            }
        });

আপনি ইন্টারফেস ব্যবহারের মতো অন্যান্য দীর্ঘ উপায়ও ব্যবহার করতে পারেন


এইভাবে চেষ্টা করুন

অ্যাডাপ্টার শ্রেণি:

 public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {

public interface OnItemClickListener {
    void onItemClick(ContentItem item);
}

private final List<ContentItem> items;
private final OnItemClickListener listener;

public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
    this.items = items;
    this.listener = listener;
}

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

@Override public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bind(items.get(position), listener);
}

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

static class ViewHolder extends RecyclerView.ViewHolder {

    private TextView name;
    private ImageView image;

    public ViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.name);
        image = (ImageView) itemView.findViewById(R.id.image);
    }

    public void bind(final ContentItem item, final OnItemClickListener listener) {
        name.setText(item.name);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                listener.onItemClick(item);
            }
        });
    }
}

}

আপনার ক্রিয়াকলাপ বা খণ্ডে:

ContentAdapter adapter = new ContentAdapter(itemList, this);

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


ক্রিয়াকলাপে আপনি পুনর্ব্যক্তিকর দৃশ্যের সংজ্ঞা দেন যেখানে এই কোডটি রাখুন।

    rv_list.addOnItemTouchListener(
            new RecyclerItemClickListener(activity, new RecyclerItemClickListener.OnItemClickListener() {
                @Override
                public void onItemClick(View v, int position) {

                    Toast.makeText(activity, "" + position, Toast.LENGTH_SHORT).show();
                }
            })
    );

তারপরে পৃথক শ্রেণি তৈরি করুন এবং এই কোডটি দিন:

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

    private OnItemClickListener mListener;
    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }
    GestureDetector mGestureDetector;
    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }
    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

ক্লিক শ্রোতা সেট করার জন্য এখানে একটি উদাহরণ is

Adapter extends  RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {  ...  }

 public static class MessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView     tv_msg;
        public TextView     tv_date;
        public TextView     tv_sendTime;
        public ImageView    sharedFile;
        public ProgressBar sendingProgressBar;

        public MessageViewHolder(View v) {
            super(v);
            tv_msg =  (TextView) v.findViewById(R.id.tv_msg);
            tv_date = (TextView)  v.findViewById(R.id.tv_date);
            tv_sendTime = (TextView)  v.findViewById(R.id.tv_sendTime);
            sendingProgressBar = (ProgressBar) v.findViewById(R.id.sendingProgressBar);
            sharedFile = (ImageView) v.findViewById(R.id.sharedFile);

            sharedFile.setOnClickListener(this);

        }

        @Override
        public void onClick(View view) {
        int position  =   getAdapterPosition();


            switch (view.getId()){
                case R.id.sharedFile:


                    Log.w("", "Selected"+position);


                    break;
            }
        }

    }

নীচের কোড সহ জাভা ফাইল তৈরি করুন

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;

public interface OnItemClickListener {
    public void onItemClick(View view, int position);
}

GestureDetector mGestureDetector;

public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
    mListener = listener;
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override public boolean onSingleTapUp(MotionEvent e) {
            return true;
        }
    });
}

@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
    View childView = view.findChildViewUnder(e.getX(), e.getY());
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
        mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
        return true;
    }
    return false;
}

@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

}

এবং কেবলমাত্র আপনার পুনর্ব্যবহারযোগ্য ভিউজে শ্রোতাদের ব্যবহার করুন।

recyclerView.addOnItemTouchListener(  
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
  @Override public void onItemClick(View view, int position) {
    // TODO Handle item click
  }
}));

প্রতিবার আমি অন্য পদ্ধতি ব্যবহার করি। লোকেরা ভিউহোল্ডার দ্বারা প্রদর্শিত কোনও অবজেক্টের রেফারেন্স সঞ্চয় করার চেয়ে ভিউতে সঞ্চয় বা অবস্থান পেয়েছে বলে মনে হয়।

পরিবর্তে আমি এই পদ্ধতির ব্যবহার করি এবং অনবাইন্ডহোল্ডার () কল করা হলে এটি কেবল ভিউহোল্ডারে সঞ্চয় করি এবং অনভিউ রাইসাইক্ল্ড () এ নালকে রেফারেন্স সেট করে।

যতবার ভিউহোল্ডার অদৃশ্য হয়ে যায়, এটি পুনর্ব্যবহারযোগ্য। সুতরাং এটি বড় মেমরির ব্যবহারে প্রভাব ফেলবে না।

@Override
public void onBindViewHolder(final ItemViewHolder holder, int position) {
    ...
    holder.displayedItem = adapterItemsList.get(i);
    ...
}

@Override
public void onViewRecycled(ItemViewHolder holder) {
    ...
    holder.displayedItem = null;
    ...
}

class ItemViewHolder extends RecyclerView.ViewHolder {
    ...
    MySuperItemObject displayedItem = null;
    ...
}

লিঙ্কটির ভিত্তিতে: রিসাইক্লার ভিউতে আইটেমিক্লিকলিস্টার () নেই কেন? এবং কীভাবে রিসাইক্লারভিউ তালিকাভুক্তির থেকে পৃথক? , এবং @ ডানকানের সাধারণ ধারণা, আমি আমার সমাধানটি এখানে দিচ্ছি:

  • অ্যাডাপ্টার থেকে Activity / Fragment বার্তা RecyclerViewClickListener জন্য একটি ইন্টারফেস RecyclerViewClickListener সংজ্ঞা দিন:

    public interface RecyclerViewClickListener {
        public void recyclerViewListClicked(View v, int position);
    }
  • Activity / Fragment ইন্টারফেসটি প্রয়োগ করে এবং শ্রোতাদের অ্যাডাপ্টারে পাস করে:

    @Override
    public void recyclerViewListClicked(View v, int position){... ...}
    
    //set up adapter and pass clicked listener this
    myAdapter = new MyRecyclerViewAdapter(context, this);
  • Adapter এবং ViewHolder :

    public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ItemViewHolder> {
       ... ... 
       private Context context;
       private static RecyclerViewClickListener itemListener;
    
    
       public MyRecyclerViewAdapter(Context context, RecyclerViewClickListener itemListener) {
           this.context = context;
           this.itemListener = itemListener;
           ... ...
       }
    
    
       //ViewHolder class implement OnClickListener, 
       //set clicklistener to itemView and, 
       //send message back to Activity/Fragment 
       public static class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
           ... ...
           public ItemViewHolder(View convertView) {
               super(convertView);
               ... ...
               convertView.setOnClickListener(this);
           }
    
           @Override
           public void onClick(View v) {
               itemListener.recyclerViewListClicked(v, this.getPosition());     
    
           }
       }
    }

পরীক্ষার পরে, এটি সূক্ষ্ম কাজ করে।


[ আপডেট ]

এপিআই 22 যেহেতু, RecyclerView.ViewHoler.getPosition() getLayoutPosition() করা হয়েছে, তাই পরিবর্তে getLayoutPosition()


কোটলিনের জন্য সংক্ষিপ্ত সম্প্রসারণ
পদ্ধতিটি সমস্ত আইটেমের পরম অবস্থান দেয় (কেবলমাত্র দৃশ্যমান আইটেমের অবস্থান নয়)।

fun RecyclerView.getChildPositionAt(x: Float, y: Float): Int {
    return getChildAdapterPosition(findChildViewUnder(x, y))
}

এবং ব্যবহার

val position = recyclerView.getChildPositionAt(event.x, event.y)

public class MyRvAdapter extends RecyclerView.Adapter<MyRvAdapter.MyViewHolder>{
    public Context context;
    public ArrayList<RvDataItem> dataItems;

    ...
    constructor
    overrides
    ...

    class MyViewHolder extends RecyclerView.ViewHolder{
        public TextView textView;
        public Context context;

        public MyViewHolder(View itemView, Context context) {
            super(itemView);

            this.context = context;

            this.textView = (TextView)itemView.findViewById(R.id.textView);

            // on item click
            itemView.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    // get position
                    int pos = getAdapterPosition();

                    // check if item still exists
                    if(pos != RecyclerView.NO_POSITION){
                        RvDataItem clickedDataItem = dataItems.get(pos);
                        Toast.makeText(v.getContext(), "You clicked " + clickedDataItem.getName(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }
}

recyclerViewObject.addOnItemTouchListener(
    new RecyclerItemClickListener(
        getContext(),
        recyclerViewObject,
        new RecyclerItemClickListener.OnItemClickListener() {
            @Override public void onItemClick(View view, int position) {
                // view is the clicked view (the one you wanted
                // position is its position in the adapter
            }
            @Override public void onLongItemClick(View view, int position) {
            }
        }
    )
);






recycler-adapter