Android RecyclerView:将布局文件LIST更改为GRID onOptionItemSelected

我正在开发一个在线购物的Android应用程序。 我创build了使用RecyclerView的产品列表的以下视图,因为我想在select选项菜单项上更改视图:

我创build了一个名为ProductAdapter 适配器 ,我已经实现了在onCreateViewHolder改变布局的代码,以便根据布尔值select布局文件。

适配器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 } } } 

之后,我已经完成代码更改RecyclerView布局从ListGrid和副版本在onOptionsItemSelected ,在这里我调用mAdapter.notifyDataSetChanged(); 所以它会再次调用适配器并更改值。

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

我得到了一点成功,如:

Grid布局的图像:

在这里输入图像说明

List布局的图像:

在这里输入图像说明

但现在当我滚动,然后改变视图显示如:

Grid布局:

在这里输入图像说明

List布局:

在这里输入图像说明

滚动后我不知道为什么会发生。 有没有其他方式来改变这样的看法。

今天我刚才看到这个问题是因为ImageView ,没有完美的工作。

请帮助,您的帮助将不胜感激。

Solutions Collecting From Web of "Android RecyclerView:将布局文件LIST更改为GRID onOptionItemSelected"

我find解决scheme,我已经设置LinearLayoutManager的活动开始:

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

之后onOptionsItemSelected写成如下所示:

 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; 

并在onCreateViewHolder更改视图,如:

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

从开始到结束,您必须pipe理isViewWithCatalogvariables,以便首先显示哪个布局。

在更改布局pipe理器之后,我通过再次将适配器设置为RecyclerView来解决了这个问题。

 listView.setLayoutManager(new LinearLayoutManager(this)); listView.setAdapter(adapter); 

在这个SDK示例中有一个完整的示例,但它使用布局pipe理器的一个布局文件

为了在切换布局时保持滚动位置,他们使用了这个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); } 

我认为滚动后,又回到网格视图,第一个项目不会重新创build。 我通过覆盖getItemViewType()来解决这个问题,并相应地在onCreateViewHolder膨胀布局文件。

我使用viewflipper和改变types显示列表与animation。 和美丽。

在主要的XML

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ViewFlipper android:id="@+id/view_flipper" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v7.widget.RecyclerView android:id="@+id/small_list" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> <android.support.v7.widget.RecyclerView android:scrollbarStyle="insideInset" android:id="@+id/big_list" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> <android.support.v7.widget.RecyclerView android:scrollbarStyle="insideInset" android:id="@+id/grid_list" android:paddingLeft="2.0dip" android:paddingRight="2.0dip" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> </ViewFlipper> 

所有的代码在活动中

  private RecyclerView smallRecycleView; private RecyclerView gridRecycleView; private RecyclerView bigRecycleView; private StaggeredGridLayoutManager gridLayoutManager; private LinearLayoutManager bigLayoutManager; private LinearLayoutManager smallLayoutManager; private AAdapter adapterGrid; private AAdapter adapterSmall; private AAdapter adapterBig; private ViewFlipper viewFlipper; private TypeShow typeShowList = TypeShow.Small; private AList list = null; @Override protected void onCreate(Bundle savedInstanceState) { setLayout( R.layout.main_layout); super.onCreate(savedInstanceState); try { list = getItems(10); viewFlipper = ((ViewFlipper)findViewById(R.id.view_flipper)); viewFlipper.setOutAnimation(MainActivity.this, R.anim.anim_fade_out_flip); viewFlipper.setInAnimation(MainActivity.this, R.anim.anim_fade_in_flip); smallRecycleView = ((RecyclerView)findViewById(R.id.small_list)); gridRecycleView = ((RecyclerView)findViewById(R.id.grid_list)); bigRecycleView = ((RecyclerView)findViewById(R.id.big_list)); smallRecycleView.setHasFixedSize(false); gridRecycleView.setHasFixedSize(false); bigRecycleView.setHasFixedSize(false); smallLayoutManager = new LinearLayoutManager(MainActivity.this); smallRecycleView.setLayoutManager(smallLayoutManager); gridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); gridRecycleView.setLayoutManager(gridLayoutManager); gridRecycleView.setItemAnimator(null); bigLayoutManager = new LinearLayoutManager(MainActivity.this); bigRecycleView.setLayoutManager(bigLayoutManager); adapterSmall = new AAdapter(MainActivity.this,list,MainActivity.this,TypeShow.Small); smallRecycleView.setAdapter(adapterSmall); adapterGrid = new AAdapter(MainActivity.this,list,MainActivity.this,TypeShow.Grid); gridRecycleView.setAdapter(adapterGrid); adapterBig = new AAdapter(MainActivity.this,list,MainActivity.this,TypeShow.Big); bigRecycleView.setAdapter(adapterBig); if (Build.VERSION.SDK_INT >= 11) { smallRecycleView.setVerticalScrollbarPosition(1); gridRecycleView.setVerticalScrollbarPosition(1); bigRecycleView.setVerticalScrollbarPosition(1); } final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.floating_action_button); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { smallRecycleView.setSelected(false); bigRecycleView.setSelected(false); gridRecycleView.setSelected(false); viewFlipper.showNext(); if(typeShowList == TypeShow.Small){ typeShowList = TypeShow.Big; fab.setImageResource(R.drawable.ic_type_grid); } else if(typeShowList == TypeShow.Big){ typeShowList = TypeShow.Grid; fab.setImageResource(R.drawable.ic_atype_small); } else { typeShowList = TypeShow.Small; fab.setImageResource(R.drawable.ic_type_big); } } }); fab.setImageResource(R.drawable.ic_type_big); } catch (Exception e){ } } 

types

 public enum TypeShow { Grid, Small, Big } 

适配器

 public class AAdapter extends RecyclerView.Adapter<AAdapter.PersonViewHolder> { private AList noteList = null; private MainActivity mContext; private TypeShow typeShow; public AAdapter(MainActivity mContext, AList noteList, OnItemClickListener mListener, TypeShow typeShow){ this.noteList = noteList; this.mContext= mContext; this.mListener= mListener; this.typeShow= typeShow; } @Override public int getItemCount() { return noteList.size(); } @Override public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { if(typeShow == TypeShow.Grid) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_row_grid, viewGroup, false); return new PersonViewHolder(v); } else if(typeShow == TypeShow.Small) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_row_small, viewGroup, false); return new PersonViewHolder(v); } else { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_row_big, viewGroup, false); return new PersonViewHolder(v); } } @Override public void onBindViewHolder(PersonViewHolder personViewHolder, int i) { } public static class PersonViewHolder extends RecyclerView.ViewHolder { PersonViewHolder(View itemView) { super(itemView); } } } 

你应该使两个适配器各自实现自己的oncreateviewholder,然后使用回收视图swapadapter方法交换适配器