Add Recyclerview in RecyclerViewPager - android-recyclerview

I added a Recyclerview in one item of RecyclerViewPager(https://github.com/lsjwzh/RecyclerViewPager).
And I want to scroll the RecyclerView when I touch on it.
I have tried :
View.OnTouchListener listener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_DOWN:
mRecyclerViewPager.requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mRecyclerViewPager.requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
};
mRecyclerView.setOnTouchListener(listener);
But I can only scroll the RecyclerView sometimes.
I think it can be sloved by implementing NestedScrollingParent in RecyclerViewPager or changing onTouchEvent in RecyclerViewPager .But I'm not familiar with them.

I followed the steps to configure and create the simple example using the Github documentation.
Main Activity XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns: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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.stackoverflow.recyclerviewstack.MainActivity">
<com.lsjwzh.widget.recyclerviewpager.RecyclerViewPager
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="1dp"
android:paddingRight="1dp"
app:rvp_triggerOffset="0.1"
app:rvp_singlePageFling="true"
android:clipToPadding="false"
/>
</RelativeLayout>
Main Activiy class
package com.stackoverflow.recyclerviewstack;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import com.lsjwzh.widget.recyclerviewpager.RecyclerViewPager;
public class MainActivity extends AppCompatActivity {
RecyclerAdapter mAdapter;
RecyclerViewPager mRecycler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecycler = (RecyclerViewPager) findViewById(R.id.list);
// setLayoutManager like normal RecyclerView, you do not need to change any thing.
LinearLayoutManager layout = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecycler.setLayoutManager(layout);
//set adapter
//You just need to implements ViewPageAdapter by yourself like a normal RecyclerView.Adpater.
mAdapter = new RecyclerAdapter(ItemListGenerator.generateCollection(15, "OutItem "));
mRecycler.setAdapter(mAdapter);
}
}
RecyclerAdapter
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
List<String> collection;
public RecyclerAdapter(List<String> collection) {
this.collection = collection;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView item;
RecyclerView mInnerRecycler;
public ViewHolder(View view) {
super(view);
item = (TextView) view.findViewById(R.id.title);
mInnerRecycler = (RecyclerView) view.findViewById(R.id.innerRecycler);
LinearLayoutManager layout = new LinearLayoutManager(view.getContext(),
LinearLayoutManager.HORIZONTAL, false);
mInnerRecycler.setLayoutManager(layout);
mInnerRecycler.setAdapter(new InnerAdapter());
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.outer_collection, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(position < 0 || position > getItemCount()) return;
String itemString = collection.get(position);
holder.item.setText(itemString);
}
#Override
public int getItemCount() {
return collection.size();
}
}
the layout use by RecyclerViewPager to create ViewHolder
The ViewHolder use the layout outer_collection:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_margin="2dip"
android:background="#color/colorPrimary"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/innerRecycler"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
The InnerAdapter
public class InnerAdapter extends RecyclerView.Adapter<InnerAdapter.ViewHolder> {
List<String> collection;
public InnerAdapter() {
this.collection = ItemListGenerator.generateCollection(15, "Inner ");
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView item;
public ViewHolder(View itemView) {
super(itemView);
item = (TextView) itemView.findViewById(R.id.item);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.simple_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(position < 0 || position > getItemCount()) return;
holder.item.setText(collection.get(position));
}
#Override
public int getItemCount() {
return collection.size();
}
}
Tip
For the RecyclerViewPager I used this orientation:
LinearLayoutManager layout = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
And for the RecyclerView inside this one:
LinearLayoutManager layout = new LinearLayoutManager(view.getContext(), LinearLayoutManager.HORIZONTAL, false);
If you use VERTICAL in the PagerView you can navigate in the horizontal collection or change to HORIZONTAL the PagerView orientation and you can scroll your inside items in the VERTICAL orientation.
You have to evaluate how do you want to use it. I hope this code help with your problem and also to rethink your design. Maybe is not a good practice or UX use the same orientation for both containers. I am not a UX expert.
I will like to be more helpful.

Related

Modify all recycler view items show all view holder stacked values

I desire to update each item of a recycled view every second with a new value. But instead of viewing only all updated values, all viewHolders seems to be stacked.
My recyclerView is declared like this :
recyclerView = findViewById(R.id.recycle);
adapter = new ExampleAdapter();
LinearLayoutManager recyclerViewLayout = new LinearLayoutManager(this);
recyclerView.setLayoutManager(recyclerViewLayout);
recyclerView.setAdapter(adapter);
I update the list of the adapter like this :
ArrayList<Integer> newList = new ArrayList<Integer>(Arrays.asList(0,1,2,3,4,5,6,7,8,9));
private void addNewInt() {
for (int i=0;i<newList.size();i++) {
newList.set(i, newList.get(i) + 10);
}
adapter.updateList(newList);
}
And this is my Adapter :
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ViewHolder> {
private ArrayList<Integer> list;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txt;
public ViewHolder(View view) {
super(view);
txt = view.findViewById(R.id.txt);
}
}
public ExampleAdapter() {
this.list = new ArrayList<>();
}
#Override
public ExampleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View cellView = inflater.inflate(R.layout.raw_example, parent, false);
return new ViewHolder(cellView);
}
#Override
public void onBindViewHolder(#NonNull ExampleAdapter.ViewHolder holder, int position) {
if (!list.isEmpty()) {
Integer val = list.get(position);
holder.txt.setText(Integer.toString(val));
}
}
#Override
public int getItemCount() {
return list.size();
}
public void updateList(ArrayList<Integer> newList) {
list.clear();
list.addAll(newList);
notifyDataSetChanged();
}
}
The problem does not seem to be linked with recycling. I tried to add holder.setIsRecyclable(false) to force recreate a new viewHolder without any effect.
I tried also to play with the recyclerView.getRecycledViewPool().setMaxRecycledViews and recyclerView.setItemViewCacheSize() methods without any success.
I try to use notifyItemRangeChange() instead of using the notifyDataSetChanged(). Nothing better.
I also try to force to clear the recyclerview before adding the new elements like this :
list.clear();
notifyDataSetChanged();
list.addAll(newList);
notifyDataSetChanged();
The xml of my Activity is the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp" >
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
What is wrong with my code?

