Управление несколькими типами просмотра - RecyclerView

Я использую эту библиотеку для отображения нескольких типов представлений внутри RecyclerView.

Здесь я использую EnumMapBindAdapter для отображения списка пользовательских страниц.

У меня есть 4 класса DataBinder, каждое связующее имеет список размером 3 (размер может меняться в зависимости от сообщения пользователей). У меня проблема с getEnumFromPosition(), согласно моим предположениям количество выполнений метода getEnumFromPosition() должно быть равно числу связующих (4). Но этого не происходит. У меня всего 4 связующих, и я предполагаю, что метод getEnumFromPosition() должен выполняться только 4 раза (0,1,2,3), но выполнение выполняется. Мое предположение может быть неправильным, если я ошибаюсь, то как можно Я управляю 4 связующими внутри getEnumFromPosition() для разных позиций. Если я положу другой раздел внутри метода getEnumFromPosition(), тогда он вернет один вид, когда позиция превысит.

Вот код SampleEnumMapAdapter.java

 public class SampleEnumMapAdapter extends EnumMapBindAdapter<SampleEnumMapAdapter.SampleViewType> {

    enum SampleViewType{
        TEXT,IMAGE_AND_TEXT, AUDIO_AND_TEXT, VIDEO_AND_TEXT
    }

    public SampleEnumMapAdapter(){
        putBinder(SampleViewType.TEXT, new TextBinder(this));
        putBinder(SampleViewType.IMAGE_AND_TEXT, new ImageAndTextBinder(this));
        putBinder(SampleViewType.AUDIO_AND_TEXT, new AudioAndTextBinder(this));
        putBinder(SampleViewType.VIDEO_AND_TEXT, new VideoAndTextBinder(this));
    }

    public void setData(List<TextData> dataSetText ,List<ImageAndTextData> dataSetTextAndImage ,List<AudioAndTextData> dataSetTextAndAudio ,List<VideoAndTextData> dataSetTextAndVideo ) {
        ((TextBinder) getDataBinder(SampleViewType.TEXT)).addAll(dataSetText);
        ((ImageAndTextBinder) getDataBinder(SampleViewType.IMAGE_AND_TEXT)).addAll(dataSetTextAndImage);
        ((AudioAndTextBinder) getDataBinder(SampleViewType.AUDIO_AND_TEXT)).addAll(dataSetTextAndAudio);
        ((VideoAndTextBinder) getDataBinder(SampleViewType.VIDEO_AND_TEXT)).addAll(dataSetTextAndVideo);
    }

    @Override
    public SampleViewType getEnumFromPosition(int position){
        if (position == 0) {
            return SampleViewType.TEXT;
        } else if (position == 1) {
            return SampleViewType.IMAGE_AND_TEXT;
        } else if(position == 2){
            return SampleViewType.AUDIO_AND_TEXT;
        }else if(position == 3){
            return SampleViewType.VIDEO_AND_TEXT;
        }
        return null;
    }

    @Override
    public SampleViewType getEnumFromOrdinal(int ordinal) {
        return SampleViewType.values()[ordinal];
    }
}

Ответы

Ответ 1

