RecyclerView의 컨텍스트 메뉴를 만드는 방법


97

RecyclerView?분명히 전화 registerForContextMenu(recyclerView)가 작동하지 않는 상황에 맞는 메뉴를 구현하는 방법 . 나는 그것을 조각에서 부르고있다. 아무도 이것을 구현하는 데 성공 했습니까?


나는 같은 배에있다. AdapterContextMenuInfo를 사용하여 다양한 ListView appraoches를 시도했지만 info.position을 가져올 수 없음
RoundSparrow hilltx

컨텍스트 메뉴의 시대는 끝났다고 생각합니다.
Binoy Babu 2014

4
이봐-나는 그것을 작동했다;) refeerence : stackoverflow.com/questions/2321332/…- 나를위한 ViewHolder는 onClick 리스너입니다-나는 또한 그것을 OnCreateContextMenuListener로 만들었습니다. 이 모든 것의 핵심은 한 번에 하나의 메뉴 만 열 수 있다는 것을 깨달았다는 것입니다. 따라서 어댑터는 메뉴를 클릭 한 마지막 RecyclerView 목록 항목을 알려주는 int 만 있으면됩니다. 그런 다음 Fragment / Activity는 실제 메뉴 항목을 클릭하면 어댑터에 문의하십시오.
RoundSparrow hilltx 2014 년

답변:


92

RecycleView는 android.view.ViewGroup을 확장 하므로 onClickListener , OnContextMenuListener 등과 같은 메서드를 직접 구현할 수 없습니다 . 따라서 우리는 이러한 방법을 직접 사용할 수 없습니다. ViewHolder 어댑터 클래스 에서 이러한 메서드를 구현할 수 있습니다 . RecycleView에서 컨텍스트 메뉴를 다음과 같이 사용할 수 있습니다.

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하지만 작동하지만 getMenuInfonull을 제공합니다. 그래서, 어떻게 얻을 수 ViewHolder있습니까?
Michael Schmidt

@MichaelSchmidt는 상황에 맞는 메뉴 정보를 구현하는 코드를 보여줄 수 있습니다.
Prabhakar

7
약간의 실험 후 이것도 작동하지 않고 getMenuInfo()null을 반환합니다 onContextItemSelected(). 아마도 그것을 작동시킨 사람들 onCreateContextMenu()이 계층 구조보다 더 높은 뷰에 메소드 를 가지고있을 수 있습니까 ( RecyclerView또는 Fragment)? 작동 할 수 있지만이 질문에 대한 다른 답변으로 이동합니다.
NeilS

3
Prabhakbar 당신은 클릭 한 항목을 얻는 방법을 언급하지 않았습니까?
Benjamin Stürmer

6
당신은 사용할 수 있습니다 menu.add(this.getAdapterPosition(), v.getId(), 0, "Call");에 대한 귀하의 콜백 메소드 시험에서 다음과 item.getGroupId()위치를 얻을 수
JacobPariseau

99

정보와 의견에 감사드립니다. ContextMenu에서 항목 을 달성 할 수있었습니다 Recyclerview.

내가 한 일은 다음과 같습니다.

Fragment의 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에 메소드 추가 :

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);
}

마지막으로 Fragment / Activity 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);
}

1
position = ((BackupRestoreListAdapter) getAdapter ()). getPosition (); -> 오류 얻을 : 방법 대해 getAdapter () 유형에 대해 정의되지 ..., 당신은 대해 getAdapter 방법을 보여줄 수
nguoixanh

1
좋은 제안, 감사합니다. 경미 : viewHolder.getPosition ()은 더 이상 사용되지 않습니다. 개선을위한 조언은 무엇입니까?
tm1701

10
viewHolder.getAdapterPosition () 대신하는 getPosition ()를 사용
사가르 Chavada

2
getAdapter () 오류가 발생하는 경우 RecyclerView에 대한 참조를 저장하여 해결 한 다음 다음과 같이 사용합니다. ((BackupRestoreListAdapter) recyclerView.getAdapter ()). getPosition ();
Kevin Amorim 2016

1
R.id.ctx_menu_remove_backup은 정확히 어디에 있습니까?
akubi

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
}

마지막으로 ViewHolder에서 :

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