Update all checkbox in nested recycler View when button in Fragment is clicked

Hello I am struggling with this problem. I have a RecyclerView with checkboxes items which is nested in another RecyclerView. My problem is that I want all the checkbox to be unchecked when the user click in a button in the fragment. So how could I access the checkbox view holder from my fragment button? Thank you.
Please be comprehensive with the mistakes in my code I am beginner, self-taught and it is my first app. Any help would be really appreciated.
fragment_index_category_filter.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="4dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Fragments.IndexCategoryFilterFragment">
<!-- TODO: Update blank fragment layout -->
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/home_activity_tb"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
android:gravity="center"
android:layout_gravity="center"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<RelativeLayout
android:id="#+id/toolbar"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="#+id/close_filters"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:padding="0dp"
app:fabCustomSize="50dp"
app:icon="#drawable/cancel"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="32dp"
app:shapeAppearanceOverlay="#style/ShapeAppearanceOverlay.MyApp.Button.Circle" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/appBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Category list"
android:textAllCaps="false"
android:textColor="#color/black"
android:textSize="24sp" />
<com.google.android.material.button.MaterialButton
android:id="#+id/save_filters"
app:icon="#drawable/ic_check_ok"
app:iconSize="32dp"
app:iconGravity="textStart"
android:layout_width="32dp"
android:layout_height="32dp"
android:padding="0dp"
app:iconPadding="0dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:insetBottom="0dp"
app:shapeAppearanceOverlay="#style/ShapeAppearanceOverlay.MyApp.Button.Circle"
app:fabCustomSize="50dp"
/>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout"
android:id="#+id/shortcuts_filter">
<com.google.android.material.button.MaterialButton
android:id="#+id/clear_filters"
style="#style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:padding="0dp"
android:text="Clear all"
android:textAllCaps="false"
android:textSize="12sp" />
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="0dp"
android:id="#+id/select_all_filters"
android:textSize="12sp"
android:text="Select all"
android:layout_alignParentEnd="true"
android:textAllCaps="false"
style="#style/Widget.MaterialComponents.Button.OutlinedButton"/>
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_margin="8dp"
app:layout_constraintTop_toBottomOf="#+id/shortcuts_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/categorySection_rv"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"/>
</androidx.constraintlayout.widget.ConstraintLayout>
IndexCategoryFilterFragment.java
public class IndexCategoryFilterFragment extends Fragment {
//Initialize variable
List<String> streamFiltersList;
RecyclerView categorySection_rv;
FirebaseDatabase firebaseDatabase;
DatabaseReference dbCategoryReference;
StreamFilterManager streamFilterManager;
MaterialButton save_filters, clear_filters, close_fragment;
FiltersViewModel filtersListObserver;
private FirebaseAuth mAuth;
FirebaseUser firebaseUser;
String userId;
SectionAdapter sectionAdapter;
List<Letter> letterList;
List<Category> categoryInLetter = new ArrayList<>();
public FilterInterface interfaceListener;
public IndexCategoryFilterFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container != null) {
container.removeAllViews();
}
// Inflate the layout for this fragment
mAuth = FirebaseAuth.getInstance();
firebaseUser = mAuth.getCurrentUser();
userId = firebaseUser.getUid();
View view = inflater.inflate(R.layout.fragment_index_category_filter, container, false);
save_filters = view.findViewById(R.id.save_filters);
categorySection_rv = view.findViewById(R.id.categorySection_rv);
clear_filters = view.findViewById(R.id.clear_filters);
close_fragment = view.findViewById(R.id.close_filters);
firebaseDatabase = FirebaseDatabase.getInstance();
dbCategoryReference = firebaseDatabase.getReference("CategoryIndexed");
save_filters.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
streamFilterManager.logOutFromUserSession();
streamFilterManager.writeListInPref(getContext(), streamFiltersList, userId);
Log.d("streamFilter", "onClick: " + streamFiltersList);
filtersListObserver = new ViewModelProvider(requireActivity()).get(FiltersViewModel.class);
filtersListObserver.setFiltersList(streamFiltersList);
getParentFragmentManager().beginTransaction().replace(R.id.fragment_container, new Home(), "home").commit();
}
});
close_fragment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getParentFragmentManager().popBackStack();
}
});
letterList = new ArrayList<>();
categoryInLetter = new ArrayList<>();
sectionAdapter = new SectionAdapter(getContext(), letterList);
categorySection_rv.setAdapter(sectionAdapter);
firebaseCategoryIndex();
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
streamFilterManager = new StreamFilterManager(getContext(), userId);
streamFiltersList = streamFilterManager.readFilterList(getContext(), userId);
if (streamFiltersList == null) {
streamFiltersList = new ArrayList<>();
}
clear_filters.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkboxUpdate();
}
});
}
private void firebaseCategoryIndex() {
// First recycler
Query queryLetter = dbCategoryReference.orderByChild("index");
queryLetter.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
letterList.clear();
for (DataSnapshot dsLetter : snapshot.getChildren()) {
Letter letter = dsLetter.getValue(Letter.class);
letterList.add(letter);
}
sectionAdapter.notifyDataSetChanged();
Log.d("letterList", "letterList: " + letterList.size());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
// solutions testing
public interface FilterInterface {
void clearSelectAllFilters(Button allFilters);
}
private void checkboxUpdate() {
// 1. get ith item of the parent recyclerView
for(int i = 0 ; i< sectionAdapter.getItemCount();i++){
SectionAdapter.ViewHolder viewHolder = (SectionAdapter.ViewHolder) categorySection_rv.findViewHolderForAdapterPosition(i);
RecyclerView recyclerView = viewHolder.section_item_rv;
ItemSectionAdapter itemSectionAdapter = (ItemSectionAdapter) recyclerView.getAdapter();
itemSectionAdapter.update();
}
}
}
SectionAdapter.java
public class SectionAdapter extends RecyclerView.Adapter<SectionAdapter.ViewHolder> implements IndexCategoryFilterFragment.FilterInterface {
Context context ;
List<Letter> letterList;
DatabaseReference categoryListRef;
public SectionAdapter(Context context, List<Letter> letterList) {
this.context = context;
this.letterList = letterList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.section_category,parent,false);
return new SectionAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
List<Category> letterCategoryList = new ArrayList<>();
Letter letter = letterList.get(position);
holder.section_letter.setText(letter.getIndex());
holder.section_title_ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int visible = holder.section_item_rv.getVisibility();
if (visible == View.VISIBLE){
holder.section_item_rv.setVisibility(View.GONE);
} else {
holder.section_item_rv.setVisibility(View.VISIBLE);
}
}
});
categoryListRef = FirebaseDatabase.getInstance().getReference("CategoryIndexed").child(letter.getIndex()).child("content");
ItemSectionAdapter itemSectionAdapter = new ItemSectionAdapter(letterCategoryList);
categoryListRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dsLetterContent : snapshot.getChildren()){
Category category = dsLetterContent.getValue(Category.class);
category.setCheckState(true);
Log.d("letterList", "letterList: "+ category.getCategoryName() + " "+ category.isCheckState());
letterCategoryList.add(category);
}
itemSectionAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.section_item_rv.setAdapter(itemSectionAdapter);
}
#Override
public int getItemCount() {
return letterList.size();
}
#Override
public void clearSelectAllFilters(Button allFilters) {
}
public class ViewHolder extends RecyclerView.ViewHolder {
public MaterialTextView section_letter;
public RecyclerView section_item_rv;
public LinearLayout section_title_ll;
public ViewHolder(#NonNull View itemView) {
super(itemView);
section_letter = itemView.findViewById(R.id.section_letter);
section_item_rv = itemView.findViewById(R.id.section_item_rv);
section_title_ll = itemView.findViewById(R.id.section_title_ll);
}
}
}
ItemSectionAdpater.java
public class ItemSectionAdapter extends RecyclerView.Adapter<ItemSectionAdapter.ViewHolder> implements IndexCategoryFilterFragment.FilterInterface {
List<Category> categoryList;
public ItemSectionAdapter(List<Category> categoryList) {
this.categoryList = categoryList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.index_category_name_item,parent,false);
return new ItemSectionAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Category category = categoryList.get(position);
holder.indexItemCategory.setText(category.getCategoryName());
holder.cb_categoryItem.setChecked(category.isCheckState());
}
#Override
public int getItemCount() {
return categoryList.size();
}
#Override
public void clearSelectAllFilters(Button allFilters) {
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView indexItemCategory;
public CheckBox cb_categoryItem;
public RelativeLayout category_item_rl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
indexItemCategory = itemView.findViewById(R.id.indexItemCategory);
cb_categoryItem = itemView.findViewById(R.id.cb_categoryItem);
category_item_rl = itemView.findViewById(R.id.category_item_rl);
}
}
public void update() {
categoryList.forEach(category -> category.setCheckState(false));
notifyDataSetChanged();
}
}
Make a public method in adapter and then pass your new data with changed checked values to true, and then notify the adapter like shown below (or update the existing method with the code given below).
public void updateList(ArrayList<Category> categoryList) {
this.categoryList = categoryList;
notifyDataSetChanged();
}
then simply call this method wherever you need with the adapter object in your fragment.

