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);
Related
I followed a tutorial to check a single radioButton. I tried to change it so you can change multiple radioButtons.
I succeeded to get the value out of the arraylist and show it on the screen, but when I click on it doesn't change. Only the radioButton that is unchecked get checked. Can anyone help me with this.
public interface ItemClickListener {
//Create method
void onClick(String s);
}
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.AdapterView;
import android.widget.RadioButton;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
//Initialize variable
RecyclerView recyclerView;
ItemClickListener itemClickListener;
MainAdapter adapter;
ArrayList<String> arrayList;
ArrayList<Boolean> arrayList_B;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Assign variable
recyclerView = findViewById(R.id.recycler_view);
fillArrayList();
//Initialize listener
itemClickListener = new ItemClickListener() {
#Override
public void onClick(String s) {
//Notify adapter
recyclerView.post(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
}
});
//Display toast
Toast.makeText(getApplicationContext(),
"Selected : " + s, Toast.LENGTH_SHORT).show();
}
};
//Set layout manager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//Initialize adapter
adapter = new MainAdapter(arrayList, arrayList_B, itemClickListener);
//Set adapter
recyclerView.setAdapter(adapter);
}
public void fillArrayList() {
//initialize array list
arrayList = new ArrayList<>();
arrayList_B = new ArrayList<>();
//Use for loop
for (int i = 0; i < 10; i++) {
//Add values in array list
arrayList.add("RB " + i);
arrayList_B.add(true);
}
arrayList_B.set(3,false);
}
}
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
//Initialize variable
ArrayList<String> arrayList;
ArrayList<Boolean> arrayList_B;
ItemClickListener itemClickListener;
int selectedPosition = -1;
//Create constructor
public MainAdapter(ArrayList<String> arrayList, ArrayList<Boolean> arrayList_B, ItemClickListener itemClickListener) {
this.arrayList = arrayList;
this.itemClickListener = itemClickListener;
this.arrayList_B = arrayList_B;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Initialize view
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_main, parent, false);
//Pass holder view
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set text on radio button
holder.radioButton.setText(arrayList.get(position));
//Set true or false radio button
holder.radioButton.setChecked(arrayList_B.get(position));
//Set listener on radio button
holder.radioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
//When checked
//Update selected position
selectedPosition = holder.getAdapterPosition();
//if (arrayList_B.get(selectedPosition).equals(true)) {
//if (b == true) {
// arrayList_B.set(selectedPosition, false);
//}
//if (b == false) {
//
//}
arrayList_B.set(selectedPosition, b);
holder.radioButton.setChecked(arrayList_B.get(selectedPosition));
//Call listener
//Get RadioButton name.
itemClickListener.onClick(holder.radioButton.getText().toString());
//set array list radiobutton
}
});
}
#Override
public long getItemId(int position) {
//Pass position
return position;
}
#Override
public int getItemViewType(int position) {
//Pass position
return position;
}
#Override
public int getItemCount() {
//Pass total List size
return arrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
RadioButton radioButton;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
radioButton = itemView.findViewById(R.id.radiobutton);
}
}
}
The Layout: activity_main.xml
<RelativeLayout xmlns: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:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_view"
tools:listitem="#layout/item_main"/>
</RelativeLayout>
The Layout: item_main.xml
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/radiobutton"
android:padding="12dp"
android:textSize="18sp"
android:textColor="#android:color/darker_gray"/>
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?
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.
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>
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.