Передача переменной (позиции) из onBindViewHolder в класс ViewHolder

Я пытаюсь передать строку (userID) из onBindViewHolder в свой класс ViewHolder. Причина в том, что мне нужна позиция для выделения правильного postID. Этот postID используется во ViewHolder в качестве ссылки для настройки Firebase valueEventListener. Однако при запуске приложения я получаю NullPointerException в postID. Это из-за синхронизации? Вызывается ли valueEventListener до установки postID?

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    final PostViewHolder holder1 = (PostViewHolder) holder;
    holder1.postID = getPostId(position)

    //...
}

//...

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

    private DatabaseReference mNoOfLikesRef;
    public String postID;
    //...

    public PostViewHolder(View itemView, postClickListener listener){
        super(itemView);

        //This line causes the NullPointerException on postID
        mNoOfLikesRef = FirebaseDatabase.getInstance().getReference().child("likes").child(postID);
        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //...
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }

        };
        mNoOfLikesRef.addListenerForSingleValueEvent(valueEventListener);

    }

Опубликуйте исходный код get postId (position)

Fazal Hussain 05.04.2018 16:56

Спасибо за ваши комментарии. @ADM, да, postID у каждого элемента разный. Причина, по которой я не установил его в onBindViewHolder, заключается в том, что я пытаюсь предотвратить вызов базы данных Firebase при каждой привязке представления. Я понял, что это нужно установить в onCreateViewHolder, но опять же, это зависит от позиции, которой у меня нет на данном этапе.

P. Wulf 05.04.2018 17:01

Слушатель для каждого пункта списка кажется мне довольно беспокойным. Зачем это нужно? Если у вас есть 100 пунктов списка, будет 100 слушателей. IMHO, вы должны зарегистрировать одного слушателя в корневом каталоге и использовать DiffUtil для уведомления об изменениях в адаптере. Если это покрытие вашей потребности! В противном случае вам нужно управлять слушателями, когда представление строки повторно используется во время прокрутки.

ADM 05.04.2018 17:06

@ADM, на самом деле у меня есть следующее: я использую Firestore для сохранения сообщений, временных меток и т. д. И передаю их в виде списка в адаптер. Каждому из этих постов можно понравиться или не понравиться, и у меня есть счетчик лайков / антипатий в Firebase RTDB (многие операции и использование транзакций). Использование DiffUtil в корневом каталоге будет запускаться для каждого лайка / антипатии в любом посте :(.

P. Wulf 05.04.2018 17:16

ОК . Что делать, если добавлен новый пост? Как добавить новую запись в адаптер? Или в том же корне нового поста не будет?

ADM 05.04.2018 17:37

Дополнительная информация о моем коде - здесь, если кому-то интересно. До сих пор я не нашел «подходящего» решения для функциональности лайков / антипатий с помощью firebase, это создавало огромные накладные расходы протокола (как проверено с помощью Stackdriver) из-за частых запросов.

P. Wulf 06.04.2018 10:13
0
6
913
2

Ответы 2

Да, вы вызываете его в конструкторе PostViewHolder, который вызывается методом onCreateViewHolder перед onBindViewHolder.

создать метод внутри класса ViewHolder и вызвать его из onBindViewHolder

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    final PostViewHolder holder1 = (PostViewHolder) holder;
    holder1.doYourTask(getPostId(position));

    //...
}

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

//...

public void doYourTask(String postID){
    DatabaseReference mNoOfLikesRef = FirebaseDatabase.getInstance().getReference().child("likes").child(postID);
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            //...
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }

    };
    mNoOfLikesRef.addListenerForSingleValueEvent(valueEventListener);
}

}

Это то, что он пытался сказать. Я попытался написать его первым, но Шалауддин Ахамад Шуза оказался быстрее. Если вы получаете NullPointerException не потому, что вы его неправильно передаете, это означает, что getPostId(position) не возвращает правильное значение.

Alex Mamo 05.04.2018 17:07

При использовании этого подхода SingleValueEventListener запускается каждый раз при привязке нового просмотра, верно? Я как-то хотел предотвратить это, вызвав это в самом ViewHolder. Есть ли способ сделать это?

P. Wulf 05.04.2018 17:07

Другие вопросы по теме