Recycler in Fragment is no showing

I have been making an app that uses a recycler view in a fragment. how the contents of the recycler view have not been showing up. I am not sure what I have done wrong as the app does not crash when it is run. Please tell me what i need to do.
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"`enter code here`
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Fragments.Home_Fragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/cetagory_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:elevation="3dp" />
</FrameLayout>
Home_Fragment.java
private RecyclerView categoryRecyclerView;
private CategoryAdapter categoryAdapter;
public Home_Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
categoryRecyclerView = view.findViewById(R.id.cetagory_recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
categoryRecyclerView.setLayoutManager(layoutManager);
List<CategoryModel> categoryModelList = new ArrayList<CategoryModel>();
categoryModelList.add(new CategoryModel("Link","Home"));
categoryModelList.add(new CategoryModel("Link","Electronicse"));
categoryModelList.add(new CategoryModel("Link","Garments"));
categoryModelList.add(new CategoryModel("Link","Fashion"));
categoryModelList.add(new CategoryModel("Link","Toys"));
categoryModelList.add(new CategoryModel("Link","Sporte"));
categoryModelList.add(new CategoryModel("Link","Furniture"));
categoryModelList.add(new CategoryModel("Link","Wall Art"));
categoryModelList.add(new CategoryModel("Link","Appliance"));
categoryAdapter = new CategoryAdapter(categoryModelList);
categoryRecyclerView.setAdapter(categoryAdapter);
categoryAdapter.notifyDataSetChanged();
return view;
}
CategoryModel.java
private String categoryItemIconLink;
private String categoryName;
public CategoryModel(String categoryItemIconLink, String categoryName) {
this.categoryItemIconLink = categoryItemIconLink;
this.categoryName = categoryName;
}
public String getCategoryItemIconLink() {
return categoryItemIconLink;
}
public void setCategoryItemIconLink(String categoryItemIconLink) {
this.categoryItemIconLink = categoryItemIconLink;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
CategoryAdapter.java
Context context;
private List<CategoryModel> categoryModelList = new ArrayList<CategoryModel>();
public CategoryAdapter(List<CategoryModel> categoryModerList) {
this.context = context;
this.categoryModelList = categoryModelList;
}
#NonNull
#Override
public CategoryAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.category_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CategoryAdapter.ViewHolder holder, int position) {
String icon = categoryModelList.get(position).getCategoryItemIconLink();
String name = categoryModelList.get(position).getCategoryName();
holder.setCategoryName(name);
}
#Override
public int getItemCount() {
return categoryModelList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView categoryIcon;
private TextView categoryName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
categoryIcon = itemView.findViewById(R.id.category_item_icon);
categoryName = itemView.findViewById(R.id.category_item_name);
}
private void setCategoryIcon() {
//Todo: set categoryIcone here
}
private void setCategoryName(String name) {
categoryName.setText(name);
}
}
You have not initialized your variables inside your adapter
Replace this...
public CategoryAdapter(List<CategoryModel> categoryModerList) {
this.context = context;
this.categoryModelList = categoryModelList;
}
With this..
public CategoryAdapter(Context context,List<CategoryModel> categoryModelList) {
this.context = context;
this.categoryModelList = categoryModelList;
}
then inside your fragment where you are calling adapters constructor add change this line.
from..
categoryAdapter = new CategoryAdapter(categoryModelList);
to..
categoryAdapter = new CategoryAdapter(getContext(),categoryModelList);

