কিভাবে রিসাইক্লার ভিউয়ের জন্য প্রসঙ্গ মেনু তৈরি করবেন


100

RecyclerView?দৃশ্যত কলিংয়ের জন্য প্রসঙ্গ মেনুটি কীভাবে আমি প্রয়োগ করব registerForContextMenu(recyclerView)। আমি এটি একটি টুকরা থেকে কল করছি। এটি বাস্তবায়নে কারও কি সাফল্য ছিল?


আমি একই নৌকায় আছি অ্যাডাপ্টারকন্টেক্সটেক্সু মেনুআইনফো সহ বিভিন্ন তালিকাভিউ অ্যাপ্রোচ চেষ্টা করেছেন - তবে
তথ্যটি পেলেন

আমি মনে করি প্রসঙ্গ মেনু এর দিন শেষ।
বিনয় বাবু

4
আরে - আমি কাজ করতে দেখে;) refeerence: stackoverflow.com/questions/2321332/... - আমার জন্য ViewHolder onClick শ্রোতা হয় - আমিও এটা OnCreateContextMenuListener প্রণীত। এই সমস্ত কী কী তা আমি বুঝতে পেরেছিলাম যে একবারে কেবলমাত্র একটি মেনু খোলা যেতে পারে - সুতরাং অ্যাডাপ্টারের কেবলমাত্র একটি ইনট প্রয়োজন যা ম্যানুতে ক্লিক করা শেষ রিক্সিলভিউ তালিকার আইটেমটি ছিল ... তারপরে খণ্ড / ক্রিয়াকলাপটি পারে অ্যাডাপ্টারটি জিজ্ঞাসা করুন যখন এটি আসল মেনু আইটেম ক্লিক করে।
রাউন্ডস্প্যারো হিলিটেক্স

উত্তর:


94

আপনি সরাসরি মত এই পদ্ধতি বাস্তবায়ন করতে পারবে না onClickListener , OnContextMenuListener ইত্যাদি কারণ RecycleView প্রসারিত android.view.ViewGroup । সুতরাং আমরা সরাসরি এই পদ্ধতিটি ব্যবহার করতে পারি না। আমরা ভিউহোল্ডার অ্যাডাপ্টার শ্রেণিতে এই পদ্ধতিগুলি প্রয়োগ করতে পারি । আমরা এইভাবে রিসাইক্ল ভিউতে প্রসঙ্গ মেনু ব্যবহার করতে পারি:

public static class ViewHolder extends RecyclerView.ViewHolder implements OnCreateContextMenuListener {

    TextView tvTitle;
    ImageView ivImage;

    public ViewHolder(View v) {
        super(v);
        tvTitle =(TextView)v.findViewById(R.id.item_title);
        v.setOnCreateContextMenuListener(this);


    }

প্রসঙ্গ মেনুটি প্রয়োগ করার সময় আমরা এখন একই পদ্ধতি অনুসরণ করি।

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {

    menu.setHeaderTitle("Select The Action");    
    menu.add(0, v.getId(), 0, "Call");//groupId, itemId, order, title   
    menu.add(0, v.getId(), 0, "SMS"); 

}

কোন অসুবিধা পেলে কমেন্টে জিজ্ঞাসা করুন।


7
ঠিক আছে, এবং তারপরে আমরা একটি onContextItemSelectedক্রিয়াকলাপ / খণ্ড স্তরের প্রয়োগ করি । getTitleকাজ করে, getItemIdকাজ করে তবে getMenuInfoশূন্য করে। সুতরাং, কিভাবে এর ahold পেতে ViewHolder?
মাইকেল শ্মিড্ট

আপনি যেখানে প্রসঙ্গ মেনু তথ্য প্রয়োগ করেন সেখানে @ মিশেলশ্মিট আপনি আমাকে আপনার কোডটি প্রদর্শন করতে পারেন।
প্রভাকর

7
কিছুটা পরীক্ষা-নিরীক্ষার পরে আমি এটি getMenuInfo()কোনওভাবেই কাজ করতে পারছি না, ফিরে আসে onContextItemSelected()। হতে পারে যে লোকেরা এটি কাজ onCreateContextMenu()করতে পেরেছিল তারা হায়ারার্কির ( RecyclerViewবা Fragment) আরও একটি দৃষ্টিতে একটি পদ্ধতি আছে বলে মনে হয় ? এটি কাজ করতে পারে তবে তারপরে আমাদের এই প্রশ্নের অন্যান্য উত্তরে নিয়ে যায়।
নিলস

4
প্রভাকবার আপনি কীভাবে ক্লিক করা আইটেমের ভিউ পাবেন তা উল্লেখ করেননি?
বেনিয়ামিন স্টারমার

6
অবস্থানটি পাওয়ার menu.add(this.getAdapterPosition(), v.getId(), 0, "Call");জন্য item.getGroupId()আপনি নিজের কলব্যাক পদ্ধতি পরীক্ষায় এবং তারপরে ব্যবহার করতে পারেন
জ্যাকবপ্যারিসৌ

102

তথ্য এবং মন্তব্যের জন্য ধন্যবাদ। আমি ContextMenuআইটেমগুলির জন্য অর্জন করতে সক্ষম হয়েছিRecyclerview

এখানে আমি কি করেছি

খণ্ডের onViewCreatedপদ্ধতিতে বা ক্রিয়াকলাপের onCreateপদ্ধতিতে:

registerForContextMenu(mRecyclerView);

তারপরে অ্যাডাপ্টারে অ্যাড করুন

private int position;

public int getPosition() {
    return position;
}

public void setPosition(int position) {
    this.position = position;
}

করতে ViewHolderবর্গ বাস্তবায়নOnCreateContextMenuListener

public static class ViewHolder extends RecyclerView.ViewHolder 
        implements View.OnCreateContextMenuListener {

    public ImageView icon;

    public TextView fileName;
    public ImageButton menuButton;


    public ViewHolder(View v) {
        super(v);
        icon = (ImageView)v.findViewById(R.id.file_icon);
        fileName = (TextView)v.findViewById(R.id.file_name);
        menuButton = (ImageButton)v.findViewById(R.id.menu_button);
        v.setOnCreateContextMenuListener(this);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, 
        ContextMenu.ContextMenuInfo menuInfo) {
        //menuInfo is null
        menu.add(Menu.NONE, R.id.ctx_menu_remove_backup, 
            Menu.NONE, R.string.remove_backup);
        menu.add(Menu.NONE, R.id.ctx_menu_restore_backup,
            Menu.NONE, R.string.restore_backup);
    }
}

onBindViewHolderOnLongClickListenerপ্রসঙ্গ মেনুটি লোড হওয়ার আগে অবস্থানটি ক্যাপচার করার জন্য পদ্ধতিটি হোল্ডার.ইটিএমভিউতে যুক্ত করুন:

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        setPosition(holder.getPosition());
        return false;
    }
});

