在 RecyclerView 项目上添加多个 onClickListener
Posted
技术标签:
【中文标题】在 RecyclerView 项目上添加多个 onClickListener【英文标题】:add multiple onClickListeners on RecyclerView items 【发布时间】:2021-01-04 21:09:37 【问题描述】:我在回收站视图中的 itemView 上添加了一个新活动,但我想在单个项目上添加多个活动。这些教程对 Button 来说非常好,但我不知道如何在 itemview 上实现。 MainActivity中调用的recyclerview如下;
private String[] channelnames="PTC Punjabi","Chakde TV","T-Series Punjabi", "9X Tashan", "Zee Punjabi" ;
private int[] channelimages=R.drawable.ptcpunjabi, R.drawable.chakde, R.drawable.tseries, R.drawable.ninex, R.drawable.zeepunjabi;
private List<channel> channelList=new ArrayList<>();
thirdrecyclerView=findViewById(R.id.third_recycler_view);
thirdrecyclerView.setHasFixedSize(true);
channelList=new ArrayList<>();
LinearLayoutManager thirdlinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
thirdrecyclerView.setLayoutManager(thirdlinearLayoutManager);
for (int i=0;i < channelnames.length;i++)
channel channel=new channel(channelnames[i],channelimages[i]);
channelList.add(channel);
适配器和viewholder类定义为;
public class channeladpater extends RecyclerView.Adapter<channeladpater.Channelviewholder>
private List<channel> channelList;
Context ctx;
public channeladpater(List<channel> channelList)
this.channelList = channelList;
this.ctx=ctx;
@NonNull
@Override
public Channelviewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view,parent,false);
return new Channelviewholder(view);
@Override
public void onBindViewHolder(@NonNull Channelviewholder holder, int position)
channel channel=channelList.get(position);
holder.channelname.setText(channel.getChannelname());
holder.channelimage.setImageResource(channel.getChannelimage());
holder.setItemClickListener(new ItemClickListener()
@Override
public void onItemClickListener(View v, int position)
Intent intent=new Intent(ctx, MainActivity2.class);
ctx.startActivity(intent);
);
@Override
public int getItemCount()
return channelList.size();
public static class Channelviewholder extends RecyclerView.ViewHolder implements View.OnClickListener
public TextView channelname;
public CircleImageView channelimage;
ItemClickListener itemClickListener;
Channelviewholder(@NonNull View itemView)
super(itemView);
this.channelname=itemView.findViewById(R.id.profile_name);
this.channelimage=itemView.findViewById(R.id.profile_image);
itemView.setOnClickListener(this);
@Override
public void onClick(View v)
this.itemClickListener.onItemClickListener(v,getLayoutPosition());
public void setItemClickListener(ItemClickListener ic)
this.itemClickListener=ic;
在这里,我想将第一个图像或文本视图 (PTC punjabi/R.drawable.ptcpunjabi) 分配给 MainActivity 2,将第二个文本视图和图像视图 (Chakde Tv/R.drawable.chakde) 分配给 MainActivity 3,依此类推。当单击整张卡片时,如何调用文本或图像视图组合到下一个活动开始。 MainActivity 2如下;
public class MainActivity2 extends AppCompatActivity
RecyclerView recyclerView;
ArrayList<VideoDetails> videoDetailsoArrayList;
Intent intent=getIntent();
String API_Key = " ";
String url="https://www.googleapis.com/youtube/v3/search?part=snippet&channelId="+channelID+"&maxResults=50&sort=date&key=[API_KEY]";
com.currentmedia.punjabinews.adapter adapter;
Context ctx;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
recyclerView=findViewById(R.id.listView);
videoDetailsoArrayList= new ArrayList<>();
adapter=new adapter(MainActivity2.this,videoDetailsoArrayList);
displayVideos();
private void displayVideos ()
RequestQueue requestQueue= Volley.newRequestQueue(this);
StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>()
@Override
public void onResponse(String response)
try
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
if (jsonObject1.has("id"))
JSONObject jsonVideoId=jsonObject1.getJSONObject("id");
if (jsonVideoId.has("kind"))
if(jsonVideoId.getString("kind").equals("youtube#video"))
JSONObject jsonObjectSnippet = jsonObject1.getJSONObject("snippet");
JSONObject jsonObjectDefault=jsonObjectSnippet.getJSONObject("thumbnails").getJSONObject("medium");
String video_id=jsonVideoId.getString("videoId");
VideoDetails vd=new VideoDetails();
vd.setVideoId(video_id);
vd.setTitle(jsonObjectSnippet.getString("title"));
vd.setDescription(jsonObjectSnippet.getString("description"));
vd.setUrl(jsonObjectDefault.getString("url"));
videoDetailsoArrayList.add(vd);
// recyclerView.setAdapter(adapter);
// adapter.notifyDataSetChanged();
catch (JSONException e)
e.printStackTrace();
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapter= new adapter(getApplicationContext(),videoDetailsoArrayList);
recyclerView.setAdapter(adapter);
, new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
Toast.makeText(getApplicationContext(),error.getMessage(), LENGTH_LONG).show();
);
requestQueue.add(stringRequest);
在String url中,我想为channelnames列表添加channelId,以避免添加多个活动。
PTC punjabi
UCHJW1_0oPzYZl89wX_jhrgA
Chakde Tv
UCaT-WGdJLyEDnxZPAKRTbqQ
T-series punjabi
UCJMSoNjSKRARSIJM3GymRjQ
9x tashan
UCrET5fR2NAUTO2Xp12G0l8A
zee punjabi
UCYF_LfBBxkFBEgaSCNrqW3w
上面提到的是我要分配给它们的频道ID列表,以便从MAin Activity中选择每个图像时,单独的频道活动开始。
【问题讨论】:
【参考方案1】:如果列表中有 10 个项目,则无需为每个项目创建 10 个活动。
您只需要一个相同的活动来显示 MainActivity 列表中的详细信息。
当您按下列表中的项目时,您需要使用Intents
将它的position
和数据(在您的情况下为channel
)传递给SecondActivity。
让我们进行这些更改。
在您的适配器类中:
您已经设置了侦听器,但请确保您正在传递数据。
holder.setItemClickListener(new ItemClickListener()
@Override
public void onItemClickListener(View v, int position)
Intent intent = new Intent(ctx, MainActivity2.class);
// Using intent pass your data to MainActivity2 class
intent.putExtra("Intent to MainActivity2", channel);
ctx.startActivity(intent);
);
MainActivity2 类:
现在您必须从以前的活动中接收数据。
在你的onCreate()
活动中,在扩展布局之后和设置任何视图之前。
Channel channel = getIntent().getParcelableExtra("Intent to MainActivity2");
从上面的代码中,您正在获取此意图所接收到的数据,您可能也从任何活动中接收到数据,因此具体来自您使用 getParcelableExtra()
内的 String
引用的活动
现在获取数据后,这样调用它的属性
yourTextView.setText(channel.channelname)
就是这样。现在您可以看到单击之前活动列表中的每个项目,并且不再需要额外的活动。
供您参考,您可以看到这个project 遵循类似的方法。
【讨论】:
实际上 MainActivity 3 或 4 5 是新的活动,其中包括用于通道 id 的通道解析的 json 数据。我怎样才能使用相同的活动? 所以您列表中的所有项目都没有引用或与频道数据无关?如果少数item数据不同或需要进一步操作,检查当前点击的item的位置或id,进行不同的操作。【参考方案2】:最好在 Activity 中使用监听器参数或方法并发送位置或Class
的 Activity 点击到 MainActivity 并基于类打开 Activity 更容易,也可以在 Google 的示例中使用。
abstract class BaseAdapter : RecyclerView.Adapter<BaseAdapter.MyViewHolder>()
private var listener: OnRecyclerViewItemClickListener? = null
inner class MyViewHolder
(// each data item is just a string in this case
private val binding: ViewDataBinding
) : RecyclerView.ViewHolder(binding.root), View.OnClickListener
internal fun bind(obj: Any)
binding.setVariable(BR.obj, obj)
binding.executePendingBindings()
// Set click listener
itemView.setOnClickListener(this)
override fun onClick(v: View)
listener?.run
onItemClicked(v, layoutPosition)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder
// create a new view
val layoutInflater = LayoutInflater.from(parent.context)
val binding =
DataBindingUtil.inflate<ViewDataBinding>(
layoutInflater,
getLayoutIdForType(viewType),
parent,
false
)
// set the view's size, margins, paddings and layout parameters
return MyViewHolder(binding)
override fun onBindViewHolder(holder: MyViewHolder, position: Int)
holder.bind(getDataAtPosition(position))
/**
* Get data in position for RecyclerView row. This method is invoked inside
* onBindViewHolder() method of RecyclerView
*
* @param position indicates the item for the current row
* @return data for the current row
*/
abstract fun getDataAtPosition(position: Int): Any
/**
* Get id of layout from R. This method is invoked from onCreateViewHolder method of Adapter
*
* @param viewType id of layout row of RecyclerView
* @return id of layout
*/
abstract fun getLayoutIdForType(viewType: Int): Int
/**
* RecyclerViewClickListener interface helps user to set a clickListener to the
* RecyclerView. By setting this listener, any item of Recycler View can respond
* to any interaction.
*/
interface OnRecyclerViewItemClickListener
/**
* This is a callback method that be overridden by the class that implements this
* interface
*/
fun onItemClicked(view: View, position: Int)
fun setOnItemClickListener(listener: OnRecyclerViewItemClickListener)
this.listener = listener
包含类名和可选描述的数据
data class ActivityClassModel(val clazz: Class<*>, val description: String = clazz.name)
适配器实现
class ChapterSelectionAdapter(private val data: List<ActivityClassModel>) : BaseAdapter()
override fun getDataAtPosition(position: Int): Any
return data[position]
override fun getLayoutIdForType(viewType: Int): Int
return R.layout.row_layout
override fun getItemCount(): Int
return data.size
主活动
class MainActivity : AppCompatActivity(), BaseAdapter.OnRecyclerViewItemClickListener
private val activityClassModels = ArrayList<ActivityClassModel>()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
val activityMainBinding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
// Add Activities to list to be displayed on RecyclerView
activityClassModels.add(
ActivityClassModel(
Activity1Basics::class.java,
"Activity BottomNavigationView with listener"
)
)
val recyclerView = activityMainBinding.recyclerView
recyclerView.apply
// Use fixed size for performance
setHasFixedSize(true)
// use a linear layout manager
layoutManager = LinearLayoutManager(this@MainActivity)
// Add vertical divider
addItemDecoration(
DividerItemDecoration(
this@MainActivity,
DividerItemDecoration.VERTICAL
)
)
// Add Adapter
recyclerView.adapter = ChapterSelectionAdapter(activityClassModels).apply
setOnItemClickListener(this@MainActivity)
@Override
override fun onItemClicked(view: View, position: Int)
Intent(this@MainActivity, activityClassModels[position].clazz).also
startActivity(it)
【讨论】:
这是java代码吗?我是 Java 编程新手,我无法理解这段代码的语法。你能像我在问题中提供的代码一样用java翻译它吗以上是关于在 RecyclerView 项目上添加多个 onClickListener的主要内容,如果未能解决你的问题,请参考以下文章
是否允许在 RecyclerView 上投放多个 AdMob 广告?另类广告网络?
RecyclerView添加动态多个HeaderView 和FooterView