Как отобразить несколько моделей в представлении ресайклера с помощью одного и того же адаптера?

У меня есть два разных типа объектов (например, Пользователь и Студент) с разными свойствами.

Пользователь: Название, описание;
Ученик: Название, описание, USN;

Есть ли способ, с помощью которого я могу сначала отобразить двух пользователей, а затем студентов в представлении ресайклера с использованием того же адаптера? Как мне его отобразить, даже если это два переходника. Мне не нужны два вида переработчиков.

Обратите внимание, что приведенный пример очень прост. Изменение касается не только пользовательского интерфейса. Если изменение только в пользовательском интерфейсе, то можно использовать getItemViewType (), но здесь изменение касается самой модели.

List<Student> и List<User>

Как настроить оба списка на один и тот же адаптер?

каковы свойства Student. Добавьте код Уважаемый, чтобы другие могли вам помочь

Jawad Zeb 10.09.2018 08:37

Для этого используйте привязку данных.

Hemant Parmar 10.09.2018 08:39

Вы можете использовать интерфейс Marker здесь.

Pankaj Kant Patel 10.09.2018 08:40

вы пробовали использовать представление об утилизации расходных материалов?

Umair 10.09.2018 08:42

Возможный дубликат Как создать RecyclerView с несколькими типами просмотра?

Manohar 10.09.2018 08:51

Есть действительно хорошие примеры того, что вы пытаетесь сделать с хорошим объяснением. Даже начиная с 2010 года: android.amberfog.com/?p=296, medium.com/@sreekumar_av/…, guides.codepath.com/android/…

Variag 14.09.2018 10:03
3
6
3 093
3

Ответы 3

просто используйте viewType, верните другой viewType и привяжите разные данные в onBindViewHolder

Вы должны использовать метод переопределения "getItemViewType (position)".

Затем просто верните ViewHolder в соответствии с ViewType следующим образом:

  @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    RecyclerView.ViewHolder viewHolder = null;
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());

    switch (viewType) {
        case ITEM:
            View v1 = inflater.inflate(R.layout.item_student, parent, false);
            viewHolder = new UserVH(v1);
            break;
        case LOADING:
            View v2 = inflater.inflate(R.layout.item_user, parent, false);
            viewHolder = new StudentVH(v2);
            break;
    }
    return viewHolder;
}

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

 public class StudentVH extends RecyclerView.ViewHolder {
    //Declare student views

    public ViewHolder(View v) {
        super(v);
        //Inialize student views
    }
}

 public class UserVH extends RecyclerView.ViewHolder {
    //Declare user views

    public ViewHolder(View v) {
        super(v);
        //Inialize user views
    }
}

Второе редактирование:

Ваш адаптер должен быть таким,

public class ClGAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<UserBean> userBeans;
private List<StudentBean> studentBeans;
private UserBean userBeanItem;
private StudentBean studentBeanItem;
private int size = 0;


public ClGAdapter(Context context, List<UserBean> userBeans, List<StudentBean> studentBeans) {
    this.context = context;
    this.userBeans = userBeans;
    this.studentBeans = studentBeans;
    this.size = userBeans.size() + studentBeans.size();
}


@Override
public int getItemViewType(int position) {

    if (position > (userBeans.size() - 1)) {
        return 2;//TYPE_STUDENT
    } else {
        return 1; //TYPE_USER
    }
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

    int viewType = holder.getItemViewType();

    userBeanItem = userBeans.get(position);
    studentBeanItem = studentBeans.get(position);
    switch (viewType) {
        case 1:
            ((UserHolder) holder).mUserName.setText(userBeanItem.getUserName());
            break;
        case 2:
            ((StudentHolder) holder).mStudentName.setText(studentBeanItem.getStudentName());
            break;
        default:
            break;
    }

}

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

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    int layout = 0;
    RecyclerView.ViewHolder viewHolder;
    switch (viewType) {
        case 1: 
            layout = R.layout.user_card;
            View userView = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
            viewHolder = new UserHolder(userView);
            break;
        case 2:
            layout = R.layout.student_card;
            View studentView = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
            viewHolder = new StudentHolder(studentView);

            break;
        default:
            viewHolder = null;
            break;
    }
    return viewHolder;
}

public class UserHolder extends RecyclerView.ViewHolder {
    private TextView mUserName;

    public UserHolder(View v) {
        super(v);
        mUserName = v.findViewById(R.id.user_name);
    }
}

public class StudentHolder extends RecyclerView.ViewHolder {
    private TextView mStudentName;

    public StudentHolder(View v) {
        super(v);
        mStudentName = v.findViewById(R.id.student_name);
    }
}
}

Изменение касается не только пользовательского интерфейса. Дело в самой модели. Как установить List <Student> и List <User> на один и тот же адаптер?

Varun A M 13.09.2018 09:31

Вы должны создать две разные модели и для ученика, и для пользователя, я уже упоминал в своем ответе. Достаточно одного RecyclerView. Спасибо.

Sana 13.09.2018 09:33

Как установить оба списка на один и тот же адаптер? Приведенный вами код относится к ViewHolder, а не к различным моделям.

Varun A M 13.09.2018 09:39

Убедитесь, что я отредактировал свой ответ, и подождите, я предоставлю код, показывающий, как получить список для разных моделей в том же адаптере, а также в том же RecyclerView

Sana 13.09.2018 09:41

Привет, спасибо за редактирование. Я вижу, что вы берете только один список в конструкторе, а у меня два списка. Вот где моя проблема :(

Varun A M 13.09.2018 10:03

Я отредактировал свой код. Пожалуйста, проверьте. Он подойдет вам. И, если вы считаете, что это полезно, отметьте его как принятый. Спасибо.

Sana 13.09.2018 10:38

Приведу свою реализацию, надеюсь поможет:

public class UserStudentAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int USER_VIEW_TYPE = 0;
    private static final int STUDENT_VIEW_TYPE = 1;

    private List<User> mUserData;
    private List<Student> mStudentData;

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case HEADER_VIEW_TYPE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_definition_header, parent, false);
                return new HeaderViewHolder(view);
            case CONTENT_VIEW_TYPE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_index, parent, false);
                return new ItemViewHolder(view);
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (getItemViewType(position)) {
            case USER_VIEW_TYPE:
                //Show User data
                break;
            case STUDENT_VIEW_TYPE:
                //Show Student data
                break;
            default:
                break;
        }
    }

    @Override
    public int getItemCount() {
        return mUserData.size() + mStudentData.size();
    }

    @Override
    public int getItemViewType(int position) {
        return (position % 2 == 0) ? STUDENT_VIEW_TYPE : USER_VIEW_TYPE;
    }

}

Изменение касается не только пользовательского интерфейса. Дело в самой модели. Как установить List <Student> и List <User> на один и тот же адаптер?

Varun A M 13.09.2018 09:31

У вас есть два варианта. Первый из них, который я представляю в своем примере, имеет два разных списка в адаптере: один для списка пользователей List <User> mUserData и один для списка студентов <Student> mStudentData. Другой вариант - если у ваших классов User и Student есть общий родительский элемент, например Person, и у вас может быть только один список в вашем адаптере List <Person> mData. В зависимости от того, какой вариант вы выберете, ваш адаптер должен иметь разные методы для обновления данных, например, public void updateData (List <Person> data) и вызов notifyDataSetChanged ()

MrVasilev 13.09.2018 09:51

@VarunAM - это мой ответ, и комментарий поможет вам? :)

MrVasilev 13.09.2018 11:15

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