有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
下面是我的代码片段:
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int newPosition = MainActivity.mRecyclerView.getChildAdapterPosition(v);
Intent cardViewIntent = new Intent(c, MainActivityCards.class);
cardViewIntent.putExtra("Position", newPosition);
c.startActivity(cardViewIntent);
}
});
v是onCreateViewHolder的视图 c为背景信息
其他回答
通常你在CardView中有多个元素,所以你需要一个布局视图来包装和组织它们。你可以添加一个OnClickListener到那个布局视图。1. 添加一个id到你的布局。在这个例子中是线性布局
<android.support.v7.widget.CardView
.....>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/card_view_linearLayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="name"
android:id="@+id/card_view_name" />
...
</LinearLayout>
</android.support.v7.widget.CardView>
2美元。在你的内部ViewHolder类中获取布局视图。
public static class ViewHolder extends RecyclerView.ViewHolder{
private TextView nameView;
...
private LinearLayout linearLayout;
public ViewHolder(View itemView) {
super(itemView);
nameView = (TextView)itemView.findViewById(R.id.card_view_name);
...
linearLayout = (LinearLayout)itemView.findViewById(R.id.card_view_linearLayout);
}
}
3美元。将监听器添加到onBindViewHolder中的布局中,并使用回调将数据发送到活动或片段(未测试)。
@Override
public void onBindViewHolder(TrackAdapter.ViewHolder holder, final int position) {
String str = mStringList.get(position);
holder.nameView.setText(str);
...
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.itemCallback(mStringList.get(position));
}
});
}
如何使用回调是另一个故事
对我来说,最干净的方法就是这个。
适配器的构造函数
private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter<EnvironmentTypeRecyclerViewAdapter.ViewHolder>
{
private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
private List<Environment> mEnvironmentsData;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public ViewHolder(View v)
{
super(v);
v.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
Environment environment = mEnvironmentsData.get(getAdapterPosition());
if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) {
mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);
}
}
public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
{
mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
mEnvironmentsData = environments;
}
}
链接接口
private interface EnvironmentTypeRecyclerViewAdapterListener
{
void onListItemSelected(Environment environment);
}
From most of the answers above, they seem to be setting their onclicklisteners to individual items. However, the solution am about to offer is very simple but yet not intuitive to many. Many are forgetting that the other components are always in a parent component which is used to display items in the List or Recycler views. This solution is just about setting a single onclick listener to this parent view and the turn is played. The solution also includes a way to pass the position of the item being clicked on from the list or recycler view. Here, our main rootview is a CardView from the android support library. Here is sample code
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
public static final String LOG_TAG = ListAdapter.class.getSimpleName();
private Cursor mDataset;
private Context mContext;
private ViewHolder mViewHolder;
// Provide a suitable constructor (depends on the kind of dataset)
public ListAdapter(Context context, Cursor Dataset) {
mDataset = Dataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_business_view, parent, false);
mViewHolder = new ViewHolder(v);
return mViewHolder;
}
public void setData(Cursor newdata) {
this.mDataset = newdata;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//Bind data to other items here. To save time, i have ommited that.
//here is where we attach a click listerner for an item in the recycler list rather than for each element of a given item.
holder.card.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, " Just cliked item at position " + itemPosition, Toast.LENGTH_LONG).show();
}
});
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
if (null != mDataset) {
return mDataset.getCount();
}
return 0;
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder{
// each data item is just a string in this case
public final TextView mBusinesssName; // View for the business name
public final TextView mBusinessCategory; //View for the category name
public final ImageView businessImage; // View for the business category image Image
public final TextView mBusinessDistance; // View for the distance
public final CardView card;
public ViewHolder(View view) {
super(view);
mBusinesssName = (TextView) view.findViewById(R.id.list_item_name_textview);
mBusinessCategory = (TextView) view.findViewById(R.id.list_item_category_textview);
mBusinessDistance = (TextView) view.findViewById(R.id.list_item_dist_textview);
businessImage = (ImageView) view.findViewById(R.id.list_item_icon);
card = (CardView) view.findViewById(R.id.card_view);
}
}
}
我有一个很好的解决方案RecyclerView的onItemClickListener的项目和子项
步骤1—创建接口
public interface OnRecyclerViewItemClickListener
{
/**
* Called when any item with in recyclerview or any item with in item
* clicked
*
* @param position
* The position of the item
* @param id
* The id of the view which is clicked with in the item or
* -1 if the item itself clicked
*/
public void onRecyclerViewItemClicked(int position, int id);
}
步骤2-然后在适配器的onBindViewHolder方法中使用它,如下所示
/**
* Custom created method for Setting the item click listener for the items and items with in items
* @param listener OnRecyclerViewItemClickListener
*/
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener)
{
this.listener = listener;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position)
{
// viewHolder.albumBg.setBackgroundResource(_itemData[position]
// .getImageUrl());
viewHolder.albumName.setText(arrayList.get(position).getName());
viewHolder.artistName.setText(arrayList.get(position).getArtistName());
String imgUrl = arrayList.get(position).getThumbImageUrl();
makeImageRequest(imgUrl, viewHolder);
viewHolder.parentView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
listener.onRecyclerViewItemClicked(position, -1);
}
});
viewHolder.settingButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
listener.onRecyclerViewItemClicked(position, v.getId());
}
});
}
// class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder
{
public TextView albumName, artistName;
public ImageView albumIcon, settingButton;
public LinearLayout parentView;
public ViewHolder(View itemLayoutView)
{
super(itemLayoutView);
// albumBg = (LinearLayout) itemLayoutView
// .findViewById(R.id.albumDlbg);
albumName = (TextView) itemLayoutView.findViewById(R.id.albumName);
artistName = (TextView) itemLayoutView
.findViewById(R.id.artistName);
albumIcon = (ImageView) itemLayoutView.findViewById(R.id.albumIcon);
parentView = (LinearLayout) itemLayoutView
.findViewById(R.id.albumDlbg);
settingButton = (ImageView) itemLayoutView
.findViewById(R.id.settingBtn);
}
}
步骤3-在活动或片段中找到并设置回收器视图,您正在使用此
recyclerView = (RecyclerView) rootview.findViewById(R.id.vmtopsongs);
lm = new LinearLayoutManager(mActivity);
lm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(lm);
recyclerView.addItemDecoration(
new HorizontalDividerItemDecoration.Builder(getActivity())
.paint(Utils.getPaint()).build());
PopularSongsadapter mAdapter = new PopularSongsadapter(gallery,
mActivity, true);
// set adapter
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(this);
// set item animator to DefaultAnimator
recyclerView.setItemAnimator(new DefaultItemAnimator());
步骤4-最后在使用recyclerview的activity或fragment中实现接口
@Override
public void onRecyclerViewItemClicked(int position, int id)
{
if(id==-1){
Toast.makeText(mActivity, "complete item clicked", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(mActivity, "setting button clicked", Toast.LENGTH_LONG).show();
}
}
更新Kotlin语言 我已经更新了kotlin的代码,其中只有整个视图有点击监听器。你可以根据上面的java代码编辑界面和代码来设置子项点击监听器。
适配器
class RecentPostsAdapter(private val list: MutableList<Post>) :
RecyclerView.Adapter<RecentPostsAdapter.ViewHolder>() {
private lateinit var onItemClickListener: OnItemClickListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.listitem_recent_post, parent, false)
)
}
override fun getItemCount(): Int {
return list.size
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
this.onItemClickListener = onItemClickListener
}
private fun getItem(position: Int): Post {
return list[position]
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position))
holder.itemView.setOnClickListener(View.OnClickListener {
onItemClickListener.onItemClick(
position
)
})
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private var imageView: NetworkImageView? = null
private var tvTitle: TextView? = null
private var tvExcerpt: TextView? = null
private var htmlSpanner: HtmlSpanner = HtmlSpanner()
init {
imageView = itemView.findViewById(R.id.niv_post_image)
tvTitle = itemView.findViewById(R.id.tv_post_title)
tvExcerpt = itemView.findViewById(R.id.tv_post_excerpt)
}
fun bind(post: Post) {
tvTitle?.text = post.title
tvExcerpt?.text = htmlSpanner.fromHtml(post.excerpt)
}
}
interface OnItemClickListener {
fun onItemClick(position: Int)
}
}
活动或片段
recyclerView = view.findViewById(R.id.rvHomeRecentPosts)
recyclerView.layoutManager = LinearLayoutManager(view.context)
list = mutableListOf()
recentPostsAdapter = RecentPostsAdapter(list)
recyclerView.adapter = recentPostsAdapter
recentPostsAdapter.setOnItemClickListener(object:RecentPostsAdapter.OnItemClickListener{
override fun onItemClick(position: Int) {
(activity as MainActivity).findNavController(R.id.nav_host_fragment).navigate(R.id.action_nav_home_to_nav_post_detail)
}
})
这是我的自定义适配器的完整代码,这段代码将用XML文件“list_item”中定义的列表项膨胀行,它还将在具有各自位置的所有列表项行上执行单击事件。
public class MyCustomAdapter extends RecyclerView.Adapter`<`AdapterMyCustomAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public onItemClickListener mListener;
public ViewHolder(View v, onItemClickListener listener) {
super(v);
mListener =listener;
v.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mListener.onRecyclerItemClick(v, getPosition());
}
public static interface onItemClickListener {
public void onRecyclerItemClick(View view , int position);
}
}
@Override
public int getItemCount() {
return 5;
}
@Override
public void onBindViewHolder(ViewHolder holder, int pos) {
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
/* here list_item is an xml file we want to inflate ...it is same as we do in case of listview for customization.*/
MyCustomAdapter.ViewHolder vh = new ViewHolder(v, new MyCustomAdapter.ViewHolder.onItemClickListener() {
@Override
public void onRecyclerItemClick(View view, int position) {
System.out.println("clicked on list item at position " +position);
}
});
return vh;
}
}
推荐文章
- 在Java中从字符串中提取数字
- 在Android中,对话框被取消或被取消有什么区别?
- 套接字的连接超时和读超时之间的区别是什么?
- 在ScrollView触摸处理中的HorizontalScrollView
- Java整数到字节数组
- 如何设置Windows环境下Java的环境变量
- Java Swing revalidate() vs repaint()
- Java中文件中的行数
- 何时在Android中使用RxJava,何时使用Android架构组件中的LiveData ?
- 如何在Android项目中使用ThreeTenABP
- 指定的子节点已经有一个父节点。你必须先在子对象的父对象上调用removeView() (Android)
- 我的Android设备没有出现在adb设备列表中
- 在没有安装apk的情况下获取Android .apk文件的VersionName或VersionCode
- Fragment onResume() & onPause()不会在backstack上被调用
- 如何设置基线对齐为假提高性能在线性布局?