তারপরে onViewRecycledশ্রোতাদের সরানোর ক্ষেত্রে যাতে কোনও রেফারেন্স সমস্যা নেই। (প্রয়োজন হতে পারে না)।

@Override
public void onViewRecycled(ViewHolder holder) {
    holder.itemView.setOnLongClickListener(null);
    super.onViewRecycled(holder);
}

অবশেষে খণ্ড / ক্রিয়াকলাপে onContextItemSelectedনীচে হিসাবে ওভাররাইড করুন :

@Override
public boolean onContextItemSelected(MenuItem item) {
    int position = -1;
    try {
        position = ((BackupRestoreListAdapter)getAdapter()).getPosition();
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage(), e);
        return super.onContextItemSelected(item);
    }
    switch (item.getItemId()) {
        case R.id.ctx_menu_remove_backup:
            // do your stuff
            break;
        case R.id.ctx_menu_restore_backup:
            // do your stuff
            break;
    }
    return super.onContextItemSelected(item);
}

4
অবস্থান = ((ব্যাকআপরেস্টরলিস্টএডাপ্টার) getAdapter ())। getPosition (); -> ত্রুটি পান: পদ্ধতিটি getAdapter () টাইপটির জন্য পূর্বনির্ধারিত ..., আপনি getAdapter পদ্ধতিটি দেখাতে পারেন
nguoixanh

4
দুর্দান্ত পরামর্শ, ধন্যবাদ। অপ্রাপ্তবয়স্ক: ভিউহোল্ডার.গেটপজিশন () হ্রাস করা হয়েছে। উন্নতির জন্য আপনার পরামর্শ কী?
tm1701

10
getPosition () এর পরিবর্তে viewHolder.getAdapterPosition () ব্যবহার করুন
সাগর চাওয়াদা

4
যারা getAdapter () ত্রুটি পান তাদের জন্য, আমি এটি আমার পুনর্ব্যবহারযোগ্য ভিউয়ের একটি রেফারেন্স সংরক্ষণ করে সমাধান করেছি এবং তারপরে এটি ব্যবহার করুন: ((ব্যাকআপরেস্টোরলিস্টএডাপ্টার) রিসাইক্লারভিউ.জেটএডাপ্টার ()) গেটপজিশন ();
কেভিন আমোরিম

4
আর আর.আইডি.সিটিএক্স_মেনু_রেমো_ব্যাকআপ ঠিক কোথায়?
আকুবি

29

বর্তমান উত্তরটি সঠিক নয়। এখানে একটি কার্যকরী বাস্তবায়ন:

public class ContextMenuRecyclerView extends RecyclerView {

  private RecyclerViewContextMenuInfo mContextMenuInfo;

  @Override
  protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
    return mContextMenuInfo;
  }

  @Override
  public boolean showContextMenuForChild(View originalView) {
    final int longPressPosition = getChildPosition(originalView);
    if (longPressPosition >= 0) {
        final long longPressId = getAdapter().getItemId(longPressPosition);
        mContextMenuInfo = new RecyclerViewContextMenuInfo(longPressPosition, longPressId);
        return super.showContextMenuForChild(originalView);
    }
    return false;
  }

  public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {

    public RecyclerViewContextMenuInfo(int position, long id) {
        this.position = position;
        this.id = id;
    }

    final public int position;
    final public long id;
  }
}

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

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mRecyclerView = view.findViewById(R.id.recyclerview);
    registerForContextMenu(mRecyclerView);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    // inflate menu
    MenuInflater inflater = getActivity().getMenuInflater();
    inflater.inflate(R.menu.my_context_menu, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    return super.onContextItemSelected(item);
    RecyclerViewContextMenuInfo info = (RecyclerViewContextMenuInfo) item.getMenuInfo();
    // handle menu item here
}

এবং অবশেষে, আপনার ভিউহোল্ডারে:

class MyViewHolder extends RecyclerView.View.ViewHolder {
    ...
    private void onLongClick() {
        itemView.showContextMenu();
    }
}

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

4
দ্রষ্টব্য: দুঃখিত, আমি যুক্ত করতে ভুলে গেছি: এতে getChildPosition()অবচয় রয়েছে com.android.support:recyclerview-v7:22.0.0
জুয়ান জোসে মেলেরো গমেজ

4
এটি কাজ করছে না। আপনি পুনর্ব্যবহারযোগ্য ভিউ.ভিউ.ভিউহোল্ডার থেকে কন্টেক্সটেক্সমেনু () অর্জন করতে পারবেন না।
মুলগার্ড

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

4
গুরুত্বপূর্ণটিও: কনটেক্সটমেনুআরসাইক্লারভিউতে পুনর্ব্যবহারকারী সম্প্রসারণ করার সময়, আইডিইর পরামর্শদাতাদের সংযোজন করতে ভুলবেন না। বিশেষত, আপনি যদি কনটেক্সট এবং অ্যাট্রিবিউটসেট গ্রহণ করে এমন দ্বি-যুক্তিযুক্ত নির্মাণকারীর প্রয়োগ না করেন, অ্যান্ড্রয়েড আপনার লেআউট এক্সএমএল স্ফীত করতে সক্ষম হবে না।
lidkxx

24

Viewরিসাইকেলভিউতে কোনও আইটেমের জন্য এটি ব্যবহার করে দেখুন

.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            menu.add("delete").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    //do what u want
                    return true;
                }
            });
        }
    });

আপনি এটি কোনও ViewHolderআইটেমে ডেটা সেট করার সাথে ব্যবহার করতে পারেন


একটি পুনর্ব্যবহারযোগ্য ভিউয়ের অভ্যন্তরীণ চিত্র দর্শনে প্রসঙ্গ মেনুর জন্য আমার ঠিক কী প্রয়োজন ছিল
থেমস

4
যে কেউ এখন এটি দেখার জন্য, এটি কেবলমাত্র 23 এবং উপরের এপিআই-তে কাজ করে।
SWoo

