java - ClassCastException:使用 DialogFragment 时应用程序崩溃

标签 java android android-fragments classcastexception

我的 MainActivity.java 中有一个 RecyclerView。在每个 RecyclerView 行中,我都有一个按钮,按下它时,它应该打开一个自定义的 fragment 对话框,其中包含 RecyclerView 列表(它是一个多选对话框)。

在我的 SecondActivity.java(这是我的其他 Activity )中,我也有相同的按钮,它应该执行相同的操作(这就是为什么我需要模式作为 fragment 对话框) 。在我的 SecondActivity.java 中,没有 RecyclerView,它只是一个帖子(详细信息页面)。

我的问题:

当我单击 SecondActivity.java 上的弹出窗口按钮时,它会正常打开对话框 fragment 弹出窗口。当我对 RecyclerView 中的任何单独行(位于 MainActivity.java 中)执行相同操作时,我收到 ClassCastException 错误:

java.lang.ClassCastException: com.example.appname.MainActivity cannot be cast to interfaces.DialogCommunicator$Communicator

我的代码:

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");

PostsListAdapter.java

//***************************//
// 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");

CustomDialogFragment.java

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);
    }

}

MultiDialogAdapter.java

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;
    }

}

DialogCommunicator.java

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)

我有在 PostsListAdapter.javaSecondActivity.java 中实现的接口(interface)。这是一个回调方法,因此我可以响应每个单独的操作并知道在 fragment 对话框弹出窗口中单击了哪个项目。

所以,我已经正确构建了对话框 fragment ,因为它在列表之外的正常 Activity 中工作,但对于 RecyclerView 列表中的每一行,该对话框 fragment 会由于 ClassCastException 导致应用程序崩溃。为什么?

最佳答案

您可以使用 parent.getContext() 在 onCreateViewHolder 中获取构造函数,而不是将上下文作为对象传递。

此外,在 onBindViewholder 中,您忘记对 viewholder.Add 进行类型转换

MultiDialogViewHolder viewholder=(MultiDialogViewHolder)holder;

然后访问viewholder.getItemTextView().setText(item);

此外,在适配器中键入上下文之前,您的对话框 fragment 应实现 DialogCommunicator。在对话框 fragment 中添加 DialogCommunicator 的实现

public class CustomDialogFragment extends DialogFragment implements DialogCommunicator {

 //override the method
}

编辑:

发生错误的主要问题是由于上下文造成的。 这里传递 MultiDialogAdapter adapter=new MultiDialogAdapter(getContext(), itemsList)

如果您将 getActivity() 传递给适配器,则相应的 Activity 必须实现接口(interface) DialogCommunicator,并且回调将传递给 Activity 而不是 CustomDialogFragment

因此,请传递 getContext() 而不是 getActivity(),因为 CustomDialogFragment 正在实现接口(interface)而不是 Activity 。

关于java - ClassCastException:使用 DialogFragment 时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46605328/

相关文章:

android - 如何加密我的密码 - Android Studio

java - Unicode 字符 ("\u232B") 不显示在按钮上

java - String 方法 isEmpty 在 Android API Levels < 10 中真的不可用吗?

android - 无法将我的头包裹在 Android Fragments 中

java - Android-按钮滑动效果

Android ViewModel 无法在 fragment 更改后继续存在

java - 拼写数字到数字?

java - 部署 war : No Spring WebApplicationInitializer types detected on classpath

java - 无法在 Ubuntu 中将 Jetty9 安装为服务

java - 从应用程序自动发送电子邮件