Skip to content Skip to sidebar Skip to footer

Switch Between Recyclerview Layouts When Click On Alertdialog Item List

I have three different layouts cardsListLayout , titleLayout , cardMagazineLayoutand there may be more in the future, which used as a views on onCreateViewHolder method. I want to

Solution 1:

To prevent mixed layout when scrolling you should use ViewFlipper with three different RecyclerView's , meaning RecyclerView for each layout.

Step 1:

  • Create a public enum for the three layouts
publicenumViewType {
    CARD_LIST_LAYOUT, TITLE_LAYOUT, CARD_MAGAZINE_LAYOUT;
}
  • In PostAdapter create a ViewType variable and pass it into constructor, and checking via if & else on onCreateViewHolder to know Which layout choosed
PostAdapter(Context context, List<Item> items, ViewType viewType) {
        this.context = context;
        this.items = items;
        this.viewType = viewType;
    }



    @NonNull@Overridepublic PostAdapter.PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflaterinflater= LayoutInflater.from(context);

        ViewcardListLayout= inflater.inflate(R.layout.post_item_card_layout, parent, false);
        ViewtitleLayout= inflater.inflate(R.layout.post_item_grid_layout, parent, false);
        ViewcardMagazineLayout= inflater.inflate(R.layout.card_magazine_layout, parent, false);

        if (this.viewType == ViewType.TITLE_LAYOUT) {
            returnnewPostViewHolder(titleLayout);
        } elseif (this.viewType == ViewType.CARD_LIST_LAYOUT) {
            returnnewPostViewHolder(cardListLayout);
        } else {
            returnnewPostViewHolder(cardMagazineLayout);
        }
    }

Step 2:

  • Create a ViewFlipper in the class that contains the main RecyclerView, with three child's Layout's and RecyclerView's
<ViewFlipperxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/parentLayout"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"
    ><LinearLayoutandroid:id="@+id/linearLayout1"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/titleRecyclerView"android:layout_width="match_parent"android:layout_height="match_parent"

                ></androidx.recyclerview.widget.RecyclerView></LinearLayout><LinearLayoutandroid:id="@+id/linearLayout2"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/cardRecyclerView"android:layout_width="match_parent"android:layout_height="match_parent"

                ></androidx.recyclerview.widget.RecyclerView></LinearLayout><LinearLayoutandroid:id="@+id/linearLayout3"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/cardMagazineRecyclerView"android:layout_width="match_parent"android:layout_height="match_parent"

                ></androidx.recyclerview.widget.RecyclerView></LinearLayout></RelativeLayout></ViewFlipper>
  • In MainActivity define variable's like this
         viewFlipper = ((ViewFlipper) findViewById(R.id.parentLayout));


        titleRecyclerView = (RecyclerView) findViewById(R.id.titleRecyclerView);
        cardRecyclerView = (RecyclerView) findViewById(R.id.cardRecyclerView);
        cardMagazineRecyclerView = (RecyclerView) findViewById(R.id.cardMagazineRecyclerView);



        linearLayoutManager1 = newLinearLayoutManager(this);
        cardRecyclerView.setLayoutManager(linearLayoutManager1);
        linearLayoutManager2 = newLinearLayoutManager(this);
        cardMagazineRecyclerView.setLayoutManager(linearLayoutManager2);

        gridLayoutManager = newGridLayoutManager(this, 2, RecyclerView.VERTICAL, false);
        titleRecyclerView.setLayoutManager(gridLayoutManager);


        adapter1 = newPostAdapter(this, items, ViewType.TITLE_LAYOUT);
        titleRecyclerView.setAdapter(adapter1);
        adapter2 = newPostAdapter(this, items, ViewType.CARD_LIST_LAYOUT);
        cardRecyclerView.setAdapter(adapter2);
        adapter3 = newPostAdapter(this, items, ViewType.CARD_MAGAZINE_LAYOUT);
        cardMagazineRecyclerView.setAdapter(adapter3);
  • add ScrollListener for each RecyclerView
titleRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {

                }

            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {

                }

            }  
        });

cardRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {

                }

            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {

                }

            }  
        });

cardMagazineRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {

                }

            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {

                }

            }  
        });

Step 3:

  • And finally on onOptionsItemSelected switch between three layout when click
@OverridepublicbooleanonOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.change_layout) {
            AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
            builder.setTitle(getString(R.string.choose_layout));

            String[] layouts = {"Title Layout", "Cards List", "Card Magazine Layout"};
            builder.setItems(layouts, newDialogInterface.OnClickListener() {
                @OverridepublicvoidonClick(DialogInterface dialog, int index) {
                    switch (index) {
                        case0: // Title layout
                            viewFlipper.setDisplayedChild(0);

                            break;
                        case1: // Cards List Layout
                            viewFlipper.setDisplayedChild(1);
                            break;
                        case2: // Cards Magazine Layout
                            viewFlipper.setDisplayedChild(2);
                    }
                }
            });

            AlertDialogdialog= builder.create();
            dialog.show();
            returntrue;
        }

[Important Note] you should doing any implementation of the old main RecyclerView three times each one for every layout or RecyclerView like the above example of ScrollListener.

Hope this working with you, and please inform me if you have any inquiries

Solution 2:

No need to use multiple Recyclerview for this

You can achieve this using single Recyclerview with Multiple viewType

When you want to change the layout of Recyclerview just change the LayoutManager and viewType of your Recyclerview it will work

SAMPLE CODE

Try this way

First Create a Three layout for your Multiple viewType

grid_layout

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="150dp"android:layout_height="150dp"app:cardElevation="10dp"app:cardUseCompatPadding="true"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="match_parent"android:layout_height="150dp"android:adjustViewBounds="true"android:contentDescription="@string/app_name"android:scaleType="centerCrop"android:src="@drawable/dishu" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="#6a000000"android:gravity="center"android:padding="10dp"android:text="dummy text"android:textColor="@android:color/white" /></RelativeLayout></android.support.v7.widget.CardView>

cardlist_layout

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"app:cardElevation="10dp"app:cardUseCompatPadding="true"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"android:orientation="vertical"><ImageViewandroid:layout_width="match_parent"android:layout_height="150dp"android:adjustViewBounds="true"android:contentDescription="@string/app_name"android:scaleType="centerCrop"android:src="@drawable/dishu" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:paddingStart="5dp"android:paddingEnd="10dp"android:text="Dummy Title"android:textColor="@android:color/black"android:textStyle="bold" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:paddingStart="5dp"android:paddingEnd="10dp"android:text="Dummy Tex" /></LinearLayout></android.support.v7.widget.CardView>

title_layout

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"app:cardElevation="10dp"app:cardUseCompatPadding="true"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:paddingStart="5dp"android:paddingEnd="5dp"android:text="dummy text"android:textColor="@android:color/black"android:textStyle="bold" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="start"android:paddingStart="5dp"android:paddingEnd="5dp"android:text="I have three different layouts cardsListLayout , titleLayout , cardMagazineLayoutand there may be more in the future, which used as a views on onCreateViewHolder method." /></LinearLayout><ImageViewandroid:layout_width="wrap_content"android:layout_height="150dp"android:adjustViewBounds="true"android:contentDescription="@string/app_name"android:scaleType="centerCrop"android:src="@drawable/dishu" /></LinearLayout></android.support.v7.widget.CardView>

DataAdapter

package neel.com.recyclerviewdemo;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

publicclassDataAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {

    publicstaticfinalintITEM_TYPE_GRID=0;
    publicstaticfinalintITEM_TYPE_CARD_LIST=1;
    publicstaticfinalintITEM_TYPE_TITLE_LIST=2;
    private Context mContext;
    privateintVIEW_TYPE=0;

    publicDataAdapter(Context mContext) {
        this.mContext = mContext;
    }

    publicvoidsetVIEW_TYPE(int viewType) {
        VIEW_TYPE = viewType;
        notifyDataSetChanged();
    }

    @NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Viewview=null;
        // check here the viewType and return RecyclerView.ViewHolder based on view typeswitch (VIEW_TYPE) {
            case ITEM_TYPE_GRID:
                // if VIEW_TYPE is Grid than return GridViewHolder
                view = LayoutInflater.from(mContext).inflate(R.layout.grid_layout, parent, false);
                returnnewGridViewHolder(view);
            case ITEM_TYPE_CARD_LIST:
                // if VIEW_TYPE is Card List than return CardListViewHolder
                view = LayoutInflater.from(mContext).inflate(R.layout.cardlist_layout, parent, false);
                returnnewCardListViewHolder(view);
            case ITEM_TYPE_TITLE_LIST:
                // if VIEW_TYPE is Title List than return TitleListViewHolder
                view = LayoutInflater.from(mContext).inflate(R.layout.title_layout, parent, false);
                returnnewTitleListViewHolder(view);
        }
        returnnewGridViewHolder(view);
    }

    @OverridepublicvoidonBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        finalintitemType= getItemViewType(position);
        // First check here the View Type// than set data based on View Type to your recyclerview itemif (itemType == ITEM_TYPE_GRID) {
        if (holder instanceof CardViewHolder) {
            GridViewHolderviewHolder= (GridViewHolder) holder;
            // write here code for your grid list
      }
        } elseif (itemType == ITEM_TYPE_CARD_LIST) {
       if (holder instanceof CardViewHolder) {
            CardListViewHolderbuttonViewHolder= (CardListViewHolder) holder;
            // write here code for your grid list
       }
        } elseif (itemType == ITEM_TYPE_TITLE_LIST) {
            if (holder instanceof CardViewHolder) {
            TitleListViewHolderbuttonViewHolder= (TitleListViewHolder) holder;
            // write here code for your TitleListViewHolder
          }
        }
    }

    @OverridepublicintgetItemCount() {
        return40;
    }

    // RecyclerView.ViewHolder class for gridLayoutManagerpublicclassGridViewHolderextendsRecyclerView.ViewHolder {

        publicGridViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }

    // RecyclerView.ViewHolder class for Card list ViewpublicclassCardListViewHolderextendsRecyclerView.ViewHolder {

        publicCardListViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }

    // RecyclerView.ViewHolder class for Title list ViewpublicclassTitleListViewHolderextendsRecyclerView.ViewHolder {

        publicTitleListViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }
}

MainActivity

package neel.com.recyclerviewdemo;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

publicclassMainActivityextendsAppCompatActivity {

    DataAdapter dataAdapter;
    private RecyclerView myRecyclerView;
    private LinearLayoutManager linearLayoutManager;
    private GridLayoutManager gridLayoutManager;

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myRecyclerView = findViewById(R.id.myRecyclerView);
        myRecyclerView.setHasFixedSize(true);

        linearLayoutManager = newLinearLayoutManager(this);
        gridLayoutManager = newGridLayoutManager(this, 3);

        myRecyclerView.setLayoutManager(gridLayoutManager);

        dataAdapter = newDataAdapter(this);
        myRecyclerView.setAdapter(dataAdapter);
    }

    @OverridepublicbooleanonCreateOptionsMenu(Menu menu) {
        MenuInflaterinflater= getMenuInflater();
        inflater.inflate(R.menu.home_menu, menu);
        // return true so that the menu pop up is openedreturntrue;
    }

    @OverridepublicbooleanonOptionsItemSelected(MenuItem item) {

        if (item.getItemId() == R.id.action_dialog) {
            AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
            builder.setTitle("Please choose a layout");

            String[] layouts = {"Title Layout", "Cards List", "Grid View"};
            builder.setItems(layouts, newDialogInterface.OnClickListener() {
                @OverridepublicvoidonClick(DialogInterface dialog, int index) {
                    switch (index) {
                        case0: // Title layout
                            dataAdapter.setVIEW_TYPE(2);
                            myRecyclerView.setLayoutManager(linearLayoutManager);
                            myRecyclerView.setAdapter(dataAdapter);
                            break;
                        case1: // Cards List
                            dataAdapter.setVIEW_TYPE(1);
                            myRecyclerView.setLayoutManager(linearLayoutManager);
                            myRecyclerView.setAdapter(dataAdapter);
                            break;
                        case2: // Grid  Layout
                            dataAdapter.setVIEW_TYPE(0);
                            myRecyclerView.setLayoutManager(gridLayoutManager);
                            myRecyclerView.setAdapter(dataAdapter);
                    }
                }
            });

            builder.show();
        }
        returnsuper.onOptionsItemSelected(item);
    }
}

activity_main layout

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><android.support.v7.widget.RecyclerViewandroid:id="@+id/myRecyclerView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

OUTPUT

https://youtu.be/L3slKTy2bzI

Solution 3:

