Java Can';t从适配器调用活动函数
我想从适配器调用活动函数。我正在尝试这样的事情:Java Can';t从适配器调用活动函数,java,android,Java,Android,我想从适配器调用活动函数。我正在尝试这样的事情: ((MainActivity)mCtx).SampleVoid(); 但是我有一个错误:java.lang.ClassCastException:android.app.Application不能强制转换为 public void SampleVoid(){ Toast.makeText(this,"Testowa metoda",Toast.LENGTH_LONG).show(); } 您可以通过适配器构造函数传递活动。 通常
((MainActivity)mCtx).SampleVoid();
但是我有一个错误:java.lang.ClassCastException:android.app.Application不能强制转换为
public void SampleVoid(){
Toast.makeText(this,"Testowa metoda",Toast.LENGTH_LONG).show();
}
您可以通过适配器构造函数传递活动。 通常,您可以通过接口来实现这一点
public class MainActivity extends AppCompatActivity implements MAdapter.Listener {
private MAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new MAdapter(this);
}
@Override
public void onClick(int position) { }
}
然后
发生该错误的原因是您试图将应用程序上下文强制转换为活动上下文。首先,我不建议您在适配器中发送和存储上下文。我建议您创建一个接口,以便在适配器的特定操作中与活动进行通信。例如: 活动代码:
SomeAdapter adapter = new SomeAdapter();
adapter.setOnAdapterActionListener(new OnAdapterActionListener() {
@Override
public void onSomeAdapterAction() {
Toast.makeText(this,"Testowa metoda",Toast.LENGTH_LONG).show();
}
});
public class SomeAdapter extends ArrayAdapter<String> { // extend from the same adapter that you are extending now.
private OnAdapterActionListener onAdapterActionListener;
public SomeAdapter(@NonNull Context context, int resource, @NonNull List<String> objects) {
super(context, resource, objects);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onAdapterActionListener != null) {
onAdapterActionListener.onSomeAdapterAction();
}
}
});
return view;
}
public void setOnAdapterActionListener(OnAdapterActionListener onAdapterActionListener) {
this.onAdapterActionListener = onAdapterActionListener;
}
}
interface OnAdapterActionListener {
void onSomeAdapterAction();
}
适配器代码:
SomeAdapter adapter = new SomeAdapter();
adapter.setOnAdapterActionListener(new OnAdapterActionListener() {
@Override
public void onSomeAdapterAction() {
Toast.makeText(this,"Testowa metoda",Toast.LENGTH_LONG).show();
}
});
public class SomeAdapter extends ArrayAdapter<String> { // extend from the same adapter that you are extending now.
private OnAdapterActionListener onAdapterActionListener;
public SomeAdapter(@NonNull Context context, int resource, @NonNull List<String> objects) {
super(context, resource, objects);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onAdapterActionListener != null) {
onAdapterActionListener.onSomeAdapterAction();
}
}
});
return view;
}
public void setOnAdapterActionListener(OnAdapterActionListener onAdapterActionListener) {
this.onAdapterActionListener = onAdapterActionListener;
}
}
interface OnAdapterActionListener {
void onSomeAdapterAction();
}
public class SomeAdapter扩展了ArrayAdapter{//从您现在扩展的同一适配器扩展。
专用OnAdapterActionListener OnAdapterActionListener;
公共SomeAdapter(@NonNull上下文上下文、int resource、@NonNull List objects){
超级(上下文、资源、对象);
}
@非空
@凌驾
公共视图getView(int位置,@Nullable视图convertView,@NonNull视图组父级){
视图=super.getView(位置、转换视图、父级);
view.setOnClickListener(新的view.OnClickListener(){
@凌驾
公共void onClick(视图v){
if(onAdapterActionListener!=null){
onAdapterActionListener.onSomeAdapterAction();
}
}
});
返回视图;
}
public void setOnAdapterActionListener(OnAdapterActionListener-OnAdapterActionListener){
this.onAdapterActionListener=onAdapterActionListener;
}
}
AdapterActionListener接口{
在SomeAdapterAction()上无效;
}
据我所知,将上下文传递给适配器是一种常见做法。您不推荐它的原因是什么?我会避免它将上下文传递给适配器和默认情况下不包含上下文的任何其他类。当然,如果可能的话。通过将上下文传递给某个类,如果我们不小心处理这种情况,我们将暴露该类,以防止可能的内存泄漏。也许对于适配器来说,这并不是什么大问题,但是如果您可以在适配器内部没有上下文的情况下完成它,那么我强烈建议您这样做。谷歌团队在默认情况下没有在适配器内部提供上下文可能有一个很好的原因。此外,如果您在需要上下文的任何位置都有viewHolder实例,您可以从其视图组件中获得一个,如下所示:viewHolder.itemView.getContext()
当上下文作为参数传递时,是否在内存中复制/复制原始上下文?viewHolder.itemView.getContext()
调用原始上下文而不是制作副本吗?我建议您阅读这篇博客文章Java如何在方法中传递参数:通过这篇博客文章,您将更好地理解这一点。传递的上下文使用指向原始实例的指针创建副本<代码>viewHolder.itemView.getContext()使用视图持有者根视图中可用的上下文。使用这种方法,您只需使用这个上下文,然后就不需要再处理它了。