Database inspector shows the database is working but not able to show it up in RecyclerView.
product.java
#Entity (tableName = "productTable")
public class product {
#PrimaryKey(autoGenerate = true)
private int pid;
#ColumnInfo(name = "product_name")
private String productName;
#ColumnInfo(name = "price")
private String price;
#ColumnInfo(name = "category")
private String category;
#ColumnInfo(name = "company")
private String companyName;
public product(String productName, String price, String category, String companyName) {
this.productName = productName;
this.price = price;
this.category = category;
this.companyName = companyName;
}
public int getPid() {
return pid;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public void setPid(int pid) {
this.pid = pid;
}
}
productDao.java
#Dao
public interface productDAO {
#Query("SELECT * FROM productTable")
LiveData<List<product>> getAllprod();
// #Query("SELECT * FROM product WHERE product_name order by product_name")
// product findByName(String product, String price);
#Query("SELECT * FROM productTable where :company order by product_name")
product section(String company);
#Query("DELETE FROM productTable WHERE pid = :id")
int deleteProduct(int id);
#Insert
void insert(product product);
#Update
void update(product product);
#Delete
void delete(product product);
#Query("DELETE FROM productTable")
void deleteAll();
}
productDatabase.java
#Database(entities = {product.class},version = 1)
public abstract class productDatabase extends RoomDatabase {
public static volatile productDatabase INSTANCE;
public abstract productDAO proDao();
public static productDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (productDatabase.class) {
if (INSTANCE == null) {
//create our db
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
productDatabase.class, "product_database")
.fallbackToDestructiveMigration()
.build();
}
}
}
return INSTANCE;
}
}
productRepository.java
public class productRepository {
private productDAO proDao;
private LiveData<List<product>> productList;
public productRepository(Application application)
{
productDatabase db = productDatabase.getDatabase(application);
proDao = db.proDao();
productList = proDao.getAllprod();
}
public LiveData<List<product>> getAllrepo(){
return productList;
}
public void insert(product prod){
new insertAsyncTask(proDao).execute(prod);
}
public void delete(product prod){
new deleteAsyncTask(proDao).execute(prod);
}
public void update(product prod){
new updateAsyncTask(proDao).execute(prod);
}
private class insertAsyncTask extends AsyncTask<product,Void,Void>{
private productDAO asyncTaskDao;
public insertAsyncTask(productDAO dao){
asyncTaskDao = dao;
}
#Override
protected Void doInBackground(product... products) {
asyncTaskDao.insert(products[0]);
return null;
}
}
private class deleteAsyncTask extends AsyncTask<product,Void,Void>{
private productDAO asyncTaskDao;
public deleteAsyncTask(productDAO proDao) {
asyncTaskDao = proDao;
}
#Override
protected Void doInBackground(product... products) {
asyncTaskDao.delete(products[0]);
return null;
}
}
private class updateAsyncTask extends AsyncTask<product,Void,Void>{
private productDAO asyncTaskDao;
public updateAsyncTask(productDAO proDao) {
asyncTaskDao = proDao;
}
#Override
protected Void doInBackground(product... products) {
asyncTaskDao.delete(products[0]);
return null;
}
}
}
productViewModel.java+
public class productViewModel extends AndroidViewModel {
private productRepository proRepo;
private LiveData<List<product>> proList;
public productViewModel(#NonNull Application application) {
super(application);
proRepo = new productRepository(application);
proList = proRepo.getAllrepo();
}
public LiveData<List<product>> getProList(){
return proList;}
public void insert(product prod){
proRepo.insert(prod);}
public void update(product prod){
proRepo.update(prod);
}
public void delete(product prod){
proRepo.delete(prod);
}
}
MainActivity.Java
public class MainActivity extends AppCompatActivity {
private productAdapter productAdapter;
private productViewModel viewModel;
private TextView nothing;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nothing = findViewById(R.id.nothing);
viewModel = ViewModelProviders.of(this)
.get(productViewModel.class);
recyclerView = findViewById(R.id.productView);
productAdapter = new productAdapter(this);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
FloatingActionButton fab = findViewById(R.id.add_component);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Add_Product.class));
}
});
viewModel.getProList().observe(this, new Observer<List<product>>() {
#Override
public void onChanged(#Nullable List<product> productLists) {
productAdapter.setList(productLists);
Log.d("hello", "process" + productLists);
}
});
if (productAdapter.getItemCount()!=0)
{
nothing.setVisibility(View.GONE);
Toast.makeText(this, "something not working",Toast.LENGTH_SHORT).show();
}
else
nothing.setVisibility(View.VISIBLE);
}
}
database inspector shows that database is made and also the saving process is also working but not able top display it in recyclerView
You forgot to attach the adapter to the RecyclerView
So, in your MainActivity activity do this in below
viewModel.getProList().observe(this, new Observer<List<product>>() {
#Override
public void onChanged(#Nullable List<product> productLists) {
productAdapter.setList(productLists);
recyclerView.setAdapter(productAdapter); // <<<<<< change here
Log.d("hello", "process" + productLists);
}
});
Related
I am using Android Paging with Room Database.I am going to fetch data using retrofit.But I am getting error No adapter attached; skipping layout.I searched a lot but dont find solution for this. Base url is working, for security reason i just hide base url.
private StoreAdapter storeAdapter;
private Store_ViewModel store_viewModel;
private RecyclerView recyclerView;
private static final String URL_DATA="https://xxxx/";
//insertion
private Store_Repository store_repository;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
store_repository=new Store_Repository(getApplication());
//adapter
storeAdapter=new StoreAdapter(getApplicationContext(), this);
//recycler
recyclerView=findViewById(R.id.recycler_store);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
store_viewModel=new ViewModelProvider(this).get(Store_ViewModel.class);
store_viewModel.pagedListLiveData.observe(this, new Observer<PagedList<StoreModel>>() {
#Override
public void onChanged(PagedList<StoreModel> storeModels) {
storeAdapter.submitList(storeModels);
recyclerView.setAdapter(storeAdapter);
}
});
getAllProducts();
}
private void getAllProducts() {
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(URL_DATA)
.addConverterFactory(GsonConverterFactory.create())
.build();
//calling api
Api api=retrofit.create(Api.class);
Call<List<StoreModel>>call=api.getAllProducts();
call.enqueue(new Callback<List<StoreModel>>() {
#Override
public void onResponse(Call<List<StoreModel>> call, Response<List<StoreModel>> response) {
if (response.isSuccessful())
{
store_repository.insert(response.body());
}
}
#Override
public void onFailure(Call<List<StoreModel>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Something get Wrong", Toast.LENGTH_SHORT).show();
}
});
}
This is my ViewModel Class
public class Store_ViewModel extends AndroidViewModel {
public LiveData<PagedList<StoreModel>>pagedListLiveData;
private StoreDao storeDao;
public Store_ViewModel(#NonNull Application application) {
super(application);
storeDao= StoreDatabase.getINSTANCE(application).storeDao();
pagedListLiveData=new LivePagedListBuilder<>(
storeDao.getAllItems(),5
).build();
}
}
And this is my adapter class
public class StoreAdapter extends PagedListAdapter<StoreModel,StoreAdapter.StoreViewHolder> {
private Context context;
private static Listener listener;
public StoreAdapter(Context context,Listener listener)
{
super(storeModelItemCallback);
this.context=context;
this.listener=listener;
}
#NonNull
#Override
public StoreViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
#Override
public void onBindViewHolder(#NonNull StoreViewHolder holder, int position) {
StoreModel storeModel=getItem(position);
holder.Product_name.setText(storeModel.getProduct_name());
holder.Product_weight.setText(storeModel.getProduct_weight());
holder.Price.setText(storeModel.getPrice());
holder.Mrp.setText(storeModel.getMrp());
}
static class StoreViewHolder extends RecyclerView.ViewHolder
{
TextView Product_name;
TextView Product_weight;
TextView Price;
TextView Mrp;
public StoreViewHolder(#NonNull View itemView) {
super(itemView);
Product_name=itemView.findViewById(R.id.product_name);
Product_weight=itemView.findViewById(R.id.product_weight);
Price=itemView.findViewById(R.id.price);
Mrp=itemView.findViewById(R.id.mrp);
//listener
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemCLickListener(getAdapterPosition());
}
});
}
}
static DiffUtil.ItemCallback<StoreModel> storeModelItemCallback=new DiffUtil.ItemCallback<StoreModel>() {
#Override
public boolean areItemsTheSame(#NonNull StoreModel oldItem, #NonNull StoreModel newItem) {
return oldItem.getDatabase_id()==newItem.getDatabase_id();
}
#SuppressLint("DiffUtilEquals")
#Override
public boolean areContentsTheSame(#NonNull StoreModel oldItem, #NonNull StoreModel newItem) {
return oldItem.equals(newItem);
}
};
Json Response from Server
{"status":1,"msg":"",
"paginate":{"limit":1000,"PageNo":1},
"data":
[
{
"product_id":23234,
"product_brand_id":130,
"product_name":"Xyz"
,"product_code":"1554729666482",
"mrp":5,
"price":4,
"product_weight":1,
"product_weight_unit":"PCS"
}
,{"product_id":23244,
"product_brand_id":130,
"product_name":"Abc - 100 Gms",
"product_code":"9A","mrp":38,"price":31.94,
"product_weight":100,"product_weight_unit":"GM"}
ApiInterface
public interface Api {
#GET("/get-products")
Call<List<StoreModel>>getAllProducts();
}
Below is my StoreModel in which i am using room database fro creating tables
#Entity(tableName = "store",indices = #Index(value="product_id",unique = true))
public class StoreModel {
#PrimaryKey(autoGenerate = true)
private int database_id;
#SerializedName("product_id")
private int product_id;
#SerializedName("product_brand_id")
private int product_brand_id;
#SerializedName("product_name")
private String product_name;
#SerializedName("product_code")
private int product_code;
#SerializedName("mrp")
private int mrp;
#SerializedName("price")
private int price;
#SerializedName("product_weight")
private int product_weight;
#SerializedName("product_weight_unit")
private String product_weight_unit;
public StoreModel() {
}
public StoreModel(int product_id, int product_brand_id, String product_name, int product_code, int mrp, int price, int product_weight, String product_weight_unit) {
this.product_id = product_id;
this.product_brand_id = product_brand_id;
this.product_name = product_name;
this.product_code = product_code;
this.mrp = mrp;
this.price = price;
this.product_weight = product_weight;
this.product_weight_unit = product_weight_unit;
}
public int getProduct_id() {
return product_id;
}
public void setProduct_id(int product_id) {
this.product_id = product_id;
}
public int getProduct_brand_id() {
return product_brand_id;
}
public void setProduct_brand_id(int product_brand_id) {
this.product_brand_id = product_brand_id;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public int getProduct_code() {
return product_code;
}
public void setProduct_code(int product_code) {
this.product_code = product_code;
}
public int getMrp() {
return mrp;
}
public void setMrp(int mrp) {
this.mrp = mrp;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getProduct_weight() {
return product_weight;
}
public void setProduct_weight(int product_weight) {
this.product_weight = product_weight;
}
public String getProduct_weight_unit() {
return product_weight_unit;
}
public void setProduct_weight_unit(String product_weight_unit) {
this.product_weight_unit = product_weight_unit;
}
public int getDatabase_id() {
return database_id;
}
public void setDatabase_id(int database_id) {
this.database_id = database_id;
}
}
Below is Dao class
#Dao
public interface StoreDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(List<StoreModel> storeModels);
#Query("DELETE FROM store")
void deleteAll();
#Query("SELECT * FROM store ORDER BY database_id ASC")
DataSource.Factory<Integer,StoreModel>getAllItems();
}
Set recyclerView.setAdapter(storeAdapter); outside of observer because each time data is observed it will set adapter. So, adapter is attached to recyclerView only once. Like
recyclerView.setAdapter(storeAdapter);
store_viewModel.pagedListLiveData.observe(this, new Observer<PagedList<StoreModel>>() {
#Override
public void onChanged(PagedList<StoreModel> storeModels) {
storeAdapter.submitList(storeModels);
//recyclerView.setAdapter(storeAdapter);
}
});
From the API you are not getting exactly the StoreModel as response. You are getting another object which is StoreModel is a child object. You have to create resposne object like below:
public class ResponseObject{
//#SerializedName("status")
//private int status;
#SerializedName("data")
private List<StoreModel> storeModelList;
//getters and setters goes here
}
And then your interface should be like below as you are expecting
ResponseObject here
public interface Api {
#GET("/get-products")
Call<ResponseObject> getAllProducts();
}
I am writing a simple application that stores 2 string values in a database using Room (I am trying to learn this library). So, I have only one line on my list. Presented for the first time. The rest are not displayed. What is the reason for this behavior?
Model
#Entity
public class Note {
#PrimaryKey(autoGenerate = true)
private long id;
private String title;
private String text;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
NoteDao
#Dao
public interface NoteDao {
#Insert
void insert(Note note);
#Delete
void delete(Note note);
#Query("SELECT * FROM Note")
List<Note> getAllNotes();
}
AppDatabase
#Database(entities = Note.class, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract NoteDao getNoteDao();
}
DataManager
public class DataManager {
private AppDatabase appDatabase;
public DataManager (AppDatabase appDatabase) {
this.appDatabase = appDatabase;
}
public List <Note> getNotes () {
try {
return new GetNotes (). execute (). get ();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace ();
return null;
}
}
public void insertNote (Note note) {
new InsertNote (note) .execute ();
}
public void deleteNote (Note note) {
new DeleteNote (note) .execute ();
}
// Get all notes
public class GetNotes extends AsyncTask <Void, Void, List <Note>> {
#Override
protected List <Note> doInBackground (Void ... voids) {
return appDatabase.getNoteDao (). getAllNotes ();
}
}
// Insert note
public class InsertNote extends AsyncTask <Void, Void, Void> {
private Note note;
InsertNote (Note note) {
this.note = note;
}
#Override
protected Void doInBackground (Void ... voids) {
appDatabase.getNoteDao (). insert (note);
return null;
}
}
// Delete note
public class DeleteNote extends AsyncTask <Void, Void, Void> {
private Note note;
public DeleteNote (Note note) {
this.note = note;
}
#Override
protected Void doInBackground (Void ... voids) {
appDatabase.getNoteDao (). delete (note);
return null;
}
}
}
Mvp
public interface NoteListView extends MvpView {
void showNoteList(List<Note> note);
}
Presenter
public class NoteListPresenter extends MvpPresenter<NoteListView> {
private DataManager dataManager;
public NoteListPresenter(DataManager dataManager) {
this.dataManager = dataManager;
}
public void getNotes(){
getView().showNoteList(dataManager.getNotes());
}
public void deleteNote(Note note) {
dataManager.deleteNote(note);
getView().showNoteList(dataManager.getNotes());
}
}
Adapter
public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.ViewHolder> {
private List<Note> listNote;
private Context context;
public NoteAdapter(Context context, List<Note> listNote) {
this.listNote = listNote;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.title.setText(listNote.get(position).getTitle());
holder.text.setText(listNote.get(position).getText());
}
#Override
public int getItemCount() {
return listNote.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title, text;
public ViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
text = itemView.findViewById(R.id.text);
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements NoteListView {
private NoteListPresenter presenter;
private RecyclerView recyclerView;
private NoteAdapter noteAdapter;
private ConstraintLayout constraintLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
constraintLayout = findViewById(R.id.coordinatorMain);
recyclerView = findViewById(R.id.recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
presenter = new NoteListPresenter(App.getDataManager());
presenter.attachView(this);
presenter.getNotes();
}
public void onNextActivity(View view){
startActivity(new Intent(MainActivity.this, AddNoteActivity.class));
}
#Override
public void showNoteList(List<Note> note) {
noteAdapter = new NoteAdapter(this, note);
recyclerView.setAdapter(noteAdapter);
}
#Override
protected void onResume() {
super.onResume();
presenter.getNotes();
}
#Override
public void showMessage(String message) {
Snackbar.make(constraintLayout, message, Snackbar.LENGTH_SHORT).show();
}
}
UPD
SaveNoteView
public interface SaveNoteView extends MvpView {
void insertNote(Note note);
}
SaveNotePresenter
public class SaveNotePresenter extends MvpPresenter<SaveNoteView> {
private DataManager dataManager;
public SaveNotePresenter(DataManager dataManager) {
this.dataManager = dataManager;
}
public void insertNote(Note note){
dataManager.insertNote(note);
getView().insertNote(note);
}
}
AddNoteActivity
public class AddNoteActivity extends AppCompatActivity implements SaveNoteView {
private TextInputEditText title, text;
private ConstraintLayout constraintLayout;
private SaveNotePresenter presenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_note);
constraintLayout = findViewById(R.id.constrainAdd);
title = findViewById(R.id.titleEditText);
text = findViewById(R.id.textEditText);
presenter = new SaveNotePresenter(App.getDataManager());
presenter.attachView(this);
}
//Save a note
public void saveNote(View view){
Note note = new Note();
note.setTitle(title.getText().toString());
note.setText(text.getText().toString());
presenter.insertNote(note);
finish();
}
#Override
public void insertNote(Note note) {
DataManager dataManager = App.getDataManager();
dataManager.insertNote(note);
}
#Override
public void showMessage(String message) {
Snackbar.make(constraintLayout, message, Snackbar.LENGTH_SHORT).show();
}
}
It's pretty likely that there is only 1 id which is beeing replaced the whole time (if this is not the case, check how often insertion is done)
I used Kotlin with Room but in this official example they have a public autogenerated primaryKey, which might be required for Room to access it and autogenerate it. So make the variable public and see if it works
There was no problem. I just specified the parent layout for item_list in full screen. Therefore, the subsequent ones were not visible. Silly mistake:D
In my code below I'm getting rowId. I've read that it's also possible to get the last inserted row id from #Insert directly. In my code I changed void insert to long and tried many other things as in examples I found on the internet, but every time I get errors. Would you like to provide me a code/solution to get the row/user ID from #Insert?
#Dao
public interface UserDao {
#Insert
void insert(UserEntity userEntity);
#Update
void update(UserEntity userEntity);
#Delete
void delete(UserEntity userEntity);
#Query("DELETE FROM user_table")
void deleteAllUsers();
#Query("SELECT * FROM user_table")
LiveData<List<UserEntity>> getAllUsers();
// ====== from here ======
#Query("SELECT * FROM user_table")
LiveData<UserEntity> getRowId();
// ====== till here ======
}
Entity
#Entity(tableName = "user_table")
public class UserEntity {
#PrimaryKey(autoGenerate = true)
private int id;
private String userName;
private String userTelephoneNumber;
public UserEntity(String userName, String userTelephoneNumber) {
this.userName = userName;
this.userTelephoneNumber = userTelephoneNumber;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getUserName() {
return userName;
}
public String getUserTelephoneNumber() {
return userTelephoneNumber;
}
}
Repository
public class UserRepository {
private UserDao userDao;
private LiveData<List<UserEntity>> allUsers;
public UserRepository(Application application) {
HandymanDatabase handymanDatabase = HandymanDatabase.getInstance(application);
userDao = handymanDatabase.userDao();
allUsers = userDao.getAllUsers();
}
public void insert(UserEntity userEntity) {
new InsertUserAsyncTask(userDao).execute(userEntity);
}
public void update(UserEntity userEntity) {
new UpdateUserAsyncTask(userDao).execute(userEntity);
}
public void delete(UserEntity userEntity) {
new DeleteUserAsyncTask(userDao).execute(userEntity);
}
public void deleteAllUsers() {
new DeleteAllUsersAsyncTask(userDao).execute();
}
public LiveData<List<UserEntity>> getAllUsers() {
return allUsers;
}
// ====== from here ======
public LiveData<UserEntity> getRowId() {
return userDao.getRowId();
}
// ====== till here ======
private static class InsertUserAsyncTask extends AsyncTask<UserEntity, Void, Void> {
private UserDao userDao;
private InsertUserAsyncTask(UserDao userDao) {
this.userDao = userDao;
}
#Override
protected Void doInBackground(UserEntity... userEntities) {
userDao.insert(userEntities[0]);
return null;
}
}
private static class UpdateUserAsyncTask extends AsyncTask<UserEntity, Void, Void> {
private UserDao userDao;
private UpdateUserAsyncTask(UserDao userDao) {
this.userDao = userDao;
}
#Override
protected Void doInBackground(UserEntity... userEntities) {
userDao.update(userEntities[0]);
return null;
}
}
private static class DeleteUserAsyncTask extends AsyncTask<UserEntity, Void, Void> {
private UserDao userDao;
private DeleteUserAsyncTask(UserDao userDao) {
this.userDao = userDao;
}
#Override
protected Void doInBackground(UserEntity... userEntities) {
userDao.delete(userEntities[0]);
return null;
}
}
private static class DeleteAllUsersAsyncTask extends AsyncTask<Void, Void, Void> {
private UserDao userDao;
private DeleteAllUsersAsyncTask(UserDao userDao) {
this.userDao = userDao;
}
#Override
protected Void doInBackground(Void... voids) {
userDao.deleteAllUsers();
return null;
}
}
}
ViewModel
public UserViewModel(#NonNull Application application) {
super(application);
userRepository = new UserRepository(application);
allUsers = userRepository.getAllUsers();
}
public void insert(UserEntity userEntity) {
userRepository.insert(userEntity);
}
public void update(UserEntity userEntity) {
userRepository.update(userEntity);
}
public void delete(UserEntity userEntity) {
userRepository.delete(userEntity);
}
public void deleteAllUsers() {
userRepository.deleteAllUsers();
}
public LiveData<List<UserEntity>> getAllUsers() {
return allUsers;
}
// ====== from here ======
public LiveData<UserEntity> getRowId() {
return userRepository.getRowId();
}
// ====== till here ======
}
Fragment/Activity
public class UserFavoritesFragment extends Fragment {
private static final String TAG = "UserFavoritesFragment";
private UserViewModel userViewModel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = getLayoutInflater().inflate(R.layout.fragment_user_favorites, container, false);
final TextView textViewUserName = view.findViewById(R.id.textViewUserName);
TextView textViewUserPhone = view.findViewById(R.id.textViewUserPhone);
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
// ====== from here ======
userViewModel.getRowId().observe(getViewLifecycleOwner(), new Observer<UserEntity>() {
#Override
public void onChanged(UserEntity userEntity) {
long rowId = userEntity.getId();
Log.d(TAG, "onChanged: " + rowId);
}
});
// ====== till here ======
return view;
}
}
You can do that using a listener interface that has a callback that accepts a long value of the inserted row id in the database.
Listener Interface
public interface NewIdListener {
void onInsert(long id);
}
Dao
#Dao
public interface UserDao {
#Insert
long insert(UserEntity userEntity); // return id of the inserted userEntity
}
Repository
public class UserRepository {
private Executor mExecutor = Executors.newSingleThreadExecutor();
private UserDao userDao;
...
public void insertUserEntity(final UserEntity entity, final NewIdListener listener) {
mExecutor.execute(new Runnable() {
#Override
public void run() {
listener.onInsert(userDao.insert(entity));
}
});
}
ViewModel
public void insertUserEntity(UserEntity entity, NewIdListener listener) {
userRepository.insertUserEntity(entity, listener);
}
Activity
userViewModel.insertUserEntity(new UserEntity("User Name", "12345678"), new NewIdListener() {
#Override
public void onInsert(final long id) {
requireActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(requireActivity(), "Id: " + id, Toast.LENGTH_SHORT).show();
}
});
}
});
Note: For background thread, I've used Executor instead of AsyncTask as AsyncTask is deprecated now.
Hi I'm doing an app and I made the database but I don't know how to read it to show in a listview for example I have a table CategoriaEntradas and I need to show all the data in a listview but I don't understand very well how it works all the classes
This is my Dao class
#Dao
public interface CategoriaEntradasDao {
#Insert
void insert(CategoriaEntradas categoriaEntradas);
#Update
void update(CategoriaEntradas categoriaEntradas);
#Delete
void delete(CategoriaEntradas categoriaEntradas);
#Query("DELETE FROM CategoriaEntradas")
void deleteAll();
#Query("SELECT * FROM CategoriaEntradas")
LiveData<List<CategoriaEntradas>> getAll();
#Query("SELECT * FROM CategoriaEntradas WHERE IdCategoria =:Id")
LiveData<CategoriaEntradas> getOne(int Id);
}
This is my Entity class
#Entity(tableName = "CategoriaEntradas")
public class CategoriaEntradas {
#PrimaryKey(autoGenerate = true)
#NonNull
#ColumnInfo(name = "IdCategoria")
private Integer _idCategoria;
#NonNull
#ColumnInfo(name = "Name")
private String _name;
#NonNull
#ColumnInfo(name = "Image")
private String _image;
public CategoriaEntradas(#NonNull String name, #NonNull String image) { _name = name; _image = image;}
public void set_idCategoria(Integer _idCategoria){
this._idCategoria = _idCategoria;
}
#NonNull
public Integer getIdCategoria() {
return _idCategoria;
}
#NonNull
public String getName() {
return _name;
}
#NonNull
public String getImage() {
return _image;
}
}
My Repository class
public class CategoriaEntradasRepository {
private CategoriaEntradasDao categoriaEntradasDao;
private LiveData<List<CategoriaEntradas>> listLiveData;
public CategoriaEntradasRepository(Application application) {
Database db = Database.getDatabase(application);
categoriaEntradasDao = db.categoriaEntradasDao();
listLiveData = categoriaEntradasDao.getAll();
}
public LiveData<List<CategoriaEntradas>> getAll() {
return listLiveData;
}
public LiveData<CategoriaEntradas> getOne(int Id) {
return categoriaEntradasDao.getOne(Id);
}
public void insert (CategoriaEntradas categoriaEntradas) {
new CategoriaEntradasRepository.insertAsyncTask(categoriaEntradasDao).execute(categoriaEntradas);
}
private static class insertAsyncTask extends AsyncTask<CategoriaEntradas, Void, Void> {
private CategoriaEntradasDao entradasDao;
insertAsyncTask(CategoriaEntradasDao dao) {
entradasDao = dao;
}
#Override
protected Void doInBackground(final CategoriaEntradas... params) {
entradasDao.insert(params[0]);
return null;
}
}
public void update(final CategoriaEntradas categoriaEntradas){
new CategoriaEntradasRepository.updateAsyncTask(categoriaEntradasDao).execute(categoriaEntradas);
}
private static class updateAsyncTask extends AsyncTask<CategoriaEntradas, Void, Void>{
private CategoriaEntradasDao entradasDao;
updateAsyncTask(CategoriaEntradasDao dao) {
entradasDao = dao;
}
#Override
protected Void doInBackground(final CategoriaEntradas... params){
entradasDao.update(params[0]);
return null;
}
}
public void delete(final CategoriaEntradas categoriaEntradas) {
new CategoriaEntradasRepository.deleteAsyncTask(categoriaEntradasDao).execute(categoriaEntradas);
}
public void delete(final int Id) {
final LiveData<CategoriaEntradas> categoriaEntradas = getOne(Id);
if (categoriaEntradas != null) {
new CategoriaEntradasRepository.deleteAsyncTask(categoriaEntradasDao).execute(categoriaEntradas.getValue());
}
}
private static class deleteAsyncTask extends AsyncTask<CategoriaEntradas, Void, Void>{
private CategoriaEntradasDao entradasDao;
deleteAsyncTask(CategoriaEntradasDao dao) {
entradasDao = dao;
}
#Override
protected Void doInBackground(final CategoriaEntradas... params){
entradasDao.delete(params[0]);
return null;
}
}
}
And my ViewModel class
public class CategoriaEntradasViewModel extends AndroidViewModel {
private CategoriaEntradasRepository repository;
private LiveData<List<CategoriaEntradas>> listLiveData;
public CategoriaEntradasViewModel (Application application) {
super(application);
repository = new CategoriaEntradasRepository(application);
listLiveData = repository.getAll();
}
public LiveData<List<CategoriaEntradas>> getAll() { return listLiveData; }
public LiveData<CategoriaEntradas> getOne(int Id) { return repository.getOne(Id); }
public void insert(CategoriaEntradas categoriaEntradas) { repository.insert(categoriaEntradas); }
public void update(CategoriaEntradas categoriaEntradas){ repository.update(categoriaEntradas);}
public void delete(CategoriaEntradas categoriaEntradas) {repository.delete(categoriaEntradas);}
public void delete(int Id) {repository.delete(Id);}
}
Try this at your Activity or fragment that have your listview.
CategoriaEntradasViewModel mViewModel = ViewModelProviders.of(this).get(CategoriaEntradasViewModel.class);
mViewModel.getAll().observe(this, new Observer<List<CategoriaEntradas>>() {
#Override
public void onChanged(List<CategoriaEntradas> categoriaEntradas) {
adapter = new YourListViewAdapter(this, categoriaEntradas);
listview.setAdapter(adapter);
}
}
Yes, if you have custom list item view. Its similar to array adapter.
I am trying to update my database using Room persistence Library and Livedata. I am very new to java, so, with the manual and various tutorial, I have setup the DAO, entity etc. But I am still struggling with how to actually add the data.
This is my database defination:
#Entity
public class PlaceSaved {
#PrimaryKey(autoGenerate = true)
private int id;
private String place;
private String lati;
private String longi;
public PlaceSaved(String place, String lati, String longi) {
this.place = place;
this.lati = lati;
this.longi = longi;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String getLongi() {
return longi;
}
public void setLongi(String longi) {
this.longi = longi;
}
public String getLati() {
return lati;
}
public void setLati(String lati) {
this.lati = lati;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
DAO
#Dao
public interface DatabaseInterface {
#Query("SELECT * FROM placesaved")
LiveData<List<PlaceSaved>> getAllItems();
#Insert
void insertAll(PlaceSaved... placeSaveds);
#Delete
void delete(PlaceSaved... placeSaveds);
#Update
void update(PlaceSaved... placeSaveds);
}
Adapter
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.RecyclerViewHolder>{
private List<PlaceSaved> items;
private View.OnClickListener ClickListener;
public PlacesAdapter(List<PlaceSaved> items){//}, View.OnClickListener ClickListener) {
this.items = items;
//this.ClickListener = ClickListener;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RecyclerViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.places_list_item, parent, false));
}
#Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
PlaceSaved placeSaved = items.get(position);
holder.itemTextView.setText(placeSaved.getPlace());
holder.nameTextView.setText(placeSaved.getLati());
holder.dateTextView.setText(placeSaved.getLongi());
/* holder.dateTextView.setText(borrowModel.getBorrowDate().toLocaleString().substring(0, 11));
holder.itemView.setTag(borrowModel);
holder.itemView.setOnLongClickListener(longClickListener);*/
}
#Override
public int getItemCount() {
return items.size();
}
public void addItems(List<PlaceSaved> items) {
this.items = items;
notifyDataSetChanged();
}
static class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView itemTextView;
private TextView nameTextView;
private TextView dateTextView;
RecyclerViewHolder(View view) {
super(view);
itemTextView = (TextView) view.findViewById(R.id.firstLine);
nameTextView = (TextView) view.findViewById(R.id.secondLine);
dateTextView = (TextView) view.findViewById(R.id.longitude);
}
}
}
and the ViewModel
public class PlacesViewModel extends AndroidViewModel {
private final LiveData<List<PlaceSaved>> PlacedatabaseList;
private PlaceDatabase appDatabase;
public PlacesViewModel(Application application) {
super(application);
appDatabase = PlaceDatabase.getDatabase(this.getApplication());
PlacedatabaseList = appDatabase.PlacedatabaseInterface().getAllItems();
}
public LiveData<List<PlaceSaved>> getPlaceList() {
return PlacedatabaseList;
}
public void deleteItem(PlaceSaved placeSaved) {
new deleteAsyncTask(appDatabase).execute(placeSaved);
}
private static class deleteAsyncTask extends AsyncTask<PlaceSaved, Void, Void> {
private PlaceDatabase db;
deleteAsyncTask(PlaceDatabase appDatabase) {
db = appDatabase;
}
#Override
protected Void doInBackground(final PlaceSaved... params) {
db.PlacedatabaseInterface().delete(params[0]);
return null;
}
}
}
Now, I am trying to add an item to database with OnClick of a fab as:
public class PlacesActivity extends AppCompatActivity {
private PlacesViewModel viewModel;
private PlacesAdapter placesAdapter;
private RecyclerView recyclerView;
FloatingActionButton fab, fab1, fab2, fab3;
LinearLayout fabLayout1, fabLayout2, fabLayout3;
boolean isFABOpen = false;
View fabBGLayout;
PlaceDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.places_layout);
viewModel = ViewModelProviders.of(this).get(PlacesViewModel.class);
Runnable r =new Runnable() {
#Override
public void run() {
recyclerView = findViewById(R.id.my_recycler_view);
placesAdapter = new PlacesAdapter(new ArrayList<PlaceSaved>());//, this);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplication()));
recyclerView.setAdapter(placesAdapter);
}
};
Thread newThread = new Thread(r);
newThread.start();
fab1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Dialog
/*
Add location manually
*/
AlertDialog.Builder placeLLDialog = new AlertDialog.Builder(PlacesActivity.this);
LayoutInflater inflater = getLayoutInflater();
final View view = inflater.inflate(R.layout.place_add_dialog, null);
placeLLDialog.setView(view);
final EditText todo = view.findViewById(R.id.placeN);
final EditText time = view.findViewById(R.id.placell);
final EditText longi = view.findViewById(R.id.placell2);
placeLLDialog.setTitle("Add Place with Latitude and Longitude")
.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if (!todo.getText().toString().equals("") &&
!time.getText().toString().equals("") &&
!longi.getText().toString().equals("")) {
Snackbar.make(view, "Running", Snackbar.LENGTH_LONG).show();
/* HERE I AM TRYING TO ADD THE DATA, WHICH IS NOT WORKING
final PlaceSaved placeSaved = new PlaceSaved(todo.getText().toString(),
time.getText().toString(), longi.getText().toString());
AsyncTask.execute(new Runnable() {
#Override
public void run() {
db.databaseInterface().insertAll(placeSaved);
items = db.databaseInterface().getAllItems();
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter = new PlacesAdapter(items, db, null);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
closeFABMenu();
}
});
}
});*/
}
}
})
.setNegativeButton("Cancel", null);
AlertDialog alertDialog = placeLLDialog.create();
alertDialog.show();
alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
});
since I am very new to java, I can't find out how to add the data to the database, which is inside fab1.setOnClickListner.
I will be grateful if someone kindly helps.
UPDATE
I forgot to add database itself, here it is:
#Database(entities = {PlaceSaved.class},version = 1)
public abstract class PlaceDatabase extends RoomDatabase {
private static PlaceDatabase INSTANCE;
public static PlaceDatabase getDatabase(Context context){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), PlaceDatabase.class,
"places_db").build();
}
return INSTANCE;
}
public abstract DatabaseInterface PlacedatabaseInterface();
Create Class AddBorrowViewModel
public class AddBorrowViewModel extends AndroidViewModel
{
private PlaceDatabase appDatabase;
public AddBorrowViewModel(#NonNull Application application) {
super(application);
appDatabase = PlaceDatabase.getDatabase(this.getApplication());
}
public void addBorrow(PlaceSaved placedSaved)
{
new addAsyncTask(appDatabase).execute(placedSaved);
}
private class addAsyncTask extends AsyncTask<PlaceSaved , Void, Void>
{
private PlaceDatabase appDatabase_;
addAsyncTask(PlaceDatabase appDatabase)
{
appDatabase_ = appDatabase;
}
#Override
protected Void doInBackground(PlaceSaved... placedSaved) {
appDatabase_.itemAndPersonModel().addBorrow(placedSaved[0]);
return null;
}
}
}
add this variable in your PlacesActivity
private AddBorrowViewModel addBorrowViewModel;
in OnCreate add this
addBorrowViewModel = ViewModelProviders.of(this).get(AddBorrowViewModel.class);
in onClickListener Of alertDilaog after snackbar
addBorrowViewModel.addBorrow(new PlaceSaved(
todo.getText().toString(),
time.getText().toString(), longi.getText().toString()
));
In your PlaceDatabase add
public abstract Dao itemAndPersonModel();