3. Настройка адаптера для пустого списка

Для начала создадим класс адаптера и настроим его поведение, когда список контактов пуст.

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

Создадим класс адаптера ContactsAdapter с классом ContactHolder внутри.

ContactsAdapter.java
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {

    private final LayoutInflater inflater;
    private final List<Contact> list;

    public ContactsAdapter(Context context, List<Contact> users) {
        this.inflater = LayoutInflater.from(context);
        this.list = users;
    }
    
    @NonNull
    @Override
    public ContactHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        
        return new ContactHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ContactHolder holder, int position) {
    }

    @Override
    public int getItemCount() {
        return list.size();
    }
    
    static class ContactHolder extends RecyclerView.ViewHolder{
        public ContactHolder(@NonNull View itemView) {
            super(itemView);
        }
    }
}

Теперь реализуем вывод сообщения о том, что список пуст. Обратите внимание, что в заготовленном проекте есть два макета - list_contact.xml и list_no_items.xml. Первый макет используется для вывода пункта списка, а второй макет будет использован, когда размер коллекции с контактами будет равен нулю.

Идея состоит в следующем - если коллекция с контактами пустая, то наш списковый элемент будет содержать один пункт, но для этого одного пункта мы будем использовать макет list_no_items.xml , в котором содержится сообщение о том, что список пустой.

Для начала изменим метод getItemCount(). Если list.size() будет равен нулю, то мы должны вернуть 1 (чтобы вывести наш один пункт списка с сообщением), если list.size() будет больше нуля, значит у нас есть контакты для отображения, а значит мы просто вернем list.size().

ContactsAdapter.java
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {

    private final List<Contact> list;
    
    ...

    @Override
    public int getItemCount() {
        if (list.size() == 0)
            return 1;
        else return list.size();
    }
}

Эту конструкцию можно сократить следующим образом

ContactsAdapter.java
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {

    private final List<Contact> list;

    ...

    @Override
    public int getItemCount() {
        return Math.max(list.size(), 1);
    }
}

То есть, в любом случае, наш список будет содержать, как минимум, один элемент.

Далее, в методе onCreateViewHolder() мы должны проверить - есть ли у нас данные в списке контактов? Если данных нет, то для создания view мы используем макет list_no_items.xml, а если данные есть, то используем макет list_contact.xml.

Для того, чтобы распознать эту ситуацию, воспользуемся таким параметром, как viewType. Переопределим метод getItemViewType() и пропишем логику установки типа пункта списка.

ContactsAdapter.java
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {

    private final List<Contact> list;

    private static final int EMPTY_LIST_TYPE = 0;
    private static final int NON_EMPTY_LIST_TYPE = 1;

    ...

    @Override
    public int getItemViewType(int position) {
        return list.isEmpty() ? EMPTY_LIST_TYPE : NON_EMPTY_LIST_TYPE;
    }
}

Теперь реализуем логику в методе onCreateViewHolder()

ContactsAdapter.java
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {

    private final LayoutInflater inflater;
    private final List<Contact> list;

    private static final int EMPTY_LIST_TYPE = 0;
    private static final int NON_EMPTY_LIST_TYPE = 1;

    ...

    @Override
    public int getItemViewType(int position) {
        return list.isEmpty() ? EMPTY_LIST_TYPE : NON_EMPTY_LIST_TYPE;
    }

    @NonNull
    @Override
    public ContactHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;

        if (viewType == EMPTY_LIST_TYPE) {
            view = inflater.inflate(R.layout.list_no_items, parent, false);
        } else {
            view = inflater.inflate(R.layout.list_contact, parent, false);
        }

        return new ContactHolder(view);
    }
}

Проверим работу приложения. При старте приложения пользователю будет показано сообщение о том, что список контактов пуст.

Last updated