RecyclerView和CardView的点击监听器实现

3
我刚刚转向使用 Android RecyclerView 和 CardView,并且意识到 RecyclerView 没有一个选项来监听点击事件,但是在实现了这个功能之后,我并没有看到任何结果。
以下是我的代码和布局:
MainActivity:
public class MainActivity extends AppCompatActivity {

    //private usefulSites_RecyclerView_Adapter mAdapter;
    final Context context = this;
    private RecyclerView mRecyclerView;
    private StaggeredGridLayoutManager mGridLayoutManager;
    private RecyclerViewAdapter mAdapter;
    private String[] mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
        CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
        mCollapsingToolbarLayout.setTitle("test");
        //通过CollapsingToolbarLayout修改字体颜色
        mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
        mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);


        //mList = getResources().getStringArray(R.array.numbers);

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.setLayoutManager(mGridLayoutManager);
        mAdapter = new RecyclerViewAdapter(getApplicationContext());
        mRecyclerView.setAdapter(mAdapter);


    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

RecyclerViewAdapter(适用于RecyclerView的适配器)
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    private Context mContext;
    private String [] mSiteTitle,mSiteLink;
    private int [] mThumbnail;

    public RecyclerViewAdapter(Context contexts, String[] list) {
        this.mContext = contexts;
        this.mSiteTitle = list;
    }
    public RecyclerViewAdapter(Context contexts) {
        this.mContext = contexts;
        initList();
    }
    private void initList(){

        UsfulSite_init mInit=new UsfulSite_init();
        mSiteTitle= mInit.initSiteTitle();
        mSiteLink=mInit.initSiteLink();
        mThumbnail=mInit.initThumbnail();


    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.usful_sites_card_view, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.sTitle.setText(mSiteTitle[position]);
        holder.sLink.setText(mSiteTitle[position]);
        holder.sImage.setImageResource(mThumbnail[position]);


        holder.setClickListener(new ItemClickListener() {
            @Override
            public void onClick(View view, int position, boolean isLongClick) {
                if (isLongClick) {
                    Toast.makeText(mContext, "#" + position + " - " + mSiteTitle[position] + " (Long click)", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(mContext, "#" + position + " - " + mSiteTitle[position], Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return mSiteTitle.length;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder
            implements View.OnClickListener, View.OnLongClickListener{
        private TextView sTitle,sLink;
        private ImageView sImage;
        private ItemClickListener clickListener;

        public ViewHolder(View itemView) {
            super(itemView);
            sTitle = (TextView)itemView.findViewById(R.id.useful_sites_Title);
            sLink=(TextView)itemView.findViewById(R.id.useful_sites_Link);
            sImage=(ImageView)itemView.findViewById(R.id.useful_sites_thumbnail);
            itemView.setTag(itemView);
            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);


        }

        public void setClickListener(ItemClickListener itemClickListener) {
            this.clickListener = itemClickListener;
        }

        @Override
        public void onClick(View view) {
            clickListener.onClick(view, getPosition(), false);
        }

        @Override
        public boolean onLongClick(View view) {
            clickListener.onClick(view, getPosition(), true);
            return true;
        }
    }
}

Activity_main.xml:

<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout

    android:layout_width="match_parent"
    android:layout_height="256dp"
    android:fitsSystemWindows="true">
    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        app:contentScrim="#30469b"
        app:expandedTitleMarginStart="48dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">
        <ImageView

            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/a"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.7"  />
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin" />
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none" />
</LinearLayout>

CardView Layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="5dp"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="4dp"
android:layout_height="match_parent">

<RelativeLayout

    android:id="@+id/mainHolder"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/useful_sites_thumbnail"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:tint="@color/photo_tint"
        android:layout_centerInParent="true"
        />

    <TextView
        android:id="@+id/useful_sites_Title"
        android:gravity="center"
        android:background="?android:selectableItemBackground"
        android:focusable="true"
        android:clickable="true"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:textSize="24sp"
        android:layout_centerInParent="true"
        android:textColor="@android:color/white"
        />
    <TextView
        android:id="@+id/useful_sites_Link"
        android:gravity="center"
        android:background="?android:selectableItemBackground"
        android:focusable="true"
        android:clickable="true"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:textSize="24sp"
        android:layout_centerInParent="true"
        android:textColor="@android:color/white"
        android:visibility="gone"
        />
</RelativeLayout>

我在RV中尝试了其他的clickListener方法,但是我卡在这里了。有人可以看看我的代码并指导我一下吗?

CardView Layout.xml:与Activity_main.xml相同。 - Norutan
哦,我的错,改一下,谢谢。 - 123
这是您问题的先前答案:链接 - Smashing
4个回答

8
如果您想为每个卡片视图实现onClick功能,可以按照以下步骤进行操作: 在您的XML文件中:
<android.support.v7.widget.CardView
    android:id="@+id/card_view">

    ...

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

然后,在您的适配器代码中:
public static class ViewHolder extends RecyclerView.ViewHolder {
        private CardView cardView;

        public ViewHolder(View itemView) {
            super(itemView);
            cardView = (CardView) itemView.findViewById(R.id.card_view);
        }
}

...

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //implement onClick
                System.out.println("Clicked");
            }
        });
    }
}