16

প্রভাকর উত্তরটি সঠিক, তবে প্রসঙ্গ মেনু আইটেমটি নির্বাচন করা হলে, চাপযুক্ত আইটেমের সাথে সম্পর্কিত কীভাবে একটি ডেটা পাবেন তা তিনি ব্যাখ্যা করেননি। আমরা onContextItemSelectedকলব্যাক ব্যবহার করতে পারি , তবে এই ক্ষেত্রে () পদ্ধতিটি যদি চাপিত দর্শনের জন্য ওভাররাইড না করা হয় ) ContextMenuInfoউপলভ্য নয়। সুতরাং, সহজ সমাধানটি হ'ল সরাসরি যুক্ত করা ।nullgetContextMenuInfo()OnMenuItemClickListenerMenuItem

private class ViewHolder extends RecyclerView.ViewHolder {
    private final TextView mTitleTextView;
    private MyItemData mData;

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

        mTitleTextView = (TextView)view.findViewById(R.id.title);

        view.setOnCreateContextMenuListener(mOnCreateContextMenuListener);
    }

    public void bind(@NonNull MyItemData data) {
         mData = data;

         String title = mData.getTitle();
         mTitleTextView.setText(title);
    }

    private final View.OnCreateContextMenuListener mOnCreateContextMenuListener = new View.OnCreateContextMenuListener() {
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            if (mData!= null) {
                MenuItem myActionItem = menu.add("My Context Action");
                myActionItem.setOnMenuItemClickListener(mOnMyActionClickListener);
            }
        }
    };

    private final MenuItem.OnMenuItemClickListener mOnMyActionClickListener = new MenuItem.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            //todo: process item click, mData is available here!!!
            return true;
        }
    };
}

4
আপনার কোড স্নিপেট কী করে এবং কীভাবে তা স্পষ্টভাবে ব্যাখ্যা করুন। কেবলমাত্র একটি অনুলিপি-পেস্ট করা কোডই যথেষ্ট নয়, এমনকি এটি মূল্যবান হলেও।
পিটারহ - মনিকা পুনরায় ইনস্টল করুন

এটি RecyclerViewকেবলমাত্র ওভাররাইড getContextMenuInfoইত্যাদির কাস্টম সাবক্লাসগুলি তৈরি করতে না চাইলে এটি একটি যুক্তিসঙ্গত আপস হিসাবে প্রতীয়মান হবে, এমনকি যদি এটি খণ্ড / ক্রিয়াকলাপের হ্যান্ডেল ক্লিকগুলি ভাগ করার মতো যথেষ্ট দক্ষ না হয়। শ্রোতাদের ধারকের ডেটাতে অ্যাক্সেস থাকবে, সুতরাং আপনার অবস্থানের দরকার হবে না। এবং তাত্ত্বিকভাবে আপনি যে কোনও উপায়ে অ্যাডাপ্টারে আবদ্ধ হওয়ার পরে অবস্থানটি ক্যাশে করতে পারেন এবং আপনার হোল্ডারের সাথে ডেকে পাঠাতে প্রতিনিধি ব্যবহার করতে পারেন, যদি আপনাকে অবশ্যই প্রয়োজন, যদিও Contextসীমাবদ্ধ মতামতের একটি থেকে কখনও কখনও ব্যবহার করা যথেষ্ট হতে পারে।
কিউস

10

@ রেনাউদের উত্তরটি আমার পক্ষে কাজ করেছে তবে প্রথমে বেশ কয়েকটি কোড ফিক্স দরকার। এটি তার কোডের বিভিন্ন পৃথক পুনরাবৃত্তি থেকে স্নিপেটগুলি পোস্ট করার মতো। যে পরিবর্তনগুলি করা দরকার তা হ'ল:

  • RecyclerContextMenuInfoএবং RecyclerViewContextMenuInfoএকই বর্গ হয়। একটি নাম বাছাই করুন এবং এটি দিয়ে আটকে দিন।
  • ViewHolderবাস্তবায়ন করতে হবে View.OnLongClickListener, এবং কল মনে রাখবেন setOnLongClickListener()কন্সট্রাকটর মধ্যে আইটেমের উপর।
  • ইন onLongClick()শ্রোতা, getView().showContextMenu()সম্পূর্ণরূপে ভুল। আপনি কল করতে হবে showContextMenuForChild()আপনার ContextMenuRecyclerView, অন্যথায় ContextMenuInfoআপনি পেতে onCreateContextMenu()এবং onContextItemSelected()নাল হতে হবে।

আমার সম্পাদিত কোডটি নীচে:

প্রসঙ্গমেনুআরসিক্রারভিউ:

public class ContextMenuRecyclerView extends RecyclerView {

    private RecyclerViewContextMenuInfo mContextMenuInfo;

    @Override
    protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
        return mContextMenuInfo;
    }

    @Override
    public boolean showContextMenuForChild(View originalView) {
        final int longPressPosition = getChildPosition(originalView);
        if (longPressPosition >= 0) {
            final long longPressId = getAdapter().getItemId(longPressPosition);
                mContextMenuInfo = new RecyclerViewContextMenuInfo(longPressPosition, longPressId);
            return super.showContextMenuForChild(originalView);
        }
        return false;
    }

    public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {

        public RecyclerViewContextMenuInfo(int position, long id) {
            this.position = position;
            this.id = id;
        }

        final public int position;
        final public long id;
    }
}

আপনার খণ্ডে:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mRecyclerView = view.findViewById(R.id.recyclerview);
    registerForContextMenu(mRecyclerView);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    // inflate menu here
    // If you want the position of the item for which we're creating the context menu (perhaps to add a header or something):
    int itemIndex = ((ContextMenuRecyclerView.RecyclerViewContextMenuInfo) menuInfo).position;
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    ContextMenuRecyclerView.RecyclerViewContextMenuInfo info = (ContextMenuRecyclerView.RecyclerViewContextMenuInfo) item.getMenuInfo();
    // handle menu here - get item index or ID from info
    return super.onContextItemSelected(item);
}

আপনার ভিউহোল্ডারটিতে:

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener {

    public MyViewHolder( View itemView ) {
        super( itemView );
        itemView.setOnLongClickListener( this );
    }

    @Override public boolean onLongClick() {
        recyclerView.showContextMenuForChild( v );
        return true;
    }
}

