Fragment 中 RecyclerView 中的 OnClickListener
OnClickListener in RecyclerView in Fragment
我创建了主从流程,在 Master Fragment 中,我有一个 RecyclerView。
我在 RecyclerView 中设置 ClickListener 时遇到问题。
我不确定我是否遗漏了一些微不足道的东西或存在更大的问题,但几乎相同的代码在标准 Activity (片段之外)中完美运行。
这是我的适配器:
//imports
public class StepsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final StepsAdapterOnClickHandler mClickHandler;
private Recipe recipe;
private List<Step> steps;
//init with Click Handler
public StepsAdapter(StepsAdapterOnClickHandler clickHandler) {
this.mClickHandler = clickHandler;
}
//set recipe and steps
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
this.steps = recipe.steps;
notifyDataSetChanged();
}
//get position as ViewType for distinguishing between first View and others
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getItemCount() {
if (steps == null) {
return 0;
}
return steps.size() + 1;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//setup different layout for first view
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view0 = inflater.inflate(R.layout.ingredients_tile, parent, false);
View view = inflater.inflate(R.layout.step_selection_tile, parent, false);
switch (viewType) {
case 0:
return new IngredientsViewHolder(view0);
default:
return new ViewHolderX(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
IngredientsViewHolder viewHolder0 = (IngredientsViewHolder) holder;
//set text
viewHolder0.ingredientsLabelTV.setText("Ingredients");
break;
default:
ViewHolderX viewHolderX = (ViewHolderX) holder;
viewHolderX.shortDescriptionTV.setText(steps.get(position - 1).shortDescription);
break;
}
}
//click interface
public interface StepsAdapterOnClickHandler {
void onClick(int stepId);
}
//viewHolder for Ingredients
public class IngredientsViewHolder extends RecyclerView.ViewHolder {
TextView ingredientsLabelTV;
public IngredientsViewHolder(View itemView) {
super(itemView);
ingredientsLabelTV = itemView.findViewById(R.id.ingredients_label_tv);
}
}
//stepsViewHolder
class ViewHolderX extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView shortDescriptionTV;
public ViewHolderX(View itemView) {
super(itemView);
shortDescriptionTV = itemView.findViewById(R.id.short_description_tv);
}
@Override
public void onClick(View v) {
mClickHandler.onClick(33);
}
}
这是我的片段代码:
//imports
public class StepSelectionFragment extends Fragment implements StepsAdapter.StepsAdapterOnClickHandler {
OnStepClickListener mCallback;
RecyclerView stepsListRV;
StepsAdapter mAdapter;
RecipeDatabase mDb;
//mandatory empty builder
public StepSelectionFragment() {
}
//onClic - sends callback to Activity
@Override
public void onClick(int stepId) {
mCallback.onStepClick(stepId);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
//attach callback to fragment
try {
mCallback = (OnStepClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement Listener");
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_step_selection, container, false);
//init db
mDb = RecipeDatabase.getInstance(getActivity());
//init recyclerView
stepsListRV = rootView.findViewById(R.id.step_selection_rv);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
stepsListRV.setLayoutManager(layoutManager);
//setup adapter with clickHandler
mAdapter = new StepsAdapter(this);
stepsListRV.setAdapter(mAdapter);
//get recipes from Db
AppExecutors.getsInstance().getDiskIO().execute(new Runnable() {
@Override
public void run() {
Recipe recipe = mDb.recipeDAO().loadRecipe(RecipeViewActivity.getRecipeId());
mAdapter.setRecipe(recipe);
}
});
return rootView;
}
public interface OnStepClickListener {
void onStepClick(int stepId);
}
我想我什么都试过了。
完整代码可以在 https://github.com/ASheler/BakingApp/tree/AddMasetDetailFlow/app/src/main/java/com/glaserproject/bakingapp
找到
在适配器 ViewHolder
中添加 itemView.setOnClickListener(this);
我创建了主从流程,在 Master Fragment 中,我有一个 RecyclerView。
我在 RecyclerView 中设置 ClickListener 时遇到问题。
我不确定我是否遗漏了一些微不足道的东西或存在更大的问题,但几乎相同的代码在标准 Activity (片段之外)中完美运行。
这是我的适配器:
//imports
public class StepsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final StepsAdapterOnClickHandler mClickHandler;
private Recipe recipe;
private List<Step> steps;
//init with Click Handler
public StepsAdapter(StepsAdapterOnClickHandler clickHandler) {
this.mClickHandler = clickHandler;
}
//set recipe and steps
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
this.steps = recipe.steps;
notifyDataSetChanged();
}
//get position as ViewType for distinguishing between first View and others
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getItemCount() {
if (steps == null) {
return 0;
}
return steps.size() + 1;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//setup different layout for first view
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view0 = inflater.inflate(R.layout.ingredients_tile, parent, false);
View view = inflater.inflate(R.layout.step_selection_tile, parent, false);
switch (viewType) {
case 0:
return new IngredientsViewHolder(view0);
default:
return new ViewHolderX(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
IngredientsViewHolder viewHolder0 = (IngredientsViewHolder) holder;
//set text
viewHolder0.ingredientsLabelTV.setText("Ingredients");
break;
default:
ViewHolderX viewHolderX = (ViewHolderX) holder;
viewHolderX.shortDescriptionTV.setText(steps.get(position - 1).shortDescription);
break;
}
}
//click interface
public interface StepsAdapterOnClickHandler {
void onClick(int stepId);
}
//viewHolder for Ingredients
public class IngredientsViewHolder extends RecyclerView.ViewHolder {
TextView ingredientsLabelTV;
public IngredientsViewHolder(View itemView) {
super(itemView);
ingredientsLabelTV = itemView.findViewById(R.id.ingredients_label_tv);
}
}
//stepsViewHolder
class ViewHolderX extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView shortDescriptionTV;
public ViewHolderX(View itemView) {
super(itemView);
shortDescriptionTV = itemView.findViewById(R.id.short_description_tv);
}
@Override
public void onClick(View v) {
mClickHandler.onClick(33);
}
}
这是我的片段代码:
//imports
public class StepSelectionFragment extends Fragment implements StepsAdapter.StepsAdapterOnClickHandler {
OnStepClickListener mCallback;
RecyclerView stepsListRV;
StepsAdapter mAdapter;
RecipeDatabase mDb;
//mandatory empty builder
public StepSelectionFragment() {
}
//onClic - sends callback to Activity
@Override
public void onClick(int stepId) {
mCallback.onStepClick(stepId);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
//attach callback to fragment
try {
mCallback = (OnStepClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement Listener");
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_step_selection, container, false);
//init db
mDb = RecipeDatabase.getInstance(getActivity());
//init recyclerView
stepsListRV = rootView.findViewById(R.id.step_selection_rv);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
stepsListRV.setLayoutManager(layoutManager);
//setup adapter with clickHandler
mAdapter = new StepsAdapter(this);
stepsListRV.setAdapter(mAdapter);
//get recipes from Db
AppExecutors.getsInstance().getDiskIO().execute(new Runnable() {
@Override
public void run() {
Recipe recipe = mDb.recipeDAO().loadRecipe(RecipeViewActivity.getRecipeId());
mAdapter.setRecipe(recipe);
}
});
return rootView;
}
public interface OnStepClickListener {
void onStepClick(int stepId);
}
我想我什么都试过了。
完整代码可以在 https://github.com/ASheler/BakingApp/tree/AddMasetDetailFlow/app/src/main/java/com/glaserproject/bakingapp
在适配器 ViewHolder
中添加itemView.setOnClickListener(this);