Reputation: 1581
I'm writing a shopping list app that will save data to a Firebase Realtime database and update the screen in real time. As of right now I have it so that when you click the "+ List item" button, it adds a ShoppingListItem to the database with the name "test". It does that correctly, but it isn't updating the screen. I've double checked that the methods are being called, but the screen isn't reflecting the updated data. I have also tried using notifyDataSetChanged() and that hasn't seemed to help either.
This is the code for the ShoppingListFragment:
public class ShoppingListFragment extends Fragment {
private ArrayList<String> listItems = new ArrayList<String>();
private ListView mListView;
private TextView addItemButton;
private LinearLayout ll;
private RecyclerView rv;
private FirebaseRecyclerAdapter<ShoppingListItem, ShoppingListHolder> firebaseRecyclerAdapter;
private DatabaseReference mDatabase;
public ShoppingListFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
mDatabase = FirebaseDatabase.getInstance().getReference();
//get reference to user
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
Query query = mDatabase.child("users").child(uid).child("shopping");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_shopping_list, container, false);
rv = view.findViewById(R.id.shopping_list);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
// find the + List Item button
final TextView addCheckBox = view.findViewById(R.id.add_check_box);
addCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addNewCheckBox(container);
}
});
FirebaseRecyclerOptions<ShoppingListItem> options = new FirebaseRecyclerOptions.Builder<ShoppingListItem>()
.setQuery(query, ShoppingListItem.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ShoppingListItem, ShoppingListHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull ShoppingListHolder holder, int position, @NonNull ShoppingListItem item) {
holder.setItem(item);
}
@NonNull
@Override
public ShoppingListHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shopping_list_item, parent, false);
return new ShoppingListHolder(view);
}
};
return view;
}
@Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
rv.setAdapter(firebaseRecyclerAdapter);
}
@Override
public void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
public void addNewCheckBox(ViewGroup container) {
String key = mDatabase.child("users").child(getUid()).child("shopping_list").push().getKey();
ShoppingListItem item = new ShoppingListItem("test");
mDatabase.child("users").child(getUid()).child("shopping_list").child(key).setValue(item);
firebaseRecyclerAdapter.notifyDataSetChanged();
}
public int convertToPx(int input) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
int px = (int) (input * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
private class ShoppingListHolder extends RecyclerView.ViewHolder {
private final EditText itemName;
public ShoppingListHolder(View itemView) {
super(itemView);
itemName = itemView.findViewById(R.id.item_name);
}
public void setItem(ShoppingListItem item) {
itemName.setText(item.getItemName());
}
}
private String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
and the ShoppingListItem:
public class ShoppingListItem {
private String itemName;
private String type;
private String unit;
private int quantity;
private String location;
public ShoppingListItem() {
}
public ShoppingListItem(String name) {
this.itemName = name;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
}
XML for the shopping list view:
<LinearLayout 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"
android:id="@+id/home_fragment_main_layout"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.jggdevelopment.wannacook.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Shopping List"
android:textStyle="bold"
android:textSize="18sp"
android:layout_marginStart="16dp"
android:layout_marginBottom="16dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/shopping_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:clipToPadding="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/add_check_box"
android:text="+ List item"
android:textSize="16sp"
android:layout_marginStart="40dp"
android:layout_marginTop="16dp"/>
</LinearLayout>
and XML for each line item in the shopping list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/item_name"
android:layout_weight="1"
android:layout_marginStart="12dp"
android:layout_marginEnd="32dp"
android:inputType="text"
android:background="@android:color/transparent"
/>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:id="@+id/xbutton"
android:layout_marginEnd="12dp"
android:src="@drawable/ic_close_white_24dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
Upvotes: 2
Views: 670
Reputation: 138834
This is not working because you forgot to set the adapter in the onCreate()
method. To solve this, add rv.setAdapter(firebaseRecyclerAdapter);
, right before you are returning the view like this:
rv.setAdapter(firebaseRecyclerAdapter);
return view;
And you can remove that line of code from the onStart()
method because is not needed there.
If you are interested, I have created a tutorial in which I'm explaining step by step, how to build a Shopping List App using Cloud Firestore and Android.
Upvotes: 1