এছাড়াও, নিশ্চিত করুন যে আপনি প্রতিস্থাপন করতে RecyclerViewসঙ্গে ContextMenuRecyclerViewআপনার লেআউট রয়েছে!


4
আমাকে টাইপস ইশারা জন্য ধন্যবাদ @ josh2112, আমি শুধু তাদের সংশোধন - কিন্তু আপনার শেষ বিন্দু সংক্রান্ত, আপনি প্রতিস্থাপন করতে পারেন recyclerView.showContextMenuForChild(itemView);দ্বারা itemView.showContextMenu()
রেনেউদ সেরাতো

4
গুরুত্বপূর্ণটিও: কনটেক্সটমেনুরিসাইক্লারভিউতে রিসাইক্লারভিউটি প্রসারিত করার সময়, আইডিইর পরামর্শদাতাদের সংযোজন করতে ভুলবেন না। বিশেষত, আপনি যদি কনটেক্সট এবং অ্যাট্রিবিউটসেট গ্রহণ করে এমন দ্বি-যুক্তিযুক্ত নির্মাণকারীর প্রয়োগ না করেন, অ্যান্ড্রয়েড আপনার লেআউট এক্সএমএল স্ফীত করতে সক্ষম হবে না।
lidkxx

7

পুনর্ব্যবহারযোগ্য আইটেমগুলিতে মেনু প্রসঙ্গটি ব্যবহার করার জন্য এখানে একটি পরিষ্কার উপায়

প্রথমত, আপনার একটি আইটেমের অবস্থান প্রয়োজন

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

 /**
 * Custom on long click item listener.
 */
onLongItemClickListener mOnLongItemClickListener;

public void setOnLongItemClickListener(onLongItemClickListener onLongItemClickListener) {
    mOnLongItemClickListener = onLongItemClickListener;
}

public interface onLongItemClickListener {
    void ItemLongClicked(View v, int position);
}

onBindViewHolderকাস্টম শ্রোতা হুক ইন :

        // Hook our custom on long click item listener to the item view.
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (mOnLongItemClickListener != null) {
                    mOnLongItemClickListener.ItemLongClicked(v, position);
                }

                return true;
            }
        });

মেইনএ্যাকটিভিটিতে (ক্রিয়াকলাপ / খণ্ড খণ্ড) একটি ক্ষেত্র তৈরি করুন:

private int mCurrentItemPosition;

আপনার অ্যাডাপ্টার অবজেক্টে কাস্টম শ্রোতা সেট করুন:

    mAdapter.setOnLongItemClickListener(new FileAdapter.onLongItemClickListener() {
        @Override
        public void ItemLongClicked(View v, int position) {
            mCurrentItemPosition = position;
        }
    });

আপনি যে কোনও আইটেমটিতে দীর্ঘকাল ক্লিক করেছেন তার জন্য এখন আপনার মুখরোচক অবস্থান 😋 😋

দ্বিতীয়ত, আপনার মেনু তৈরি করুন

পুনরায় -> মেনুতে আপনার মেনু আইটেমটি সংযুক্ত করে একটি ফাইল তৈরি করুন context_menu_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/delete" android:title="Delete"/>
<item android:id="@+id/share" android:title="Share"/>
</menu>

মেইনএ্যাকটিভিটিতে:onCreateContextMenu এবং উভয়ই প্রয়োগ করুন onContextItemSelected:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context_menu_main, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.delete) {

    }

    if (id == R.id.share) {

    }

    return true;
}

তৃতীয়ত, আপনার অ্যাডাপ্টার অবজেক্টে ফিরে আসুন

  1. আপনার প্রসঙ্গ মেনু নিবন্ধন করুন।
  2. প্রসঙ্গ মেনু প্রদর্শন করুন।

    registerForContextMenu(mRecyclerView);
    mAdapter.setOnLongItemClickListener(new FileAdapter.onLongItemClickListener() {
        @Override
        public void ItemLongClicked(View v, int position) {
            mCurrentItemPosition = position;
            v.showContextMenu();
        }
    });
    

আশা করি আমি কিছু ভুলে যাব না 🤔

মেনু ডকুমেন্টেশনে আরও তথ্য


ধন্যবাদ! প্রসঙ্গ মেনুতে কীভাবে ডেটা পাস করবেন? উদাহরণস্বরূপ, আইটেম আইডি, আইটেম পাঠ্য এবং আরও অনেক কিছু।
শীতলমান্ড

4

আমার পক্ষে কাজ করা কোটলিনের সাথে এটি করার একটি সহজ উপায়। বড় চ্যালেঞ্জটি হ'ল চাপ দেওয়া আইটেমটির অবস্থান নির্ধারণ করা। আপনার অ্যাডাপ্টারের অভ্যন্তরে, আপনি এই কোড স্নিপেট রাখতে পারেন এবং এটি আইটেমের অবস্থানটি ক্যাপচার করতে সক্ষম হবে যার জন্য প্রসঙ্গ মেনু প্রদর্শিত হবে; এখানেই শেষ.

override fun onBindViewHolder(holder: YourViewHolder, position: Int) {

...     

    holder.view.setOnCreateContextMenuListener { contextMenu, _, _ -> 
            contextMenu.add("Add").setOnMenuItemClickListener {
                    longToast("I'm pressed for the item at position => $position")
                    true    
            }       
    }       

} 

4
এটি করার সবচেয়ে প্রাকৃতিক এবং নিয়ন্ত্রনযোগ্য উপায়
নিমা

3

আমি হয়ত পার্টিতে দেরি করেছি তবে আমার একটা কার্যকরী সমাধান রয়েছে । আমি এটির জন্য একটি বাক্য তৈরি করেছি।

পুনর্ব্যবহারযোগ্য ভিউতে প্রসঙ্গ মেনু যুক্ত করুন

ক্রিয়াকলাপ নাম.জভা

//Import Statements

public class ActivityName extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_birthdays);


        //Recycle View
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        mLayoutManager = new LinearLayoutManager(getApplicationContext());
        mRecyclerView.setLayoutManager(mLayoutManager);
        mAdapter = new BirthdaysListAdapter(data, this);
        mRecyclerView.setAdapter(mAdapter);


    }

রিসাইক্লারএডাপ্টার.জভা

//Import Statements


public class BirthdaysListAdapter extends RecyclerView.Adapter<BirthdaysListAdapter.ViewHolder> {
    static Context ctx;

    private List<typeOfData> Data;