Ранее я работал над подобной проблемой, но я настроил RecyclerView Adapter вручную, я не использовал для этого никакой библиотеки. Я даю вам образец кода здесь. Это полный адаптер типа Multile View Type

    public class UserPostAdapter extends RecyclerView.Adapter<UserPostAdapter.PostViewHolder> {

    private List<UserPostsListItem> postlist;
    Context conetxt;
    LayoutInflater inflater;
    private ViewClickListener mClickListener;
    private ItemViewClickListener itemViewClickListener;
    int count;

    public UserPostAdapter() {

    }

    public UserPostAdapter(Context conetxt, List<UserPostsListItem> postlist) {
        this.postlist = postlist;
        this.conetxt = conetxt;
        inflater = LayoutInflater.from(this.conetxt);
    }

    @Override
    public int getItemCount() {
        int size = 0;
        if (postlist != null)
            size = postlist.size();
        return size;
    }

    @Override
    public int getItemViewType(int position) {
        int viewTypePosition =0;

        String attachment_type = postlist.get(position).getAttachment_type();

        switch (attachment_type){

            case "text":
                viewTypePosition = 0 ;
                break;
            case "image":
                viewTypePosition = 1 ;
                break;
            case "audio":
                viewTypePosition = 2 ;
                break;
            case "video":
                viewTypePosition = 3 ;
                break;
            default:
        }

        return viewTypePosition;
    }

    @Override
    public void onBindViewHolder(final PostViewHolder videoViewHolder, final int position) {

        //Log.d("onBindViewHolder",Integer.toString(position));
        final UserPostsListItem item = postlist.get(position);

        switch (item.getAttachment_type()){
            case "audio":

                break;
            case "video":

                break;
            case "text":

                break;
            case "image":

                break;           
            default:
        }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public interface ItemViewClickListener {
        void onItemChildClicked(int position ,String type);
    }

    public void setItemViewClickListener (ItemViewClickListener viewClickListener) {
        itemViewClickListener = viewClickListener;
    }


    public List<UserPostsListItem> getUserPostsList() {
        return postlist;
    }

    @Override
    public PostViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){

        Log.d("ViewType", Integer.toString(viewType));
        switch (viewType) {
            case 0:
                View itemViewText = inflater.inflate(R.layout.userposts_listitem_text, viewGroup, false);
                return new PostViewHolder(itemViewText ,viewType);

            case 1:
                View itemViewTextImage = inflater.inflate(R.layout.userposts_listitem_textandimage, viewGroup, false);
                return new PostViewHolder(itemViewTextImage,viewType);

            case 2:
                View itemViewTextAudio = inflater.inflate(R.layout.userposts_listitem_audioandtext, viewGroup, false);
                return new PostViewHolder(itemViewTextAudio,viewType);

            case 3:
                View itemViewTextVideo = inflater.inflate(R.layout.userposts_listitem_videoandtext, viewGroup, false);
                return new PostViewHolder(itemViewTextVideo,viewType);

            default:
        }

        return null;

    }

    public interface ViewClickListener {
        void onVideoClicked(int position,View v);
    }

    public List<UserPostsListItem> getVideoItems() {
        return postlist;
    }

    public void setViewClickListener (ViewClickListener viewClickListener) {
        mClickListener = viewClickListener;
    }

    public static class PostViewHolder extends RecyclerView.ViewHolder {
        ImageView attachment;
        CircleImageView circleImageView;
        ImageView audio;
        public PostViewHolder(View v,int viewtype) {
            super(v);
            switch (viewtype){
                //For Audio
                case 2:                    
                    break;                  
                //For Video
                case 3:                    
                    break;
                //For Text only
                case 0:
                    break;
                //For Image
                case 1:                    
                    break;                
                default:

            }
        }
    }

}

Ответ 2

Не управляйте привязками по положению, управляйте привязками по типу данных, которые нужно сохранить/отобразить в этой позиции. Добавьте поле типа SampleViewType и в каждой позиции сопоставьте тип со своим соответствующим связующим и загрузите соответствующие данные.

Пример для объяснения: -

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

@Override
public SampleViewType getEnumFromPosition(int position){
    return data.get(position).getViewType();
}

В приведенных выше строках кода данные - это ваш список, и метод get получает один из объектов из списка. Этот объект имеет тип SampleViewType. В вашем классе SampleViewType вам необходимо создать элемент данных, называемый типом, который будет хранить тип каждого объекта вашего класса SampleViewType и будет иметь функцию getter с именем getViewType(). Эта функция getViewType() вернет тип этого конкретного объекта SampleViewType, например SampleViewType.TEXT и т.д., Как вы вернулись относительно позиции.

Вам может потребоваться создать отдельный класс с именем SampleView и раздуть его с ним, в то время как ваш класс SampleViewType будет содержать важную информацию для всех типов ваших SampleViews.

Надеюсь, этот пример объяснит вам то, что я хочу передать, в случае какой-либо путаницы, пожалуйста, не стесняйтесь спрашивать.