web-dev-qa-db-ja.com

Recyclerview内のアイテムのタッチイベントを処理する-android

私は、カスタムレイアウト(テキストビューとスイッチ)とカスタムアダプターを備えたシンプルなrecyclerviewを構築しています。

私の問題は、スイッチのクリックイベントを処理できない(状態を切り替える)、RecyclerViewのタッチリスナーを構築し、Switch

多くの試行の後、スイッチタッチリスナーも起動しますが、スイッチがクリックされた場合、recyclerViewのタッチイベントを無効にしたいと思います。

ここに私のレイアウトコードがあります:

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="60.0dip"
Android:layout_weight="1.0"
Android:orientation="horizontal"
Android:paddingLeft="16dp">

<TextView
    Android:id="@+id/category_name"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_alignParentLeft="true"
    Android:layout_alignParentStart="false"
    Android:layout_centerVertical="true"
    Android:layout_gravity="center_vertical"
    Android:text="Category Name"
    Android:textAppearance="?android:textAppearanceLarge" />

<Android.support.v7.widget.SwitchCompat
    Android:id="@+id/category_switch"
    Android:layout_width="80dp"
    Android:layout_height="wrap_content"
    Android:layout_alignParentEnd="true"
    Android:layout_alignParentRight="true"
    Android:layout_centerVertical="true"
    Android:layout_gravity="center_vertical"
    Android:checked="true"
    Android:clickable="true"
    Android:focusable="false"
    Android:focusableInTouchMode="false"
    Android:paddingRight="16dp" />

</RelativeLayout>

これは私のアダプターコードです:

public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View row = layoutInflater.inflate(R.layout.single_row_category, parent, false);
    CategoryViewHolder holder = new CategoryViewHolder(row);

    return holder;
}

public void onBindViewHolder(CategoryViewHolder holder, final int position) {
    AlarmCategory thisCat = categories.get(position);

    holder.catName.setText(thisCat.getCategoryName());

    holder.catStatus.setChecked(thisCat.isOn());

    holder.catStatus.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            Log.d("fpp", view.getClass().getName() + " is clicked");
            return true;
        }
    });
}

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

    public TextView catName;
    public SwitchCompat catStatus;

    public CategoryViewHolder(View itemView) {
        super(itemView);
        itemView.setOnCreateContextMenuListener(this);

        catName = (TextView) itemView.findViewById(R.id.category_name);
        catStatus = (SwitchCompat) itemView.findViewById(R.id.category_switch);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
        menu.add(0, 1001, 0, "Edit");//groupId, itemId, order, title
        menu.add(0, 1002, 1, "Delete");
    }
}

ここに私のrecyclerViewタッチハンドラーがあります:

class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    private GestureDetector gestureDetector;
    private ClickListener clickListener;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {

        this.clickListener = clickListener;

        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildPosition(child));
                }
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));

            Log.d("fpp", child.getClass().getName() + " is clicked");

            return false;
        }

        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

およびonCreateメソッド内で私はそれを呼び出します:

recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, recyclerView, new ClickListener() {
        @Override
        public void onClick(View view, int position) {
            Intent i = new Intent(CategoriesList.this, AlarmList.class);
            i.putExtra("catID", categories.get(position).getCategoryID());
            startActivity(i);
        }

        @Override
        public void onLongClick(View view, int position) {
            catPos = position;
        }
    }));

助けてください、私はすでに多くの解決策を試してみましたが、申し訳ありませんが機能しませんでした。

前もって感謝します。

12
Fareed

1つの方法は、所有者を更新して、ビューのクリックを内部で処理することです。

public class CategoryViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener, CompoundButton.OnSetCheckedListener {
    public CategoryViewHolder(View itemView) {
        super(itemView);
        itemView.setOnCreateContextMenuListener(this);
        itemView.setOnClickListener(this);

        catName = (TextView) itemView.findViewById(R.id.category_name);
        catStatus = (SwitchCompat) itemView.findViewById(R.id.category_switch);
        catStatus.setOnCheckChangedListener(this);
    }

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // deal with catStatus change
    }

    public void onClick(View view) {
        // deal with itemView click
    }
}
8
Dimitar Genov
  1. クラスを作成RecyclerTouchListener

    public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
    private GestureDetector gestureDetector;
    private ClickListener clickListener;
    
    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
    
            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildPosition(child));
                }
            }
        });
    }
    
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));
        }
        return false;
    }
    
    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    
    }
    
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    
    }
    
    public interface ClickListener {
        void onClick(View view, int position);
    
        void onLongClick(View view, int position);
      }
    }
    
  2. アクティビティでこのリスナーを使用する

    recyclerview.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerview, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
    
               // Write your code here
    
            }
    
            @Override
            public void onLongClick(View view, int position) {
    
            }
        }));
    
4
rhaldar