Подтвердить что ты не робот

Android RecyclerView.Adapter onCreateViewHolder() работает

Я использую RecyclerView.Adapter, но я немного смущен относительно работы его метода onCreateViewHolder.

  @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    if(viewType==TYPE_ITEM) {

        View mView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.inflate_common_item, viewGroup, false);
        ViewHolder vh = new ViewHolder(mView);
        return vh;

    } else {
        View mView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.inflate_uncommon_item, viewGroup, false);
        ViewHolderFooter vh = new ViewHolderFooter(mView);
        return vh;

    }
}

Итак, у меня есть 10 элементов в моем списке, поэтому для каждого элемента этот метод будет вызван, и каждый раз, когда будет создан новый ViewHolder, он будет один раз для каждого представления, но теперь мой вопрос, когда мы были используя ListView и BaseAdapter с ними, мы храним ViewHolder в теге и используем это. Мы не создаем ViewHolder для каждого элемента.

 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
            MyViewHolder mViewHolder;

            if(convertView == null) {
                    convertView = inflater.inflate(R.layout.layout_list_item, null);
                    mViewHolder = new MyViewHolder();
                    convertView.setTag(mViewHolder);
            } else {
                    mViewHolder = (MyViewHolder) convertView.getTag();
            }

            mViewHolder.tvTitle = detail(convertView, R.id.tvTitle, myList.get(position).getTitle());
            mViewHolder.tvDesc  = detail(convertView, R.id.tvDesc,  myList.get(position).getDescription());
            mViewHolder.ivIcon  = detail(convertView, R.id.ivIcon,  myList.get(position).getImgResId());

            return convertView;
    }

Итак, мы не создаем дополнительный объект зрителей. Пожалуйста, помогите мне понять плюсы и минусы.

Спасибо

4b9b3361

Ответ 1

onCreateViewHolder создает только новый держатель вида, если нет существующих держателей вида, которые RecyclerView может повторно использовать. Например, если ваш RecyclerView может отображать по 5 элементов за раз, он будет создавать 5-6 ViewHolders, а затем автоматически повторно использовать их при каждом вызове onBindViewHolder.

Схож с тем, что делает ваш код в ListView (проверка if convertView на null, а если нет, захват существующего ViewHolder из тега), кроме, с RecyclerView, это все сделано автоматически.

Я полагаю, что это один из плюсов с использованием RecyclerView - вам не нужно так беспокоиться о повторном использовании ViewHolders, как и в случае с ListView. Кон, RecyclerView очень настраиваемый, но имеет очень мало встроенных функций - в отличие от ListView, который не очень настраиваемый, но имеет множество встроенных функций.

Ответ 2

Вы можете использовать это:

→ Создать конструктор:

/**  * Создано Deepak Sharma 31/10/17.  */

public class StoreListAdapter<T> extends RecyclerView.Adapter<StoreListAdapter.ViewHolder> implements Filterable {

    private Collection<T> mItems;
    private Context context;
    private int mLayout;
    IClickable iClickable;
    private boolean isAnimationAllowed;
    private StoreSearchFilter<T> mSearchFilter;

    public StoreListAdapter(Context context)
    {
        this.context = context;
    }
    public void setData(Collection<T> items, boolean isAnimationAllowed)
    {
        mItems = items;
        this.isAnimationAllowed = isAnimationAllowed;
    }

    public void setCallback(int layout, IClickable iClickable)
    {
        this.mLayout = layout;
        this.iClickable = iClickable;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(mLayout, viewGroup, false);
        iClickable.init(view);

        StoreListAdapter.ViewHolder viewHolder = new StoreListAdapter.ViewHolder(view);    
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
//        viewHolder.itemView.getLayoutParams().width = width;
        viewHolder.itemView.getLayoutParams().height = height+24;

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(StoreListAdapter.ViewHolder viewHolder, int i) {
        iClickable.execute(viewHolder, mItems.toArray()[i],viewHolder.getAdapterPosition());
        if (isAnimationAllowed)
            setAnimation(viewHolder.itemView, i);
    }

    @Override
    public int getItemCount() {
        return mItems.size()>0?mItems.size():0;
    }

    @Override
    public Filter getFilter() {
        if (mSearchFilter == null)
            mSearchFilter = new StoreSearchFilter<T>((ArrayList<StoreModel>) mItems, new IFilteredList<T>() {
                @Override
                public void onListFiltered(ArrayList<T> list) {
                    setData(list, false);
                    notifyDataSetChanged();
                }
            });
        return mSearchFilter;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private final TextView mTextView;
        //private CheckBox mCheckBox;

        ViewHolder(View v) {
            super(v);
            mTextView = (TextView)v.findViewById(R.id.list_item);

            // Handle item click and set the selection
            /*v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // Redraw the old selection and the new
                    notifyItemChanged(selectedItem);
                    selectedItem = getLayoutPosition();
                    notifyItemChanged(selectedItem);
                }
            });*/
        }

    }

    public interface IClickable<T> {
        public void init(View view);
        public void execute(StoreListAdapter.ViewHolder holder, T object, int position);
    }

    /**
     * Here is the key method to apply the animation
     */
    private void setAnimation(View viewToAnimate, int position)
    {
            Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
            viewToAnimate.startAnimation(animation);
    }

}

→ В вашей деятельности/фрагменте:

ArrayList<StoreModel> mStoreList = new ArrayList<>();
 mStoreListAdapter = new StoreListAdapter(getActivity());
        boolean isAnimate = false;
        mStoreListAdapter.setData(mStoreList, isAnimate);

затем вызовите обратный вызов

mStoreListAdapter.setCallback(R.layout.store_item, new StoreListAdapter.IClickable() {
            @Override
            public void init(View view) {
                //    Toast.makeText(getActivity(), "Initialized", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void execute(StoreListAdapter.ViewHolder viewHolder, Object object, int position) {
                final StoreModel model = (StoreModel) object;

                View view = viewHolder.itemView;
                StoreListAdapter.ViewHolder holder = viewHolder;

                final CoordinatorLayout fabGameview = (CoordinatorLayout) view;
                final CardView cardView = (CardView) fabGameview.findViewById(R.id.store_item_cardview);

                TextView txtStoreName = (TextView) cardView.findViewById(R.id.txtStoreName);
                TextView txtStoreAddress = (TextView) cardView.findViewById(R.id.txtStoreAddress);
                TextView txtStoreCity = (TextView) cardView.findViewById(R.id.txtStoreCity);
                TextView txtPrizes = (TextView) cardView.findViewById(R.id.txtPrizes);
                txtStoreName.setText(model.getStoreName());
                txtStoreAddress.setText(model.getStoreAddress());
                txtStoreCity.setText(model.getStoreCity());
                txtPrizes.setText(String.valueOf(model.getPrizesAvailable()));

                LinearLayout linearDetails = (LinearLayout) cardView.findViewById(R.id.linearDetails);
                LinearLayout linearPrize = (LinearLayout) cardView.findViewById(R.id.linearPrize);

                if (clickedMarkerModel != null && clickedMarkerModel == model) {
                    holder.itemView.setSelected(true);
//                    holder.itemView.setPressed(true);
//                    linearDetails.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
//                    linearPrize.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
//                    mRecyclerStore.stopScroll();
                } else {
                    holder.itemView.setSelected(false);
//                    holder.itemView.setPressed(false);
//                    linearDetails.setBackground(ContextCompat.getDrawable(getActivity(), R.drawable.store_selector));
//                    linearPrize.setBackground(ContextCompat.getDrawable(getActivity(), R.drawable.store_selector));
                }

                // TODO Here scroll recycler view upto selected item
                /*mRecyclerStore.smoothScrollToPosition(mStoreListAdapter.getItemCount() - 1);*/

                cardView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        boolean isAddedToBackStack = true;
                        StoreDetailsAndProductListFragment storeDetailsAndProductListFragment = new StoreDetailsAndProductListFragment();
                        Bundle bundle = new Bundle();
                        bundle.putParcelable(ExtrasUtil.STORE, model);
                        storeDetailsAndProductListFragment.setArguments(bundle);
                        showOtherFragment(storeDetailsAndProductListFragment, getActivity().getFragmentManager(), isAddedToBackStack);
                    }
                });
            }
        });
        mRecyclerStore.setAdapter(mStoreListAdapter);