[英]How to do you implement a recyclerview onClick in a Fragment?
My question is similar to this one. 我的问题与此类似。
Best approach to communicate between Fragment/Activity and RecyclerView.Adapter? 在Fragment / Activity和RecyclerView.Adapter之间进行通信的最佳方法?
I know how to implement an onClickListener, an Interface and an OnItemSelected method in the corresponding activity when the user clicks on a button in a Fragment. 我知道当用户单击Fragment中的按钮时,如何在相应的活动中实现onClickListener,Interface和OnItemSelected方法。 I have a fragment with an array list.
我有一个带有数组列表的片段。 By clicking on each item in the array list in the fragment, an ExoPlayer will open in a new activity or a fragment.
通过单击片段中数组列表中的每个项目,ExoPlayer将在新活动或片段中打开。 As I understand it, onItemClickListener doesn't work with Recyclerview.
据我了解,onItemClickListener不适用于Recyclerview。 How do I set the onClick method to the items in the list?
如何将onClick方法设置为列表中的项目? Also, do I set onClick outside of RecyclerView?
另外,我是否在RecyclerView之外设置onClick? This is my RecyclerView adapter class.
这是我的RecyclerView适配器类。 Should the interface take additional parameters?
接口是否应该使用其他参数? Thank you in advance.
先感谢您。
public class StepsAdapter extends RecyclerView.Adapter { 公共类StepsAdapter扩展了RecyclerView.Adapter {
private static final String TAG = StepsAdapter.class.getSimpleName();
private ArrayList<Steps> stepsList = new ArrayList<Steps>();
private StepsAdapter.StepsAdapterOnClickHandler mClickHandler;
/**
* The interface that receives onClick messages.
*/
public interface StepsAdapterOnClickHandler {
void onClick(Steps stepClick);
}
/**
* Creates a StepsAdapter.
*
* @param clickHandler The on-click handler for this adapter. This single handler is called
* when an item is clicked.
*/
public StepsAdapter(StepsAdapterOnClickHandler clickHandler,ArrayList<Steps> stepsList) {
mClickHandler = clickHandler;
this.stepsList = stepsList;
}
/**
* Cache of the children views for a steps list item.
*/
public class StepsAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
@BindView(R.id.step_short_desc)
public TextView stepShortDescription;
@BindView(R.id.step_description)
public TextView stepDescription;
public StepsAdapterViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
view.setOnClickListener(this);
}
/**
* This gets called by the child views during a click.
*
* @param v The View that was clicked
*/
@Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
Steps stepClick = stepsList.get(adapterPosition);
mClickHandler.onClick(stepClick);
}
}
@Override
public StepsAdapter.StepsAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.steps_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new StepsAdapter.StepsAdapterViewHolder(view);
}
@Override
public void onBindViewHolder(StepsAdapter.StepsAdapterViewHolder holder, int position) {
//Binding data
final Steps stepsView = stepsList.get(position);
holder.stepShortDescription.setText(stepsView.getStepShortDescription());
holder.stepDescription.setText(stepsView.getStepDescription());
}
@Override
public int getItemCount() {
return stepsList.size();
}
public void setStepsList(ArrayList<Steps> mStepsList) {
this.stepsList = mStepsList;
notifyDataSetChanged();
}
} }
The corresponding fragment. 相应的片段。 Is the click method implemented correctly?
click方法是否正确实施?
public class StepsListFragment extends Fragment implements StepsAdapter.StepsAdapterOnClickListener {
// Tag for logging
private final String TAG = StepsListFragment.class.getSimpleName();
@BindView(R.id.recyclerview_steps)
RecyclerView mRecyclerView;
ArrayList<Steps> stepsArrayList;
Recipes recipes;
// Final Strings to store state information about the list of steps and list index
public static final String STEPS_LIST_INDEX = "list_index";
// Define a new interface OnStepsClickListener that triggers a callback in the host activity
OnStepClickListener mCallback;
// OnStepsClickListener interface, calls a method in the host activity named onStepSelected
public interface OnStepClickListener {
void onClick(Steps stepClick);
}
// Override onAttach to make sure that the container activity has implemented the callback
@Override
public void onAttach(Context context) {
super.onAttach(context);
// // This makes sure that the host activity has implemented the callback interface
// // If not, it throws an exception
try {
mCallback = (OnStepClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnStepSelectedListener");
}
}
/**
* Mandatory empty constructor for the fragment manager to instantiate the fragment
*/
public StepsListFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// //Inflate the Steps fragment layout
View rootView = inflater.inflate(R.layout.fragment_steps, container, false);
// // Bind the views
ButterKnife.bind(this, rootView);
Bundle bundle = this.getArguments();
if (bundle != null) {
recipes = getArguments().getParcelable("Recipes");
stepsArrayList = new ArrayList<>();
stepsArrayList = recipes.getRecipeSteps();
}
if (savedInstanceState != null) {
//Restore the fragment's state here
stepsArrayList = savedInstanceState.getParcelableArrayList(STEPS_LIST_INDEX);
}
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
mRecyclerView.setLayoutManager(mLayoutManager);
Log.i("listSteps", stepsArrayList.size() + "");
StepsAdapter stepsAdapter = new StepsAdapter(this, stepsArrayList);
mRecyclerView.setAdapter(stepsAdapter);
// Return the root view
return rootView;
}
public void onClick(Steps stepClick){
mCallback.onClick(stepClick);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveIn`enter code here`stanceState(outState);
//Save the fragment's state here
outState.putParcelableArrayList(STEPS_LIST_INDEX, stepsArrayList);
super.onSaveInstanceState(outState);
} }
The best way to implement click function on each item of recyclerview is initialise onClickListener when the view is populated inside in the recyclerview viewholder. 在recyclerview Viewholder中填充视图时,在recyclerview的每个项目上实现点击功能的最佳方法是初始化onClickListener。 Then in the onClick method, use a custom interface/listener to catch the click activity in your parent fragment/activity.
然后在onClick方法中,使用自定义界面/监听器来捕获父片段/活动中的点击活动。
eg: create a custom interface like this; 例如:创建一个这样的自定义界面;
public interface RecyclerviewOnClickListener{
void recyclerviewClick(int position);
}
Now implement this interface in your parent activity/fragment containing the recyclerview. 现在,在包含recyclerview的父活动/片段中实现此接口。 Suppose your fragment name is ChatFragment.
假设您的片段名称是ChatFragment。 Then,
然后,
public class ChatFragment extends Fragment implements RecyclerviewOnClickListener{
.
.
}
This will implement the function onClick(int position) in your fragment. 这将在片段中实现onClick(int position)函数。 In your adapter constructor, you should create a field for the RecyclerviewOnClickListener.
在您的适配器构造函数中,您应该为RecyclerviewOnClickListener创建一个字段。 Suppose your adapter name is ChatAdapter, then
假设您的适配器名称是ChatAdapter,然后
Adapter Constructor. 适配器构造函数。
public ChatAdapter(RecyclerviewClickListener listener, .....<other params>){
this.listener = listener;
}
In your fragment, you can initialise your adapter like the following 在片段中,您可以像下面那样初始化适配器
ChatAdapter adapter = new ChatAdapter(this, <any additional params>);
You should pass the same instance of 'listener' to your viewholder also, and initialise the listener there also 您还应该将相同的“侦听器”实例传递给您的观看者,并在那里也初始化监听器
Now in your recyclerview ViewHolder, you can set view.setOnClickListener(new OnClickListener{ this.listener.recyclerviewClick(getAdapterPosition()) });
现在,您可以在recyclerview ViewHolder中设置
view.setOnClickListener(new OnClickListener{ this.listener.recyclerviewClick(getAdapterPosition()) });
The getAdapterPosition()
function returns the position of the click in the recyclerview, which will get a callback in the recyclerviewClick() function in your fragment. getAdapterPosition()
函数返回单击在recyclerview中的位置,这将在片段的recyclerviewClick()函数中获得回调。
About the number of parameter you are passing, you can use as much as you want, but for a click function in recyclerview, the ideal way is to use only one param which the position. 关于要传递的参数数量,可以根据需要使用任意数量,但是对于recyclerview中的click函数,理想的方法是仅使用该位置的一个参数。 Now you can modify the contents in the list that you are passing from your fragment to adapter and call notifyDataSetChanged() which will update the recyclerview.
现在,您可以修改从片段传递到适配器的列表中的内容,并调用notifyDataSetChanged()来更新recyclerview。 Hope it's clear.
希望清楚。
Try this inside OnBindviewHolder 在OnBindviewHolder中尝试一下
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//code here
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.