Переопределение getContextMenuInfo() из пользовательского адаптера

Я создаю список, который должен был иметь возможность изменить порядок позиции элемента.

К счастью для себя, я нашел внешнюю библиотеку, в которой есть именно то, что мне нужно.

К сожалению, я не смог реализовать действие удаления элемента с помощью onContextItemSelected(), потому что menuInfo всегда возвращает значение null, поэтому я не могу прочитать позицию выбранного элемента, который хочу удалить.

Это сообщение в блоге пользователя дало решение путем переопределения getContextMenuInfo().

Если item.getMenuInfo() имеет значение null в методе onContextItemSelected (MenuItem item), я предполагаю, что вы используете пользовательский ListView или GridView вместо стандартных по умолчанию для Android. В таком случае ваш пользовательский вид не реализует метод getContextMenuInfo(). Не волнуйтесь, мы можем это исправить, если у вас есть исходный код. Откройте файл представления и переопределите метод getContextMenuInfo().

Я пробовал это разными способами, но, похоже, я делаю что-то неправильно.

Это единственное решение или я что-то упустил?

Мероприятия

public class SurveyAdd extends AppCompatActivity {

private ArrayList<Pair<Long, String>> mItemArray = new ArrayList<>();
private DragListView mDragListView;
ItemAdapter listAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_survey_add);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mDragListView = (DragListView) findViewById(R.id.surveyadd_list);
    mDragListView.getRecyclerView().setVerticalScrollBarEnabled(true);
    mDragListView.setDragListListener(new DragListView.DragListListener() {
        @Override
        public void onItemDragStarted(int position) {
        }

        @Override
        public void onItemDragEnded(int fromPosition, int toPosition) {
            if (fromPosition != toPosition) {
                setSurveyChange(true);
            }
        }
    });

    mDragListView.setCanDragHorizontally(false);
    mDragListView.setCustomDragItem(new MyDragItem(context, R.layout.item_survey_add));
    mDragListView.setLayoutManager(new LinearLayoutManager(context));


        mDragListView.setLayoutManager(new LinearLayoutManager(context));
        ItemAdapter listAdapter = new ItemAdapter(mItemArray, R.layout.item_survey_add, R.id.item_add_image_button, false);
        mDragListView.setAdapter(listAdapter, true);

    registerForContextMenu(mDragListView);
}

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

@Override
public boolean onContextItemSelected(MenuItem item) {

    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

    switch (item.getItemId()) {
        case R.id.surveyadd_action_delete:
            if (item.getMenuInfo() == null) {
                Toast.makeText(SurveyAdd.this, "NULL", Toast.LENGTH_SHORT).show();
            }
    int position = info.position;  // CAN'T USE THIS, ALWAYS THROWS NULLPOINTEREXCEPTION
    Toast.makeText(SurveyAdd.this, "" + position, Toast.LENGTH_SHORT).show();
            return true;
    }
}
}
// The activity was simplified for posting

ItemAdapter

импортированный и отредактированный класс

public class ItemAdapter extends DragItemAdapter<Pair<Long, String>, ItemAdapter.ViewHolder> {

private int mLayoutId;
private int mGrabHandleId;

public ItemAdapter(ArrayList<Pair<Long, String>> list, int layoutId, int grabHandleId, boolean dragOnLongPress) {
    super(dragOnLongPress);
    mLayoutId = layoutId;
    mGrabHandleId = grabHandleId;
    setHasStableIds(true);
    setItemList(list);
}

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

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    super.onBindViewHolder(holder, position);
    String text = mItemList.get(position).second;
    String[] separated = text.split("::");
    holder.mText.setText(separated[1]);
    holder.itemView.setTag(text);
}

@Override
public long getItemId(int position) {
    return mItemList.get(position).first;
}

public class ViewHolder extends DragItemAdapter<Pair<Long, String>, ItemAdapter.ViewHolder>.ViewHolder {
    public TextView mText;
    public ImageView mIcon;

    public ViewHolder(final View itemView) {
        super(itemView, mGrabHandleId);
        mText = (TextView) itemView.findViewById(R.id.item_add_question);
        mIcon = (ImageView) itemView.findViewById(mGrabHandleId);
    }

    @Override
    public void onItemClicked(View view) {
    }

    @Override
    public boolean onItemLongClicked(View view) {

        return false;
    }
}
}

DragListView

импортированный и заблокированный класс

public class DragListView extends FrameLayout {

public interface DragListListener {
    void onItemDragStarted(int position);

    void onItemDragEnded(int fromPosition, int toPosition);
}

private DragItemRecyclerView mRecyclerView;
private DragListListener mDragListListener;
private DragItem mDragItem;
private boolean mDragEnabled = true;
private float mTouchX;
private float mTouchY;

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

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

public DragListView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    mDragItem = new DragItem(getContext());
    mRecyclerView = createRecyclerView();
    mRecyclerView.setDragItem(mDragItem);
    addView(mRecyclerView);
    addView(mDragItem.getDragItemView());
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    boolean retValue = handleTouchEvent(event);
    return retValue || super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean retValue = handleTouchEvent(event);
    return retValue || super.onTouchEvent(event);
}

