J'utilise RecyclerView.Adapter mais je suis un peu confus quant au fonctionnement de sa méthode 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;
}
}
Donc, si j'ai 10 éléments dans ma liste, alors pour chaque élément, cette méthode sera appelée et chaque fois qu'un nouveau ViewHolder
sera créé bien sûr, il y aura une fois pour chaque affichage, mais maintenant ma question concerne l'utilisation de ListView
et BaseAdapter
avec nous les stockons ViewHolder
dans une balise et l’utilisons. Nous ne créons pas ViewHolder
pour chaque élément.
@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;
}
Nous ne créons donc pas d'objet de détenteurs de vues supplémentaire. S'il vous plaît aidez-moi à comprendre les avantages et les inconvénients.
Merci
onCreateViewHolder
crée uniquement un nouveau détenteur de vue lorsqu'il n'y a aucun détenteur de vue existant que RecyclerView
puisse réutiliser. Ainsi, par exemple, si votre RecyclerView
peut afficher 5 éléments à la fois, il créera 5-6 ViewHolders
, puis les réutilisera automatiquement, en appelant à chaque fois onBindViewHolder
.
Cela ressemble à ce que votre code dans ListView
fait (en vérifiant si convertView
est null
et si ce n'est pas le cas, en récupérant le ViewHolder
existant de la balise), sauf que, avec RecyclerView
, tout se fait automatiquement.
Je suppose que c’est l’un des avantages de l’utilisation de RecyclerView
- vous n'avez pas à vous préoccuper autant de la réutilisation de ViewHolders
que de ListView
. Le problème est que RecyclerView
est très personnalisable, mais n’a que très peu de fonctionnalités intégrées - contrairement à ListView
qui n’est pas très personnalisable, mais possède de nombreuses fonctionnalités intégrées.
Vous pouvez utiliser ceci:
-> Créer un constructeur:
/** * Créé par Deepak Sharma le 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);
}
}
-> In you Activity/Fragment:
ArrayList<StoreModel> mStoreList = new ArrayList<>();
mStoreListAdapter = new StoreListAdapter(getActivity());
boolean isAnimate = false;
mStoreListAdapter.setData(mStoreList, isAnimate);
puis rappelez
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);