3
您可以将监听器从适配器传递到视图持有者(ViewHolder)中,然后在那里监听事件,您还可以将事件从适配器传递到您的Activity或者创建此适配器的位置。
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {

private List<Album> albums;
private Context context;
public AlbumAdapterClickListener recListener;

public AlbumAdapter(List<Album> albums, Context context, AlbumAdapterClickListener recListener) {
    this.albums = albums;
    this.context = context;
    this.recListener = recListener;
}

public interface AlbumAdapterClickListener {
    void recyclerViewClick(String albumID);
}


public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView title;
    public TextView count;
    public ImageView picture;
    public String albumID;
    public AlbumClickListener listener;

    //listener passed to viewHolder
    public interface AlbumClickListener {
        void albumOnClick(String albumID);
    }

    public ViewHolder(View v, AlbumClickListener listener) {
        super(v);
        title = (TextView) v.findViewById(R.id.album_list_title);
        count = (TextView) v.findViewById(R.id.album_list_count);
        picture = (ImageView) v.findViewById(R.id.album_list_picture);

        this.listener = listener;
        v.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        listener.albumOnClick(this.albumID);
    }
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.album_list_item, viewGroup, false),
            new ViewHolder.AlbumClickListener() {
                @Override
                public void albumOnClick(String albumID) {
                    //TODO show gridView with current albumID
                    Log.e("fdf", albumID);
                    // albumID going to Fragment
                    recListener.recyclerViewClick(albumID);
                }

            });
}


@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    Album album = albums.get(i);
    viewHolder.albumID = album.getId();
    viewHolder.count.setText(album.getPhotoCount());
    viewHolder.title.setText(album.getName());
    Picasso.with(context).load(albums.get(i).getCoverURL()).placeholder(R.mipmap.fb_place_holder).resize(140, 140)
            .centerCrop().into(viewHolder.picture);
}

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

}


我选择了这个。虽然我只是在viewholder中重用了clicklistener,而不是使用它自己的。 - Ryan Newsom

1

对我来说,VLeong的回答非常好用!但需要稍作澄清。这个代码: holder.cardView.setOnClickListener(new View.OnClickListener() { 需要更改为:

holder.itemView.setOnClickListener(new View.OnClickListener(){

0

您可以将监听器添加到View Holder的构造函数中。

public ViewHolder(View v) {
    super(v);
    title = (TextView) v.findViewById(R.id.album_list_title);
    count = (TextView) v.findViewById(R.id.album_list_count);
    picture = (ImageView) v.findViewById(R.id.album_list_picture);

    v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Handel yout event here
            }
        });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接