我的问题与此类似。
Best approach to communicate between Fragment/Activity and RecyclerView.Adapter?
当用户单击“片段”中的按钮时,我知道如何在相应的活动中实现onClickListener,Interface和OnItemSelected方法。我有一个带有数组列表的片段。通过单击片段中数组列表中的每个项目,ExoPlayer将在新活动或片段中打开。据我了解,onItemClickListener不适用于Recyclerview。如何将onClick方法设置为列表中的项目?另外,我是否在RecyclerView之外设置onClick?这是我的RecyclerView适配器类。接口是否应该使用其他参数?先感谢您。
公共类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();
}
}
相应的片段。点击方法是否正确实施?
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);
} }
答案 0 :(得分:1)
在recyclerview Viewholder内部填充视图时,在recyclerview的每个项目上实现点击功能的最佳方法是初始化onClickListener。然后在onClick方法中,使用自定义界面/监听器来捕获父片段/活动中的点击活动。
例如:创建一个这样的自定义界面;
public interface RecyclerviewOnClickListener{
void recyclerviewClick(int position);
}
现在在包含recyclerview的父活动/片段中实现此接口。假设您的片段名称是ChatFragment。然后,
public class ChatFragment extends Fragment implements RecyclerviewOnClickListener{
.
.
}
这将在片段中实现onClick(int position)函数。在您的适配器构造函数中,您应该为RecyclerviewOnClickListener创建一个字段。假设您的适配器名称是ChatAdapter,然后
适配器构造器。
public ChatAdapter(RecyclerviewClickListener listener, .....<other params>){
this.listener = listener;
}
在片段中,您可以像下面那样初始化适配器
ChatAdapter adapter = new ChatAdapter(this, <any additional params>);
您还应该将相同的“侦听器”实例传递给您的观看者,并在那里也初始化监听器
现在,在您的recyclerview ViewHolder中,您可以设置view.setOnClickListener(new OnClickListener{
this.listener.recyclerviewClick(getAdapterPosition())
});
getAdapterPosition()
函数返回单击在recyclerview中的位置,这将在片段的recyclerviewClick()函数中获得回调。
关于您传递的参数数量,您可以根据需要使用任意数量,但是对于recyclerview中的click函数,理想的方法是仅使用该位置的一个参数。现在,您可以修改从片段传递到适配器的列表中的内容,并调用notifyDataSetChanged()来更新recyclerview。希望一切都清楚。
答案 1 :(得分:0)
在OnBindviewHolder中尝试
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//code here
}