java.lang.ClassCastException: действие не может быть приведено к адаптеру при попытке преобразовать действие во фрагмент - PullRequest
0 голосов
/ 24 ноября 2018

Я пытаюсь преобразовать Activity в Fragment и пытаюсь понять, как сделать это правильно с этим.

По сути, я пытаюсь адаптировать эту MainActivity так, чтобы она соответствовала нижней панели навигации, и помимо того, что я теряюсь в контексте, я имею дело с этой конкретной проблемой:

E / AndroidRuntime: ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: основной Процесс: com.example.com, PID: 5213 java.lang.ClassCastException: com.example.com.MainActivity не может быть приведен к com.example.com.adapter.NotesAdapter$ OnNoteItemClick на com.example.com.adapter.NotesAdapter. (NotesAdapter.java:27) на com.example.com.RoomMarkdownActivity.onCreateView (RoomMarkdownActivity.java:54) на android.support.v4.app.Fragment.performCreateView (Fragment.java:2439) в android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1460) в android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManager.java:4supp.jroid:4suppv) и.app.FragmentManagerImpl.moveToState (FragmentManager.java:1852) в android.support.v4.app.BackStackRecord.executeOps (BackStackRecord.java:802) в android.support.v4.app.: 2366) по адресу android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:2273) по адресу android.support.v4.app.FragmentManagerImpl $ 1.(Handler.java:873) в android.os.Handler.dispatchMessage (Handler.java:99) в android.os.Looper.loop (Looper.java:193) в android.app.ActivityThread.main (ActivityThread.java:6669) в java.lang.reflect.Method.invoke (собственный метод) в com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run (RuntimeInit.java:493) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:858)

I / Процесс: отправка сигнала.PID: 5213 SIG: 9 Приложение завершено.

Вот копия фрагмента кода, над которым я работаю:

public class RoomMarkdownActivity extends Fragment implements NotesAdapter.OnNoteItemClick {

    public static RoomMarkdownActivity newInstance() { return new RoomMarkdownActivity(); }

    public RecyclerView recyclerView;
    public TextView textViewMsg;
    public NoteDatabase noteDatabase;
    public List<Note> notes;
    public NotesAdapter notesAdapter;
    public int pos;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.room_markdown_activity, container, false);

        textViewMsg = view.findViewById(R.id.textview_empty);
        FloatingActionButton fab = view.findViewById(R.id.fab);
        fab.setOnClickListener(listener);
        recyclerView = view.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        notes = new ArrayList<>();
        notesAdapter = new NotesAdapter(notes, getActivity());
        recyclerView.setAdapter(notesAdapter);
        noteDatabase = NoteDatabase.getInstance(getActivity());
        new RetrieveTask(this).execute();

        return view;
    }

    private static class RetrieveTask extends AsyncTask<Void, Void, List<Note>> {

        private WeakReference<RoomMarkdownActivity> activityReference;

        RetrieveTask(RoomMarkdownActivity context) {
            activityReference = new WeakReference<>(context);
        }

        @Override
        protected List<Note> doInBackground(Void... voids) {
            if (activityReference.get() != null)
                return activityReference.get().noteDatabase.getNoteDao().getNotes();
            else
                return null;
        }

        @Override
        protected void onPostExecute(List<Note> notes) {
            if (notes != null && notes.size() > 0) {
                activityReference.get().notes.clear();
                activityReference.get().notes.addAll(notes);
                activityReference.get().textViewMsg.setVisibility(View.GONE);
                activityReference.get().notesAdapter.notifyDataSetChanged();
            }
        }
    }

    private View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivityForResult(new Intent(getActivity(), RoomMarkdownAddNoteActivity.class), 100);
        }
    };

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 100 && resultCode > 0) {
            if (resultCode == 1) {
                notes.add((Note) data.getSerializableExtra("note"));
            } else if (resultCode == 2) {
                notes.set(pos, (Note) data.getSerializableExtra("note"));
            }
            listVisibility();
        }
    }

    @Override
    public void onNoteClick(final int pos) {
        new AlertDialog.Builder(recyclerView.getContext())
                .setTitle("Select:")
                .setItems(new String[]{"Read", "Update", "Delete"}, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        switch (i) {
                            case 0:
                                RoomMarkdownActivity.this.pos = pos;
                                startActivityForResult(
                                        new Intent(getActivity(),
                                                RoomMarkdownViewNoteActivity.class).putExtra(
                                                "note", notes.get(pos)), 100);
                                break;
                            case 1:
                                RoomMarkdownActivity.this.pos = pos;
                                startActivityForResult(
                                        new Intent(getActivity(),
                                                RoomMarkdownAddNoteActivity.class).putExtra(
                                                "note", notes.get(pos)), 100);
                                break;
                            case 2:
                                noteDatabase.getNoteDao().deleteNote(notes.get(pos));
                                notes.remove(pos);
                                listVisibility();
                                break;
                        }
                    }
                }).show();
    }

    private void listVisibility() {
        int emptyMsgVisibility = View.GONE;
        if (notes.size() == 0) {
            if (textViewMsg.getVisibility() == View.GONE)
                emptyMsgVisibility = View.VISIBLE;
        }
        textViewMsg.setVisibility(emptyMsgVisibility);
        notesAdapter.notifyDataSetChanged();
    }

    @Override
    public void onDestroy() {
        noteDatabase.cleanUp();
        super.onDestroy();
    }

}

