Comment utiliser Spinner Recyclerview?
Qui sont les meilleures pratiques pour gérer un Spinner dans un RecyclerView
Adaptateur?
C'est mon RecyclerView
Adaptateur:
public class CartAdapter extends BaseAdapter<Object> {
public CartAdapter(AbstractBaseActivity activity) {
super(activity);
}
public static final int TYPE_PRODOTTO = 1;
public static final int TYPE_SCONTO = 2;
@Override
public int getItemViewType(int position) {
if (items.get(position) instanceof Article)
return TYPE_PRODOTTO;
else
return TYPE_SCONTO;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowView = LayoutInflater.from(parent.getContext()).inflate(viewType == TYPE_PRODOTTO ? R.layout.item_cart : R.layout.item_cart_sconto, parent, false);
return new ViewHolder(rowView);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
final ViewHolder viewHolder = (ViewHolder) holder;
final Object object = items.get(position);
if (object instanceof Article) {
viewHolder.getBinding().setVariable(BR.article, object);
viewHolder.getBinding().executePendingBindings();
assert viewHolder.quantitySpinner != null;
assert viewHolder.cartoneQuantity != null;
assert viewHolder.cartoneValue != null;
CartSpinnerAdapter adapter = (CartSpinnerAdapter) viewHolder.quantitySpinner.getAdapter();
adapter.clear();
adapter.setCount(((Article) object).getQuantityAvailable());
adapter.notifyDataSetChanged();
viewHolder.quantitySpinner.setSelection(((Article) object).getQuantity() - 1); //In teoria qui la quantità non deve mai essere zero
viewHolder.cartoneQuantity.setVisibility(position % 2 == 1 ? View.GONE : View.VISIBLE); //Controllo da togliere in futuro
viewHolder.cartoneValue.setVisibility(position % 2 == 1 ? View.GONE : View.VISIBLE); //Controllo da togliere in futuro
}
final PopupMenu popup = new PopupMenu(getContext(), viewHolder.deleteMenu);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.delete_menu, popup.getMenu());
viewHolder.deleteMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popup.show();
}
});
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.action_delete) {
removeData(holder.getAdapterPosition());
((CartActivity) activity).checkIfEmpty();
}
return true;
}
});
}
public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.item)
View item;
@Nullable
@BindView(R.id.cart_image)
ImageView cartImage;
@BindView(R.id.delete_menu)
ImageView deleteMenu;
@Nullable
@BindView(R.id.product_cartone_quantity)
TextView cartoneQuantity;
@Nullable
@BindView(R.id.product_cartone_value)
TextView cartoneValue;
@Nullable
@BindView(R.id.quantity_spinner)
AppCompatSpinner quantitySpinner;
private ViewDataBinding binding;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
binding = DataBindingUtil.bind(itemView);
if (quantitySpinner != null)
quantitySpinner.setAdapter(new CartSpinnerAdapter(itemView.getContext(), R.layout.support_simple_spinner_dropdown_item));
}
public ViewDataBinding getBinding() {
return binding;
}
}
}
et c'est mon Spinner
Adaptateur:
public class CartSpinnerAdapter extends ArrayAdapter<String> {
LayoutInflater inflater;
int count;
public CartSpinnerAdapter(Context context, int resource) {
super(context, resource);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public CartSpinnerAdapter(Context context, int resource, int count) {
super(context, resource);
this.count = count;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setCount(int count) {
this.count = count;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getStandardView(position, parent, true);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getStandardView(position, parent, false);
}
@Override
public int getCount() {
return count;
}
private View getStandardView(int position, ViewGroup parent, boolean dropdown) {
View row = inflater.inflate(R.layout.support_simple_spinner_dropdown_item, parent, false);
TextView title = (TextView) row.findViewById(android.R.id.text1);
title.setText(String.valueOf(position + 1));
if (dropdown)
title.setMinWidth(Utils.dpToPx(getContext(), 64));
else
title.setAlpha(0.5f);
return row;
}
}
De cette façon, quand j'ai faites défiler la RecyclerView
je suis en train de vivre gal.
Si je supprime ces lignes tout fonctionne bien:
CartSpinnerAdapter adapter = (CartSpinnerAdapter) viewHolder.quantitySpinner.getAdapter();
adapter.clear();
adapter.setCount(((Article) object).getQuantityAvailable());
adapter.notifyDataSetChanged();
Donc, le problème est la façon dont je le manipuler l'adaptateur de la Spinner
, comment puis-je gérer cela?
Merci d'avance.
OriginalL'auteur Bronx | 2016-08-04
Vous devez vous connecter pour publier un commentaire.
Court
Pour améliorer les performances,
Fond
Lors de l'utilisation d'un adaptateur pour le défilement, la chose la plus importante à faire est sûr, c'est que nous NE PAS allouer de nouveaux objets (ou réduire autant que possible).
Tout le but d'un RecyclerView avec un Adaptateur est de faire en sorte que nous Recyclons nos objets, de sorte que le travail nécessaire au cours de défilement est minime.
Depuis l'allocation de mémoire est très "cher", afin d'améliorer les performances de défilement, la première chose à vérifier est les allocations au cours de la onBindViewHolder. Toutes les allocations si tout doit être fait dans le onCreateViewHolder.
Une fois que toutes les affectations sont effacées, si nous avons encore à la traîne, il est temps pour certains micro améliorations. Ceux-ci incluent l'amélioration de la qualité du code, la réutilisation de la logique de résultats, etc.
Que faire?
1) Supprimer les allocations à partir onBindViewHolder
Dans le code suivant:
Vous avez actuellement des 3 allocations directes (nouveau) et certains indirecte dotations (gonfler). Modifier ce code afin que toutes les affectations sont dans le onCreateViewHolder. Par exemple:
Dans onCreateViewHolder ne les allocations comme suit:
Dans onBindViewHolder lier les données pertinentes comme:
2) Réutilisation LayoutInflater, au lieu d'obtenir un nouveau à chaque fois.
Dans le code suivant:
Vous êtes l'obtention d'un nouvel LayoutInflater à chaque fois. C'est un gaspillage. Mieux d'en obtenir un dans le constructeur de l'Adaptateur et de l'enregistrer en tant que membre.
3) Minimiser le travail répétitif dans onBindViewHolder mise en œuvre
Par exemple, dans le code suivant:
Vous êtes le calcul de la logique elle-même deux fois. Mieux calculer une seule fois, et de réutiliser le résultat:
4)Spinner Adaptateur devrait également recycler les points de vue
Dans
CartSpinnerAdapter.getView()
vous êtes également l'allocation de mémoire. Il arrive (à chaque fois * élément de liste * comte) - C'est beaucoup d'allocations. Veuillez utiliser le convertView à la place. Jetez un oeil sur ce tutoriel dzone.com/articles/android-listview-optimizationsVeuillez voir mon edit de la section (1) de la solution.
Aussi, appliquer des suggestions à la CartSpinnerAdapter. Là, vous n'êtes pas à l'aide de la carte correctement, puisque vous n'avez pas recycler les points de vue. Utiliser le convertView.
Donc, comme je l'ai dit, dans CartSpinnerAdapter. getView vous allouez de la mémoire. Il arrive à chaque fois * élément de liste * nombre de - C'est beaucoup d'allocations. Où, en fait, vous avez besoin d'0 allocations. Veuillez utiliser le convertView à la place. Jetez un oeil sur ce tutoriel dzone.com/articles/android-listview-optimizations
dans ce cas, la "Liaison" est le setCount fonction. Dans d'autres cas, nous pourrions avoir d'autres liaisons. En tout cas, la chose la plus importante à retenir est qu'il ne faut pas allouer de la mémoire dans les fonctions qui sont appelées rapidement lors de la disposition de l'INTERFACE utilisateur. Trouver les allocations, les faire sortir, et vous êtes de l'or 🙂
OriginalL'auteur Eyal Biran