Получить идентификатор документа из FirebaseRecyclerAdapter и передать значение на новую страницу - PullRequest
0 голосов
/ 06 февраля 2019

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

По сути, я хочу передать идентификатор документа, по которому щелкнулина следующую страницу.Тем не менее, моя кнопка выдает исключение нулевого указателя при нажатии.

Этот код принадлежит моему классу 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); Я думаю, этоможет быть связано с тем, что моя переменная контекста ссылается на себя, но также не уверена, правильно ли я получаю идентификатор.Может кто-нибудь помочь с этим?

Это моя ошибка:

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)

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

это потому что вы назначаете "контекст с самим собой".передать контекст из класса, где вы инициализируете свой адаптер.

предположим, у меня есть адаптер с именем "ClubAdapter" и вызывающим классом с именем "ClubClass"

в 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"msgstr "вы можете передать интерфейс в Адаптер как параметр.

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());
                }
            });
            }
            }
            }
0 голосов
/ 06 февраля 2019

Чтобы решить эту проблему, переместите следующие строки кода в метод 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.

Редактировать:

В соответствии с вашими комментариями, пожалуйста, также выполните следующие операции.Измените конструктор на:

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

И когда вы создадите объект своего класса адаптера внутри действия, передайте также context в конструктор.

...