FirebaseRecyclerAdapter не распознает первый макет как позицию - PullRequest
0 голосов
/ 09 июня 2018

Мой заголовок довольно сложен для понимания, но в основном, когда я добавляю элементы в свою базу данных, он должен отображаться в RecyclerView.Теперь в моем RecyclerView у меня есть два макета, но проблема в том, что первый элемент моей базы данных идет позади моего первого элемента в моем другом макете.Поэтому, если у меня есть 3 элемента в моей базе данных, он показывает только 2 элемента из базы данных, и первый элемент прячется за моим первым элементом в RecyclerView, который представляет собой другой макет, который вообще не использует базу данных.

Это мой код:

 FirebaseRecyclerOptions<Event> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Event>()
            .setQuery(query1, Event.class).build();
    AccAdapter = new FirebaseRecyclerAdapter<Event, RecyclerView.ViewHolder>(firebaseRecyclerOptions){

        final static int TYPE_HEADER = 0;
        final static int TYPE_ITEM = 1;


        @Override
        public int getItemViewType(int position) {
            if (position == 0) return TYPE_HEADER;
            return TYPE_ITEM;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            if (viewType == TYPE_HEADER){
                View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_add_items,
                        parent, false);
                return new ProdudctHolder3(view);
            } else {
                View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_acc,
                        parent, false);
                return new ProductHolder2(view);
            }
        }

        @Override
        protected void onBindViewHolder(final RecyclerView.ViewHolder holder, int position, final Event model) {
            if (holder instanceof ProdudctHolder3){
                ((ProdudctHolder3) holder).addBackground.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        startActivity(new Intent(getActivity(), AccAddItems.class ));
                    }
                });
            } else{

                final ProductHolder2 productHolder2 = (ProductHolder2) holder;


                productHolder2.mName.setText(model.getName());
                productHolder2.view.setBackgroundResource(getBackgroundDrawable(Integer.valueOf(model.getProductAmount())));
                productHolder2.mbackground.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        dialog = new Dialog(getActivity());
                        dialog.setContentView(R.layout.popup_edit_product);

                        SeekBar amountSeekBar = dialog.findViewById(R.id.amountSeekBar);
                        amountSeekBar.setMax(100);
                        amountSeekBar.setProgress(Integer.valueOf(model.getProductAmount()));
                        amountSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                            @Override
                            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                                progress = i;
                            }

                            @Override
                            public void onStartTrackingTouch(SeekBar seekBar) {

                            }

                            @Override
                            public void onStopTrackingTouch(SeekBar seekBar) {
                                getRef(holder.getAdapterPosition()).child("productAmount").setValue(String.valueOf(progress));
                                dialog.dismiss();

                            }
                        });

                        dialog.show();

                    }
                });

                productHolder2.mbackground.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View view) {
                        final PopupMenu popupMenu = new PopupMenu(getActivity(), productHolder2.mbackground);

                        popupMenu.inflate(R.menu.menu_acc);
                        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem menuItem) {
                                switch (menuItem.getItemId()){
                                    case R.id.deleteProduct:
                                        getRef(productHolder2.getAdapterPosition()).removeValue();
                                        popupMenu.dismiss();
                                        return true;

                                    default:
                                        return false;
                                }
                            }
                        });

                        popupMenu.show();

                        return true;
                    }
                });

            }
        }

    };

    mAccRecyclerViewRef.setAdapter(AccAdapter);

Мои два держателя продукта

закрытый класс ProdudctHolder3 расширяет RecyclerView.ViewHolder {

    private RelativeLayout addBackground;

    public ProdudctHolder3(View itemView) {
        super(itemView);
        addBackground = itemView.findViewById(R.id.mBackground2);
    }
}

private class ProductHolder2 extends RecyclerView.ViewHolder{

    private TextView mName;
    private RelativeLayout mbackground;
    private View view;

    public ProductHolder2(View itemView) {
        super(itemView);

        mName = itemView.findViewById(R.id.ItemName);
        mbackground = itemView.findViewById(R.id.mBackground1);
        view = itemView.findViewById(R.id.amountIndicator);

    }
}

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Идеальным решением было бы установить два адаптера на один RecyclerView, но, к сожалению, это невозможно.Тем не менее, вы можете создать один специальный адаптер, который обрабатывает два типа элементов.Я объясню это на примере.

Предположим, вам нужно отобразить объекты двух типов, humans и aliens.Ваши объекты требуют совершенно разных макетов и совершенно разных ViewHolders.Пожалуйста, смотрите код ниже для ViewHolders:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static class HumanViewHolder extends RecyclerView.ViewHolder {
        public HumanViewHolder(View itemView) {
            super(itemView);

            //Prepare your ViewHolder
        }

        public void bind(Human human) {

            //Display your human object
        }
    }

    private static class AlienViewHolder extends RecyclerView.ViewHolder {
        public AlienViewHolder(View itemView) {
            super(itemView);

            //Prepare your ViewHolder
        }

        public void bind(Alien alien) {

            //Display your alien object
        }
    }
}

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

