Ich entwickle eine Android Online-Shopping-Anwendung. Ich habe die folgende Ansicht für die Produktliste mit RecyclerView
erstellt, um die Ansicht zu ändern bei Auswahl der Option) Menüpunkt:
Ich habe folgendes Adapter mit dem Namen ProductAdapter
erstellt, indem ich Code zum Ändern des Layouts in onCreateViewHolder
implementiert habe, um die Layoutdatei basierend auf dem Booleschen Wert auszuwählen.
Code des Adapters 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
}
}
}
Danach habe ich Code für das Ändern des RecyclerView
Layouts von List
zu Grid
und umgekehrt in onOptionsItemSelected
gemacht, hier rufe ich mAdapter.notifyDataSetChanged();
auf so ruft es den Adapter erneut auf und ändert den Wert.
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);
}
Ich habe ein bisschen Erfolg wie:
Bild von Grid
Layout:
Bild von List
Layout:
ABER JETZT, WENN ICH SCROLLE und dann CHANGING VIEW ANZEIGE wie:
Grid
Layout:
List
Layout:
Ich weiß nicht, warum es nach dem Scrollen passiert. Gibt es eine andere Möglichkeit, die Ansicht so zu ändern?
Heute habe ich gesehen, dass dieses Problem an
ImageView
liegt, ohne dass es perfekt funktioniert.
Helfen Sie bitte, Ihre Hilfe wird geschätzt.
Ich habe eine Lösung mit dem Start der Aktivität gefunden, die ich gesetzt habe LinearLayoutManager
wie:
mLayoutManager = new LinearLayoutManager(this);
mProductListRecyclerView.setLayoutManager(mLayoutManager);
danach onOptionsItemSelected
geschrieben wie:
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;
und Ändern der Ansicht in onCreateViewHolder
wie:
@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;
}
Von Anfang bis Ende müssen Sie die Variable isViewWithCatalog verwalten, um das Layout zuerst anzuzeigen.
Ich habe dieses Problem behoben, indem ich den Adapter nach dem Ändern des Layout-Managers wieder auf RecyclerView
gesetzt habe.
listView.setLayoutManager(new LinearLayoutManager(this));
listView.setAdapter(adapter);
In diesem SDK-Beispiele gibt es ein vollständiges Beispiel. Es wird jedoch eine Layoutdatei für beide LayoutManager verwendet
Um die Bildlaufposition beim Layoutwechsel beizubehalten, wurde diese Funktion verwendet
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);
}
Ich denke, nachdem ich gescrollt und wieder in die Rasteransicht gewechselt habe, wird das erste Element nicht neu erstellt. Ich habe dies durch Überschreiben von getItemViewType()
gelöst und die Layoutdateien in onCreateViewHolder
entsprechend aufgeblasen.