А вот адаптер:

public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.BeanHolder> {

    private List<Note> list;
    public Context context;
    private LayoutInflater layoutInflater;
    private OnNoteItemClick onNoteItemClick;

    public NotesAdapter(List<Note> list, Context context) {
        layoutInflater = LayoutInflater.from(context);
        this.list = list;
        this.context = context;
        this.onNoteItemClick = (OnNoteItemClick) context;
    }

    @Override
    public BeanHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = layoutInflater.inflate(R.layout.room_markdown_note_list_item, parent, false);
        return new BeanHolder(view);
    }

    @Override
    public void onBindViewHolder(BeanHolder holder, int position) {
        Log.e("bind", "onBindViewHolder: " + list.get(position));
        holder.textViewTitle.setText(list.get(position).getTitle());
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class BeanHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView textViewTitle;

        private BeanHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            textViewTitle = itemView.findViewById(R.id.textview_title);
        }

        @Override
        public void onClick(View view) {
            onNoteItemClick.onNoteClick(getAdapterPosition());
        }
    }

    public interface OnNoteItemClick {
        void onNoteClick(int pos);
    }

}

Кажется, что-то сломалось между notesAdapter = new NotesAdapter(notes, getActivity()); и this.onNoteItemClick = (OnNoteItemClick) context;, но я не смог найти хорошую альтернативу getActivity(), и я думаю, что я решил эту проблему ранее в другом подходе, однако это быловыдает еще одну похожую ошибку, если я правильно помню (этот файл полон this, и я не сомневаюсь, что некоторые getActivity() неуместны).

Код компилируется, но, как тольконажата кнопка, которая вызывает конкретный Fragment к экрану, выдается ошибка, и приложение немедленно прекращает работу.

Заранее благодарю за внимание и помощь и, пожалуйста, дайте мне знатьесли вам нужно больше узнать об этой проблеме, чтобы я мог предоставить больше информации здесь.

Ответы [ 3 ]

0 голосов
/ 24 ноября 2018

заменить

notesAdapter = new NotesAdapter(notes, getActivity());

на

notesAdapter = new NotesAdapter(notes, RoomMarkdownActivity.this);
0 голосов
/ 27 ноября 2018

Благодаря тому, что Майк М. и Реза.Абедини сказал среди ответов и комментариев, я смог понять, что происходит, и преодолеть эту проблему.

Проблема была в Adapter, который был подготовлен для получения Context из Activity, поэтому мне пришлось преобразовать параметр в Fragment, и в итоге он работал так:

public NotesAdapter(List<Note> list, RoomMarkdownActivity fragment) {
    this.layoutInflater = LayoutInflater.from(fragment.getActivity());
    this.list = list;
    this.fragment = fragment;
    this.onNoteItemClick = fragment;
}

Fragment нравится:

public class RoomMarkdownActivity extends Fragment implements NotesAdapter.OnNoteItemClick {

    public static RoomMarkdownActivity newInstance() {
        return new RoomMarkdownActivity();
    }

