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

Pra*_*ani 34 android android-edittext android-recyclerview

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

我创建了以下适配器名称ProductAdapter,因为我已经实现了用于更改布局的代码,onCreateViewHolder用于根据布尔值选择布局文件.

适配器代码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
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

之后,我已经完成了将RecyclerView布局从更改ListGrid和反向Versa的代码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);
    }
Run Code Online (Sandbox Code Playgroud)

我得到了一些成功,如:

图像Grid布局:

在此输入图像描述

图像List布局:

在此输入图像描述

但是,当我滚动然后CHANGING VIEW显示为:

Grid 布局:

在此输入图像描述

List 布局:

在此输入图像描述

我不知道滚动后为什么会发生这种情况.有没有其他方法来改变这样的观点.

今天我刚看到这个问题是因为ImageView没有它完美运作.

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

Pra*_*ani 35

我找到了解决方案,开始我设置的活动LinearLayoutManager:

mLayoutManager = new LinearLayoutManager(this);
mProductListRecyclerView.setLayoutManager(mLayoutManager);
Run Code Online (Sandbox Code Playgroud)

之后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;
Run Code Online (Sandbox Code Playgroud)

并改变视图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;
}
Run Code Online (Sandbox Code Playgroud)

从开始到结束,您必须管理isViewWithCatalog变量以首先显示哪个布局.


Ale*_*aro 8

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

listView.setLayoutManager(new LinearLayoutManager(this));
listView.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

  • 滚动到 30-40 个项目后,如果我尝试更改视图,它将再次从 1 个位置开始滚动。有什么解决办法吗? (2认同)

Moh*_*hia 8

在这个SDK示例中有一个完整的示例,但是它为LayoutManagers使用了一个布局文件

为了在切换布局时保持滚动位置,他们使用了这个功能

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 看到这个 https://android.googlesource.com/platform/development/+/77b5d39/samples/browseable/RecyclerView/src/com.example.android.recyclerview/RecyclerViewFragment.java (3认同)