RecyclerView Onclick(调用非静态方法)
RecyclerView Onclick (call non-static method)
我在为我的 RecyclerView 项目设置 OnItemClickListener 时遇到了问题。我尝试按照 Android Studio 的 RecyclerView 示例中描述的方式设置侦听器。因此,在我的 RecyclerView 的 ViewHolder class 中设置了一个侦听器。
public class ProgramViewHolder extends RecyclerView.ViewHolder {
protected TextView vName;
protected ImageView vProgramImage;
public ProgramViewHolder(View v) {
super(v);
vName = (TextView) v.findViewById(R.id.programName);
vProgramImage = (ImageView) v.findViewById(R.id.programImage);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// HERE PROBLEM !!
MainActivity.openSettings(1);
}
});
}
}
现在我想调用我的 MainActivity openSettings(int ) 的方法来加载片段:
public void openSettings(int layoutId) {
settingsFragment setFrag = new settingsFragment();
Bundle information = new Bundle();
information.putInt("layoutId", layoutId);
setFrag.setArguments(information);
getFragmentManager().beginTransaction()
.replace(R.id.fragmentContainer, setFrag)
.commit();
}
但是现在问题来了。当我尝试编译时,它显示 "Non-static method 'openSettings(int )' cannot be referenced from a static context."
我很不明白这个错误。为什么它是静态上下文? class ProgramViewHolder 未声明为静态。
最重要的部分:我该如何修复它?我想为 RecyclerView 的每个项目设置一个 OnClickListener 并调用 MainActivity 的 public 方法。
非常感谢您花时间帮助我。
并不是说 ProgramViewHolder 是静态的,而是因为试图从静态上下文中调用您的 activity(您没有调用 activity 的特定实例)。
您应该做的是将 activity 传递到您的 recyclerViewAdapter 中,以便您可以访问它。
例如
MainActivity mainActivity;
public CustomRecyclerViewAdapter(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
并从 MainActivity 创建 recyclerViewAdapter
CustomRecyclerView recyclerViewAdapter = new CustomRecyclerViewAdapter(this);
recyclerViewAdapter.setAdapter(recyclerViewAdapter);
然后您应该能够像这样访问您的方法
mainActivity.openSettings(1);
如果您有任何问题,请告诉我
//编辑
以下是从 bindViewHolder 设置 onClick 的方法。由于 RecyclerView "recycles" 数据的方式,您想在此处设置任何 onClickListeners。例如,如果每一行都应该对点击执行不同的操作,则需要确保点击监听器绑定到特定的行。在 onBindViewHolder 中创建它可以确保这一点。如果你想让整行都可以点击,而不是里面的元素,只需创建一个填充整行的外部视图。然后将 onClickListener 绑定到那个。
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
ProgramViewHolder programViewHolder = (ProgramViewHolder) holder;
programViewHolder.vName.setOnClicklistener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainActivity.openSettings(1);
}
});
}
如果 context
个 activity 包含 recyclerView,那么您可以简单地这样做:
your_view_holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// HERE SOLUTION!!
((MainActivity)context).openSettings(1);
}
});
您可以将其放在 onBindViewHolder(...)
如何获取上下文:
在适配器的构造函数中创建上下文的另一个参数,并在实例化适配器后从 activity 传递上下文。
为什么要传递上下文:
我建议您始终传递上下文并将其分配给任何适配器的变量,因为这是您在使用适配器时不时需要的东西,因此不要每次都对上下文使用解决方法,只需保存曾经.
我在为我的 RecyclerView 项目设置 OnItemClickListener 时遇到了问题。我尝试按照 Android Studio 的 RecyclerView 示例中描述的方式设置侦听器。因此,在我的 RecyclerView 的 ViewHolder class 中设置了一个侦听器。
public class ProgramViewHolder extends RecyclerView.ViewHolder {
protected TextView vName;
protected ImageView vProgramImage;
public ProgramViewHolder(View v) {
super(v);
vName = (TextView) v.findViewById(R.id.programName);
vProgramImage = (ImageView) v.findViewById(R.id.programImage);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// HERE PROBLEM !!
MainActivity.openSettings(1);
}
});
}
}
现在我想调用我的 MainActivity openSettings(int ) 的方法来加载片段:
public void openSettings(int layoutId) {
settingsFragment setFrag = new settingsFragment();
Bundle information = new Bundle();
information.putInt("layoutId", layoutId);
setFrag.setArguments(information);
getFragmentManager().beginTransaction()
.replace(R.id.fragmentContainer, setFrag)
.commit();
}
但是现在问题来了。当我尝试编译时,它显示 "Non-static method 'openSettings(int )' cannot be referenced from a static context." 我很不明白这个错误。为什么它是静态上下文? class ProgramViewHolder 未声明为静态。
最重要的部分:我该如何修复它?我想为 RecyclerView 的每个项目设置一个 OnClickListener 并调用 MainActivity 的 public 方法。
非常感谢您花时间帮助我。
并不是说 ProgramViewHolder 是静态的,而是因为试图从静态上下文中调用您的 activity(您没有调用 activity 的特定实例)。
您应该做的是将 activity 传递到您的 recyclerViewAdapter 中,以便您可以访问它。
例如
MainActivity mainActivity;
public CustomRecyclerViewAdapter(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
并从 MainActivity 创建 recyclerViewAdapter
CustomRecyclerView recyclerViewAdapter = new CustomRecyclerViewAdapter(this);
recyclerViewAdapter.setAdapter(recyclerViewAdapter);
然后您应该能够像这样访问您的方法
mainActivity.openSettings(1);
如果您有任何问题,请告诉我
//编辑
以下是从 bindViewHolder 设置 onClick 的方法。由于 RecyclerView "recycles" 数据的方式,您想在此处设置任何 onClickListeners。例如,如果每一行都应该对点击执行不同的操作,则需要确保点击监听器绑定到特定的行。在 onBindViewHolder 中创建它可以确保这一点。如果你想让整行都可以点击,而不是里面的元素,只需创建一个填充整行的外部视图。然后将 onClickListener 绑定到那个。
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
ProgramViewHolder programViewHolder = (ProgramViewHolder) holder;
programViewHolder.vName.setOnClicklistener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainActivity.openSettings(1);
}
});
}
如果 context
个 activity 包含 recyclerView,那么您可以简单地这样做:
your_view_holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// HERE SOLUTION!!
((MainActivity)context).openSettings(1);
}
});
您可以将其放在 onBindViewHolder(...)
如何获取上下文:
在适配器的构造函数中创建上下文的另一个参数,并在实例化适配器后从 activity 传递上下文。
为什么要传递上下文:
我建议您始终传递上下文并将其分配给任何适配器的变量,因为这是您在使用适配器时不时需要的东西,因此不要每次都对上下文使用解决方法,只需保存曾经.