    RecyclerView recyclerView;
    TextView textViewMsg;
    NoteDatabase noteDatabase;
    List<Note> notes;
    NotesAdapter notesAdapter;
    int pos;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.room_markdown_activity, container, false);
        textViewMsg = view.findViewById(R.id.textview_empty);
        FloatingActionButton fab = view.findViewById(R.id.fab);
        fab.setOnClickListener(listener);
        recyclerView = view.findViewById(R.id.recycler_view);
        initializeViews();
        displayList();
        return view;
    }

    private void displayList() {
        noteDatabase = NoteDatabase.getInstance(getActivity());
        new RetrieveTask(this).execute();
    }

    private static class RetrieveTask extends AsyncTask<Void, Void, List<Note>> {

        private WeakReference<RoomMarkdownActivity> activityReference;

        RetrieveTask(RoomMarkdownActivity context) {
            activityReference = new WeakReference<>(context);
        }

        @Override
        protected List<Note> doInBackground(Void... voids) {
            if (activityReference.get() != null)
                return activityReference.get().noteDatabase.getNoteDao().getNotes();
            else
                return null;
        }

        @Override
        protected void onPostExecute(List<Note> notes) {
            if (notes != null && notes.size() > 0) {
                activityReference.get().notes.clear();
                activityReference.get().notes.addAll(notes);
                activityReference.get().textViewMsg.setVisibility(View.GONE);
                activityReference.get().notesAdapter.notifyDataSetChanged();
            }
        }
    }

    public void initializeViews() {
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        notes = new ArrayList<>();
        notesAdapter = new NotesAdapter(notes, this);
        recyclerView.setAdapter(notesAdapter);
    }

    private View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivityForResult(new Intent(getActivity(), RoomMarkdownAddNoteActivity.class), 100);
        }
    };

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 100 && resultCode > 0) {
            if (resultCode == 1) {
                notes.add((Note) data.getSerializableExtra("note"));
            } else if (resultCode == 2) {
                notes.set(pos, (Note) data.getSerializableExtra("note"));
            }
            listVisibility();
        }
    }

    @Override
    public void onNoteClick(final int pos) {
        new AlertDialog.Builder(getActivity())
                .setTitle("Select:")
                .setItems(new String[]{"Read", "Update", "Delete"}, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        switch (i) {
                            case 0:
                                RoomMarkdownActivity.this.pos = pos;
                                startActivityForResult(
                                        new Intent(getActivity(),
                                                RoomMarkdownViewNoteActivity.class).putExtra(
                                                "note", notes.get(pos)), 100);
                                break;
                            case 1:
                                RoomMarkdownActivity.this.pos = pos;
                                startActivityForResult(
                                        new Intent(getActivity(),
                                                RoomMarkdownAddNoteActivity.class).putExtra(
                                                "note", notes.get(pos)), 100);
                                break;
                            case 2:
                                noteDatabase.getNoteDao().deleteNote(notes.get(pos));
                                notes.remove(pos);
                                listVisibility();
                                break;
                        }
                    }
                }).show();
    }

    public void listVisibility() {
        int emptyMsgVisibility = View.GONE;
        if (notes.size() == 0) {
            if (textViewMsg.getVisibility() == View.GONE)
                emptyMsgVisibility = View.VISIBLE;
        }
        textViewMsg.setVisibility(emptyMsgVisibility);
        notesAdapter.notifyDataSetChanged();
    }

    @Override
    public void onDestroy() {
        noteDatabase.cleanUp();
        super.onDestroy();
    }

}

Большое спасибо за помощь, и я надеюсь, что этот вопрос / ответ также поможет другим!

0 голосов
/ 24 ноября 2018

Вы не можете привести Activity к OnNoteItemClick, потому что вы внедрили его в свой фрагмент, вы можете назначить OnNoteItemClick для вашего адаптера, чтобы вы могли изменить свой код на: adapter:

public NotesAdapter(List<Note> list, OnNoteItemClick onNoteItemClick) {
    layoutInflater = LayoutInflater.from(context);
    this.list = list;
    this.context = context;
    this.onNoteItemClick = onNoteItemClick;
}

инициализировать ваш адаптер во фрагменте thisпуть:

notesAdapter = new NotesAdapter(notes, this); //Your class implements OnNoteItemClick interface so you can use 'this'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...