private boolean handleTouchEvent(MotionEvent event) {
    mTouchX = event.getX();
    mTouchY = event.getY();
    if (isDragging()) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                mRecyclerView.onDragging(event.getX(), event.getY());
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mRecyclerView.onDragEnded();
                break;
        }
        return true;
    }
    return false;
}

private DragItemRecyclerView createRecyclerView() {
    final DragItemRecyclerView recyclerView = (DragItemRecyclerView) LayoutInflater.from(getContext()).inflate(R.layout.drag_item_recycler_view, this, false);
    recyclerView.setMotionEventSplittingEnabled(false);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setVerticalScrollBarEnabled(false);
    recyclerView.setHorizontalScrollBarEnabled(false);
    recyclerView.setDragItemListener(new DragItemRecyclerView.DragItemListener() {
        private int mDragStartPosition;

        @Override
        public void onDragStarted(int itemPosition, float x, float y) {
            getParent().requestDisallowInterceptTouchEvent(true);
            mDragStartPosition = itemPosition;
            if (mDragListListener != null) {
                mDragListListener.onItemDragStarted(itemPosition);
            }
        }

        @Override
        public void onDragging(int itemPosition, float x, float y) {
        }

        @Override
        public void onDragEnded(int newItemPosition) {
            if (mDragListListener != null) {
                mDragListListener.onItemDragEnded(mDragStartPosition, newItemPosition);
            }
        }
    });
    return recyclerView;
}

public RecyclerView getRecyclerView() {
    return mRecyclerView;
}

public DragItemAdapter getAdapter() {
    if (mRecyclerView != null) {
        return (DragItemAdapter) mRecyclerView.getAdapter();
    }
    return null;
}

public void setAdapter(DragItemAdapter adapter, boolean hasFixedItemSize) {
    mRecyclerView.setHasFixedSize(hasFixedItemSize);
    mRecyclerView.setAdapter(adapter);
    adapter.setDragEnabled(mDragEnabled);
    adapter.setDragStartedListener(new DragItemAdapter.DragStartedListener() {
        @Override
        public void onDragStarted(View itemView, long itemId) {
            mRecyclerView.onDragStarted(itemView, itemId, mTouchX, mTouchY);
        }
    });
}

public void setLayoutManager(RecyclerView.LayoutManager layout) {
    mRecyclerView.setLayoutManager(layout);
}

public void setDragListListener(DragListListener listener) {
    mDragListListener = listener;
}

public boolean isDragEnabled() {
    return mDragEnabled;
}

public void setDragEnabled(boolean enabled) {
    mDragEnabled = enabled;
    if (mRecyclerView.getAdapter() != null) {
        ((DragItemAdapter) mRecyclerView.getAdapter()).setDragEnabled(mDragEnabled);
    }
}

public void setCustomDragItem(DragItem dragItem) {
    removeViewAt(1);

    DragItem newDragItem;
    if (dragItem != null) {
        newDragItem = dragItem;
    } else {
        newDragItem = new DragItem(getContext());
    }

    newDragItem.setCanDragHorizontally(mDragItem.canDragHorizontally());
    newDragItem.setSnapToTouch(mDragItem.isSnapToTouch());
    mDragItem = newDragItem;
    mRecyclerView.setDragItem(mDragItem);
    addView(mDragItem.getDragItemView());
}

public boolean isDragging() {
    return mRecyclerView.isDragging();
}

public void setCanDragHorizontally(boolean canDragHorizontally) {
    mDragItem.setCanDragHorizontally(canDragHorizontally);
}

public void setSnapDragItemToTouch(boolean snapToTouch) {
    mDragItem.setSnapToTouch(snapToTouch);
}

public void setCanNotDragAboveTopItem(boolean canNotDragAboveTop) {
    mRecyclerView.setCanNotDragAboveTopItem(canNotDragAboveTop);
}

public void setScrollingEnabled(boolean scrollingEnabled) {
    mRecyclerView.setScrollingEnabled(scrollingEnabled);
}
}

person Mauricio Ramalho Custodio    schedule 03.02.2016    source источник


Ответы (1)


Это старый пост, но я понял это, используя тот же вид списка перетаскивания.

Я использую Xamarin, но он достаточно близок к тому же. Просто введите С# в Java по мере необходимости:

protected override IContextMenuContextMenuInfo ContextMenuInfo
    {
        get
        {
            IContextMenuContextMenuInfo menuInfo = base.ContextMenuInfo;
            if (menuInfo == null)
            {
                IListAdapter adapter = Adapter;
                int pos = GetPositionForView(selectedView);
                menuInfo = new AdapterContextMenuInfo(selectedView, pos, adapter.GetItemId(pos));
            }
            return menuInfo;
        }
    }


public void OnLongPress(MotionEvent e){
        int position = PointToPosition(mDownX, mDownY);
        int itemNum = position - FirstVisiblePosition;
        selectedView = GetChildAt(itemNum); //class variable
...
}
person NateVarghese    schedule 28.09.2016
comment
Спасибо за отзыв Нейт! - person Mauricio Ramalho Custodio; 28.09.2016