    public BirthdaysListAdapter(List<typeOfData> list, Context context) {
        Data = list;
        this.ctx = context;

    }

    BirthdaysListAdapter() {
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener {
        public TextView name;
        public TextView Birthday;
        public ImageView colorAlphabet;
        public TextView textInImg;


        public ViewHolder(View v) {
            super(v);
            name = (TextView) v.findViewById(R.id.name);
            Birthday = (TextView) v.findViewById(R.id.Birthday);
            colorAlphabet = (ImageView) v.findViewById(R.id.colorAlphabet);
            textInImg = (TextView) v.findViewById(R.id.textInImg);


            v.setOnCreateContextMenuListener(this); //REGISTER ONCREATE MENU LISTENER
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v                         //CREATE MENU BY THIS METHOD
                                        ContextMenu.ContextMenuInfo menuInfo) {
            new BirthdaysListAdapter().info = (AdapterView.AdapterContextMenuInfo) menuInfo;
            MenuItem Edit = menu.add(Menu.NONE, 1, 1, "Edit");
            MenuItem Delete = menu.add(Menu.NONE, 2, 2, "Delete");
            Edit.setOnMenuItemClickListener(onEditMenu);
            Delete.setOnMenuItemClickListener(onEditMenu);


        }
//ADD AN ONMENUITEM LISTENER TO EXECUTE COMMANDS ONCLICK OF CONTEXT MENU TASK
        private final MenuItem.OnMenuItemClickListener onEditMenu = new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {


                DBHandler dbHandler = new DBHandler(ctx);
                List<WishMen> data = dbHandler.getWishmen();

                switch (item.getItemId()) {
                    case 1:
                        //Do stuff
                        break;

                    case 2:
                       //Do stuff

                        break;
                }
                return true;
            }
        };


    }


    public List<ViewBirthdayModel> getData() {
        return Data;
    }


    @Override
    public long getItemId(int position) {

        return super.getItemId(position);
    }


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

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.name.setText(Data.get(position).getMan().getName());
        holder.Birthday.setText(Data.get(position).getMan().getBday());
        holder.colorAlphabet.setBackgroundColor(Color.parseColor(Data.get(position).getColor()));
        holder.textInImg.setText(String.valueOf(Data.get(position).getMan().getName().toUpperCase().charAt(0)));
           }


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

    private int position;

    public int getPosition() {

        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }

}

3

আমি আমার সমাধানটি @ হার্দিক শাহের সমাধানের সাথে একত্রিত করেছি:

আমার ক্রিয়াকলাপে:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    if (v.getId() == R.id.rvQuests) {
        getMenuInflater().inflate(R.menu.list_menu, menu);
    }
}

অ্যাডাপ্টারে আমার আছে:

private MainActivity context;
private int position;

public int getPosition() {
    return position;
}

public void setPosition(int position) {
    this.position = position;
}

public QuestsAdapter(MainActivity context, List<Quest> objects) {
    this.context = context;
    this.quests.addAll(objects);
}

public class QuestViewHolder extends RecyclerView.ViewHolder {
    private QuestItemBinding questItemBinding;

    public QuestViewHolder(View v) {
        super(v);
        questItemBinding = DataBindingUtil.bind(v);
        v.setOnCreateContextMenuListener(context);
    }
}

@Override
public void onBindViewHolder(final QuestViewHolder holder, int position) {
    Quest quest = quests.get(position);
    holder.questItemBinding.setQuest(quest);
    holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            setPosition(holder.getAdapterPosition());
            return false;
        }
    });
}

@Override
public void onViewRecycled(QuestViewHolder holder) {
    holder.itemView.setOnLongClickListener(null);
    super.onViewRecycled(holder);
}

খণ্ডে আমার আছে:

@Override
public boolean onContextItemSelected(MenuItem item) {
    int position = ((QuestsAdapter) questsList.getAdapter()).getPosition();
    switch (item.getItemId()) {
        case R.id.menu_delete:
            Quest quest = questsAdapter.getItem(position);
            App.getQuestManager().deleteQuest(quest);
            questsAdapter.remove(quest);
            checkEmptyList();
            return true;
        default:
            return super.onContextItemSelected(item);
    }
}

2

যারা কল করার সময় আইটেম আইডি পেতে চান তাদের জন্য একটি সমাধান ContextMenu

আপনার যদি RecyclerViewএই জাতীয় আইটেমগুলির সাথে থাকে (ক্লিকযোগ্য এমন ImageView):

তালিকা

তাহলে আপনার কাছ থেকে কলব্যাকগুলি গ্রহণ করা উচিত onClickListener

অ্যাডাপ্টার

class YourAdapter(private val contextMenuCallback: ContextMenuCallback) :
    RecyclerView.Adapter<YourAdapter.ViewHolder>() {

    private var items: MutableList<Item> = mutableListOf()

    ...

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        val item = items[position] as Item
        updateItem(viewHolder, item)

        setOnClickListener(viewHolder.itemView, items[position].id, items[position].title)
    }

    private fun setOnClickListener(view: View, id: Int, title: String) {
//        view.setOnClickListener { v ->  }
        // A click listener for ImageView `more`.
        view.more.setOnClickListener {
            // Here we pass item id, title, etc. to Fragment.
            contextMenuCallback.onContextMenuClick(view, id, title)
        }
    }


    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val titleTextView: TextView = itemView.title
    }

    class Item(
        val id: Int,
        val title: String
    )

    interface ContextMenuCallback {
        fun onContextMenuClick(view: View, id: Int, title: String)
    }
}

টুকরা

class YourFragment : Fragment(), YourAdapter.ContextMenuCallback {

    private var adapter: YourAdapter? = null
    private var linearLayoutManager: LinearLayoutManager? = null
    private var selectedItemId: Int = -1
    private lateinit var selectedItemTitle: String


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        adapter = YourAdapter(this)
        view.recycler_view.apply {
            layoutManager = linearLayoutManager
            adapter = this@YourFragment.adapter
            setHasFixedSize(true)
        }

        registerForContextMenu(view.recycler_view)
    }

    override fun onCreateContextMenu(menu: ContextMenu?, v: View?,
                                     menuInfo: ContextMenu.ContextMenuInfo?) {
        activity?.menuInflater?.inflate(R.menu.menu_yours, menu)
    }

    override fun onContextItemSelected(item: MenuItem?): Boolean {
        super.onContextItemSelected(item)
        when (item?.itemId) {
            R.id.action_your -> yourAction(selectedItemId, selectedItemTitle)
            ...
        }
        return true
    }

    override fun onContextMenuClick(view: View, id: Int, title: String) {
        // Here we accept item id, title from adapter and show context menu.
        selectedItemId = id
        selectedItemTitle = title
        view.showContextMenu()
    }
}

