【问题标题】:Get Document ID from FirebaseRecyclerAdapter and pass value to new page从 FirebaseRecyclerAdapter 获取文档 ID 并将值传递到新页面
【发布时间】:2019-02-06 12:06:30
【问题描述】:

我有一个显示文档列表的 FirestoreRecyclerAdapter。我在列表中的每个项目旁边都有一个按钮。 单击此按钮时,我想获取所选项目的唯一 ID,然后将用户带到显示该项目的个人详细信息的页面。

基本上我想将点击的文档的 ID 传递到下一页。但是,我的按钮在单击时会引发空指针异常。

这段代码来自我的 ClubAdapter 类。

public class ClubAdapter1 extends FirestoreRecyclerAdapter<Club, ClubAdapter1.ClubHolder> {

    private String clubId;
    private Context context;

    public ClubAdapter1(@NonNull FirestoreRecyclerOptions<Club> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull ClubHolder holder, int position, @NonNull Club model) {
        holder.lblName.setText(model.getClubName());
        //getting the ID of the particular event clicked
        clubId = getSnapshots().getSnapshot(position).getId();

        holder.btnDetails.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(context, ViewSingleClub.class);
                i.putExtra("id", clubId);
                context.startActivity(i);
            }
        });
    }

    @NonNull
    @Override
    public ClubHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.clublist_layout, parent, false);
        return new ClubHolder(v);
    }

    class ClubHolder extends RecyclerView.ViewHolder {

        TextView lblName;
        Button btnDetails;

        public ClubHolder(@NonNull View itemView) {
            super(itemView);

            lblName = itemView.findViewById(R.id.lblName);
            btnDetails = itemView.findViewById(R.id.btnDetails);
        }
    }
}

我一直收到错误消息 Intent i = new Intent(context, ViewSingleClub.class); 我认为这可能与我的上下文变量引用自身有关,但也不确定我是否正确获取了 ID。 有人可以帮忙吗?

这是我的错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.marykate.marykatefordefyp, PID: 2718
    java.lang.NullPointerException
        at android.content.ComponentName.<init>(ComponentName.java:77)
        at android.content.Intent.<init>(Intent.java:3842)
        at com.example.marykate.marykatefordefyp.ClubAdapter1$1.onClick(ClubAdapter1.java:36)
        at android.view.View.performClick(View.java:4457)
        at android.view.View$PerformClick.run(View.java:18491)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5336)
        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:865)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:681)
        at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

    标签: java android firebase google-cloud-firestore firebaseui


    【解决方案1】:

    这是因为您正在分配“自身的上下文”。从初始化适配器的类中传递上下文。

    假设我有名为“ClubAdapter”的适配器和名为“ClubClass”的调用类

    在俱乐部类:

    ClubAdapter clubAdapter = new ClubAdapter(list, context);
    // if you'r calling it from activity then pass "Activity.this" and if fragment then "getContext()" as context.
    并在 ClubAdapter

    public class ClubAdapter extends RecyclerView.Adapter<ClubAdapter.ClubHolder> {
        private Context context;
        private List<String> list;
       
    
        public ClubAdapter(List<String> list, Context context) {
            this.list = list;
            this.context = context;
        }
        
        @NonNull
        @Override
        public ClubHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            View itemView = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.item_sample, viewGroup, false);
            return new ClubHolder(itemView, context);
        }
        
        
        public class ClubHolder extends RecyclerView.ViewHolder {
    
            private Context context;
    
            private ClunHolder(@NonNull View itemView,Context context) {
                super(itemView);
                this.context = context;
               
            }
            }
    }

    或者你可以制作这样的界面。

    public interface RecycleViewOnItemClickListener {
        void onItemClick(int position);
    }

    并将其从调用类传递给您的适配器。

    假设我有名为“SampleAdapter”的适配器和名为“SampleClass”的调用类 在“SampleClass”中,您可以将适配器中的接口作为参数传递。

    SampleAdapter sampleAdapter = new SampleAdapter(list, new RecycleViewOnItemClickListener() {
                @Override
                public void onItemClick(int position) {
                    // do what you want to perform
                }
            });

    在“ClubAdapter”中

    public class ClubAdapter extends RecyclerView.Adapter<ClubAdapter.ClubHolder> {
            private RecycleViewOnItemClickListener recycleViewOnItemClickListener;
            private List<String> list;
           
    
            public ClubAdapter(List<String> list, RecycleViewOnItemClickListener recycleViewOnItemClickListener) {
                this.list = list;
                this.recycleViewOnItemClickListener = recycleViewOnItemClickListener;
            }
            
            @NonNull
            @Override
            public ClubHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                View itemView = LayoutInflater.from(viewGroup.getContext())
                        .inflate(R.layout.item_sample, viewGroup, false);
                return new ClubHolder(itemView, recycleViewOnItemClickListener);
            }
            
            
            public class ClubHolder extends RecyclerView.ViewHolder {
    
                private RecycleViewOnItemClickListener recycleViewOnItemClickListener;
    
                private ClunHolder(@NonNull View itemView,RecycleViewOnItemClickListener recycleViewOnItemClickListener) {
                    super(itemView);
                    this.recycleViewOnItemClickListener = recycleViewOnItemClickListener;
                   //you can callback onItemClick method from here on button click event so it give callback in "ClubActivity".
                   btn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        recycleViewOnItemClickListener.onItemClick(getAdapterPosition());
                    }
                });
                }
                }
                }

    【讨论】:

    • 嗨,谢谢你的回答。我是安卓新手,所以我不太明白你的意思。我的适配器在一个单独的类 ViewClubsActivity 中调用。如何使用 .getContext()?
    • 如果您在 Activity 中使用了适配器,那么您可以使用“ViewClubsActivity.this”传递上下文
    • Intent i = new Intent(ViewClubsActivity.this, ViewSingleClub.class);我想这就是你的意思。我收到一条错误消息“ViewClubsActivity.this 不是封闭类”
    • 你能添加整个 ClubsAdapter 类的代码吗?
    • 很抱歉问了这么多问题,但是您究竟是如何通过 ViewClubsActivity 的呢?
    【解决方案2】:

    要解决这个问题,请将以下代码行移动到 onBindViewHolder() 方法中,如下所示:

    holder.btnDetails.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(context, ViewSingleClub.class);
            i.putExtra("id", clubId);
            context.startActivity(i);
        }
    });
    

    看,我在holder.btnDetails 上添加了点击监听器。

    编辑:

    根据您的cmets,还请进行以下操作。将构造函数更改为:

    public ClubAdapter1(@NonNull FirestoreRecyclerOptions<Club> options, Context context) {
        super(options);
        this.context = context;
    }
    

    当您在 Activity 中创建适配器类的对象时,还将 context 传递给构造函数。

    【讨论】:

    • 我在这一行仍然得到一个空指针异常: Intent i = new Intent(context, ViewSingleClub.class);
    • 请添加整个错误(堆栈跟踪)并指出它发生的确切行。
    • 将错误及其所在行添加到我的问题底部
    • 错误发生在哪一行代码?
    • Intent i = new Intent(context, ViewSingleClub.class);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多