简体   繁体   English

使用意图从ViewHolder内部启动活动会使应用程序崩溃

[英]Using intent to start an activity from inside my ViewHolder crashes the app

I am trying to call another activity using Intent - the code generates a list of cards and I want the user to be able to edit a card by clicking it. 我正在尝试使用Intent调用另一个活动-该代码生成了卡片列表,我希望用户能够通过单击它来编辑卡片。 The rest of the code works fine but the app crashes when I click a card. 其余代码工作正常,但是当我单击卡片时应用程序崩溃。

public class NoteCardAdapter extends RecyclerView.Adapter<NoteCardAdapter.NoteCardViewHolder> {

    private Context mCtx;
    private List<NoteCard> noteCardList;

    public NoteCardAdapter(Context mCtx, List<NoteCard> noteCardList) {
        this.mCtx = mCtx;
        this.noteCardList = noteCardList;
    }

    @Override
    public NoteCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        LayoutInflater inflater = LayoutInflater.from(mCtx);
        View view = inflater.inflate(R.layout.note_layout, null);
        return new NoteCardViewHolder(view);

    }

    @Override
    public void onBindViewHolder(final NoteCardViewHolder holder, int position) {

        final NoteCard noteCard = noteCardList.get(position);

        holder.noteCardTitle.setText(noteCard.getNoteCardTitle());
        holder.noteCardSummary.setText(noteCard.getNoteCardSummary());
    }

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



    class NoteCardViewHolder extends RecyclerView.ViewHolder {

        public TextView noteCardTitle, noteCardSummary;
        public LinearLayout linearLayout;


        private AdapterView.OnItemClickListener itemClickListener;

        public NoteCardViewHolder(final View itemView) {
            super(itemView);

            noteCardTitle = itemView.findViewById(R.id.noteTitleView);
            noteCardSummary = itemView.findViewById(R.id.noteSummaryView);
            linearLayout = itemView.findViewById(R.id.linearLayout);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

//THIS IS WHERE THE APP CRASHES

                    itemView.getContext().startActivity(new Intent(itemView.getContext(), NoteEdit.class));
                }
            });
        }
    }
}

The crash log reads: 崩溃日志显示为:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.dlimited.mydolist, PID: 4007
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dlimited.mydolist/com.dlimited.mydolist.NoteEdit}: java.lang.NullPointerException
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
                      at android.app.ActivityThread.access$800(ActivityThread.java:135)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:136)
                      at android.app.ActivityThread.main(ActivityThread.java:5017)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:515)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
                      at dalvik.system.NativeStart.main(Native Method)
                   Caused by: java.lang.NullPointerException
                      at com.dlimited.mydolist.NoteEdit.onCreate(NoteEdit.java:31)
                      at android.app.Activity.performCreate(Activity.java:5231)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
                      at android.app.ActivityThread.access$800(ActivityThread.java:135) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:136) 
                      at android.app.ActivityThread.main(ActivityThread.java:5017) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:515) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
                      at dalvik.system.NativeStart.main(Native Method) 

Any help will be much appreciated. 任何帮助都感激不尽。

First things first. 首先是第一件事。 When you have those kind of problems, please, also post the crash's log, so we can help you with more accuracy. 遇到此类问题时,请同时发布崩溃日志,以便我们为您提供更高的准确性。

Let me get that straight, you want to call an activity when you click on a Recyclerview's list, right? 让我说清楚,您想在单击Recyclerview的列表时调用一个活动,对吗? Yes, it should work, if you this right. 是的,如果您说对了,它应该可以工作。 You can implement a click listener with your ViewHolder and override the onClick method.. 您可以使用ViewHolder实现点击侦听器,并覆盖onClick方法。

 class NoteCardViewHolder extends RecyclerView.ViewHolder 
                 iplements View.onClickListener {
 ....
    @Override
    public void onClick(View view) {

       Intent intent = new Intent(getActivity(), YourActivity.class);
       startActivity(intent);

    }
 }

use the mCtx you have above. 使用上面的mCtx

            mCtx.startActivity(new Intent(mCtx, NoteEdit.class));

Edit: 编辑:

after adding your logcat. 添加您的logcat之后。 the problem is not in your activity. 问题不在于您的活动。 it's in the second activity 在第二个活动中

You should not starting the activity from Adapter. 不应该从适配器启动活动。 An Adapter should only handling the view for each item in the data set. 适配器仅应处理数据集中每个项目的视图 All related to the item view in adapter can be done in it but no more. 与适配器中的项目视图相关的所有操作都可以在其中完成,但不能再进行其他操作。

You need to use Callback/Listener to tell the Activity or Fragment where Adapter reside to start the Activity. 您需要使用回调/侦听器来告诉活动或片段适配器在何处启动活动。

Add a listener to your adapter, something like this: 将侦听器添加到您的适配器,如下所示:

public class NoteCardAdapter extends RecyclerView.Adapter<NoteCardAdapter.NoteCardViewHolder> {

    private Listener mListener;
    public interface Listener {
      void itemClicked();
    }

    ...

    public NoteCardAdapter(Listener, listener, List<NoteCard> noteCardList) {
        this.mListener = listener;
        this.noteCardList = noteCardList;
    }

    ...

    class NoteCardViewHolder extends RecyclerView.ViewHolder {
      ...
      public NoteCardViewHolder(final View itemView) {
        super(itemView);
        ...

        itemView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            mListener.itemClicked();
          }
        });
      }
    }
    ...
}

Then in your Activity caller you need to implement the listener for Adapter: 然后,在您的Activity调用程序中,您需要实现Adapter的侦听器:

NoteCardAdapter.Listener listener = new NoteCardAdapter.Listener() {
      @Override public void onItemClicked() {
        // start the activity here.
        startActivity(new Intent(YourActivity.this, NoteEdit.class));
      }
    });

NoteCardAdapter adapter = new NoteCardAdapter(listener, noteCardList);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM