Android RecyclerView.Adapter onCreateViewHolder() 工作

Android RecyclerView.Adapter onCreateViewHolder() working

我正在使用 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 当然每个视图都会调用一次,但现在我的问题当我们使用 ListViewBaseAdapter 时,我们将 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;
    }

我们不是在创建额外的 viewholders 对象吗?请帮助我了解利弊。

谢谢

onCreateViewHolder 仅在没有 RecyclerView 可以重用的现有视图持有者时创建新的视图持有者。因此,例如,如果您的 RecyclerView 可以一次显示 5 个项目,它将创建 5-6 个 ViewHolders,然后自动重用它们,每次调用 onBindViewHolder

它类似于 ListView 中的代码(检查 convertView 是否为 null,如果不是,则从标签中获取现有的 ViewHolder) , 除了 RecyclerView, 这都是自动完成的。

我想这是使用 RecyclerView 的优点之一 - 您不必像使用 ListView 那样担心重用 ViewHolders。缺点是,RecyclerView 非常可定制,但内置功能很少 - 不像 ListView 不是很可定制,但有很多内置功能。

你可以使用这个:

--> 创建一个构造器:

/** * 由 Deepak Sharma 于 2017 年 10 月 31 日创建。 */

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);
    }

}

--> 在你Activity/Fragment :

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);