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

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.

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?

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);

Attempt to invoke virtual method 'android.text.Editable com.rengwuxian.materialedittext.MaterialEditText.getText()'

please help me
Pressing the register button does not return a toast message, the app stops, and the following code:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable com.rengwuxian.materialedittext.MaterialEditText.getText()' on a null object reference
I also used String.ofValue instead of toString.
public class RegisterActivity extends AppCompatActivity {
MaterialEditText username, email, password;
Button btn_register;
FirebaseAuth auth;
DatabaseReference reference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Register");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
username = findViewById(R.id.username);
email = findViewById(R.id.email);
password = findViewById(R.id.password);
btn_register = findViewById(R.id.btn_register);
auth = FirebaseAuth.getInstance();
btn_register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String txt_username = username.getText().toString();
String txt_email = email.getText().toString();
String txt_password = password.getText().toString();
if (TextUtils.isEmpty(txt_username) || TextUtils.isEmpty(txt_email) || TextUtils.isEmpty(txt_password)){
Toast.makeText(RegisterActivity.this, "All fields are required", Toast.LENGTH_SHORT).show();
} else if (txt_password.length() < 6){
Toast.makeText(RegisterActivity.this, "password must be at least 6 character", Toast.LENGTH_SHORT).show();
} else {
register(txt_username, txt_email, txt_password);
}
}
});
}
private void register(final String username, String email, String password) {
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
FirebaseUser firebaseUser = auth.getCurrentUser();
assert firebaseUser != null;
String userid = firebaseUser.getUid();
reference = FirebaseDatabase.getInstance().getReference("Users" ).child(userid);
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("id", userid);
hashMap.put("username", username);
hashMap.put("imageURL", "default");
reference.setValue(hashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}
});
} else {
Toast.makeText(RegisterActivity.this, "You can't register with this email or password", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Copy my codes and compare your codes with mine
Java Code
Look carefully at the Java code
public class RegisterActivity extends AppCompatActivity {
MaterialEditText username, email, password;
Button btn_register;
FirebaseAuth auth;
DatabaseReference reference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Register");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
username = findViewById(R.id.username);
email = findViewById(R.id.email);
password = findViewById(R.id.password);
btn_register = findViewById(R.id.btn_register);
auth = FirebaseAuth.getInstance();
btn_register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String txt_username = username.getText().toString();
String txt_email = email.getText().toString();
String txt_password = password.getText().toString();
if (TextUtils.isEmpty(txt_username) || TextUtils.isEmpty(txt_email) || TextUtils.isEmpty(txt_password)){
Toast.makeText(RegisterActivity.this, "All fileds are required", Toast.LENGTH_SHORT).show();
}else if (txt_password.length() < 6){
Toast.makeText(RegisterActivity.this, "password must be at least 6 characters", Toast.LENGTH_SHORT).show();
} else {
register(txt_username, txt_email, txt_password);
}
}
});
}
private void register(String username, String email, String password){
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
FirebaseUser firebaseUser = auth.getCurrentUser();
assert firebaseUser != null;
String userid = firebaseUser.getUid();
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("id", userid);
hashMap.put("username", username);
hashMap.put("imageURL", "default");
reference.setValue(hashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}
});
}else {
Toast.makeText(RegisterActivity.this, "You can't register woth this email or password", Toast.LENGTH_SHORT).show();
}
}
});
}
}
XML Code
Look carefully at the xml code
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".RegisterActivity">
<include
android:id="#+id/toolbar"
layout="#layout/bar_layout"/>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_below="#+id/toolbar"
android:padding="16dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create a new account"
android:textSize="20sp"
android:textStyle="bold"/>
<com.rengwuxian.materialedittext.MaterialEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/username"
android:layout_marginTop="10dp"
app:met_floatingLabel="normal"
android:hint="Username"/>
<com.rengwuxian.materialedittext.MaterialEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/email"
android:inputType="textEmailAddress"
android:layout_marginTop="10dp"
app:met_floatingLabel="normal"
android:hint="Email"/>
<com.rengwuxian.materialedittext.MaterialEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/password"
android:inputType="textPassword"
android:layout_marginTop="10dp"
app:met_floatingLabel="normal"
android:hint="Password"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="register"
android:id="#+id/btn_register"
android:background="#color/colorPrimaryDark"
android:layout_marginTop="10dp"
android:textColor="#fff"/>
</LinearLayout>
</RelativeLayout>

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>

Add Recyclerview in RecyclerViewPager

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.