webentwicklung-frage-antwort-db.com.de

Android RecyclerView: Ändern Sie die Layoutdatei LIST in GRID onOptionItemSelected

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:

enter image description here

Bild von List Layout:

enter image description here

ABER JETZT, WENN ICH SCROLLE und dann CHANGING VIEW ANZEIGE wie:

Grid Layout:

enter image description here

List Layout:

enter image description here

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

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

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.

2
user3377402