12

に を設定する方法はありますonClickListenerRecyclerView?

その中RecyclerViewにいくつかの子供がいてOnClickListener、親にを設定していRecyclerViewます。ただし、onClickそのビューをクリックしても起動しません。以下のサンプル コードを参照してください。子ではなく、親でクリックを取得します。このシナリオでは、アイテムのクリックは気にしません。

私は子供たちにsetFocusable(false)setClickable(false)、およびを試してみましたが、役に立ちませんでした。setOnClickListener(null)いずれにせよ、子が親からクリックを盗んでいるとは思いません。なぜなら、子がいない領域をクリックすると、クリックも登録されないからです。

package com.formagrid.hellotest;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.Arrays;
import java.util.List;

public class HelloActivity extends Activity {

    private RecyclerView mRecyclerView;
    private RecyclerAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hello);

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new RecyclerAdapter(Arrays.asList("hi", "this", "is", "some", "text"));
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("patricia", view.toString());
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.Holder> {

        public class Holder extends RecyclerView.ViewHolder {

            protected TextView textView;

            public Holder(TextView itemView) {
                super(itemView);
                this.textView = itemView;
            }

        }

        private List<String> contents;

        public RecyclerAdapter(List<String> contents) {
            this.contents = contents;
        }

        @Override
        public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new Holder(new TextView(parent.getContext()));
        }

        @Override
        public void onBindViewHolder(Holder holder, int position) {
            holder.textView.setText(contents.get(position));
        }

        @Override
        public int getItemCount() {
            return contents.size();
        }

    }

}
4

4 に答える 4

7

に を設定する方法はありますonClickListenerRecyclerView?

いいえ。つまり、 を設定できOnClickListenerますが、RecyclerView呼び出すことはありません。RecyclerViewはすべてのタッチ イベントをインターセプトしますが、 を呼び出すことはありません。これがリスナーを呼び出すperformClick()方法です。View

ただし、とOnClickListenerを使用して をシミュレートすることはできます。のリスナーには、 メソッドだけを実装する を使用できます。OnTouchListenerGestureDetectorGestureDetectorSimpleOnGestureListeneronSingleTapUp()

class ClickListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        Toast.makeText(HelloActivity.this, "Clicked", 0).show();
        return true;
    }
};

次に、からGestureDetectortheをフィードし、 return をチェックして、スクロールやドラッグなどを妨げないように、イベントを消費するかどうかを決定するだけです。MotionEventOnTouchListener

final GestureDetector detector = new GestureDetector(HelloActivity.this, new ClickListener());

mRecyclerView.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(detector.onTouchEvent(event)) {
                return true;
            }
            return false;
        }
    }
);

RecyclerView上記の解決策は、質問で説明および指定されているような「単純な」ものでのみ機能することに注意してください。ドラッグ アンド ドロップやスワイプなど、より複雑なアイテム処理を使用している場合は、タッチ イベント チェーンの少し先でジェスチャ検出を処理する必要があります。

これを行うために、メソッドRecyclerViewで検出をサブクラス化して実行できます。dispatchTouchEvent()単一のタップが検出された場合は、 を呼び出すだけで、performClick()RecyclerViewが起動されOnClickListenerます。

public class ClickableRecyclerView extends RecyclerView {

    private final GestureDetectorCompat detector;

    public ClickableRecyclerView(Context context) {
        this(context, null);
    }

    public ClickableRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        detector = new GestureDetectorCompat(context, new ClickListener());
    }

    private class ClickListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            performClick();
            return true;
        }
    };

    @Override
    public boolean dispatchTouchEvent(MotionEvent e) {
        detector.onTouchEvent(e);
        return super.dispatchTouchEvent(e);
    }
}

通常の の代わりにこのサブクラスを使用し、通常どおりに をRecyclerView設定します。OnClickListenerこれをインスタンス化する方法によっては、追加のコンストラクターが必要になる場合があります。

于 2016-07-08T01:02:08.680 に答える