সতর্কতা!

আপনি যদি একটি ViewPagerখণ্ডের উপর ভিত্তি করে ব্যবহার করেন (সমস্ত পৃষ্ঠাগুলির অনুরূপ তালিকাগুলি), আপনি সমস্যার মুখোমুখি হবেন। onContextItemSelectedকোন মেনু আইটেমটি নির্বাচিত হয়েছে তা বোঝার জন্য আপনি যখন ওভাররাইড করবেন, আপনি প্রথম পৃষ্ঠা থেকে একটি তালিকা আইটেম আইডি পাবেন! এই সমস্যাটি কাটিয়ে উঠতে দেখুন ভিউপাগারে থাকা ভুল খণ্ডটি কনটেক্সট আইটেমসিলিটেড কলটি গ্রহণ করে


1

হ্যালো ছেলেরা এমন একটি বিকল্প নিয়ে এসেছিল যা আমার পক্ষে কার্যকর। আমি কেবলমাত্র আমার আইটেম ভিউটি রেজিস্টারকন্টেক্সটেমেনু y ভিউহোল্ডার কনস্ট্রাক্টরের সাথে নিবন্ধভুক্ত করেছি, একই ভিউতে একটি অন লং ক্লিক্কলিস্টনার সেটও করেছি set অনলংকলিক (ভি ভি) বাস্তবায়নে, আমি সহজভাবে getLayoutP पोজিশন () দিয়ে ক্লিক করা অবস্থানটি পাই এবং একটি উদাহরণ পরিবর্তনশীলে সংরক্ষণ করি (কনটেক্সটমেনুআইএনফোর যেমন কাজ করার আশা করা হয় ঠিক তেমনই আমি এই ডেটা উপস্থাপনের জন্য একটি শ্রেণি তৈরি করেছি), তবে আরও গুরুত্বপূর্ণটি তৈরি করা হয় নিশ্চিত যে আপনি এই পদ্ধতিতে মিথ্যা ফিরে । এখন আপনাকে যা করতে হবে তা অনকন্টেক্সটেমটিলেটেড (মেনু আইটেম আইটেম) এ রয়েছে, আপনি আপনার দৃষ্টান্ত পরিবর্তনশীলে যে ডেটা সংরক্ষণ করেন তা পড়ুন এবং যদি তা বৈধ হয় তবে আপনি আপনার ক্রিয়াকলাপ দিয়ে এগিয়ে যান proceed এখানে এটি একটি স্নিপেট।

  public MyViewHolder(View itemView){
super(itemView);
registerForContextMenu(itemView);
itemView.setOnLongClickListener(this);
}

আমি ভিউহোল্ডারটি অনলং ক্লিকলিস্টনার প্রয়োগ করে, তবে আপনি এটি যে কোনও উপায়ে পছন্দ করতে পারেন।

@Override
public boolean onLongClick(View v){
    mCurrentLongItem = new ListItemInfo(v.getId(), getLayoutPosition());
    return false; // REMEMBER TO RETURN FALSE.
  }

আপনি এটি অ্যাডাপ্টারে বা ভিউহোল্ডারটিতে (যেমন একটি টেক্সটভিউ) অন্য কোনও ভিউতেও সেট করতে পারেন। গুরুত্বপূর্ণ হ'ল অনলংকলিক () বাস্তবায়ন।

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.client_edit_context_menu:
            if(mCurrentLongItem != null){
                 int position = mCurrentLongItem.position;
                //TAKE SOME ACTIONS.
                mCurrentLongItem = null;
            }
            return true;
    }
    return super.onContextItemSelected(item);
}

সর্বোত্তম অংশটি হ'ল আপনি এখনও লংক্লিক ইভেন্টটি যেটি চান তার ক্ষেত্রে সত্য হয়ে ফিরে প্রক্রিয়াকরণ করতে পারেন এবং কনটেক্সেমেনু প্রদর্শন করবে না।

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


1

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