ContextMenuRecyclerView에서 구현해야하는 RecyclerView 생성자를 추가하세요. 또한 getChildPosition()이제 더 이상 사용되지 않습니다. getChildAdapterPosition()대신 사용 했습니다.
Juan José Melero Gómez 2015-06-30

1
참고 : 죄송합니다 . 추가하는 것을 잊었습니다. getChildPosition()은에서 더 이상 사용되지 않습니다 com.android.support:recyclerview-v7:22.0.0.
Juan José Melero Gómez 2015-06-30

1
이것은 작동하지 않습니다. RecyclerView.View.ViewHolder에서 getView (). showContextMenu ()에 액세스 할 수 없습니다.
Mulgard 2015-07-25

4
이것은 나를 위해 작동합니다. 하지만 MyViewHolder에 onLongClick ()을 가질 필요는 없습니다. 생성자에서 itemView.setLongClickable (true)을 설정하면 충분합니다. OnLongClickListener가 등록되지 않은 경우 컨텍스트 메뉴가 나타납니다.
alders

2
또한 중요 : RecyclerView를 ContextMenuRecyclerView로 확장하는 동안 IDE에서 제안한 구성자를 추가하는 것을 잊지 마십시오. 특히 Context 및 AttributeSet을 사용하는 두 인수 생성자를 구현하지 않으면 Android가 레이아웃 XML을 확장 할 수 없습니다.
lidkxx

24

ViewrecycleView 의 항목에 대해 시도하십시오.

.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항목 에 대한 설정 데이터와 함께 사용할 수 있습니다.


정확히 내가 재활용 내부보기 이미지보기에 상황에 맞는 메뉴에 필요한 것
Themos

2
지금보고있는 모든 사람은 API 23 이상에서만 작동합니다.
SWoo

16

Prabhakar 대답 은 정확하지만 상황에 맞는 메뉴 항목을 선택할 때 누른 항목과 관련된 데이터를 얻는 방법을 설명하지 않았습니다. onContextItemSelected콜백 을 사용할 수 있지만 이 경우에는 ContextMenuInfo사용할 수 없습니다 ( null) ( getContextMenuInfo()누른보기에 대해 메서드가 재정의되지 않은 경우 ). 그래서, 가장 간단한 해결책은 추가하는 것입니다 OnMenuItemClickListener받는 직접 MenuItem.

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;
        }
    };
}

1
코드 조각의 기능과 방법을 명확하게 설명하십시오. 복사하여 붙여 넣은 코드만으로는 충분하지 않습니다.
peterh-Monica 복원

프래그먼트 / 액티비티가 클릭을 처리하도록하는 것만 큼 효율적이지 않더라도 RecyclerView오버라이드 getContextMenuInfo등 의 사용자 지정 하위 클래스를 생성하지 않으려면 합리적인 절충안으로 보입니다 . 청취자는 홀더의 데이터에 액세스 할 수 있으므로 위치가 필요하지 않습니다. 그리고 이론적으로는 어댑터에 바인딩 할 때 위치를 캐시하고 필요한 경우 위임을 사용하여 홀더를 ​​호출 할 수 있지만 Context바인딩 된 뷰 중 하나를 사용하는 것으로도 충분할 수 있습니다.
qix

10

@Renaud의 대답은 나를 위해 일했지만 먼저 몇 가지 코드 수정이 필요했습니다. 그는 자신의 코드를 여러 번 반복하여 스 니펫을 게시 한 것과 같습니다. 변경해야 할 사항은 다음과 같습니다.

  • RecyclerContextMenuInfoRecyclerViewContextMenuInfo 같은 클래스입니다. 이름을 정하고 그것에 충실하십시오.
  • ViewHolder구현해야 View.OnLongClickListener하고, 전화를 기억 setOnLongClickListener()생성자의 항목.
  • 에서 onLongClick()리스너, getView().showContextMenu()완전히 잘못된 것입니다. 당신은 호출해야 showContextMenuForChild()당신에 ContextMenuRecyclerView그렇지 않으면, ContextMenuInfo당신이 얻을 onCreateContextMenu()onContextItemSelected()null가됩니다.

아래 수정 된 코드 :

ContextMenuRecyclerView :

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);
}

ViewHolder에서 :

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;
    }
}

또한, 당신이 대체 할 RecyclerViewContextMenuRecyclerView레이아웃에!


