I have a RecyclerView which gets populated by a RealmRecyclerViewAdapter but somehow there are no animations playing when the data changes.
The adapter class uses multiple ViewHolders for different layouts but that should not affect animations right?
public class DiaryPageEntryAdapter extends RealmRecyclerViewAdapter<Entry, RecyclerView.ViewHolder> {
static class MealEntryViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.item_diary_entry_drink_title) TextView tvMealEntryTitle;
#BindView(R.id.item_diary_entry_meal_time) TextView tvMealEntryTime;
BindView(R.id.item_diary_entry_meal_bullet_list) RecyclerView rvBulletList;
MealEntryBulletAdapter bulletAdapter;
public MealEntryViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
this.bulletAdapter = new MealEntryBulletAdapter();
rvBulletList.setLayoutManager(new LinearLayoutManager(itemView.getContext()));
rvBulletList.setAdapter(this.bulletAdapter);
}
void bindData(MealEntry mealEntry) {
tvMealEntryTitle.setText(mealEntry.getTitle());
tvMealEntryTime.setText(DateTimeUtils.timeValueToText(itemView.getContext(), mealEntry.getTime()));
this.bulletAdapter.updateData(mealEntry.getConsumedMeals() ,mealEntry.getConsumedDrinks());
}
}
// Other ViewHolders
public DiaryPageEntryAdapter(#Nullable OrderedRealmCollection<Entry> data, boolean autoUpdate) {
super(data, autoUpdate, true);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case MEAL_ENTRY:
// Inflate meal entry layout and then create a new meal view holder with it
View rowMeal = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_diary_entry_meal, parent, false);
return new MealEntryViewHolder(rowMeal);
// Other case options.
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Entry entry = getItem(position);
if(Entry.isMealEntry(entry)) {
MealEntryViewHolder mealHolder = (MealEntryViewHolder) holder;
mealHolder.bindData(Entry.getMealEntryFromEntry(entry));
}
// Other if branches.
}
#Override
public int getItemViewType(int position) {
Entry entry = getItem(position);
if(Entry.isMealEntry(entry)) return MEAL_ENTRY;
// Other if branches.
}
The code for setting up the RecyclerView and adapter looks as following:
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.frag_diary_page_rv_entries);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
entryAdapter = new DiaryPageEntryAdapter(null, true);
recyclerView.setAdapter(entryAdapter);
The code that binds the data to the adapter is stated below:
RealmResults<Entry> sortedEntries = diaryEntry.getEntries()
.where()
.findAllSortedAsync("time");
entryAdapter.updateData(sortedEntries);
The auto-updates work fine but somehow no there is no animation when the data changes. A new entry simply appears but without animations. Furthermore I want a short animation to play once the RecyclerView is populated for the first time - an entrance animation similar to [http://anthony-skr.com/article/recyclerview-items-animation-with-rebound-effect][1].
Note: In my appĀ“s build.gradle file
dependencies {
// Other dependencies
compile 'io.realm:android-adapters:2.1.0'
}
In the Project build.gradle file:
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
classpath "io.realm:realm-gradle-plugin:3.1.4"
}
From your code sample, it isn't easy to see where you call entryAdapter.updateDate() from, but calling this method continuously on every update will disable all animations as it just calls notifyDataSetChanged().
A more standard pattern would look like this:
RealmResults<Entry> sortedEntries = diaryEntry.getEntries()
.where()
.findAllSortedAsync("time");
entryAdapter = new DiaryPageEntryAdapter(sortedEntries, true);
recyclerView.setAdapter(entryAdapter);
Animations should work if you do the above.
Related
I'm making an app using TMDB API and have gotten stuck at a small issue.
TMDB API shows seasons and episodes which are empty, basically, those are yet to air but since those are empty, the app shows a blank item that I'm trying to get rid of.
Here's my adapter:
public class SeasonAdapter extends RecyclerView.Adapter<SeasonAdapter.ViewHolder> {
private final List<Season> seasons;
private final Context context;
private final RequestOptions requestOptions;
public SeasonAdapter(List<Season> seasons, Context context) {
this.seasons = seasons;
this.context = context;
requestOptions = new RequestOptions().centerCrop().placeholder(R.drawable.poster_placeholder).error(R.drawable.poster_placeholder);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_season_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Season season = seasons.get(position);
holder.tvTitle.setText(season.getSeasonTitle());
if (season.getSeasonDate() != null && !season.getSeasonDate().isEmpty()) {
holder.tvDate.setText(context.getResources().getString(R.string.aired_on) + season.getSeasonDate());
} else {
holder.tvDate.setVisibility(View.GONE);
}
if (season.getSeasonEpisodes() == 0) {
seasons.remove(position);
}
holder.tvEpisodes.setText(String.valueOf(season.getSeasonEpisodes()) + context.getResources().getString(R.string.total_episodes));
Glide.with(context).load(season.getSeasonImageURL()).apply(requestOptions).into(holder.ivPoster);
holder.itemView.setOnClickListener(v -> {
Intent intent = new Intent(context, EpisodeActivity.class);
intent.putExtra("title", season.getShowTitle());
intent.putExtra("seasonTitle", season.getSeasonTitle());
intent.putExtra("seasonNo", season.getSeasonNo());
intent.putExtra("tvId", season.getTvId());
v.getContext().startActivity(intent);
});
}
#Override
public int getItemCount() {
return seasons.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView ivPoster;
public TextView tvTitle, tvDate, tvEpisodes;
public ViewHolder(#NonNull View itemView) {
super(itemView);
ivPoster = itemView.findViewById(R.id.ivSeasonPoster);
tvTitle = itemView.findViewById(R.id.tvSeasonTitle);
tvDate = itemView.findViewById(R.id.tvSeasonAired);
tvEpisodes = itemView.findViewById(R.id.tvSeasonEpisodes);
//Poster Corners
ivPoster.setClipToOutline(true);
}
}
}
I tried doing this:
if (season.getSeasonEpisodes() == 0) {
seasons.remove(position);
}
It does seem to hide the season which has no episodes but if a show has multiple seasons without episodes, my app crashes so I figured this isn't the right solution so any help is appreciated.
I suggest performing that removal logic in the constructor of the adapter rather than in onBind. onBind happens as the recycler view is finalising the details of each view holder immediately before it's shown to the user. You want to do as little as possible logic in here to keep the recycler view performant.
Inside the constructor (or even before the list is passed in) you should perform a loop and remove those items that don't meet the criteria before setting the instance variable.
It's been a long time since I wrote code in java and so I'd end up with unhelpful incorrect syntax if I tried to do it here.
Context:
I've implemented a RecyclerView in my to-do list app.
I wanted to be able to use various onClick methods for items within the RecyclerView so I created an interface called onTaskListener.
This interface has two method stubs, one for onClick and one for onLongClick. In my ViewHolder, I implement both the onClick() and onLongClick() methods which simply pass off control to my onTaskClickListener().
In my adapter, I create an onTaskClickListener().
Then in my main activity, I implement the methods within onTaskClickListener().
My issue is that while my onTaskClick() works perfectly, my onTaskLongClick doesn't seem to function at all. Is there something wrong with the way I set up my RecyclerView/Adapter/ViewHolder/ViewModel pattern?
Question: If the way I have implemented my interface is wrong, how do I include multiple types of click events within a single interface?
Here are the relevant contents of each file (I know it's a lot, I'm very sorry for the wall of code):
onTaskClickListener.java:
public interface OnTaskListener {
void onTaskClick(int position); // Interfaces are implicitly abstract
void onTaskLongClick(int position);
}
itemViewHolder.java:
public class itemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
View itmView; // This is the general view
TextView txtView; // This is the specific text view that shows up as a singular task in the list of to-do tasks
OnTaskListener onTaskListener; // Create an OnTaskListener inside our view holder which allows the view holder to realize it's been clicked
public itemViewHolder(#NonNull View itemView, OnTaskListener inputOnTaskListener) {
super(itemView);
itmView = itemView;
txtView = itemView.findViewById(R.id.txtTask);
this.onTaskListener = inputOnTaskListener; // Take an onTaskListener that is passed into the object and store it internally
itemView.setOnClickListener(this); // passes the View.OnClickListener context to the itemView via "this"
}
#Override
public void onClick(View view) {
onTaskListener.onTaskClick(getAdapterPosition()); // This says that whenever we register a click event, we pass the logic onto the taskClick event
}
#Override
public boolean onLongClick(View view) {
onTaskListener.onTaskLongClick(getAdapterPosition()); // This says that whenever we register a longClick event, we pass the logic onto the taskClick event
return true; // This means that we have successfully consumed the long click event. No other click events will be notified
}
}
dataAdapter.java
public class dataAdapter extends RecyclerView.Adapter<itemViewHolder> {
List<taskItem> taskItemList;
private OnTaskListener onTaskListener;
public dataAdapter(List<taskItem> inputTaskItemList, OnTaskListener inputOnTaskListener){
this.taskItemList = inputTaskItemList;
this.onTaskListener = inputOnTaskListener;
}
#NonNull
#Override
public itemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View localView = LayoutInflater.from(parent.getContext()).inflate(R.layout.taskholder, parent, false); //Don't even know what this line does, it's all so over my head
return new itemViewHolder(localView, onTaskListener); // Return an instance of whatever we made directly above this line
}
#Override
public void onBindViewHolder(#NonNull itemViewHolder holder, final int position) {
holder.txtView.setText(taskItemList.get(position).taskTitle);
// Look inside our ViewModel and get the text for this specific instance of the ViewModel, which corresponds to the current position
}
#Override
public int getItemCount() {
return taskItemList.size();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements OnTaskListener{
private RecyclerView taskList; // Creates a RecyclerView to hook up to our RecyclerView widget in the UI
private dataAdapter localAdapter; // Instantiates our custom adapter class
List<taskItem> myItems; // Stores the items in a list of taskItem's
private RecyclerView.LayoutManager localLayoutManager; // God knows what this does :(
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
taskList = findViewById(R.id.taskList); // Connects our list from UI to recycler view code
localLayoutManager = new LinearLayoutManager(this); // assigns our localLayoutManager to an actual Layout Manager
taskList.setLayoutManager(localLayoutManager); // connecting our layout manager to our recycler view
taskList.setHasFixedSize(true);
myItems = new ArrayList<>(); // Now we FINALLY make our to-do list and populate it with actual tasks
myItems.add(new taskItem("groceries"));
myItems.add(new taskItem("practice bjj"));
localAdapter = new dataAdapter(myItems, this); // Pass the to do list to the adapter so it can feed it to the recycler view
taskList.setAdapter(localAdapter); // Lastly set the recycler view's adapter to the one we made above
}
#Override
public void onTaskClick(int position) {
taskItem currentTask = myItems.get(position);
if(!(currentTask.taskTitle.startsWith("Done: "))){ // Logic that marks a task as done on tap
currentTask.taskTitle = "Done: " + currentTask.taskTitle;
//logic that moves the tapped item to bottom of list
myItems.remove(position);
myItems.add(myItems.size(), currentTask);
localAdapter.notifyItemMoved(position, myItems.size());
}
else if(myItems.get(position).taskTitle.startsWith("Done: ")){ // Logic for if user taps a task already marked "done"
currentTask.taskTitle = currentTask.taskTitle.replaceFirst("Done: ", "");
myItems.set(position, currentTask); // Remove prefix
localAdapter.notifyItemChanged(position);
myItems.remove(position);
myItems.add(0, currentTask);
}
localAdapter.notifyDataSetChanged(); // Let the activity know that the data has changed
}
#Override
public void onTaskLongClick(int position) { // This branch deals with deleting tasks on long click
myItems.remove(position);
localAdapter.notifyItemRemoved(position); // Item has been deleted
}
}
You never call setOnLongClickListener():
public itemViewHolder(#NonNull View itemView, OnTaskListener inputOnTaskListener) {
super(itemView);
itmView = itemView;
txtView = itemView.findViewById(R.id.txtTask);
this.onTaskListener = inputOnTaskListener; // Take an onTaskListener that is passed into the object and store it internally
itemView.setOnClickListener(this); // passes the View.OnClickListener context to the itemView via "this"
// Add this line
itemView.setOnLongClickListener(this); // passes the View.OnLongClickListener context to the itemView via "this"
}
Alternatively, you can avoid going through this entirely by inlining the entire OnLongClickListener (and similarly for the OnClickListener):
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
onTaskListener.onTaskLongClick(getAdapterPosition()); // This says that whenever we register a longClick event, we pass the logic onto the taskClick event
return true; // This means that we have successfully consumed the long click event. No other click events will be notified
}
});
Thus avoiding having your itemViewHolder class implement the OnLongClickListener interface and making it impossible to forget to call setOnLongClickListener().
I created a custom class named Food that contained all the elements from my layout which I want to populate.
I set the setters and getter method in that class
// Recycler View
private RecyclerView mFrooderList;
private DatabaseReference mDatabase;
//Setting Parameters for RecyclerView
mFrooderList =(RecyclerView) findViewById(R.id.frooder_list);
mFrooderList.setHasFixedSize(true);
mFrooderList.setLayoutManager(new LinearLayoutManager(this));
mDatabase = FirebaseDatabase.getInstance().getReference().child("Food");
Then I use Firebase Recycler adapter to populate my layout from Firebase Database
FirebaseRecyclerOptions<Food> options =
new FirebaseRecyclerOptions.Builder<Food>()
.setQuery(mDatabase, Food.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Food, FoodViewHolder>(options) {
#Override
public FoodViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_frooder_post, parent, false);
return new FoodViewHolder(view);
}
#Override
protected void onBindViewHolder(FoodViewHolder holder, int position, Food model) {
mFrooderList.setAdapter(adapter);
}
};
But when I run the app it runs but I dont see my layout in the main Activity and in the run time I get this error
I don't know what I am doing wrong Please help
onBindViewHolder is where you take values from Food model and set them to the FoodViewHolder holder.
It is not where you set the adapter.
In other words, it should look like this
#Override
protected void onBindViewHolder(FoodViewHolder holder, int position, Food model) {
// TODO: Bind the ViewHolder
}
}; // end of adapter definition
mFrooderList.setAdapter(adapter);
} // end onCreate
I am working on an android project and I am putting some TextViews inside a RecyclerView and at the same time I am trying to put those things in an array list as ViewHolder type. After some tests on the program i understood that the items that are inserted in the ArrayList are only the items that are shown in the screen. For example if my screen fits 15 textviews and i put 30 textviews inside the recycler view and arraylist, the size of the arraylist will be only 15 so i can't make any changes to the rest of the items.
Also when i scroll down the recycler view the arraylist get a size of the items that has been shown while scrolling but when i scroll back to the top and try to change the number of the TextViews and make them less the program crashes.
What i want is to have all of the items that have been added to the recycler view also in the arraylist in order to can use them.
Recycler View class code:
public class Tab1Child1Numbers extends RecyclerView.Adapter<Tab1Child1Numbers.ViewHolder> {
ArrayList<Integer> textFront;
ArrayList<Integer> textBack;
ArrayList<Integer> colors;
Context context;
ArrayList<ViewHolder> texts = new ArrayList<>();
public Tab1Child1Numbers(Context context, ArrayList<Integer> textFront, ArrayList<Integer> textBack, ArrayList<Integer> colors) {
super();
this.context = context;
this.textFront = textFront;
this.textBack = textBack;
this.colors = colors;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.tab1_child1_numbers, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
viewHolder.textFront.setText(textFront.get(i)+"");
viewHolder.textBack.setText(textBack.get(i)+"");
viewHolder.textFront.setBackgroundColor(colors.get(i));
viewHolder.textBack.setBackgroundColor(colors.get(i));
texts.add(viewHolder);
// cardsFront.add(viewHolder.imageFront);
// cardsBack.add(viewHolder.imgThumbnail);
viewHolder.setClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
if (isLongClick) {
} else {
Deck deck = new Deck();
deck.flipCard(texts.get(position).frame, texts.get(position).textFront, texts.get(position).textBack);
}
}
});
}
#Override
public int getItemCount() {
return textFront.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public TextView textFront;
public TextView textBack;
public FrameLayout frame;
public LinearLayout layout;
private ItemClickListener clickListener;
public ViewHolder(View itemView) {
super(itemView);
textFront = (TextView) itemView.findViewById(R.id.txt1);
textBack = (TextView) itemView.findViewById(R.id.txt2);
frame = (FrameLayout) itemView.findViewById(R.id.list_frame);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
public void setClickListener(ItemClickListener itemClickListener) {
this.clickListener = itemClickListener;
}
#Override
public void onClick(View view) {
clickListener.onClick(view, getPosition(), false);
}
#Override
public boolean onLongClick(View view) {
clickListener.onClick(view, getPosition(), true);
return true;
}
}
class Deck {
private void flipCard(View rootLayout, View cardFace, View cardBack) {
FlipAnimation flipAnimation = new FlipAnimation(cardFace, cardBack);
if (cardFace.getVisibility() == View.GONE) {
flipAnimation.reverse();
}
rootLayout.startAnimation(flipAnimation);
}
public void flipAll(){
System.out.println(texts.size()+"--------");
randomize();
for (int i = 0; i < texts.size(); i++) {
flipCard(texts.get(i).frame, texts.get(i).textFront, texts.get(i).textBack);
}
}
private void randomize(){
for (int i=0; i<texts.size(); i++){
if (texts.get(i).textFront.getVisibility() == View.GONE) {
texts.get(i).textFront.setText(textFront.get(i) + "");
texts.get(i).textFront.setBackgroundColor(colors.get(i));
}
else {
texts.get(i).textBack.setText(textBack.get(i) + "");
texts.get(i).textBack.setBackgroundColor(colors.get(i));
}
}
}
}
It looks like you're trying to do something that you shouldn't.
onBindViewHolder() is called by the system whenever it is about to display a ViewHolder to the user. So it will initially be called once for every view on the screen, plus once for a small number of views just off-screen (so that they can scroll on screen nicely).
However, this means it will also be called repeatedly as the user scrolls through the data in your adapter. In these cases, the ViewHolder being passed to onBindViewHolder() might have been recycled, meaning it might previously have been used to display different data and is now being re-used to display new data.
Let's say you have one million items in your data set, but your layout is set up in such a way that only 15 items are visible on screen at any one time. Chances are good that the system will wind up creating about 20 ViewHolder instances (15 on the screen, 5 available for re-use just off-screen). These same 20 ViewHolders will be used to display all one million items if the user scrolls enough. They'll just keep being re-used over and over.
That's why this line is problematic:
texts.add(viewHolder);
You're going to wind up building a list with potentially millions of objects in it, with the same 20 ViewHolders appearing multiple times in your list.
It would be much better to think about storing your data in a different way, rather than trying to store ViewHolders passed to onBindViewHolder().
Good day all,
I have a Recyclerview, where on first load achieves the result I want which is grouping all the Trades a specific seller is selling, by that seller.
Example:
Bob selling a watch.
Bob selling a car.
Bob selling a horse.
Button to remove all Bobs trades
Jim selling a house.
Jim selling a monkey.
Button to remove all Jims trades
ect
Example:
The issue is the minute I start scrolling the recyclerview, the rows of items get mixed up.
The way I did this was, I have a single layout that holds a Vertical Linear Layout with a green button below the LinearLayout.
Now I was programatically inflating the view for each Row, then setting the data for that row.
This is my onBindViewHolder:
#Override
public void onBindViewHolder(final ParentCartResultsViewHolder holder, int position) {
final LinkedHashMap<Long, List<Trade>> mapTradesBySeller = CartUtils.getUserToFixedPriceTradeMap();
mTradesBySeller = (new ArrayList<>(mapTradesBySeller.values())).get(holder.getAdapterPosition());
if (mTradesBySeller != null) {
for (Trade trade : mTradesBySeller) {
View singleTrade = LayoutInflater.from(MyApplication.getAppContext()).inflate(R.layout.item_trade_details_include_row, holder.mLinearLayout, false);
TextView tradeTitle = (TextView) singleTrade.findViewById(R.id.trade_details_include_trade_title);
tradeTitle.setText(trade.getTitle());
TextView endDate = (TextView) singleTrade.findViewById(R.id.trade_details_include_trade_ending_time);
endDate.setText(trade.getUserAlias() + " : " + trade.getUserId());
holder.mLinearLayout.addView(singleTrade);
}
}
}
My onCreateViewHolder:
#Override
public ParentCartResultsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_grouped_by_seller, parent, false);
return new ParentCartResultsViewHolder(v);
}
Now I think I know what the issue is, its just I cant figure out how I can fix it.
The problem is the creating of the views and adding them to the LinearLayout is in the onBindViewHolder, as this runs numerous times
You can use the library SectionedRecyclerViewAdapter to easily group your data into sections and add a footer to each section.
First create a Section class:
class TradeSection extends StatelessSection {
List<String> list;
public TradeSection(List<String> list) {
// call constructor with layout resources for this Section header, footer and items
super(-1, R.layout.section_item, R.layout.section_footer);
// remove header
this.setHasHeader(false);
this.list = list;
}
#Override
public int getContentItemsTotal() {
return list.size(); // number of items of this section
}
#Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
// return a custom instance of ViewHolder for the items of this section
return new MyItemViewHolder(view);
}
#Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
MyItemViewHolder itemHolder = (MyItemViewHolder) holder;
// bind your view here
itemHolder.tvItem.setText(list.get(position));
}
#Override
public RecyclerView.ViewHolder getFooterViewHolder(View view) {
return new MyFooterViewHolder(view);
}
#Override
public void onBindFooterViewHolder(RecyclerView.ViewHolder holder) {
MyFooterViewHolder footerHolder = (MyFooterViewHolder) holder;
// bind your footer view here
footerHolder.tvItem.setText(title);
}
}
Then you set up the RecyclerView with your Sections:
// Create an instance of SectionedRecyclerViewAdapter
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter();
// Create your sections with the list of data for each year
TradeSection section1 = new TradeSection(bobDataList);
TradeSection section2 = new TradeSection(jimDataList);
// Add your Sections to the adapter
sectionAdapter.addSection(section1);
sectionAdapter.addSection(section2);
// Set up your RecyclerView with the SectionedRecyclerViewAdapter
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);