【发布时间】:2018-11-23 21:00:09
【问题描述】:
我正在尝试将 Activity 转换为 Fragment 并且我正在努力了解如何正确使用这个。
基本上,我正在尝试调整this MainActivity,使其适合底部导航栏,除了在上下文中迷失之外,我正在处理这个特定问题:
E/AndroidRuntime: 致命异常: main 进程: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:1784) 在 android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852) 在 android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802) 在 android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625) 在 android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411) 在 android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366) 在 android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273) 在 android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733) 在 android.os.Handler.handleCallback(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/Process:发送信号。 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 调用到屏幕的按钮,就会引发错误并且应用程序会立即停止运行。
提前感谢您的关注和帮助,如果您需要了解有关此问题的更多信息,请告诉我,以便我能够在此处提供更多信息。
【问题讨论】:
-
您在
NotesAdapter构造函数调用中为Context参数传递了getActivity()。那是托管Fragment的Activity,而不是Fragment本身。你的Activity显然没有实现OnNoteItemClick接口,这就是你得到Exception的原因。你想通过Fragment——即this——作为OnNoteItemClick实现者。您可以将Context参数更改为Fragment,将其转换为您的接口,然后在构造函数中调用getActivity()以获取您的Context。 -
迈克,非常感谢您的评论以及您对本主题的参与!您的话足以向我展示方法,并且 MainActivity 中包含大部分代码的简单帮助程序类解决了这个问题(现在我只需要了解该怎么做才能将数据库内容显示在正确的位置)。如果您愿意,请随时发表您的评论作为答案。
-
哦,我很好。 :-) 这只是一个快速的建议。不过谢谢。我真的很感激这个提议。如果您愿意,请在您的解决方案中发布答案。真高兴你做到了。干杯!
-
我一定会这样做,我只需要先让它按预期工作。祝你周末愉快,再次感谢迈克!
标签: android android-fragments android-activity casting android-adapter