Je développe une Android pour les achats en ligne. J'ai créé la vue suivante pour la liste des produits en utilisant RecyclerView
, en ce que je souhaite changer de vue en sélectionnant l'option élément de men:
J'ai créé ce qui suit adaptateur nommé ProductAdapter
, en ce que j'ai implémenté du code pour changer la disposition dans onCreateViewHolder
pour sélectionner le fichier de disposition en fonction de la valeur booléenne.
Code de l'adaptateur ProductAdapter
:
/***
* ADAPTER for Product to binding rows in List
*/
private class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductRowHolder> {
private List<Product> productList;
private Context mContext;
public ProductAdapter(Context context, List<Product> feedItemList) {
this.productList = feedItemList;
this.mContext = context;
}
@Override
public ProductRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(isProductViewAsList ? R.layout.product_row_layout_list : R.layout.product_row_layout_grid, null);
ProductRowHolder mh = new ProductRowHolder(v);
return mh;
}
@Override
public void onBindViewHolder(ProductRowHolder productRowHolder, int i) {
Product prodItem = productList.get(i);
// Picasso.with(mContext).load(feedItem.getName())
// .error(R.drawable.ic_launcher)
// .placeholder(R.drawable.ic_launcher)
// .into(productRowHolder.thumbnail);
double price = prodItem.getPrice();
double discount = prodItem.getDiscount();
double discountedPrice = price - (price * discount / 100);
String code = "";
if(prodItem.getCode() != null)
code = "[" + prodItem.getCode() + "] ";
productRowHolder.prodIsNewView.setVisibility(prodItem.getIsNew() == 1 ? View.VISIBLE : View.INVISIBLE);
productRowHolder.prodNameView.setText(code + prodItem.getName());
productRowHolder.prodOriginalRateView.setText("Rs." + new BigDecimal(price).setScale(2,RoundingMode.DOWN));
productRowHolder.prodDiscView.setText("" + new BigDecimal(discount).setScale(2,RoundingMode.DOWN) + "% off");
productRowHolder.prodDiscRateView.setText("Rs." + new BigDecimal(discountedPrice).setScale(2,RoundingMode.DOWN));
productRowHolder.prodOriginalRateView.setPaintFlags(productRowHolder.prodOriginalRateView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
@Override
public int getItemCount() {
return (null != productList ? productList.size() : 0);
}
public class ProductRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
//Declaration of Views
public ProductRowHolder(View view) {
super(view);
view.setOnClickListener(this);
//Find Views
}
@Override
public void onClick(View view) {
//Onclick of row
}
}
}
Après cela, j'ai fait du code pour changer la disposition de RecyclerView
de List
en Grid
et vice-versa dans onOptionsItemSelected
, ici j'appelle mAdapter.notifyDataSetChanged();
donc il appellera à nouveau l'adaptateur et changera la valeur.
onOptionsItemSelected:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (id) {
case R.id.action_settings:
return true;
case Android.R.id.home:
finish();
break;
case R.id.product_show_as_view:
isProductViewAsList = !isProductViewAsList;
supportInvalidateOptionsMenu();
mRecyclerView.setLayoutManager(isProductViewAsList ? new LinearLayoutManager(this) : new GridLayoutManager(this, 2));
mAdapter.notifyDataSetChanged();
break;
}
return super.onOptionsItemSelected(item);
}
J'ai eu un petit succès comme:
Image de la disposition Grid
:
Image de la disposition List
:
MAIS MAINTENANT QUAND JE DÉFILE, puis CHANGER DE VUE s'affiche comme:
Grid
mise en page:
List
mise en page:
Je ne sais pas pourquoi cela se produit après le défilement. Y a-t-il une autre façon de changer la vue comme ça.
Aujourd'hui, je viens de voir que ce problème est dû à
ImageView
, sans qu'il fonctionne parfaitement.
Aidez s'il vous plaît, votre aide sera appréciée.
J'ai trouvé une solution avec le démarrage de l'activité que j'ai définie LinearLayoutManager
comme:
mLayoutManager = new LinearLayoutManager(this);
mProductListRecyclerView.setLayoutManager(mLayoutManager);
après cela onOptionsItemSelected
écrit comme:
case R.id.menu_product_change_view:
isViewWithCatalog = !isViewWithCatalog;
supportInvalidateOptionsMenu();
//loading = false;
mProductListRecyclerView.setLayoutManager(isViewWithCatalog ? new LinearLayoutManager(this) : new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
mProductListRecyclerView.setAdapter(mAdapter);
break;
et changer la vue dans onCreateViewHolder
comme:
@Override
public ProductRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(isViewWithCatalog ? R.layout.product_row_layout_list : R.layout.product_row_layout_grid, null);
ProductRowHolder mh = new ProductRowHolder(v);
return mh;
}
Du début à la fin, vous devez gérer la variable isViewWithCatalog pour afficher la disposition en premier.
J'ai résolu ce problème en définissant à nouveau l'adaptateur sur RecyclerView
, après avoir changé le gestionnaire de disposition.
listView.setLayoutManager(new LinearLayoutManager(this));
listView.setAdapter(adapter);
Dans ce exemples SDK il y a un exemple complet mais il utilise un fichier de mise en page pour les deux LayoutManagers
Pour conserver la position de défilement lors du changement de disposition, ils ont utilisé cette fonction
public void setRecyclerViewLayoutManager(LayoutManagerType layoutManagerType) {
int scrollPosition = 0;
// If a layout manager has already been set, get current scroll position.
if (mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
switch (layoutManagerType) {
case GRID_LAYOUT_MANAGER:
mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT);
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;
break;
case LINEAR_LAYOUT_MANAGER:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
break;
default:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
}
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(scrollPosition);
}
Je pense qu'après le défilement et le retour à la vue grille, le premier élément n'est pas recréé. J'ai résolu ce problème en remplaçant getItemViewType()
et en gonflant les fichiers de disposition dans onCreateViewHolder
en conséquence.