public class CUSTOMVIEWNAME extends RecyclerView { 

public CUSTOMVIEWNAME(Context context) {
    super(context);
}

public CUSTOMVIEWNAME (Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CUSTOMVIEWNAME (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

private RecyclerContextMenuInfo mContextMenuInfo;

@Override
protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
    return mContextMenuInfo;
}

@Override
public boolean showContextMenuForChild(View originalView) {
    final int longPressPosition = getChildAdapterPosition(originalView);
    if (longPressPosition >= 0) {
        final long longPressId = getAdapter().getItemId(longPressPosition);
        mContextMenuInfo = new RecyclerContextMenuInfo(longPressPosition,    `           longPressId);
        return super.showContextMenuForChild(originalView);
    }
    return false;
}

public class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo             {

    public RecyclerContextMenuInfo(int position, long id) {
        this.position = position;
        this.id = id;
    }

    final public int position;
    final public long id;
}
}

এখন আপনার খণ্ড বা ক্রিয়াকলাপে নিম্নলিখিত পদ্ধতিগুলি প্রয়োগ করুন।

  @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);

    // Inflate Menu from xml resource
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.context_menu, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    ContextMenuRecyclerView.RecyclerContextMenuInfo info = (ContextMenuRecyclerView.RecyclerContextMenuInfo) item.getMenuInfo();
    Toast.makeText(InstanceOfContext , " User selected  " + info.position, Toast.LENGTH_LONG).show();

    return false;
}

অবশেষে পুনর্ব্যবহারযোগ্য প্রসঙ্গে মেনু প্রসঙ্গে নিবন্ধন করুন

   //for showing a popup on LongClick of items in recycler.
    registerForContextMenu(recyclerView);

কাজ করা উচিত!


1

এখানে আপনি কীভাবে পুনর্ব্যবহারযোগ্য ভিউয়ের জন্য প্রসঙ্গ মেনু বাস্তবায়িত করতে এবং আইটেমের অবস্থান পেতে পারেন, যার জন্য প্রসঙ্গ মেনু আইটেমটি নির্বাচন করা হয়েছে:

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

... 

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

    ...

    viewHolder.itemView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            menu.add(0, R.id.mi_context_disable, 0, R.string.text_disable)
                    .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {
                            // can do something with item at position given below,
                            // viewHolder is final
                            viewHolder.getAdapterPosition();
                            return true;
                        }
                    });
            menu.add(0, R.id.mi_context_remove, 1, R.string.text_remove)
                    .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {                                
                            // can do something with item at position given below,
                            // viewHolder is final
                            viewHolder.getAdapterPosition();
                            return true;
                        }
                    });
        }
    });
}

static class ViewHolder extends RecyclerView.ViewHolder {
    private View itemView;

    private ViewHolder(@NonNull View itemView) {
        super(itemView);
        this.itemView = itemView;
    }
}

}


0

আমি এ নিয়ে লড়াই করে চলেছি কারণ অ্যান্ড্রয়েড আমার জন্য রিসাইক্লার ভিউতে এটি সুন্দরভাবে পরিচালনা করে না, যা লিস্টভিউয়ের পক্ষে খুব ভালভাবে কাজ করে।

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

সুতরাং আপনার একটি মোড়কের দরকার হবে যা আপনাকে কার্যকলাপের তথ্য সম্পর্কিত তথ্য সরবরাহ করতে সহায়তা করে।

public class RecyclerContextMenuInfoWrapperView extends FrameLayout {
private RecyclerView.ViewHolder mHolder;
private final View mView;

public RecyclerContextMenuInfoWrapperView(View view) {
    super(view.getContext());
    setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    mView = view;
    addView(mView);
}

public void setHolder(RecyclerView.ViewHolder holder) {
    mHolder = holder;
}

@Override
protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
    return new RecyclerContextMenuInfo(mHolder.getPosition(), mHolder.getItemId());
}

public static class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo {

    public RecyclerContextMenuInfo(int position, long id) {
        this.position = position;
        this.id = id;
    }

    final public int position;
    final public long id;
}

}

তারপরে আপনার রিসাইক্লার অ্যাডাপ্টারে, আপনি ভিউহোল্ডারগুলি তৈরি করার সময়, আপনাকে র্যাপারকে মূল দৃশ্য হিসাবে সেট করতে হবে এবং প্রতিটি দৃশ্যে প্রসঙ্গমেনু নিবন্ধভুক্ত করতে হবে।

public static class AdapterViewHolder extends RecyclerView.ViewHolder {
    public AdapterViewHolder(  View originalView) {
        super(new RecyclerContextMenuInfoWrapperView(originalView);
        ((RecyclerContextMenuInfoWrapperView)itemView).setHolder(this);
        yourActivity.registerForContextMenu(itemView);
        itemView.setOnCreateContextMenuListener(yourListener);
    }

}

এবং সর্বশেষে, আপনার ক্রিয়াকলাপে আপনি সাধারণত যা করেন তা করতে সক্ষম হবেন:

@Override
public boolean onContextItemSelected(MenuItem item) {
    int position = ((RecyclerContextMenuInfoWrapperView.RecyclerContextMenuInfo)item.getMenuInfo()).position;
    // do whatever you need as now you have access to position and id and everything

0

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

@Override
protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
    return mContextMenuInfo;
}

আমি তৈরি এই টুকরো একবার দেখুন:

https://gist.github.com/resengapt/2b2e26c949b28f8973e5


0

কিছুটা উপরে উপরে কিছু উত্তর প্রসারিত করা, আপনি যদি অ্যাডাপ্টার / ভিউহোল্ডারটিতে আপনার কোডের মেনুটিকে ম্যানুয়ালি সংজ্ঞা দিতে এড়াতে চান তবে আপনি একটি পপআপমেনু ব্যবহার করতে পারেন এবং মানক মেনু.এক্সএমএল রিসোর্স ফাইল থেকে মেনু বিকল্পগুলি স্ফীত করতে পারেন।

নীচের উদাহরণগুলির মধ্যে শ্রোতার মধ্যে পাস করার ক্ষমতা সহ এটি দেখায় যা আপনি প্রসঙ্গ মেনু ক্লিকগুলিতে প্রতিক্রিয়া জানানোর জন্য আপনার খণ্ড / ক্রিয়াকলাপে প্রয়োগ করতে পারেন।

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

private List<CustomObject> objects;
private OnItemSelectedListener listener;
private final boolean withContextMenu;

class ViewHolder extends RecyclerView.ViewHolder
        implements View.OnClickListener, View.OnCreateContextMenuListener, PopupMenu.OnMenuItemClickListener {

    @BindView(R.id.custom_name)
    TextView name;

    @BindView(R.id.custom_value)
    TextView value;

    ViewHolder(View view) {
        super(view);
        ButterKnife.bind(this, view);
        view.setOnClickListener(this);
        if (withContextMenu) {
            view.setOnCreateContextMenuListener(this);
        }
    }

    @Override
    public void onClick(View v) {
        int position = getAdapterPosition();
        if (listener != null) {
            listener.onCustomerSelected(objects.get(position));
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        PopupMenu popup = new PopupMenu(v.getContext(), v);
        popup.getMenuInflater().inflate(R.menu.custom_menu, popup.getMenu());
        popup.setOnMenuItemClickListener(this);
        popup.show();
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        if (listener != null) {
            CustomObject object = objects.get(getAdapterPosition());
            listener.onCustomerMenuAction(object, item);
        }
        return false;
    }
}

public CustomerAdapter(List<CustomObject> objects, OnItemSelectedListener listener, boolean withContextMenu) {
    this.listener = listener;
    this.objects = objects;
    this.withContextMenu = withContextMenu;
}

public interface OnItemSelectedListener {

    void onSelected(CustomObject object);

    void onMenuAction(CustomObject object, MenuItem item);
}

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

@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
    CustomObject object = objects.get(position);
    holder.name.setText(object.getName());
    holder.value.setText(object.getValue());
}

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

এখানে সম্পূর্ণ বক্তব্য https://gist.github.com/brettwold/45039b7f02ce752ae0d32522a8e2ad9c


0

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

     public static class ItemViewHolder extends RecyclerView.ViewHolder
     {


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


        }
        void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) {
            itemView.setOnCreateContextMenuListener(listener);
        }

}

অ্যাডাপ্টারে:

      @Override
     public void onBindViewHolder(ItemViewHolder viewHolder,
                    int position) {
         final MyObject myObject = mData.get(position);
         viewHolder.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){

                    @Override
                    public void onCreateContextMenu(ContextMenu menu,
                            View v, ContextMenuInfo menuInfo) {
                        switch (myObject.getMenuVariant() {
                            case MNU_VARIANT_1:
                                menu.add(Menu.NONE, CTX_MNU_1, 
                                        Menu.NONE,R.string.ctx_menu_item_1);    
                                menu.add(Menu.NONE, CTX_MNU_2,Menu.NONE, R.string.ctx_menu_item_2); 
                            break;
                            case MNU_VARIANT_2:
                                menu.add(Menu.NONE, CTX_MNU_3,Menu.NONE, R.string.ctx_menu_item_3); 
                            break;
                            default:
                                menu.add(Menu.NONE, CTX_MNU_4, 
                                        Menu.NONE, R.string.ctx_menu_item_4);   

                        }
                    }

                });
     }

0

আমার ক্ষেত্রে onContextItemSelected()পদ্ধতিতে আমার খণ্ড থেকে ডেটা ব্যবহার করতে হয়েছিল । যে সমাধানটির সাথে আমি শেষ করেছিলাম তা হ'ল আমার অ্যাডাপ্টারে টুকরোটির একটি উদাহরণ পাস করা এবং ভিউ ধারকটিতে ভিউ আইটেমটি নিবন্ধ করা:

@Override
public void onBindViewHolder(final MyListAdapter.ViewHolder viewHolder, int position) {
    final Object rowObject = myListItems.get(position);

    // Do your data binding here

    viewHolder.itemView.setTag(position);
    fragment.registerForContextMenu(viewHolder.itemView);
}

তারপরে আপনি onCreateContextMenu()স্থানীয় ভেরিয়েবলে সূচকটি সংরক্ষণ করতে পারেন:

selectedViewIndex = (int)v.getTag();

এবং এটি পুনরুদ্ধার onContextItemSelected()


0

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

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

/**
 * Interface for objects that wish to create and handle selections from a context
 * menu associated with a view
 */
public interface ContextMenuHandler extends View.OnCreateContextMenuListener {

  boolean onContextItemSelected(MenuItem item);
}

এরপরে একটি ইন্টারফেস যা কোনও রিসাইক্লার ভিউয়ের তাত্ক্ষণিক শিশু হিসাবে ব্যবহৃত হতে পারে এমন কোনও ভিউ দ্বারা প্রয়োগ করা উচিত।

public interface ViewWithContextMenu {
  public void setContextMenuHandler(FragmentWithContextMenu fragment, ContextMenuHandler handler);

  public ContextMenuHandler getContextMenuHandler();
}

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

public class LinearLayoutWithContextMenu extends LinearLayout implements ViewWithContextMenu {

  public LinearLayoutWithContextMenu(Context context) {
    super(context);
   }

  public LinearLayoutWithContextMenu(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  private ContextMenuHandler handler;

  @Override
  public void setContextMenuHandler(FragmentWithContextMenu fragment, ContextMenuHandler handler) {
    this.handler = handler;
    setOnCreateContextMenuListener(fragment);
  }

  @Override
  public ContextMenuHandler getContextMenuHandler() {
    return handler;
  }
}

এবং পরিশেষে, প্রসঙ্গ মেনু কলগুলিতে বাধা দিতে এবং সেগুলি যথাযথ হ্যান্ডলারের দিকে পুনর্নির্দেশ করতে আমাদের একটি স্যুপ আপ ফ্র্যাগমেন্ট ক্লাস প্রয়োজন।

public class FragmentWithContextMenu extends Fragment {

  ContextMenuHandler handler = null;

  @Override
  public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, view, menuInfo);
    handler = null;
    if (view instanceof ViewWithContextMenu) {
      handler = ((ViewWithContextMenu)view).getContextMenuHandler();
      if (handler != null) handler.onCreateContextMenu(menu, view, menuInfo);
    }
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    if (handler != null) {
      if (handler.onContextItemSelected(item)) return true;
    }
    return super.onContextItemSelected(item);
  }
}

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

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

  private final FragmentWithContextMenu fragment;

  Adapter(FragmentWithContextMenu fragment) {
    this.fragment = fragment;
  }

  @Override
  public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(context)
        .inflate(R.layout.child_view, parent, false);
    return new ViewHolder(view);
  }

  @Override
  public void onBindViewHolder(final Adapter.ViewHolder holder, int position) {
    // Logic needed to bind holder to specific position
    // ......
  }

  @Override
  public int getItemCount() {
    // Logic to return current item count
    // ....
  }

  public class ViewHolder extends RecyclerView.ViewHolder implements ContextMenuHandler {

    ViewHolder(View view) {
      super(view);
      ((ViewWithContextMenu)view).setContextMenuHandler(fragment, this);

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

          // Do stuff to handle simple clicks on child views
          // .......
        }
      });
    }

   @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {

      // Logic to set up context menu goes here
      // .... 
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {

      // Logic to handle context menu item selections goes here
      // ....

      return true;
    }
  }
}

এটা সম্বন্ধে. এটি সব কাজ করছে বলে মনে হচ্ছে। এটি সমস্ত ইউটিলিটি ক্লাসগুলিকে একটি পৃথক প্রসঙ্গমেনু প্যাকেজে রেখেছিল যাতে আমি ক্লাসের নামগুলি দিতে পারতাম যেগুলি সেখানে সাবক্লাসিংয়ের ক্লাসগুলির সাথে মেলে, তবে আমি ভেবেছিলাম আরও বিভ্রান্তিকর হবে।


-1

ঠিক আছে, @ ফ্লেক্সোর উত্তর থেকে ভিত্তিক, আমি অর্ডার করার জন্য এমপজিশন রাখব ...

protected class ExampleViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener {

    int mPosition;

    public KWViewHolder(View itemView) {
        super(itemView);
        itemView.setOnCreateContextMenuListener(this);
    }

    public void setPosition(int position) {
        mPosition = position;
    }

    @Override
    public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
        contextMenu.setHeaderTitle(R.string.menu_title_context);
        contextMenu.add(0, R.id.menu_delete, mPosition, R.string.delete);
    }
}

তারপরে অনকন্টেক্সটায় আইটেম নির্বাচন করা আমি ব্যবহার করি

item.getOrder() 

এবং সমস্ত কাজ ঠিকঠাক আমি অ্যারের অবস্থান সহজেই পাই get

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.