私は、カスタムレイアウト(テキストビューとスイッチ)とカスタムアダプターを備えたシンプルな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;
}
}));
助けてください、私はすでに多くの解決策を試してみましたが、申し訳ありませんが機能しませんでした。
前もって感謝します。
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
}
}
クラスを作成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);
}
}
アクティビティでこのリスナーを使用する
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) {
}
}));