How can I include a recyclerView (contains a list of items) in one activity that has other views

I want to achieve something like below, my list data is coming from a restful server. Everything is working except that the list is empty.
I used the following;
* Recyclerview Adaptor
* Created a pojo for list items, logs show that that the data is coming through from the server except that the list is not populated
//TransactionsFragment
public class TransactionsFragment extends Fragment {
View rootView;
RecyclerView recyclerView;
String transaction_amount;
String transaction_date_created;
public String authToken;
public TransactionsFragment() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_transactions_list, container, false);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView = rootView.findViewById(R.id.rv_transactions);
recyclerView.setLayoutManager(linearLayoutManager);
TransactionListAdapter transactionListAdapter = new TransactionListAdapter(getContext(), getTransactions());
recyclerView.setAdapter(transactionListAdapter);
transactionListAdapter.notifyDataSetChanged();
return rootView;
}
private List<Transaction> getTransactions() {
List<Transaction> transactionList = new ArrayList<>();
/........
#Override
public void onNext(List<Transaction> transactions) {
Integer transactionSize = transactions.size();
for (int i =0;i<transactionSize;i++) {
transaction_amount = transactions.get(i).getAmount();
transaction_date_created = transactions.get(i).getDateCreated();
transactionList.add(new Transaction(transactions.get(i).getId(),null,transactions.get(i).getAmount(), transactions.get(i).getDateCreated(), transactions.get(i).getAccount()));
}
/// Data is shown here after running the app so it tells me that we are getting response from the server
Toast.makeText(getActivity(), "Transaction Date Created: " + transaction_date_created + "!", Toast.LENGTH_LONG).show();
}
#Override
public void onError(Throwable e) {
if (e instanceof HttpException) {
HttpException response = (HttpException) e;
int code = response.code();
String msg = response.message();
Toast.makeText(getActivity(), "Transaction Error message: " + msg + "!", Toast.LENGTH_LONG).show();
}
}
#Override
public void onComplete() {
}
});
//...
return transactionList;
}
}
//..TransactionListAdapter
public class TransactionListAdapter extends RecyclerView.Adapter {
private List transactionList;
private Context mContext;
public TransactionListAdapter(Context context, List<Transaction> transactions) {
this.mContext = context;
this.transactionList = transactions;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_transactions_single, parent, false);
vh = new OriginalViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int i) {
if (holder instanceof TransactionListAdapter.OriginalViewHolder) {
TransactionListAdapter.OriginalViewHolder view = (TransactionListAdapter.OriginalViewHolder) holder;
Transaction transaction = transactionList.get(i);
view.tvTransactionAmount.setText(transaction.getAmount());
view.tvTransactionDateCreated.setText(transaction.getDateCreated());
}
}
#Override
public int getItemCount() {
return transactionList.size();
}
public class OriginalViewHolder extends RecyclerView.ViewHolder{
ImageView imgTransactionType;
TextView tvTransactionName, tvTransactionAmount, tvTransactionDateCreated, tvDefaultCurrency, getTvTransactionUSD;
public OriginalViewHolder(View itemView) {
super(itemView);
tvTransactionDateCreated = itemView.findViewById(R.id.tv_transaction_date_created);
tvTransactionAmount = itemView.findViewById(R.id.tv_transaction_amount);
}
}
}
//..MainActivity
public class MainActivity extends AppCompatActivity implements
View parent_view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkConnection();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
setContentView(R.layout.activity_home);
initiateViews();
Fragment transFragment = new TransactionsFragment();
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.transactions_frame_container, transFragment);
transaction.addToBackStack(null);
transaction.commit();
}
private void initiateViews() {
parent_view = (CoordinatorLayout)findViewById(R.id.home_container);
home_container_id = R.id.frame_container;
}
private void loadFragment(Fragment fragment, Integer container_id) {
// create a FragmentManager
FragmentManager fm = getSupportFragmentManager();
// create a FragmentTransaction to begin the transaction and replace the Fragment
FragmentTransaction fragmentTransaction = fm.beginTransaction();
// replace the FrameLayout with new Fragment
fragmentTransaction.replace(container_id, fragment);
fragmentTransaction.commit(); // save the changes
}
}
//..fragment_transactions_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/grey_10" />
<View
android:layout_width="0dp"
android:layout_height="#dimen/spacing_middle" />
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/rv_transactions"
android:scrollbars="vertical"
android:scrollingCache="true"/>
</LinearLayout>

