Android RecyclerView: cambie la LISTA de archivos de diseño a GRID en OptionItemSelected

4 minutos de lectura

avatar de usuario
Pratik Butani

Estoy desarrollando una aplicación Android para compras en línea. He creado la siguiente vista para la Lista de productos usando RecyclerViewen eso quiero cambiar de vista al seleccionar el elemento del menú de opciones:

he creado siguiendo adaptador llamado ProductAdapteren el que he implementado código para cambiar el diseño en onCreateViewHolder para seleccionar el archivo de diseño en función del valor booleano.

Código de adaptador 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
            }
        }
    }

Después de eso, hice el código para cambiar RecyclerView diseño de List para Grid y viceversa en onOptionsItemSelectedaquí estoy llamando mAdapter.notifyDataSetChanged(); por lo que volverá a llamar al adaptador y cambiará el valor.

onOptionsItemSeleccionado:

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

Obtuve un poco de éxito como:

Imagen de Grid diseño:

ingrese la descripción de la imagen aquí

Imagen de List diseño:

ingrese la descripción de la imagen aquí

PERO AHORA CUANDO ME DESPLAZO y luego CAMBIO DE VISTA se muestra me gusta:

Grid diseño:

ingrese la descripción de la imagen aquí

List diseño:

ingrese la descripción de la imagen aquí

No sé por qué sucede después de desplazarse. ¿Hay alguna otra forma de cambiar la vista como esta?

Hoy acabo de ver que este problema se debe a ImageViewsin que funcione perfectamente.

Ayuda por favor, su ayuda será apreciada.

  • Esta respuesta podría ayudar: stackoverflow.com/a/24933117/2649012

    – Phantommaxx

    18 de febrero de 2015 a las 11:03

  • usa este RecyclerView.setHasFixedSize(true);

    – Amrut Bidri

    26 de febrero de 2015 a las 6:52

  • su mRecyclerView.setHasFixedSize(true); pero no me funciona. alguna otra solución?

    – Pratik Butani

    26 de febrero de 2015 a las 7:03

  • Creo que esta respuesta puede ayudarlo: RecyclerView: ¿cómo borrar las vistas en caché/recicladas?

    – Luciano

    14/03/2015 a las 20:27


  • ya resolviste esto?

    -Bojan Kseneman

    25/04/2015 a las 19:32

En esto Muestras SDK hay un ejemplo completo, sin embargo, utiliza un archivo de diseño para ambos LayoutManagers

Para mantener la posición de desplazamiento al cambiar el diseño, usaron esta función

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

  • Sé que hace mucho tiempo que no esta respuesta, veo que no se encuentra la página de ejemplo actual, por favor, si hay un ejemplo completo como este, infórmeme.

    – Doctor Mido

    17 de marzo de 2019 a las 9:17

  • mira esto android.googlesource.com/plataforma/desarrollo/+/77b5d39/samples/…

    – Mohammad Yahia

    17 de marzo de 2019 a las 14:45

  • Que es isViewWithCatalog como conseguir eso?

    – Ramesh sambu

    13 de enero de 2018 a las 5:59

  • @R2R isViewWithCatalog es una variable booleana definida en esa actividad, que decidirá qué diseño será el primero.

    – Pratik Butani

    13 de enero de 2018 a las 6:10

  • Sí, eso lo he pasado en argumento de constructor. @SavaDimitrijević

    – Pratik Butani

    19 de febrero de 2019 a las 11:15


  • Eso tiene sentido. ¡Gracias por la respuesta!

    – Sava Dimitrijević

    19 de febrero de 2019 a las 11:16

  • Gracias por su voto a favor: ahora Q/A ambos son iguales 32:32: D @SavaDimitrijević

    – Pratik Butani

    19 de febrero de 2019 a las 11:18


avatar de usuario
usuario3377402

Creo que después de desplazarme y volver a cambiar a la vista de cuadrícula, el primer elemento no se vuelve a crear. Resolví esto por anulación getItemViewType() e inflar los archivos de diseño en onCreateViewHolder respectivamente.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad