0

我使用advanced recycler view创建拖放网格视图&。我基于库的作者提供的示例基于我的代码。一切似乎工作得很好,拖放很好地保存它的状态,交换位置等,但我无法附加到这个简单的项目点击监听器。这就像RecyclerViewDragDropManager与它的包装适配器只能做那些拖放操作。 我很困惑,在这种情况下点击侦听器应该去哪里,因为通常在RecyclerView中,您可以附加到您的适配器bindView,但是我的适配器只有在长时间点击后才会触发,并且只处理拖放操作。高级回收站视图 - 处理物品单击和长按拖动操作

我试图从堆栈上的每一个解释如何将点击侦听器附加到RecyclerView,似乎没有任何工作。

我需要的是截取动作,如果长时间的点击没有被激发并知道它发生在哪个项目上。

下面是片段建立recyclerview和适配器代码:

private void setLayout() { 
    mRecyclerView = (RecyclerView) mView.findViewById(R.id.recycler_view); 
    mLayoutManager = new GridLayoutManager(mContext, Const.GRID_ROW_SIZE, GridLayoutManager.VERTICAL, false); 

    //drag & drop manager 
    mRecyclerViewDragDropManager = new RecyclerViewDragDropManager(); 
    mRecyclerViewDragDropManager.setDraggingItemShadowDrawable(
      (NinePatchDrawable) ContextCompat.getDrawable(mContext, R.drawable.material_shadow_z3)); 

    //start dragging after long press 
    mRecyclerViewDragDropManager.setInitiateOnLongPress(true); 
    mRecyclerViewDragDropManager.setInitiateOnMove(false); 
    mRecyclerViewDragDropManager.setLongPressTimeout(Const.LONG_PRESS_DRAG_TIMEOUT); 
} 

private void setWrappedAdapter(DraggableGridAdapter draggableGridAdapter) { 
    mAdapter = draggableGridAdapter; 

    mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(draggableGridAdapter); //wrap for dragging 

    final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator(); 

    mRecyclerView.setLayoutManager(mLayoutManager); 
    mRecyclerView.setAdapter(mWrappedAdapter); // requires *wrapped* adapter 
    mRecyclerView.setItemAnimator(animator); 

    if (supportsViewElevation()) { 
     // Lollipop or later has native drop shadow feature. ItemShadowDecorator is not required. 
    } else { 
     mRecyclerView.addItemDecoration(new ItemShadowDecorator((NinePatchDrawable) 
       ContextCompat.getDrawable(mContext, R.drawable.material_shadow_z1))); 
    } 

    mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView); 

    mRecyclerViewDragDropManager.setItemMoveMode(RecyclerViewDragDropManager.ITEM_MOVE_MODE_DEFAULT); 
    mAdapter.setItemMoveMode(RecyclerViewDragDropManager.ITEM_MOVE_MODE_DEFAULT); 
} 

而且适配器的代码:

public class DraggableGridAdapter extends RecyclerView.Adapter<DraggableGridAdapter.MyViewHolder> 
    implements DraggableItemAdapter<DraggableGridAdapter.MyViewHolder> { 

private static final String TAG = "MyDraggableItemAdapter"; 
private int mItemMoveMode = RecyclerViewDragDropManager.ITEM_MOVE_MODE_DEFAULT; 

// NOTE: Make accessible with short name 
private interface Draggable extends DraggableItemConstants { 
} 

private AbstractDataProvider mProvider; 

public static class MyViewHolder extends AbstractDraggableItemViewHolder { 
    public FrameLayout mContainer; 
    public View mDragHandle; 
    public TextView mTextView; 

    public MyViewHolder(View v) { 
     super(v); 
     mContainer = (FrameLayout) v.findViewById(R.id.container); 
     mDragHandle = v.findViewById(R.id.drag_handle); 
     mTextView = (TextView) v.findViewById(android.R.id.text1); 
    } 
} 

public DraggableGridAdapter(AbstractDataProvider dataProvider) { 
    mProvider = dataProvider; 

    // DraggableItemAdapter requires stable ID, and also 
    // have to implement the getItemId() method appropriately. 
    // Ids must be unique not changing with position. 
    setHasStableIds(true); 
} 

public void setItemMoveMode(int itemMoveMode) { 
    mItemMoveMode = itemMoveMode; 
} 

@Override 
public long getItemId(int position) { 
    return mProvider.getItem(position).getId(); 
} 

@Override 
public int getItemViewType(int position) { 
    return mProvider.getItem(position).getViewType(); 
} 

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

@Override 
public void onBindViewHolder(MyViewHolder holder, final int position) { 
    final AbstractDataProvider.Data item = mProvider.getItem(position); 

    // TODO: 2016-09-09 Add switch for checklist items 

    //set text 
    holder.mTextView.setText(item.getPlainText()); 

    final int dragState = holder.getDragStateFlags(); 

    if (((dragState & Draggable.STATE_FLAG_IS_UPDATED) != 0)) { 
     int bgResId; 

     if ((dragState & Draggable.STATE_FLAG_IS_ACTIVE) != 0) { 
      bgResId = R.drawable.bg_item_dragging_active_state; 
      com.example.Utilities.DrawableUtils.clearState(holder.mContainer.getForeground()); 
     } else if ((dragState & Draggable.STATE_FLAG_DRAGGING) != 0) { 
      bgResId = R.drawable.bg_item_dragging_state; 
     } else { 
      bgResId = R.drawable.bg_item_normal_state; 
     } 
     holder.mContainer.setBackgroundResource(bgResId); 
    } 

} 


@Override 
public int getItemCount() { 
    return mProvider.getCount(); 
} 

@Override 
public void onMoveItem(int fromPosition, int toPosition) { 
    Log.d(TAG, "onMoveItem(fromPosition = " + fromPosition + ", toPosition = " + toPosition + ")"); 

    if (fromPosition == toPosition) { 
     return; 
    } 

    if (mItemMoveMode == RecyclerViewDragDropManager.ITEM_MOVE_MODE_DEFAULT) { 
     mProvider.moveItem(fromPosition, toPosition); 
     notifyItemMoved(fromPosition, toPosition); 
    } else { 
     mProvider.swapItem(fromPosition, toPosition); 
     notifyDataSetChanged(); 
    } 
} 

@Override 
public boolean onCheckCanStartDrag(MyViewHolder holder, int position, int x, int y) { 
    return true; 
} 

@Override 
public ItemDraggableRange onGetItemDraggableRange(MyViewHolder holder, int position) { 
    // no drag-sortable range specified 
    return null; 
} 

@Override 
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) { 
    return true; 
} 

这里的示例代码我试过,但没有工作,从适配器onBindViewHolder方法:

public void onBindViewHolder(MyViewHolder holder, final int position) { 

    holder.itemView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.d(TAG, "Clicked " + position); 
     } 
    }); 
} 

回答

0

Okey,所以,我的问题的解决方案是在onBindViewHolder中将监听器分配给itemView而不是mContainer。

public void onBindViewHolder(MyViewHolder holder, final int position) { 

holder.mContainer.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Log.d(TAG, "Clicked " + position); 
    } 
}); 
} 

mContainer FrameLayout里被消耗,因为点击=“真”在布局XML语句的所有点击。

<FrameLayout 
    android:id="@+id/container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:clickable="true" 
    android:foreground="?attr/selectableItemBackground" 
    tools:ignore="UselessParent"> 

    <TextView 
     android:id="@android:id/text1" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_gravity="top|left" 
     android:gravity="center" 
     tools:ignore="RtlHardcoded"/> 

</FrameLayout> 
相关问题