Nullpointerexception on RecyclerView

All im trying to do is create a recyclerview inside of a tablayout i have tried setting up the adapter in the main activity as well as the fragment im using in the tablayout however either way im still getting this error
java.lang.RuntimeException: Unable to start activity ComponentInfo{knightsrealms.managment_app/knightsrealms.managment_app.Dashboard}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference
package knightsrealms.managment_app;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import java.util.ArrayList;
import java.util.Calendar;
public class Dashboard extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPageAdapter viewPagerAdapter;
ArrayList<knightsrealms.managment_app.Calendar> contacts = new ArrayList<knightsrealms.managment_app.Calendar>(5);
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
tabLayout = (TabLayout) findViewById(R.id.tabs);
viewPager = (ViewPager) findViewById(R.id.viewpager);
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
viewPagerAdapter = new ViewPageAdapter(getSupportFragmentManager());
viewPager.setAdapter(viewPagerAdapter);
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
setSupportActionBar(toolbar);
final TabLayout.Tab messages = tabLayout.newTab();
final TabLayout.Tab dashboard = tabLayout.newTab();
messages.setText("Messages");
dashboard.setText("Dashboard");
tabLayout.addTab(dashboard, 0);
tabLayout.addTab(messages, 1);
tabLayout.setTabTextColors(ContextCompat.getColorStateList(this, R.color.tab_selector));
tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(this, R.color.indicator));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
RecyclerView rvContacts = (RecyclerView)findViewById(R.id.rvcal);
contacts.add(0, new knightsrealms.managment_app.Calendar("Number 1",true));
contacts.add(1, new knightsrealms.managment_app.Calendar("Number 2",true));
CalendarAdapter adapter = new CalendarAdapter(contacts);
rvContacts.setAdapter(adapter);
rvContacts.setLayoutManager(new LinearLayoutManager(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.dashboard_menu, menu);
return true;
}
void selectPage(int pageIndex){
tabLayout.setScrollPosition(pageIndex,0f,true);
viewPager.setCurrentItem(pageIndex);
}
}
this is my adapter
package knightsrealms.managment_app;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.util.List;
public class CalendarAdapter extends RecyclerView.Adapter<CalendarAdapter.ViewHolder> {
// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
public static class ViewHolder extends RecyclerView.ViewHolder {
// Your holder should contain a member variable
// for any view that will be set as you render a row
public TextView nameTextView;
public Button messageButton;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public ViewHolder(View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
nameTextView = (TextView) itemView.findViewById(R.id.contact_name);
messageButton = (Button) itemView.findViewById(R.id.message_button);
}
}
private List<Calendar> mContacts;
// Pass in the contact array into the constructor
public CalendarAdapter(List<Calendar> contacts) {
mContacts = contacts;
}
// Usually involves inflating a layout from XML and returning the holder
#Override
public CalendarAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View contactView = inflater.inflate(R.layout.recyclercell, parent, false);
// Return a new holder instance
ViewHolder viewHolder = new ViewHolder(contactView);
return viewHolder;
}
// Involves populating data into the item through holder
#Override
public void onBindViewHolder(CalendarAdapter.ViewHolder viewHolder, int position) {
// Get the data model based on position
Calendar contact = mContacts.get(position);
// Set item views based on the data model
TextView textView = viewHolder.nameTextView;
textView.setText(contact.getName());
Button button = viewHolder.messageButton;
if (contact.isOnline()) {
button.setText("Message");
button.setEnabled(true);
}
else {
button.setText("Offline");
button.setEnabled(false);
}
}
// Return the total count of items
#Override
public int getItemCount() {
return mContacts.size();
}
}
This code is for the fragment which is inside the tablayout
<android.support.v7.widget.RecyclerView
android:id="#+id/rvcal"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
And this is the main activity xml
<RelativeLayout xmlns: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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar"
></include>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:layout_below="#+id/tool_bar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:tabIndicatorHeight="3dp"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tabs"
/>
</RelativeLayout>
any insight/help into this is greatly appreciated thank you!!
have you already try in :
tabLayout.setupWithViewPager(viewPager);
Well because recyclerView is in your fragment xml not in your activity xml, thus the recyclerView is return null.
Ok, So your code is almost done, but you need 2 more things:
first, is a class that extends FragmentPagerAdapter for your ViewPager, I don't know if your ViewPageAdapter class is already do that, but let's assume you're not yet done that.
second, is a fragment for your FragmentPagerAdapter.
Oke Lets start :
Create FragmentContacts for the FragmentPagerAdapter, in this fragment you should manage your RecyclerView and it's adapter not in the Activity.
public class FragmentContacts extends Fragment {
ArrayList<knightsrealms.managment_app.Calendar> contacts = new ArrayList<knightsrealms.managment_app.Calendar>(5);
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = (View) inflater.inflate(R.layout.your_fragment_xml, container, false);
contacts.add(0, new knightsrealms.managment_app.Calendar("Number 1",true));
contacts.add(1, new knightsrealms.managment_app.Calendar("Number 2",true));
CalendarAdapter adapter = new CalendarAdapter(contacts);
RecyclerView rvContacts = (RecyclerView) rootView.findViewById(R.id.rvcal);
rvContacts.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
rvContacts.setAdapter(adapter);
return rootView;
}
}
Lastly, back in your Dashboard Activity, in onCreate, setUp your Viewpager :
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPagerAdapter = new ViewPageAdapter(getSupportFragmentManager());
viewPager.setAdapter(viewPagerAdapter);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(0);
}
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
if(position == 0) return new FragmentContacts();
if(position == 1) return new FragmentContacts();
throw new IllegalStateException("Unexpected position " + position);
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
if(position == 0) return "Messages";
if(position == 1) return "Dashboard";
throw new IllegalStateException("Unexpected position " + position);
}
}