Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android RecyclerView: Change layout file LIST to GRID onOptionItemSelected

I am developing an Android Application for Online Shopping. I have created following view for List of Products using RecyclerView, in that i want to change view on selecting option menu item:

I have created following adapter named ProductAdapter, in that I have implemented code for changing layout in onCreateViewHolder for selecting layout file based on boolean value.

Code of Adapter 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             }         }     } 

After that i have done code for Changing RecyclerView layout from List to Grid and Vice Versa in onOptionsItemSelected, here i am calling mAdapter.notifyDataSetChanged(); so it will call adapter again and change value.

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

I got little bit success like:

Image of Grid layout:

enter image description here

Image of List layout:

enter image description here

BUT NOW WHEN I SCROLL and then CHANGING VIEW is Displaying like:

Grid layout:

enter image description here

List layout:

enter image description here

I dont know why it happens after scrolling. Is there any other way to change view like this.

Today i just saw that this problem is because of ImageView, without it working perfectly.

Help please, You help will be appreciated.

like image 512
Pratik Butani Avatar asked Feb 18 '15 10:02

Pratik Butani


Video Answer


2 Answers

I found solution with the starting of activity I have set LinearLayoutManager like:

mLayoutManager = new LinearLayoutManager(this); mProductListRecyclerView.setLayoutManager(mLayoutManager); 

after that onOptionsItemSelected written like:

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; 

and changing view in onCreateViewHolder like:

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

From Starting to Ending you have to manage isViewWithCatalog variable for displaying which layout first.

like image 132
Pratik Butani Avatar answered Sep 18 '22 05:09

Pratik Butani


In this SDK samples there is a complete example however it uses one layout file for both LayoutManagers

For keeping the scrolling position when switching the layout they used this function

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); } 
like image 26
Mohammad Yahia Avatar answered Sep 21 '22 05:09

Mohammad Yahia