You can simply achieve this by implementing VIEW_TYPE inside your adapter. There is a overridden method in RecyclerView Adapter public int getViewType(int position), generally this method is used for mixing various types of views into a RecyclerView.

But you can use this in your case too. First define an enumeration of your view types. Then inside your adapter maintain a variable to store the current viewType, update that variable accordingly from the alert dialog item click.

Use that current viewType value into your onCreateViewHolder and onBindViewHolder methods to determine which layout you should use currently and which UI elements need to be updated now. Also update the RecyclerView layout manager from the alert dialog items on click.

publicclassPostAdapterextendsRecyclerView.Adapter<PostAdapter.PostViewHolder> {

    publicenumViewType {
         VIEW_TYPE_GRID, VIEW_TYPE_CARD, VIEW_TYPE_CARD_MAGAZINE
    }

    private Context context;
    private List<Item> items;
    private ViewType currentViewType;

    publicPostAdapter(Context context, List<Item> items, ViewType viewType) {
        this.context = context;
        this.items = items;
        this.currentViewType = viewType;
    }

    // Call this method from alert dialog item click.publicvoidupdateViewType(ViewType type) {
        this.currentViewType = type;
    }

    @OverridepublicintgetItemViewType(int position) {
        returnthis.currentViewType.ordinal();
    }

    @OverridepublicintgetItemCount() {
        return items.size();
    }

    @Overridepublic PostAdapter.PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflaterinflater= LayoutInflater.from(context);

        // here's the layouts that you want to switch between, based on the viewTypeif (viewType == ViewType.VIEW_TYPE_CARD.ordinal()) {
            ViewcardLayout= inflater.inflate(R.layout. post_item_card_layout, parent, false);
            returnnewPostViewHolder(cardLayout);
        }
        elseif (viewType == ViewType.VIEW_TYPE_GRID.ordinal()) {
            ViewgridLayout= inflater.inflate(R.layout. post_item_grid_layout,parent,false);
            returnnewPostViewHolder(gridLayout);
        }
        else {
            ViewcardMagazineLayout= inflater.inflate(R.layout. card_magazine_layout, parent, false);
            returnnewPostViewHolder(cardMagazineLayout);
        }
    }

    @OverridepublicvoidonBindViewHolder(@NonNull PostViewHolder holder, int position) {
        finalItemitem= items.get(position);
        // Similarly handle different view layout items here based on the viewType returned from getItemViewType method.if (getItemViewType(position) == ViewType.VIEW_TYPE_CARD.ordinal()) {

        } elseif (getItemViewType(position) == ViewType.VIEW_TYPE_GRID.ordinal()) {

        } else {

        }
    }
}

Update: Every time you called the updateViewType method you also need to call the notifyDataSetChanged method like this:

mAdapter.updateViewType(PostAdapter.ViewType.VIEW_TYPE_GRID);
mAdapter.notifyDataSetChanged()

*** I have tested this code on my device and it is working as expected. Please note that you should carefully handle the VIEW_TYPE when inflating layouts and using layout elements like TextView and ImageView. In my previous answer I have mixed up the view types with wrong layouts, that might be the only reason so that you have seen mixed layouts as output.

*** Also, the getItemViewType method was mistakenly renamed as getViewType and that was another culprit in my code which causes mixed output.

Solution 4:

Don't Do Longer. Just Change the layout of recyclerview on alertdialog click. If you want to use grid layout than change it to the grid layout, LinearLayout and set adapter.notifydatasetchanged, And if you want to change the layout of recyclerview Adapter row than Add a parameterized constructor to the adapter of recyclerview.After that Read the parameters and set views according to that.like this

public CategoryRecyclerview(List<MainCategory> mainCategories, Context context, FragmentManager fragmentManager,String layouttype) {
    this.context = context;
    layouttype= this.layouttype;}

and in the oncreateviewholder put this

if(layouttype.equals("GRID")){
        View view = inflater.inflate(R.layout.grid, viewGroup, false);
        CategoryRecyclerview.Myviewholder viewHolder = new CategoryRecyclerview.Myviewholder(view);
        holders.add(viewHolder);
        return viewHolder;
    }

after that notifydatasetchanged.

Post a Comment for "Switch Between Recyclerview Layouts When Click On Alertdialog Item List"