在RecycleView中实现Click In CardView

时间:2016-08-20 19:42:13

标签: android

所以我正在尝试让我的卡片可点击,当他们点击它时会打开一个新的活动(虽然在下面的代码中没有实现),这是我的代码:

对于接口

导入android.view.View;

public interface ClickListener {

    public void itemClicked(View view , int position);

}

适用于适配器:

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.SensorViewHolder> {

    private  ClickListener clicklistener = null;

    List<SensorData> sensors;
    RVAdapter(List<SensorData> sensors) {
        this.sensors = sensors;
    }

    public class SensorViewHolder extends RecyclerView.ViewHolder {

        CardView cv;
        TextView sensorName;
        TextView sensorDesc;
        ImageView sensorPhoto;
        private LinearLayout main;

        SensorViewHolder(final View itemView) {
            super(itemView);
            cv = (CardView) itemView.findViewById(R.id.cv);
            sensorName = (TextView) itemView.findViewById(R.id.sensor_name);
            sensorDesc = (TextView) itemView.findViewById(R.id.sensor_desc);
            sensorPhoto = (ImageView) itemView.findViewById(R.id.sensor_photo);

            main = (LinearLayout) itemView.findViewById(R.id.main);
            main.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(itemView.getContext(), "Position:" + Integer.toString(getPosition()), Toast.LENGTH_SHORT).show();
                    if(clicklistener != null){
                        clicklistener.itemClicked(v, getAdapterPosition());
                    }
                }
            });
        }
    }
    public void setClickListener(ClickListener clickListener){
        this.clicklistener = clickListener;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public SensorViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        SensorViewHolder pvh = new SensorViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(SensorViewHolder SensorViewHolder, int i) {
        SensorViewHolder.sensorName.setText(sensors.get(i).name);
        SensorViewHolder.sensorDesc.setText(sensors.get(i).descriptor);
        SensorViewHolder.sensorPhoto.setImageResource(sensors.get(i).iconID);
    }

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

以下是MainActivity的代码:

public class MainActivity extends AppCompatActivity {

    private List<SensorData> sensorData;
    private RecyclerView rv;

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

        //Find the recycler view for the <code>
        rv = (RecyclerView) findViewById(R.id.rv);

        //Initialising a linear layout manager
        final LinearLayoutManager llm = new LinearLayoutManager(this);
        rv.setLayoutManager(llm);
        rv.setHasFixedSize(true);

        initializeData();
        initializeAdapter();
        rv.setClickListener(this);
    }

    private void initializeData() {
        sensorData = new ArrayList<>();
        sensorData.add(new SensorData("Accelerometer", "Measures the acceleration of a moving or vibrating body.", R.mipmap.ic_accl));
        sensorData.add(new SensorData("GPS Sensor", "Provides real-time user location and time information.", R.mipmap.ic_gps));
        sensorData.add(new SensorData("Proximity Sensor", "Provides ambient light and proximity sensing.", R.mipmap.ic_als));
    }

    private void initializeAdapter() {
        RVAdapter adapter = new RVAdapter(sensorData);
        rv.setAdapter(adapter);
    }
}

但似乎我无法访问setClickListener。我必须提到我是一个相当初学者。

cp

我在哪里弄错了?这是实现卡上点击的正确方法还是我遗漏了什么?

如果需要,还有MainActivity XML。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:id="@+id/main">

    <android.support.v7.widget.RecyclerView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:id="@+id/rv">

    </android.support.v7.widget.RecyclerView>
</LinearLayout>

和items.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cv"
    app:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/sensor_photo"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginRight="16dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/sensor_name"
            android:layout_toRightOf="@+id/sensor_photo"
            android:layout_alignParentTop="true"
            android:textSize="30sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/sensor_desc"
            android:layout_toRightOf="@+id/sensor_photo"
            android:layout_below="@+id/sensor_name" />

    </RelativeLayout>

</android.support.v7.widget.CardView>

编辑:为了避免混淆,**我希望能够点击卡片并转到新活动。 **我如何以最简单的方式实现它?我真的很困惑如何在RecyclerView

中做到这一点

非常感谢和问候。

5 个答案:

答案 0 :(得分:1)

由于旧的ListView和新的RecyclerView组件之间存在差异,我有一段可重复使用的代码,用于处理点击事件(常规点击和LongClicks):

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

   @SuppressWarnings("CanBeFinal")
   private GestureDetector mGestureDetector;
   @SuppressWarnings("CanBeFinal")
   private OnItemClickListener mListener;

   public interface OnItemClickListener {
      void onItemClick(View view, int position);
      void onItemLongClick(View view, int position);

   }

   public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener)
   {
      mListener = listener;

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

          @Override
          public void onLongPress(MotionEvent e)
          {
             View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());

             if(childView != null && mListener != null)
             {
                 mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
             }
          }
      });
   }

   @Override
   public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e)
   {
      View childView = view.findChildViewUnder(e.getX(), e.getY());

      if(childView != null && mListener != null && mGestureDetector.onTouchEvent(e))
      {
         mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
      }

      return false;
   }

   @Override
   public void onTouchEvent(RecyclerView view, MotionEvent motionEvent){}

   @Override
   public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

   }
}

然后只需在您要处理点击事件的活动或片段中执行此操作:

mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, mRecyclerView, new RecyclerItemClickListener
            .OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            //start new activity here
        }

        @Override
        public void onItemLongClick(View view, int position) {

        }
    }));

这应该是最简单的方法!

我希望这会对你有所帮助!祝你好运,编码愉快!

答案 1 :(得分:1)

基本上你需要在Viewholder中设置监听器

public class SensorViewHolder extends RecyclerView.ViewHolder {

    CardView cv;
    TextView sensorName;
    TextView sensorDesc;
    ImageView sensorPhoto;
    private LinearLayout main;

    SensorViewHolder(final View itemView) {
        super(itemView);
        cv = (CardView) itemView.findViewById(R.id.cv);
        //Add the following line below
        cv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //The intent firing goes here
            }
        });
        sensorName = (TextView) itemView.findViewById(R.id.sensor_name);
        sensorDesc = (TextView) itemView.findViewById(R.id.sensor_desc);
        sensorPhoto = (ImageView) itemView.findViewById(R.id.sensor_photo);

        main = (LinearLayout) itemView.findViewById(R.id.main);
        main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(itemView.getContext(), "Position:" + Integer.toString(getPosition()), Toast.LENGTH_SHORT).show();
                if(clicklistener != null){
                    clicklistener.itemClicked(v, getAdapterPosition());
                }
            }
        });
    }
}

希望它有所帮助。

答案 2 :(得分:0)

要修复编译器错误,设置OnClickListener的正确方法是

rv.setOnClickListener()

请注意,错误是因为您缺少单词开启。通常,您应该在Android Studio中使用自动填充功能来帮助避免这些类型的问题。如果自动填充不会自动弹出,您可以按Ctrl-Space来获取它。

作为旁注,您可以点击主菜单中的Build -> Make Project来构建项目。这将给出一个包含错误消息的窗口,您可以比通常的错误气球更容易地复制和粘贴。

答案 3 :(得分:0)

在findViewById中,您将视图转换为RecyclerView,因此您将引用Android框架的标准RecyclerView实现。所以这永远不会奏效。

接下来是您正在尝试将侦听器设置为RecyclerView,但在适配器中定义setListener方法。

所以你应该做的是通过以下方式获得对适配器的引用:

((RvAdapter) rv.getAdapter()).setClickListener();
设置之后

,或者在调用之前更好地设置监听器

rv.setAdapter()

经由

RvAdapter adapter = new RvAdapter();
adapter.setClickListener(listener)

答案 4 :(得分:0)

首先在onBindViewHolder上为你的卡片设置标签:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.cv.setTag(position);
}

然后在适配器的视图持有者中添加卡片的点击监听器:

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    public CardLayout cv;
    public ViewHolder(View itemView) {
        super(itemView);
        cv = (CardView)  itemView.findViewById(Rid.cv);
        cv.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //for find item that hold in list
        int postition = (Integer) v.getTag();
        ...
    }