I have three different layouts cardsListLayout
, titleLayout
, cardMagazineLayout
and there may be more in the future, which used as a views on onCreateViewHolder
method.
I want to switch between views in onCreateViewHolder
method so when user choose from AlertDialog list
this onOptionsItemSelected in MainActivity Where there is menu Item "change the layout" so that when the user presses it it appears AlertDialog list
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.change_layout) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.choose_layout));
String[] layouts = {"Title Layout", "Cards List", "Card Magazine Layout"};
builder.setItems(layouts, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int index) {
switch (index) {
case 0: // Title layout
Toast.makeText(MainActivity.this,
"Title layout", Toast.LENGTH_LONG).show();
break;
case 1: // Cards List
Toast.makeText(MainActivity.this,
"Card list", Toast.LENGTH_LONG).show();
break;
case 2: // Cards Magazine Layout
Toast.makeText(MainActivity.this,
"Card Magazine Layout", Toast.LENGTH_LONG).show();
}
}
});
and this my custom adapter class PostAdapter
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.PostViewHolder> {
private Context context;
private List<Item> items;
public PostAdapter(Context context, List<Item> items) {
this.context = context;
this.items = items;
}
@NonNull
@Override
public PostAdapter.PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
// here's the three layouts that I can't switch between it
View cardsListLayout = inflater.inflate(R.layout.post_item_card_layout, parent, false);
View titleLayout = inflater.inflate(R.layout.post_item_grid_layout, parent, false);
View cardMagazineLayout = inflater.inflate(R.layout.card_magazine_layout,parent,false);
return new PostViewHolder(titleLayout);
}
@Override
public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
final Item item = items.get(position);
holder.postTitle.setText(item.getTitle());
final Document document = Jsoup.parse(item.getContent());
Elements elements = document.select("img");
Log.e("CODE", "Image: " + elements.get(0).attr("src"));
// Log.d("Text",document.text());
// holder.postDescription.setText(document.text());
Glide.with(context).load(elements.get(0).attr("src"))
.into(holder.postImage);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, DetailsActivity.class);
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc.isEmpty()) {
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
} else {
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
}
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return items.size();
}
public class PostViewHolder extends RecyclerView.ViewHolder {
ImageView postImage;
TextView postTitle;
TextView postDescription;
public PostViewHolder(View itemView) {
super(itemView);
postImage = itemView.findViewById(R.id.postImage);
postTitle = itemView.findViewById(R.id.postTitle);
postDescription = itemView.findViewById(R.id.postDescription);
}
}
}
I created two different Layout Manager for each one, there's a LinearLayoutManager and GridLayoutManager, currently I used GridLayout so I commented the LinearLayoutManger temporarily until I know how to switch between them
// linearLayoutManager = new LinearLayoutManager(this);
gridLayoutManager = new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false);
// recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setLayoutManager(gridLayoutManager);
The result I aspire to
To prevent mixed layout when scrolling you should use
ViewFlipper
with three different RecyclerView's , meaning RecyclerView for each layout.Step 1:
ViewType
variable and pass it into constructor, and checking via if & else ononCreateViewHolder
to know Which layout choosedStep 2:
ViewFlipper
in the class that contains the main RecyclerView, with three child's Layout's and RecyclerView'sScrollListener
for each RecyclerViewStep 3:
onOptionsItemSelected
switch between three layout when click[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
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
andonBindViewHolder
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.Update: Every time you called the
updateViewType
method you also need to call thenotifyDataSetChanged
method like this:*** 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 asgetViewType
and that was another culprit in my code which causes mixed output.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
and in the oncreateviewholder put this
after that notifydatasetchanged.
No need to use multiple
Recyclerview
for thisYou can achieve this using single
Recyclerview
withMultiple viewType
When you want to change the layout of
Recyclerview
just change theLayoutManager
andviewType
of yourRecyclerview
it will workSAMPLE CODE
Try this way
First Create a Three layout for your Multiple viewType
OUTPUT
https://youtu.be/L3slKTy2bzI