I am creating a notes app with java, i added room database to my app and when user saves a notes it adds it to database but doesn't shows in recyclerView immediately, when i reloads the app then it shows up, how and where should i insert notifyiteminserted so that recyclerView changes immediately
I have tried onResume Method but that results in app crash.
This is my MainActivity.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
#SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
This is my add_Activity.
package com.example.keepnotes;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import java.util.Objects;
public class addActivity extends AppCompatActivity {
MainActivity mainActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
Toolbar toolbar_add = findViewById(R.id.toolbar_add_activity);
setSupportActionBar(toolbar_add);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
toolbar_add.setNavigationIcon(R.drawable.back_button);
toolbar_add.setNavigationOnClickListener(view -> onBackPressed());
EditText titleText = findViewById(R.id.add_activity_title);
EditText bodyText = findViewById(R.id.add_activity_text);
Button saveBtn = findViewById(R.id.button);
DatabaseHelper database = DatabaseHelper.getDatabase(this);
saveBtn.setOnClickListener(view -> {
String titleBody = titleText.getText().toString();
String textBody = bodyText.getText().toString();
if (titleBody.equals("") && textBody.equals("")) {
Toast.makeText(addActivity.this, "Fields can't be empty",
Toast.LENGTH_LONG).show();
} else {
database.notesDao().addNotes(new Notes(titleBody, textBody));
finish();
}
});
}
}
How can i notify adapter the changes on each item add in database.
Here is my MainActivity after update to liveData.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
#SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
modelView = new ViewModelProvider(this).get(notesModelView.class);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
#Override
public void onChanged(List<Notes> notes) {
arrNotes = (ArrayList<Notes>) notes;
}
});
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
this is Dao.
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
#Dao
public interface NotesDao {
#Query("SELECT * FROM notesTable")
List<Notes> getAllNotes();
#Query("SELECT * FROM notesTable")
LiveData<List<Notes>> findAllNotes();
#Insert
void addNotes(Notes note);
#Update
void updateNotes(Notes note);
#Delete
void deleteNotes(Notes note);
}
And here is my ViewModel
package com.example.keepnotes;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class notesModelView extends AndroidViewModel {
DatabaseHelper databaseHelper;
public notesModelView(#NonNull Application application) {
super(application);
databaseHelper = DatabaseHelper.getDatabase(application.getApplicationContext());
}
public LiveData<List<Notes>> getAllNotes() {
return databaseHelper.notesDao().findAllNotes();
}
}
Here is my RecyclerView adapter
package com.example.keepnotes;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
Context context;
ArrayList<Notes> arrNotes;
DatabaseHelper databaseHelper;
RecyclerViewAdapter(Context context, ArrayList<Notes> arrNotes, DatabaseHelper databaseHelper) {
this.context = context;
this.arrNotes = arrNotes;
this.databaseHelper = databaseHelper;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.single_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") int position) {
holder.title.setText(arrNotes.get(position).title);
holder.body.setText(arrNotes.get(position).text);
holder.index.setText(String.valueOf(position + 1));
holder.llView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
AlertDialog.Builder alert = new AlertDialog.Builder(context)
.setTitle("Delete view")
.setMessage("Are you sure to delete")
.setIcon(R.drawable.ic_baseline_delete_24)
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
databaseHelper.notesDao().deleteNotes(new Notes(arrNotes.get(position).id,arrNotes.get(position).title,arrNotes.get(position).text));
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alert.show();
return true;
}
});
}
#Override
public int getItemCount() {
return arrNotes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title, body, index;
CardView llView;
public ViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.text_title_view);
body = itemView.findViewById(R.id.text_text_view);
index = itemView.findViewById(R.id.index);
llView = itemView.findViewById(R.id.card_View);
databaseHelper = DatabaseHelper.getDatabase(context);
}
}
}
It deletes the selected notes but also crashes immediately after confirming delete.
and it throws following error
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{535e3b3 position=5 id=-1, oldPos=4, pLpos:4 scrap [attachedScrap] tmpDetached not recyclable(1) no parent} androidx.recyclerview.widget.RecyclerView{11f4816 VFED..... ......ID 31,171-689,1048 #7f090165 app:id/recycler_view}, adapter:com.example.keepnotes.RecyclerViewAdapter#fd652a0, layout:androidx.recyclerview.widget.StaggeredGridLayoutManager#32e1e59, context:com.example.keepnotes.MainActivity#286bccd
Remove this two line
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());
OLD ANSWER
First, if you use liveData you don't need to call the method
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
just keep a reference to the adapter instance and whenever there is a change from liveData call the notifyDataSetChanged method.
adapter = new RecyclerViewAdapter(this,new List<Notes>());
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
#Override
public void onChanged(List<Notes> notes) {
arrNotes.clear();
arrNotes.addAll(notes);
adapter.notifyDataSetChanged()
}
});
observe a LiveData object as it is not a LifecycleOwner
Use observeForever() on the LiveData, manually unregistering via removeObserver() when appropriate (onDestroy() of the service, if not sooner).
Bear in mind that standard service limitations apply here (e.g., services run for ~1 minute on Android 8.0+ unless they are foreground services), so it may be that you need to consider other approaches anyway. 🤞
Also you can read more in original post in here -> Link
Related
My data doesn't add to Recylerview after pressing the add button until I either restart the app or press the back button that's built in the action bar. My activity doesn't close after pressing the button so I usually use the back button on my device. Nothing gets added to my Recyclerview until the app restarts or when I add a new set of data and press the back button from the action bar, then 2 sets of data will be added.
I have also tried to finish the activity right after the button press but then that also doesn't add data into Recyclerview.
I want to know how I can make my activity finish after button press and display data in the Recyclerview or make it so that pressing the back button from my device still makes it display.
MainActivity Code:
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
FloatingActionButton newTaskBtn;
myDatabase myDB;
ArrayList<String> task_id, task_subject, task_description, task_due_date;
CustomAdapter customAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerTasks);
newTaskBtn = findViewById(R.id.floatingBtn);
newTaskBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
}
});
myDB = new myDatabase(MainActivity.this);
task_id = new ArrayList<>();
task_subject = new ArrayList<>();
task_description = new ArrayList<>();
task_due_date = new ArrayList<>();
storeDataArray();
customAdapter = new CustomAdapter(MainActivity.this, task_id, task_subject, task_description, task_due_date);
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}
void storeDataArray() {
Cursor cursor = myDB.readAllData();
if (cursor.getCount() == 0) {
Toast.makeText(this, "No data", Toast.LENGTH_SHORT).show();
} else {
while (cursor.moveToNext()) {
task_id.add(cursor.getString(0));
task_subject.add(cursor.getString(1));
task_description.add(cursor.getString(2));
task_due_date.add(cursor.getString(3));
}
}
}
}
Add Data Activity Code:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
public class AddActivity extends AppCompatActivity {
EditText subjectEntry, descEntry, dateEntry;
Button addBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
subjectEntry = findViewById(R.id.subjectEntry);
descEntry = findViewById(R.id.descEntry);
dateEntry = findViewById(R.id.dateEntry);
addBtn = findViewById(R.id.addbtn);
addBtn.setOnClickListener(view -> {
myDatabase myDB = new myDatabase(AddActivity.this);
myDB.addTask(subjectEntry.getText().toString().trim(),
descEntry.getText().toString().trim(),
Integer.valueOf(dateEntry.getText().toString().trim()));
});
}
}
Adapter Code
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.myViewHolder> {
private Context context;
private ArrayList task_id, task_subject, task_description, task_due_date;
private int position;
CustomAdapter(Context context, ArrayList task_id, ArrayList task_subject, ArrayList task_description, ArrayList task_due_date){
this.context = context;
this.task_id = task_id;
this.task_description = task_description;
this.task_subject = task_subject;
this.task_due_date = task_due_date;
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from (context);
View view = inflater.inflate(R.layout.to_do_list, parent, false);
return new myViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final myViewHolder holder, final int position) {
this.position = position;
holder.taskid_txt.setText(String.valueOf(task_id.get(position)));
holder.taskSubject_txt.setText(String.valueOf(task_subject.get(position)));
holder.taskDescription_txt.setText(String.valueOf(task_description.get(position)));
holder.taskDate_txt.setText(String.valueOf(task_due_date.get(position)));
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", String.valueOf(task_id.get(position)));
intent.putExtra("Description", String.valueOf(task_description.get(position)));
intent.putExtra("Subject", String.valueOf(task_subject.get(position)));
intent.putExtra("Due Date", String.valueOf(task_due_date.get(position)));
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return task_id.size();
}
public class myViewHolder extends RecyclerView.ViewHolder {
TextView taskid_txt, taskSubject_txt, taskDescription_txt, taskDate_txt;
LinearLayout mainLayout;
public myViewHolder(#NonNull View itemView) {
super(itemView);
taskid_txt = itemView.findViewById(R.id.taskid_txt);
taskSubject_txt = itemView.findViewById(R.id.taskSubject_txt);
taskDescription_txt = itemView.findViewById(R.id.taskDescription_txt);
taskDate_txt = itemView.findViewById(R.id.taskDate_txt);
mainLayout = itemView.findViewById(R.id.mainLayout);
}
}
;
}
Refresh recycle view in onResume of MainActivity
#Override
public void onResume() {
super.onResume();
storeDataArray();
}
I am using recyclerview in fragment dynamically, now i want to open new activity on click of items with the same object / item.
AllCoursesFeagment.java
package com.example.learningapp.ui.NavigationDrawer.AllCourses;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.learningapp.Adapters.AllCoursesMyAdapter;
import com.example.learningapp.Interface.APIinterface;
import com.example.learningapp.Models.CourseListModel;
import com.example.learningapp.R;
import com.example.learningapp.Responses.CourseListResponse;
import com.example.learningapp.RetrofitAPIs.RetrofitAPI;
import com.example.learningapp.utility.ConstantData;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class AllCoursesFragment extends Fragment {
private RecyclerView recyclerView;
private List<CourseListModel> courseListModelList;
public AllCoursesFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static AllCoursesFragment newInstance() {
return new AllCoursesFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_all_courses,null);
recyclerView = view.findViewById(R.id.allCourseList_RV);
APIinterface apIinterface = RetrofitAPI.getClient().create(APIinterface.class);
Call<CourseListResponse> call = apIinterface.getAllCourses(ConstantData.AppKey);
call.enqueue(new Callback<CourseListResponse>() {
#Override
public void onResponse(Call<CourseListResponse> call, Response<CourseListResponse> response){
if (response.isSuccessful()){
courseListModelList = response.body().getCourseList();
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(new AllCoursesMyAdapter(getActivity(),courseListModelList));
}
}
#Override
public void onFailure(Call<CourseListResponse> call, Throwable t) {
Toast.makeText(getActivity(),"Something went wrong",Toast.LENGTH_LONG).show();
}
});
return view;
}
}
AllCoursesMyAdapter.java
This is my adapter class.
package com.example.learningapp.Adapters;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.learningapp.Activities.CheckoutActivity;
import com.example.learningapp.Models.CourseListModel;
import com.example.learningapp.R;
import java.util.List;
public class AllCoursesMyAdapter extends RecyclerView.Adapter<AllCoursesMyAdapter.RecyclerVH> {
Context context;
List<CourseListModel> courseListModelList;
public AllCoursesMyAdapter(Context context, List<CourseListModel> courseListModelList) {
this.context = context;
this.courseListModelList = courseListModelList;
}
#NonNull
#Override
public RecyclerVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.single_row_design_allcourses,parent,false);
return new RecyclerVH(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerVH holder, int position) {
final CourseListModel courseListModel = courseListModelList.get(position);
holder.courseTitle.setText(courseListModel.getCourseName());
holder.courseDesc.setText(courseListModel.getCourseDescription());
holder.buyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
moveToNewActivity();
//Toast.makeText(context,"Item Clicked"+position,Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, CheckoutActivity.class);
intent.putExtra("coursetitle",courseListModel.getCourseName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
private void moveToNewActivity () {
Activity activity = new Activity();
Intent i = new Intent(activity, CheckoutActivity.class);
context.startActivity(i);
((Activity) context).overridePendingTransition(0, 0);
}
#Override
public int getItemCount() {
return courseListModelList.size();
}
public class RecyclerVH extends RecyclerView.ViewHolder {
TextView courseTitle,courseDesc;
Button buyBtn;
public RecyclerVH(#NonNull View itemView) {
super(itemView);
courseTitle = itemView.findViewById(R.id.course_title);
courseDesc = itemView.findViewById(R.id.course_desc);
buyBtn = itemView.findViewById(R.id.btn_buycourse);
}
}
}
I'm gettng crashed when i clicked item
holder.buyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
moveToNewActivity();
//Toast.makeText(context,"Item Clicked"+position,Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, CheckoutActivity.class);
intent.putExtra("coursetitle",courseListModel.getCourseName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
Here i am using a stored list of objects and now i want to move to the new activity when i clicked on an item with given position, but i am not able to do that.
private void moveToNewActivity () {
Activity activity = new Activity(); //this is wrong, delete this
...
}
you can't and shouldn't create an instance of an activity like this, it's something the OS has to schedule and handle for you.
you already seem to have context defined somewhere, so that means:
private void moveToNewActivity () {
Intent i = new Intent(context, CheckoutActivity.class);
context.startActivity(i);
...
}
so that means:
#Override
public void onClick(View v) {
moveToNewActivity();
}
I'm having some issues referencing a particular collection that is nested (I think that the term) I have attached an image of my database structure below:
EDIT: image of Foods collection
I basically have multiple documents that have a collection within them with the same name. Is there a way I can dynamically select the "Foods" collection depending on the restaurant ID that a user has clicked on the previous page. ie if the user selects a restaurant with ID 01, it should Load "Foods" from a document with ID 01, etc.
here is my code for the fragment loading the foods:
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.hostapp.Adapters.FoodAdapter;
import com.example.hostapp.Models.FoodModel;
import com.example.hostapp.R;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
public class MainsFragment extends Fragment {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference menuref = db.collection("Foods");
private FoodAdapter adapter;
String restaurantid = "";
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mains, container, false);
Query query = menuref.whereEqualTo("menuid", restaurantid).orderBy("name");
FirestoreRecyclerOptions<FoodModel> options = new FirestoreRecyclerOptions.Builder<FoodModel>().
setQuery(query, FoodModel.class)
.build();
adapter = new FoodAdapter(options);
RecyclerView recyclerView = view.findViewById(R.id.recycler_mains);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
recyclerView.setAdapter(adapter);
return view;
}
private void setUpRecyclerView() {
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
for the previous page on click:
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RelativeLayout;
import com.example.hostapp.Adapters.RestaurantAdapter;
import com.example.hostapp.Adapters.categoryCardAdapter;
import com.example.hostapp.Models.Restaurant;
import com.example.hostapp.Models.categoryCard;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
public class RestaurantList extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference restaurantref = db.collection("restaurants");
private RestaurantAdapter adapter;
String categoryid="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant_list);
setUpRecyclerView();
}
private void setUpRecyclerView(){
//Get intent
if(getIntent() != null)
categoryid = getIntent().getStringExtra("categoryid");
if(!categoryid.isEmpty() && categoryid != null)
{
Query query = restaurantref.whereEqualTo("categoryid", categoryid).orderBy("name");
final FirestoreRecyclerOptions<Restaurant> options = new FirestoreRecyclerOptions.Builder<Restaurant>().setQuery(query, Restaurant.class).build();
adapter = new RestaurantAdapter(options);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.restaurant_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListerner(new RestaurantAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
Restaurant restaurant = documentSnapshot.toObject(Restaurant.class);
Intent foodlist = new Intent(RestaurantList.this, Foodlist.class);
foodlist.putExtra("restaurantid", documentSnapshot.getId());
startActivity(foodlist);
}
});
}
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
According to your comments, to get all Food documents that exist in all sub-collections according to the menuid property, a Firestore collection group query is needed. This query looks like this:
Query menuIdQuery = db.collectionGroup("Foods").whereEqualTo("menuid", yourMenuId);
can anyone explain to me how can I create a new recycle and add items to that recycle view staring from another recycle view inside another activity?
Basically I want to create a shopping cart, for now, I retrieved the data from Firebase dataset and displayed it inside a recycle view but now I would like to send this data to the shopping cart(the shopping cart is inside another activity), I'm able to send the data but I can't understand how to display the data inside the new recycle view of this new activity. I need this because I want to see the items that I added to the shopping list so then I can pay.
Below I will attach a photo to explain myself better.
My problem is that I can't understand how to add the sent data to a recycle view again in the new activity.
I'm new to android so it's the first time I'm doing this thing.
Thank you in advance for your help.
My code:
SearchItemsActivity :
package com.example.ipill;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.Intent;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import java.util.ArrayList;
import java.util.List;
public class FirebaseSearch extends AppCompatActivity {
private EditText mSearchField;
private ImageButton mSearchBtn;
private ImageButton AddToCart;
private ImageButton Cart;
String searchText="";
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
private static ArrayList<Users> arrayList = new ArrayList<>();
public static int cart_count = 0;
RecyclerView productRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_firebasesearch);
mUserDatabase = FirebaseDatabase.getInstance().getReference("Users");
mSearchField = findViewById(R.id.search_field);
mSearchBtn = findViewById(R.id.search_btn);
mResultList = findViewById(R.id.result_list_cart);
AddToCart = findViewById(R.id.imageButton2);
Cart = findViewById(R.id.cartButton);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
}
});
Cart.setOnClickListener(new View.OnClickListener() {
private Object Tag="Activity";
#Override
public void onClick(View v) {
if (cart_count < 1) {
} else {
startActivity(new Intent(FirebaseSearch.this, CartActivity.class));
}
}
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(FirebaseSearch.this, "Started Search", Toast.LENGTH_LONG).show();
Query firebaseSearchQuery =
mUserDatabase.orderByChild("Name").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerAdapter<Users, UsersViewHolder> firebaseRecyclerAdapter = new
FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.list_layout,
UsersViewHolder.class,
firebaseSearchQuery
) {
#Override
protected void populateViewHolder(UsersViewHolder viewHolder, Users model, int position) {
viewHolder.getDetails(model.getName(), model.getSurname(),model.getPrice());
viewHolder.setDetails(model.getName(), model.getSurname(),model.getPrice());
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
#Override
protected void onStart() {
super.onStart();
invalidateOptionsMenu();
}
// View Holder Class
public static class UsersViewHolder extends RecyclerView.ViewHolder {
View mView;
String nome;
String surname;
Long prezzo;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
ImageButton addToCart = (ImageButton)mView.findViewById(R.id.imageButton2);
addToCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cart_count++;
Context context = v.getContext();
Intent intent = new Intent(context, CartActivity.class);
intent.putExtra("Name",nome);
intent.putExtra("Surname",surname);
intent.putExtra("Prezzo",Long.toString(prezzo));
context.startActivity(intent);
}
});
}
public void getDetails(String name,String cognome,Long price){
nome=name;
surname=cognome;
prezzo=price;
}
public void setDetails(String name, String surname, Long price) {
TextView user_name = (TextView) mView.findViewById(R.id.name_text);
TextView user_surname = (TextView)mView.findViewById(R.id.status_text);
TextView user_price = (TextView)mView.findViewById(R.id.price);
user_name.setText(name);
user_surname.setText(surname);
user_price.setText(Long.toString(price));
}
}
}
enter code here
The second activity where I receive the data and where I want to create the recycle view
package com.example.ipill;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collection;
public class CartActivity extends AppCompatActivity {
public static TextView grandTotal;
public static int grandTotalplus;
// create a temp list and add cartitem list
public static ArrayList<Users> temparraylist;
RecyclerView cartRecyclerView;
Button proceedToBook;
Context context;
String name,surname,price;
private static ArrayList<Users> arrayList2 = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
context = this;
temparraylist = new ArrayList<>();
proceedToBook = findViewById(R.id.buyNow);
grandTotal = findViewById(R.id.TotalPrice);
cartRecyclerView=findViewById(R.id.cartList);
String passedArg = getIntent().getExtras().getString("Name");
name=passedArg;
String passedArg2 = getIntent().getExtras().getString("Surname");
surname=passedArg2;
String passedArg3 = getIntent().getExtras().getString("Price");
price=passedArg3;
System.out.println("DATA"+name+surname+price);
cartRecyclerView.setHasFixedSize(true);
cartRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
you can re use the cart adapter just implement a recylerView into new Activity and make the cart adater object and set it into the new reyclerView and it done
I'm new to stackoverflow, please forgive me if I did anything wrong or broke any rules and regulations. But I hope someone can help me with this problem.I'm having this problem where I have an error to do an itemclicklistener in recyclerview. Here is the code
My Adapter
package com.fyp.eventlocater;
import android.content.Context;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.firebase.database.DataSnapshot;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
ArrayList<Event> events;
private RecyclerViewClickItemInterface recyclerViewClickItemInterface;
public MyAdapter( Context c, ArrayList<Event> e, RecyclerViewClickItemInterface recyclerViewClickItemInterface)
{
context = c;
events = e;
this.recyclerViewClickItemInterface = recyclerViewClickItemInterface;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.card_view, parent, false));
// View v = LayoutInflater.from(context).inflate(R.layout.card_view, parent, false);
// MyViewHolder mvh = new MyViewHolder(v, (OnItemClickListener) mListener);
// return mvh;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.eventTitle.setText(events.get(position).getEventTitle());
holder.eventTime.setText(events.get(position).getEventTime());
holder.eventDesc.setText(events.get(position).getEventDesc());
holder.eventLocation.setText(events.get(position).getEventLocation());
}
#Override
public int getItemCount() {
return events.size();
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView eventTitle, eventTime, eventDesc, eventLocation;
public MyViewHolder(View itemView) {
super(itemView);
eventTitle = itemView.findViewById(R.id.eventTitle);
eventTime = itemView.findViewById(R.id.eventTime);
eventDesc = itemView.findViewById(R.id.eventDesc);
eventLocation = itemView.findViewById(R.id.eventLocation);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recyclerViewClickItemInterface.onItemClick(getAdapterPosition());
}
});
}
}
}
This is my Interface
package com.fyp.eventlocater;
public interface RecyclerViewClickItemInterface {
void onItemClick(int position);
}
This is my activity
package com.fyp.eventlocater;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.Toast;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class CominSoonActivity extends AppCompatActivity implements RecyclerViewClickItemInterface {
DatabaseReference reference;
RecyclerView recyclerView;
ArrayList<Event> list;
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comin_soon);
recyclerView = findViewById(R.id.myRecycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<Event>();
reference = FirebaseDatabase.getInstance().getReference().child("EventDisplay");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren())
{
Event e = dataSnapshot1.getValue(Event.class);
list.add(e);
}
adapter = new MyAdapter(CominSoonActivity.this, list, this);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(CominSoonActivity.this, "Opps.... Something went wrong", Toast.LENGTH_SHORT).show();
}
});
//add back button
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
//taking the user back to the previous activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home) {
Intent homeActivity = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(homeActivity);
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemClick(int position) {
Uri uri = Uri.parse("http://wwww.google.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
This is my error output
I'm a student and new to android studio. I don't know what this means
This is another error. I hope it helps.
It says this
So it seems that you are initializing a new adapter every time the data changes. You can change it to be:
public class CominSoonActivity extends AppCompatActivity implements RecyclerViewClickItemInterface {
DatabaseReference reference;
RecyclerView recyclerView;
ArrayList<Event> list;
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comin_soon);
recyclerView = findViewById(R.id.myRecycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<Event>();
adapter = new MyAdapter(CominSoonActivity.this, list, this);
recyclerView.setAdapter(adapter);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren())
{
Event e = dataSnapshot1.getValue(Event.class);
list.add(e); // This will add it to the adapter
adapter.notifyDataSetChanged();
}
}
// the rest of the class
This way when you reference this in the adapter you get CominSoonActivity rather than ValueEventListener.
create adapter instance like below in your activity class:
adapter = new MyAdapter(CominSoonActivity.this, list, CominSoonActivity.this);
your activity class looks like:
package com.fyp.eventlocater;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.Toast;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class CominSoonActivity extends AppCompatActivity implements RecyclerViewClickItemInterface {
DatabaseReference reference;
RecyclerView recyclerView;
ArrayList<Event> list;
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comin_soon);
recyclerView = findViewById(R.id.myRecycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<Event>();
reference = FirebaseDatabase.getInstance().getReference().child("EventDisplay");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren())
{
Event e = dataSnapshot1.getValue(Event.class);
list.add(e);
}
adapter = new MyAdapter(CominSoonActivity.this, list, CominSoonActivity.this);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(CominSoonActivity.this, "Opps.... Something went wrong", Toast.LENGTH_SHORT).show();
}
});
//add back button
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
//taking the user back to the previous activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home) {
Intent homeActivity = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(homeActivity);
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemClick(int position) {
Uri uri = Uri.parse("http://wwww.google.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}