Java ClassCastException:使用DialogFragment时应用程序崩溃
我的Java ClassCastException:使用DialogFragment时应用程序崩溃,java,android,android-fragments,classcastexception,Java,Android,Android Fragments,Classcastexception,我的MainActivity.java中有一个RecyclerView。在每个RecyclerView行中,我都有一个按钮,当按下它时,它应该会打开一个自定义的片段对话框,其中包含RecyclerView列表(这是一个多选对话框) 在我的SecondActivity.java,这是我的另一个活动,我也有同样的按钮,它应该做同样的事情(这就是为什么我需要模态作为片段对话框)。在我的SecondActivity.java中,没有RecyclerView,只有一篇文章(详细信息页) 我的问题: 10-
MainActivity.java
中有一个RecyclerView
。在每个RecyclerView行中,我都有一个按钮,当按下它时,它应该会打开一个自定义的片段对话框,其中包含RecyclerView列表(这是一个多选对话框)
在我的SecondActivity.java
,这是我的另一个活动,我也有同样的按钮,它应该做同样的事情(这就是为什么我需要模态作为片段对话框)。在我的SecondActivity.java
中,没有RecyclerView,只有一篇文章(详细信息页)
我的问题:
10-06 14:35:12.353 21683-21683/com.example.appname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.appname, PID: 21683
java.lang.ClassCastException: com.example.appname.MainActivity@e06db1e
at adapters.MultiDialogAdapter.<init>(MultiDialogAdapter.java:40)
at fragments.CustomDialogFragment.onViewCreated(CustomDialogFragment.java:60)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1430)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
当我单击SecondActivity.java
上弹出窗口的按钮时,它会正常打开对话框片段弹出窗口。当我对RecyclerView(位于MainActivity.java
中)中的任何一行执行相同操作时,我会得到一个ClassCastException
错误:
java.lang.ClassCastException: com.example.appname.MainActivity cannot be cast to interfaces.DialogCommunicator$Communicator
我的代码:
10-06 14:35:12.353 21683-21683/com.example.appname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.appname, PID: 21683
java.lang.ClassCastException: com.example.appname.MainActivity@e06db1e
at adapters.MultiDialogAdapter.<init>(MultiDialogAdapter.java:40)
at fragments.CustomDialogFragment.onViewCreated(CustomDialogFragment.java:60)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1430)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
SecondActivity.java
//*****************//
// THIS CODE WORKS //
//*****************//
// This code will run when the button is clicked.
// postOptions is a string array of menu items.
Bundle args = new Bundle();
args.putStringArray("displaymenu", postOptions);
mDialogFragment = new CustomDialogFragment();
mDialogFragment.setArguments(args);
mDialogFragment.show(getSupportFragmentManager(), "title");
//***************************//
// THIS CODE CRASHES THE APP //
//***************************//
// This code is planted in onClick method listener in onBindViewHolder
// for the button that's supposed to open the fragment dialog.
FragmentManager fm = ((MainActivity) mContext).getSupportFragmentManager();
String[] items = mContext.getResources().getStringArray(R.array.post_options);
CustomDialogFragment customDialogFragment = CustomDialogFragment.newInstance(items);
customDialogFragment.show(fm, "title");
public class CustomDialogFragment extends DialogFragment {
private RecyclerView mRecyclerView;
public CustomDialogFragment() {
// Empty constructor is required for DialogFragment
// Make sure not to add arguments to the constructor
// Use `newInstance` instead as shown below
}
public static CustomDialogFragment newInstance(String[] items) {
CustomDialogFragment customDialogFragment = new CustomDialogFragment();
Bundle args = new Bundle();
args.putStringArray("displaymenu", items);
customDialogFragment.setArguments(args);
return customDialogFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_multiselect_dialog, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
String[] items = args.getStringArray("displaymenu");
List<String> itemsList = Arrays.asList(items);
// THIS LINE CRASHES ON POSTSLISTADAPTER!!!
MultiDialogAdapter adapter = new MultiDialogAdapter(getActivity(), itemsList);
mRecyclerView = (RecyclerView) view.findViewById(R.id.items_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(adapter);
getDialog().setTitle(null);
}
}
public class MultiDialogAdapter extends RecyclerView.Adapter<MultiDialogViewHolder> {
private List<String> mItems;
private LayoutInflater mInflater;
private CustomFonts mCustomFont;
private DialogCommunicator.Communicator mCommunicator;
public MultiDialogAdapter(Context context, List<String> items) {
this.mInflater = LayoutInflater.from(context);
this.mItems = items;
this.mCustomFont = new CustomFonts(context);
try {
mCommunicator = (DialogCommunicator.Communicator) context;
} catch (ClassCastException e) {
// THIS IS WHERE THE CLASSCASTEXCEPTION HAPPENS!
throw new ClassCastException(context.toString());
}
}
@Override
public MultiDialogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.layout_multiselect_dialog_row, parent, false);
return new MultiDialogViewHolder(view);
}
@Override
public void onBindViewHolder(MultiDialogViewHolder holder, int position) {
final String item = mItems.get(position);
holder.getItemTextView().setText(item);
holder.getItemTextView().setTypeface(mCustomFont.getPrimaryFontMedium());
holder.getItemTextView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCommunicator.onDialogButtonResponse(item);
}
});
}
@Override
public int getItemCount() {
return mItems.size();
}
}
class MultiDialogViewHolder extends RecyclerView.ViewHolder {
private TextView mItemTextView;
public MultiDialogViewHolder(View rootView) {
super(rootView);
mItemTextView = (TextView) rootView.findViewById(R.id.item_text_view);
}
public TextView getItemTextView() {
return mItemTextView;
}
}
public class DialogCommunicator {
public interface Communicator {
public void onDialogButtonResponse(String responseMessage);
}
}
PostsListAdapter.java
//*****************//
// THIS CODE WORKS //
//*****************//
// This code will run when the button is clicked.
// postOptions is a string array of menu items.
Bundle args = new Bundle();
args.putStringArray("displaymenu", postOptions);
mDialogFragment = new CustomDialogFragment();
mDialogFragment.setArguments(args);
mDialogFragment.show(getSupportFragmentManager(), "title");
//***************************//
// THIS CODE CRASHES THE APP //
//***************************//
// This code is planted in onClick method listener in onBindViewHolder
// for the button that's supposed to open the fragment dialog.
FragmentManager fm = ((MainActivity) mContext).getSupportFragmentManager();
String[] items = mContext.getResources().getStringArray(R.array.post_options);
CustomDialogFragment customDialogFragment = CustomDialogFragment.newInstance(items);
customDialogFragment.show(fm, "title");
public class CustomDialogFragment extends DialogFragment {
private RecyclerView mRecyclerView;
public CustomDialogFragment() {
// Empty constructor is required for DialogFragment
// Make sure not to add arguments to the constructor
// Use `newInstance` instead as shown below
}
public static CustomDialogFragment newInstance(String[] items) {
CustomDialogFragment customDialogFragment = new CustomDialogFragment();
Bundle args = new Bundle();
args.putStringArray("displaymenu", items);
customDialogFragment.setArguments(args);
return customDialogFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_multiselect_dialog, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
String[] items = args.getStringArray("displaymenu");
List<String> itemsList = Arrays.asList(items);
// THIS LINE CRASHES ON POSTSLISTADAPTER!!!
MultiDialogAdapter adapter = new MultiDialogAdapter(getActivity(), itemsList);
mRecyclerView = (RecyclerView) view.findViewById(R.id.items_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(adapter);
getDialog().setTitle(null);
}
}
public class MultiDialogAdapter extends RecyclerView.Adapter<MultiDialogViewHolder> {
private List<String> mItems;
private LayoutInflater mInflater;
private CustomFonts mCustomFont;
private DialogCommunicator.Communicator mCommunicator;
public MultiDialogAdapter(Context context, List<String> items) {
this.mInflater = LayoutInflater.from(context);
this.mItems = items;
this.mCustomFont = new CustomFonts(context);
try {
mCommunicator = (DialogCommunicator.Communicator) context;
} catch (ClassCastException e) {
// THIS IS WHERE THE CLASSCASTEXCEPTION HAPPENS!
throw new ClassCastException(context.toString());
}
}
@Override
public MultiDialogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.layout_multiselect_dialog_row, parent, false);
return new MultiDialogViewHolder(view);
}
@Override
public void onBindViewHolder(MultiDialogViewHolder holder, int position) {
final String item = mItems.get(position);
holder.getItemTextView().setText(item);
holder.getItemTextView().setTypeface(mCustomFont.getPrimaryFontMedium());
holder.getItemTextView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCommunicator.onDialogButtonResponse(item);
}
});
}
@Override
public int getItemCount() {
return mItems.size();
}
}
class MultiDialogViewHolder extends RecyclerView.ViewHolder {
private TextView mItemTextView;
public MultiDialogViewHolder(View rootView) {
super(rootView);
mItemTextView = (TextView) rootView.findViewById(R.id.item_text_view);
}
public TextView getItemTextView() {
return mItemTextView;
}
}
public class DialogCommunicator {
public interface Communicator {
public void onDialogButtonResponse(String responseMessage);
}
}
CustomDialogFragment.java
//*****************//
// THIS CODE WORKS //
//*****************//
// This code will run when the button is clicked.
// postOptions is a string array of menu items.
Bundle args = new Bundle();
args.putStringArray("displaymenu", postOptions);
mDialogFragment = new CustomDialogFragment();
mDialogFragment.setArguments(args);
mDialogFragment.show(getSupportFragmentManager(), "title");
//***************************//
// THIS CODE CRASHES THE APP //
//***************************//
// This code is planted in onClick method listener in onBindViewHolder
// for the button that's supposed to open the fragment dialog.
FragmentManager fm = ((MainActivity) mContext).getSupportFragmentManager();
String[] items = mContext.getResources().getStringArray(R.array.post_options);
CustomDialogFragment customDialogFragment = CustomDialogFragment.newInstance(items);
customDialogFragment.show(fm, "title");
public class CustomDialogFragment extends DialogFragment {
private RecyclerView mRecyclerView;
public CustomDialogFragment() {
// Empty constructor is required for DialogFragment
// Make sure not to add arguments to the constructor
// Use `newInstance` instead as shown below
}
public static CustomDialogFragment newInstance(String[] items) {
CustomDialogFragment customDialogFragment = new CustomDialogFragment();
Bundle args = new Bundle();
args.putStringArray("displaymenu", items);
customDialogFragment.setArguments(args);
return customDialogFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_multiselect_dialog, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
String[] items = args.getStringArray("displaymenu");
List<String> itemsList = Arrays.asList(items);
// THIS LINE CRASHES ON POSTSLISTADAPTER!!!
MultiDialogAdapter adapter = new MultiDialogAdapter(getActivity(), itemsList);
mRecyclerView = (RecyclerView) view.findViewById(R.id.items_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(adapter);
getDialog().setTitle(null);
}
}
public class MultiDialogAdapter extends RecyclerView.Adapter<MultiDialogViewHolder> {
private List<String> mItems;
private LayoutInflater mInflater;
private CustomFonts mCustomFont;
private DialogCommunicator.Communicator mCommunicator;
public MultiDialogAdapter(Context context, List<String> items) {
this.mInflater = LayoutInflater.from(context);
this.mItems = items;
this.mCustomFont = new CustomFonts(context);
try {
mCommunicator = (DialogCommunicator.Communicator) context;
} catch (ClassCastException e) {
// THIS IS WHERE THE CLASSCASTEXCEPTION HAPPENS!
throw new ClassCastException(context.toString());
}
}
@Override
public MultiDialogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.layout_multiselect_dialog_row, parent, false);
return new MultiDialogViewHolder(view);
}
@Override
public void onBindViewHolder(MultiDialogViewHolder holder, int position) {
final String item = mItems.get(position);
holder.getItemTextView().setText(item);
holder.getItemTextView().setTypeface(mCustomFont.getPrimaryFontMedium());
holder.getItemTextView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCommunicator.onDialogButtonResponse(item);
}
});
}
@Override
public int getItemCount() {
return mItems.size();
}
}
class MultiDialogViewHolder extends RecyclerView.ViewHolder {
private TextView mItemTextView;
public MultiDialogViewHolder(View rootView) {
super(rootView);
mItemTextView = (TextView) rootView.findViewById(R.id.item_text_view);
}
public TextView getItemTextView() {
return mItemTextView;
}
}
public class DialogCommunicator {
public interface Communicator {
public void onDialogButtonResponse(String responseMessage);
}
}
崩溃日志:
10-06 14:35:12.353 21683-21683/com.example.appname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.appname, PID: 21683
java.lang.ClassCastException: com.example.appname.MainActivity@e06db1e
at adapters.MultiDialogAdapter.<init>(MultiDialogAdapter.java:40)
at fragments.CustomDialogFragment.onViewCreated(CustomDialogFragment.java:60)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1430)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
10-06 14:35:12.353 21683-21683/com.example.appname E/AndroidRuntime:FATAL EXCEPTION:main
进程:com.example.appname,PID:21683
java.lang.ClassCastException:com.example.appname。MainActivity@e06db1e
MultiDialogAdapter.java:40)
在fragments.CustomDialogFragment.onViewCreated(CustomDialogFragment.java:60)
位于android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1430)
位于android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
位于android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
位于android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
位于android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
在android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
在android.support.v4.app.FragmentManagerImpl.removedandtoperationsandexecute(FragmentManager.java:2322)
位于android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
位于android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
位于android.os.Handler.handleCallback(Handler.java:751)
位于android.os.Handler.dispatchMessage(Handler.java:95)
位于android.os.Looper.loop(Looper.java:154)
位于android.app.ActivityThread.main(ActivityThread.java:6776)
位于java.lang.reflect.Method.invoke(本机方法)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
我有一个在PostsListAdapter.java
和SecondActivity.java
中实现的接口。这是一个回调方法,因此我可以响应每个单独的操作,并知道在片段对话框弹出窗口中单击了哪些项
因此,我正确地构建了对话框片段,因为它在列表之外的正常活动中工作,但是对于RecyclerView列表中的每一行,该对话框片段会因为
ClassCastException
而使应用程序崩溃。为什么?您可以使用parent.getContext()在onCreateViewHolder中获取构造函数,而不是将上下文作为对象传递。
此外,在onBindViewholder中,您忘了键入Cast viewholder。添加
MultiDialogViewHolder viewholder=(MultiDialogViewHolder)holder;
然后访问viewholder.getItemTextView().setText(item)代码>
同样,在转换适配器中的上下文之前,对话框片段应实现DialogCommunicator
。在对话框片段中添加DialogCommunicator
的实现
public class CustomDialogFragment extends DialogFragment implements DialogCommunicator {
//override the method
}
编辑:
发生错误的另一个主要问题是由于上下文。
这里传递multi-dialogadapter=new-multi-dialogadapter(getContext(),itemsList)
如果要将getActivity()传递给适配器,则相应的activity必须实现接口DialogCommunicator
,回调将转到activity,而不是CustomDialogFragment
因此,传递getContext()
而不是getActivity()
,因为CustomDialogFragment实现的是接口而不是活动。而不是将上下文作为对象传递,您可以使用parent.getContext()在onCreateViewHolder中获取构造函数。
此外,在onBindViewholder中,您忘了键入Cast viewholder。添加
MultiDialogViewHolder viewholder=(MultiDialogViewHolder)holder;
然后访问viewholder.getItemTextView().setText(item)代码>
同样,在转换适配器中的上下文之前,对话框片段应实现DialogCommunicator
。在对话框片段中添加DialogCommunicator
的实现
public class CustomDialogFragment extends DialogFragment implements DialogCommunicator {
//override the method
}
编辑:
发生错误的另一个主要问题是由于上下文。
这里传递multi-dialogadapter=new-multi-dialogadapter(getContext(),itemsList)
如果要将getActivity()传递给适配器,则相应的activity必须实现接口DialogCommunicator
,回调将转到activity,而不是CustomDialogFragment
因此,请传递getContext()
而不是getActivity()
,因为CustomDialogFragment正在实现接口而不是活动。您的崩溃非常明显:
MainActivity
无法转换为DialogCommunicator$Communicator
根据您发布的内容,您尚未在MainActivity
中实现此接口。你说:
我有一个在PostsListAdapter.java
和SecondActivity.java
中实现的接口
从postslistatadapterimplements DialogCommunicator.Communicator
行的可能性非常大