private static final int ITEM_TYPE_HUMAN;
private static final int ITEM_TYPE_ALIEN;

Для простотыдавайте также предположим, что вы храните ваши объекты в списке:

private List<Object> items = new ArrayList<>();

public MyAdapter(List<Object> items) {
    this.items.addAll(items);

    //Other stuff if needed
}

Теперь, первое, что вам нужно сделать, это реализовать метод getItemViewType():

@Override
public int getItemViewType(int position) {
    if (items.get(position) instanceof Human) {
        return ITEM_TYPE_HUMAN;
    } else {
        return ITEM_TYPE_ALIEN;
    }
} 

Во-вторых, вынеобходимо использовать тип элемента внутри метода onCreateViewHolder() следующим образом:

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

    if (viewType == ITEM_TYPE_HUMAN) {
        View view = layoutInflater.inflate(R.layout.item_human, parent, false);

        return new HumanViewHolder(view);
    } else {      
        View view = layoutInflater.inflate(R.layout.item_alien, parent, false);

        return new AlienViewHolder(view);
    } 
} 

В конце вам просто нужно привязать соответствующий держатель вида следующим образом:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    Object item = items.get(position);

    if (viewHolder instanceof HumanViewHolder) {
        ((HumanViewHolder) viewHolder).bind((Human) item);
    } else {
        ((AlienViewHolder) viewHolder).bind((Alien) item);
    } 
} 
0 голосов
/ 12 июня 2018

Зачем использовать Адаптер Firebase Recycler, если вы легко можете создать его?Если я правильно понял, вы хотите, чтобы элемент был зафиксирован в позиции 0 (заголовок), в то время как другие будут добавлены ниже первого, верно?Если да, то вот решение, которое мне нравится использовать:

public interface ViewType {
    public int getViewType();
}

public interface ViewTypeDelegateAdapter {
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent);
    public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item);
}

public class ViewTypes {
    public static int HEADER = 0
    public static int ITEM = 1
}

public class ProductDelegateAdapter implements ViewTypeDelegateAdapter {

    private int resID;
    private Context context;

    public ProductDelegateAdapter(int resID, Context context) {
        this.resID = resID;
        this.context = context;
    }

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
        return new ProductHolder(LayoutInflater.from(parent.context).inflate(resID, parent, false));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item) {
        (holder as ProductHolder).bind("test");
    }

    class ProductHolder extends RecyclerView.ViewHolder {

        public ProductHolder(View view) {
            super(view);
        }

        public void bind(String test) {

        }

    }

}

public class HeaderDelegateAdapter implements ViewTypeDelegateAdapter {

    private int resID;
    private Context context;

    public ProductDelegateAdapter(int resID, Context context) {
        this.resID = resID;
        this.context = context;
    }

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
        return new HeaderHolder(LayoutInflater.from(parent.context).inflate(resID, parent, false));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item) {
        (holder as HeaderHolder).bind("test");
    }

    class HeaderHolder extends RecyclerView.ViewHolder {

        public HeaderHolder(View view) {
            super(view);
        }

        public void bind(String test) {

        }

    }

}

public class AccAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private Context context;
    private List<ViewType> items;
    private SparseArrayCompat<ViewTypeDelegateAdapter> delegateAdapters;
    private ViewType headerItem;

    public AccAdapter(Context context) {
        this.context = context;
        this.items = new ArrayList();
        this.delegateAdapters = new SparseArrayCompat();
        this.headerItem = new ViewType() {
            @Override
            public int getViewType() {
                return ViewTypes.HEADER;
            }
        };

        this.items.add(this.headerItem);
        this.delegateAdapters.put(ViewTypes.HEADER, HeaderDelegateAdapter(R.id.test, this.context));
        this.delegateAdapters.put(ViewTypes.ITEM, ProductDelegateAdapter(R.id.test, this.context));
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, Int viewType) {
        return delegateAdapters.get(viewType).onCreateViewHolder(parent);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, Int position) {
        delegateAdapters.get(getItemViewType(position)).onBindViewHolder(holder, items[position])
    }

    @Override
    public Int getItemViewType(Int position) {
        return items.get(position).getViewType();
    }

    @Override
    public Int getItemCount() {
        return items.getSize();
    }

    public void add(ViewType viewType) {
        val initPosition = this.items.size - 1
        this.items.add(item)
        notifyItemRangeChanged(initPosition, this.items.size + 1)
    }

}

public class Event implements ViewType {

    private String id;

    @Override
    public int getViewType() {
        return ViewTypes.ITEM;
    }

}

Извините за некоторые синтаксические ошибки, я перевел на Java с Kotlin, чтобы помочь вам.Надеюсь, это поможет!

...