Switch Between Recyclerview Layouts When Click On Alertdialog Item List
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 ononCreateViewHolder
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
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"