回收器视图中的手势检测器发生故障

时间:2015-12-16 06:13:29

标签: android android-recyclerview android-gesture

对于我的应用,我正在实施recyclerview以网格格式显示图像 onlongPress我需要删除多个项目 onclick我需要在新活动中显示点击的图片。

所以我使用SimpleOnGestureListener来实现它。

首先我实现了onLongPress它运行正常。但是如果我在除了图像之外的其他地方回收id,则返回id为-1。我通过放置条件id !=-1来处理它。
问题1:这是正确的做法,还是我做错了什么?

接下来,我点击了onSingleTapUp。当我onLongPress时,onSingleTapUp也会被调用。我处理了它,我放了一个标志来表示它的长按 现在,如果我单击图像,onSingleTapUp将以递增的方式多次调用。例如:如果我按第一次调用2次。下次时间6并继续进行。
问题2:如何解决onSingleTapUp onLongPress被调用onSingleTapUpMainActivity多次被调用?

更新 @Override public void onItemClicked(int position) { if (actionMode != null) { toggleSelection(position); } } private void toggleSelection(int position) { mAdapter.toggleSelection(position); int count = mAdapter.getSelectedItemCount(); if (count == 0) { actionMode.finish(); } else { actionMode.setTitle(String.valueOf(count)); actionMode.invalidate(); } } @Override public boolean onItemLongClicked(int position) { if (actionMode == null) { actionMode = startSupportActionMode(actionModeCallback); } toggleSelection(position); return true; } private class ActionModeCallback implements ActionMode.Callback { @SuppressWarnings("unused") private final String TAG = ActionModeCallback.class.getSimpleName(); @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.getMenuInflater().inflate (R.menu.menu_main, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.delete: // TODO: actually remove items Log.d(TAG, "Delete called"); List<Integer> selectedItemPositions = mAdapter.getSelectedItems(); int i; int currPos; for (i = (selectedItemPositions.size()) - 1; i >= 0; i--) { currPos = selectedItemPositions.get(i); mAdapter.removeData(currPos,filePath); } getDirectoryFiles(); setUpRecyclerView(); mode.finish(); return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode mode) { mAdapter.clearSelection(); actionMode = null; } }`

`

Adapter

public class GridAdapter extends SelectableAdapter<GridAdapter.ViewHolder> { List<images> mItems; private ArrayList<String> filePath; final Context mContext; private ViewHolder.ClickListener clickListener; public GridAdapter(Context context, ArrayList<String> fileName, ArrayList<String> filePath, ViewHolder.ClickListener clickListener) { super(); this.clickListener = clickListener; this.filePath = filePath; mItems = new ArrayList<images>(); this.mContext = context; for (int i = 0; i < fileName.size(); i++) { images img = new images(); img.setName(fileName.get(i)); img.setThumbnail(i); mItems.add(img); } } public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.grid_item, parent, false); // View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false); ViewHolder viewHolder = new ViewHolder(v,clickListener,mContext,filePath); return viewHolder; } @Override public void onBindViewHolder(final ViewHolder viewHolder, int i) { // Decode the filepath with BitmapFactory followed by the position Bitmap bmp = null; try { bmp = decodeFile(new File(filePath.get(i))); } catch (IOException e) { e.printStackTrace(); } //Picasso.with(mContext).load(new File(filePath.get(i))).into(viewHolder.imgThumbnail); // Set the decoded bitmap into ImageView viewHolder.imgThumbnail.setImageBitmap(bmp); } @Override public int getItemCount() { return mItems.size(); } public void removeData(int currPos, ArrayList<String> filePath) { File f=new File(filePath.get(currPos)); f.delete(); } public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { public ImageView imgThumbnail; private ClickListener listener; private Context mContext; private ArrayList<String> filePath; public int press_flag=0; public ViewHolder(View itemView, ClickListener listener,Context context,ArrayList<String> filePath) { super(itemView); imgThumbnail = (ImageView) itemView.findViewById(R.id.img_thumbnail); this.listener = listener; this.mContext=context; this.filePath=filePath; itemView.setOnClickListener(this); itemView.setOnLongClickListener(this); // Log.v("method","viewholder constructor"); } @Override public void onClick(View v) { if(press_flag==0) { Log.d("onclick", "Item clicked at position " + getPosition()); int j = getPosition(); Intent i = new Intent(mContext, image_preview.class); i.putExtra("j", j); i.putExtra("filepath", filePath.get(j)); mContext.startActivity(i); } if (listener != null) { listener.onItemClicked(getPosition()); } } @Override public boolean onLongClick(View v) { Log.d("Onlongclick", "Item long-clicked at position " + getPosition()); if (listener != null) { return listener.onItemLongClicked(getPosition()); } return false; } public interface ClickListener { public void onItemClicked(int position); public boolean onItemLongClicked(int position); } } `

SelectedDate = "{x:Static sys:DateTime.Now.AddDays(5)}"

}`

1 个答案:

答案 0 :(得分:0)

这个答案是关于OP遇到的第二个问题:在从SimpleOnGestureListener切换到简单OnClickListenerOnLongClickListener之后,当点击某个项目时,预览活动(应该显示)即使用户处于选择模式,也会显示正常模式时。

单击某个项目时,实际上有两个地方被调用。从ViewHolder(在适配器文件中):

    @Override
    public void onClick(View v) {
        if(press_flag==0) {
            Log.d("onclick", "Item clicked at position " + getPosition());
            int j = getPosition();
            Intent i = new Intent(mContext, image_preview.class);
            i.putExtra("j", j);
            i.putExtra("filepath", filePath.get(j));
            mContext.startActivity(i);
        }
        if (listener != null) {
            listener.onItemClicked(getPosition());
        }

    }

在这种情况下,来自听众的MainActivity

@Override
public void onItemClicked(int position) {
    if (actionMode != null) {
        toggleSelection(position);
    }
}

那么,那里会发生什么?首先,调用您的ViewHolder侦听器方法。如果press_flag等于0(我猜这是尝试解决您的问题,并且始终为真),则启动预览活动。在任何情况下。然后,您通知MainActivity。此MainActivity负责将项目设置为已选择或未选中,并了解当前选择状态。

您可以在此处进行简单的修复:将预览开始代码移至MainActivity。你的代码就是这样的:

ViewHolder

@Override
public void onClick(View v) {
    if (listener != null) {
        listener.onItemClicked(getPosition());
    }
}

MainActivity

@Override
public void onItemClicked(int position) {
    // If we are already selecting something
    if (actionMode != null) {
        toggleSelection(position);
    } else { // Or if we're not
        Log.d("onclick", "Item clicked at position " + position);
        Intent i = new Intent(this, image_preview.class); // mContext is useless here as we already are in a Context
        i.putExtra("j", position);
        i.putExtra("filepath", mAdapter.getFilePath(position); // New method to create in the adapter
        startActivity(i); // Again, no need for an additional Context here
    }
}

Adater: 您需要一种新方法来从MainActivity获取文件路径,这非常简单。您可能已经拥有MainActivity ...

中的信息
public String getFilePath(int position) {
    return filePath.get(position); // You may need to check for position being valid (compare to 0 and filePath.size())
}