1
오타 나 지적 josh2112 @ 감사합니다, 나는 그냥 수정 -하지만 당신의 마지막 지점에 대한, 당신은 대체 할 수 있습니다 recyclerView.showContextMenuForChild(itemView);itemView.showContextMenu().
Renaud Cerrato 2015 년

1
또한 중요 : RecyclerView를 ContextMenuRecyclerView로 확장하는 동안 IDE에서 제안한 구성자를 추가하는 것을 잊지 마십시오. 특히 Context 및 AttributeSet을 사용하는 두 인수 생성자를 구현하지 않으면 Android가 레이아웃 XML을 확장 할 수 없습니다.
lidkxx

5

RecyclerView 항목에서 메뉴 컨텍스트를 사용하는 깨끗한 방법은 다음과 같습니다.

먼저 항목 위치가 필요합니다.

어댑터 클래스에서 :

 /**
 * 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;
            }
        });

MainActivity (Activity / Fragment)에서 필드를 만듭니다.

private int mCurrentItemPosition;

Adapter 객체에서 사용자 정의 리스너를 설정합니다.

    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>

MainActivity에서 :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;
}

셋째, Adapter 객체로 돌아가십시오.

  1. 컨텍스트 메뉴를 등록하십시오.
  2. 상황에 맞는 메뉴를 표시합니다.

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

아무것도 잊지 않길 바래 🤔

메뉴 문서 에서 더 많은 정보


감사! 컨텍스트 메뉴에 데이터를 전달하는 방법은 무엇입니까? 예를 들어 항목 ID, 항목 텍스트 등이 있습니다.
CoolMind

4

나를 위해 일한 Kotlin으로 작업을 수행하는 더 간단한 방법이 있습니다. 가장 큰 도전은 눌린 항목의 위치를 ​​파악하는 것입니다. 어댑터 내부에이 코드 조각을 배치하면 상황에 맞는 메뉴가 표시되는 항목의 위치를 ​​캡처 할 수 있습니다. 그게 다야.

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    
            }       
    }       

} 

2
이것은 그 일을 가장 자연스럽고 제어 방법
니마

3

내 솔루션을 @Hardik Shah의 솔루션과 결합했습니다.

활동에서 나는 :

@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

파티에 늦었을 수도 있지만 해결 방법이 있습니다. 있습니다. 나는 그것에 대한 요점을 만들었습니다.

RecyclerView에 컨텍스트 메뉴 추가

ActivityName.java

//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);


    }

RecyclerAdapter.java

//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;
    }

}

1

안녕하세요 여러분, 저에게 맞는 대안이 나왔습니다. 내 itemView를 registerContextMenu y ViewHolder 생성자에 등록하고 onLongClikcListener를 동일한 View로 설정합니다. onLongClick (View v) 구현에서는 getLayoutPosition ()을 사용하여 클릭 한 위치를 가져오고 인스턴스 변수에 저장합니다 (ContextMenuInfo가 작동 할 것으로 예상되는 것처럼이 데이터를 나타내는 클래스를 만들었습니다).하지만 더 중요한 것은 이 메서드에서 false 를 반환해야합니다 . 지금해야 할 일은 onContextItemSelected (MenuItem item)에서 인스턴스 변수에 저장 한 데이터를 읽고 유효하면 작업을 진행하는 것입니다. 여기에 스 니펫이 있습니다.

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

ViewHolder가 OnLongClickListener를 구현하도록 만들었지 만 원하는 방식으로 수행 할 수 있습니다.

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

어댑터 또는 ViewHolder에있는 다른보기 (예 : TextView)에서이를 설정할 수도 있습니다. 중요한 것은 onLongClik () 구현입니다.

@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);
}

가장 좋은 점은 원하는 경우 true를 반환하는 LongClick 이벤트를 처리 할 수 ​​있으며 conextMenu가 표시되지 않는다는 것입니다.

이 메서드는 registerForContextView가 View를 LongClickable로 만들고 ContextMenu를 처리 할 때 시스템이 performLongClick을 호출하여 먼저 onLongClick 구현을 호출하고 false를 반환하면 showContextMenu를 호출하기 때문에 작동합니다.


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;
}

마지막으로 recyclerview에서 contextMenu에 등록하십시오.

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

작동합니다!


1

RecyclerView에 대한 컨텍스트 메뉴를 구현하고 컨텍스트 메뉴 항목이 선택된 항목의 위치를 ​​가져 오는 방법은 다음과 같습니다.

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;
    }
}

}


1

전화 할 때 아이템 ID를 받고 싶은 분들을위한 솔루션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선택한 메뉴 항목을 이해하기 위해 재정의 하면 첫 페이지에서 목록 항목 ID를 받게됩니다! 이 문제를 해결하려면 ViewPager의 잘못된 조각onContextItemSelected 호출을받습니다 .


0

Android가 ListView에서 매우 잘 작동하는 RecyclerView에서 나를 위해 잘 처리하지 않기 때문에 나는 이것에 어려움을 겪고 있습니다.

가장 어려운 부분은 ContextMenuInfo 부분이 뷰에 포함되어 있다는 것입니다. 뷰를 재정의하는 것 외에는 쉽게 연결할 수 없습니다.

따라서 활동에 위치 정보를 전달하는 데 도움이되는 래퍼가 필요합니다.

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;
}

}

그런 다음 RecyclerAdapter에서 ViewHolders를 만들 때 Wrapper를 루트 뷰로 설정하고 각 뷰에 contextMenu를 등록해야합니다.

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/resengupta/2b2e26c949b28f8973e5


0

Adaptor / ViewHolder의 코드에서 메뉴를 수동으로 정의하지 않으려면 위의 일부 답변을 확장하면 PopupMenu를 사용하고 표준 menu.xml 리소스 파일에서 메뉴 옵션을 확장 할 수 있습니다.

아래 예는 컨텍스트 메뉴 클릭에 응답하기 위해 Fragment / Activity에서 구현할 수있는 리스너를 전달하는 기능을 포함하여이를 보여줍니다.

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

바인딩시 OnCreateContextMenuListener를 ViewHolder에 전달할 수 있습니다. 이 리스너는 각 데이터 항목에 대한 사용자 정의 메뉴를 만들 수 있습니다. ViewHolder에 setOnCreateContextMenuListener를 추가하고 바인딩 중에 호출하면됩니다.

     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

일반 어댑터에서 처음으로이 문제가 발생했을 때 사용자 정의 View 하위 클래스를 만들고 필요한 항목을 저장했습니다. 저는 그 솔루션이 정말 마음에 들지 않았고 사람들이 제안한 훌륭한 아이디어를 보는 데 많은 시간을 보냈으며 더 이상 좋아하지 않는다고 결정했습니다. 그래서 저는 모든 것을한데 모아 잠시 흔들고 제가 좋아하는 새로운 것을 나왔습니다.

몇 가지 유틸리티 클래스로 시작합니다. ContextMenuHandler는 컨텍스트 메뉴를 처리 할 객체에 대한 인터페이스입니다. 실제로 이것은 ViewHolder 하위 클래스가 될 것이지만 이론적으로는 거의 모든 것이 될 수 있습니다.

/**
 * 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);
}

다음은 RecyclerView의 직계 자식으로 사용될 모든 View에 의해 구현되어야하는 인터페이스입니다.

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

  public ContextMenuHandler getContextMenuHandler();
}

다음으로, RecylcerView의 자식으로 컨텍스트 메뉴를 만들 모든 뷰는 ViewWIthContextMenu를 구현해야합니다. 제 경우에는 LinearLayout의 하위 클래스 만 필요했습니다.

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;
  }
}

마지막으로 상황에 맞는 메뉴 호출을 가로 채서 적절한 핸들러로 리디렉션하기 위해 강화 된 Fragment 클래스가 필요합니다.

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);
  }
}

이 모든 것이 제자리에 있으면 최종 구현은 매우 간단합니다. 주요 조각은 FragmentWithContextMenu를 하위 클래스로 만들어야합니다. 메인 RecylerWindow를 정상적으로 설정하고 Adapter 하위 클래스로 전달합니다. Adapter 하위 클래스는 다음과 같습니다.

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

좋아, @Flexo의 답변에 따라 mPosition을 주문할 것입니다 ...

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);
    }
}

다음에 onContextItemSelected I 사용

item.getOrder() 

그리고 모두 잘 작동합니다. 배열의 위치를 ​​쉽게 얻습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.