Using SearchView with Room by Java - java

how are you, I hope you are well
- I am using Room library to store products in RecyclerView.
- When using SearchView to search for a product by its name, the product name appears only when typing the first letter (that is, SearchView only interacts with the first letter of the product name).
Also, when you delete the letter, the complete list of products does not appear again.
Please help me find the error in the code
Warm regards, artist
dependencies
implementation "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
//noinspection LifecycleAnnotationProcessorWithJava8
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
ProductEntry
#Entity(tableName = "product")
public class ProductEntry {
#PrimaryKey(autoGenerate = true)
private int id;
#ColumnInfo(name = "productName")
private final String productName;
private final String productBarcode, productQuantity
, productPurchasingPrice, productSellingPrice, productDescription, productCategory;
#Ignore
public ProductEntry(String productName, String productBarcode, String productQuantity
, String productPurchasingPrice, String productSellingPrice, String productDescription, String productCategory) {
this.productName = productName;
this.productBarcode = productBarcode;
this.productQuantity = productQuantity;
this.productPurchasingPrice = productPurchasingPrice;
this.productSellingPrice = productSellingPrice;
this.productDescription = productDescription;
this.productCategory = productCategory;
}
public ProductEntry(int id, String productName, String productBarcode, String productQuantity
, String productPurchasingPrice, String productSellingPrice, String productDescription, String productCategory) {
this.id = id;
this.productName = productName;
this.productBarcode = productBarcode;
this.productQuantity = productQuantity;
this.productPurchasingPrice = productPurchasingPrice;
this.productSellingPrice = productSellingPrice;
this.productDescription = productDescription;
this.productCategory = productCategory;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public String getProductBarcode() {
return productBarcode;
}
public String getProductQuantity() {
return productQuantity;
}
public String getProductPurchasingPrice() {
return productPurchasingPrice;
}
public String getProductSellingPrice() {
return productSellingPrice;
}
public String getProductDescription() {
return productDescription;
}
public String getProductCategory() {
return productCategory;
}
}
ProductDao
#Dao
public interface ProductDao {
#Query("SELECT * FROM product ORDER BY id")
LiveData<List<ProductEntry>> loadAllTasks();
#Query("SELECT * FROM product WHERE id = :id")
LiveData<ProductEntry> loadTaskById(int id);
#Query("SELECT * FROM product WHERE productName LIKE :findProductName")
LiveData<List<ProductEntry>> findProduct(String findProductName);
#Insert
void insertTask(ProductEntry productEntry);
#Update(onConflict = OnConflictStrategy.REPLACE)
void updateTask(ProductEntry productEntry);
#Delete
void deleteTask(ProductEntry productEntry);
}
FindProductViewModel
public class FindProductViewModel extends ViewModel {
private final LiveData<List<ProductEntry>> findProduct;
public FindProductViewModel(AppDatabase database, String searchQuery) {
findProduct = database.productDao().findProduct(searchQuery);
}
public LiveData<List<ProductEntry>> getFindProduct() {
return findProduct;
}
}
FindProductViewModelFactory
public class FindProductViewModelFactory extends ViewModelProvider.NewInstanceFactory {
private final AppDatabase mDb;
private final String mProductQuery;
public FindProductViewModelFactory(AppDatabase database, String productQuery) {
mDb = database;
mProductQuery = productQuery;
}
#NonNull
#Override
public <T extends ViewModel> T create(#NonNull Class<T> modelClass) {
//noinspection unchecked
return (T) new FindProductViewModel(mDb, mProductQuery);
}
}
ProductsActivity
public class ProductsActivity extends AppCompatActivity implements ProductAdapter.ItemClickListener {
private FloatingActionButton fabAddProduct;
private RecyclerView recyclerView;
private ProductAdapter productAdapter;
private AppDatabase mDb;
private View emptyView;
private SearchView productSearchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_products);
initView();
setupViewModel();
setupRecycleView();
fabAddProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent addProductIntent = new Intent(ProductsActivity.this, AddProductActivity.class);
startActivity(addProductIntent);
}
});
productSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
getItemFromDb(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
getItemFromDb(newText);
// productAdapter.getFilter().filter(newText);
return false;
}
});
}
private void getItemFromDb(String query) {
String searchText = "%" + query + "%";
FindProductViewModelFactory factory = new FindProductViewModelFactory(mDb, searchText);
final FindProductViewModel viewModel = ViewModelProviders
.of(ProductsActivity.this, (ViewModelProvider.Factory) factory)
.get(FindProductViewModel.class);
viewModel.getFindProduct().observe(this, new Observer<List<ProductEntry>>() {
#Override
public void onChanged(#Nullable List<ProductEntry> productEntries) {
viewModel.getFindProduct().removeObserver(this);
productAdapter.setProductEntries(productEntries);
}
});
}
private void initView() {
emptyView = findViewById(R.id.empty_view);
fabAddProduct = findViewById(R.id.fabAddProducts);
recyclerView = findViewById(R.id.recyclerViewProducts);
productSearchView = findViewById(R.id.productSearchView);
}
private void setupRecycleView() {
mDb = AppDatabase.getInstance(getApplicationContext());
productAdapter = new ProductAdapter(this, this, mDb);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(productAdapter);
}
private void setupViewModel() {
MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.getProducts().observe(this, new Observer<List<ProductEntry>>() {
#Override
public void onChanged(#Nullable List<ProductEntry> productEntries) {
productAdapter.setProductEntries(productEntries);
if (productAdapter.getItemCount() == 0) {
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
productSearchView.setVisibility(View.GONE);
} else {
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
productSearchView.setVisibility(View.VISIBLE);
}
}
});
}
#Override
public void onItemClickListener(int itemId) {
Intent intent = new Intent(ProductsActivity.this, AddProductActivity.class);
intent.putExtra(AddProductActivity.EXTRA_PRODUCT_ID, itemId);
startActivity(intent);
}
}

To give you the simple answer, the reason you are getting only the first update is the line with viewModel.getFindProduct().removeObserver(this);

Thank you very much
I solved the problem by adding the following code
package com.artist.bookkeeper.activities;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.artist.bookkeeper.database.entry.ProductEntry;
import com.artist.bookkeeper.viewmodel.MainViewModel;
import com.artist.bookkeeper.adapters.ProductsAdapter;
import com.artist.bookkeeper.R;
import com.artist.bookkeeper.database.AppDatabase;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.List;
public class ProductStoreActivity extends AppCompatActivity implements ProductsAdapter.ItemClickListener {
private FloatingActionButton addProductFab;
private RecyclerView productsRv;
private ProductsAdapter productsAdapter;
private AppDatabase appDatabase;
private View productsEmptyView;
private SearchView productsSv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_store);
initProductView();
setupProductViewModel();
setupProductRecycleView();
addProductFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(ProductStoreActivity.this, AddProductActivity.class));
}
});
productsSv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
setupProductViewModel();
productsFilter(newText);
return true;
}
});
}
private void productsFilter(String text) {
ArrayList<ProductEntry> productsList = new ArrayList<>();
for (ProductEntry product : productsAdapter.getProductEntries()) {
if (product.getProductName().toLowerCase().contains(text.toLowerCase())) {
productsList.add(product);
}
}
if (productsList.isEmpty()) {
Toast.makeText(this, getString(R.string.no_product), Toast.LENGTH_SHORT).show();
} else {
productsAdapter.setProductEntries(productsList);
}
}
private void initProductView() {
productsEmptyView = findViewById(R.id.productEmptyView);
addProductFab = findViewById(R.id.addProductFab);
productsRv = findViewById(R.id.productRv);
productsSv = findViewById(R.id.productSv);
}
private void setupProductRecycleView() {
appDatabase = AppDatabase.getInstance(getApplicationContext());
productsAdapter = new ProductsAdapter(this, this, appDatabase);
productsRv.setHasFixedSize(true);
productsRv.setLayoutManager(new LinearLayoutManager(this));
productsRv.setAdapter(productsAdapter);
}
private void setupProductViewModel() {
MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
mainViewModel.getListProductsLiveData().observe(this, new Observer<List<ProductEntry>>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onChanged(#Nullable List<ProductEntry> productEntries) {
productsAdapter.setProductEntries(productEntries);
productsAdapter.notifyDataSetChanged();
if (productsAdapter.getItemCount() == 0) {
productsRv.setVisibility(View.GONE);
productsEmptyView.setVisibility(View.VISIBLE);
productsSv.setVisibility(View.GONE);
} else {
productsRv.setVisibility(View.VISIBLE);
productsEmptyView.setVisibility(View.GONE);
productsSv.setVisibility(View.VISIBLE);
}
}
});
}
#Override
public void onItemClickListener(int productId, String productName) {
Intent intent = new Intent(ProductStoreActivity.this, ProductDetailsActivity.class);
intent.putExtra("productId", productId);
intent.putExtra("productName", productName);
startActivity(intent);
}
}

Related

Can't pass null for argument 'pathString' in child() error

ModelOrderUser.java
package my.anupamroy.smartcanteenapp.models;
public class ModelOrderUser {
String orderId,orderTime,orderStatus,orderCost,orderBy,orderTo;
public ModelOrderUser(){
}
public ModelOrderUser(String orderId, String orderTime, String orderStatus, String orderCost, String orderBy, String orderTo) {
this.orderId = orderId;
this.orderTime = orderTime;
this.orderStatus = orderStatus;
this.orderCost = orderCost;
this.orderBy = orderBy;
this.orderTo = orderTo;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getOrderTime() {
return orderTime;
}
public void setOrderTime(String orderTime) {
this.orderTime = orderTime;
}
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getOrderCost() {
return orderCost;
}
public void setOrderCost(String orderCost) {
this.orderCost = orderCost;
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getOrderTo() {
return orderTo;
}
public void setOrderTo(String orderTo) {
this.orderTo = orderTo;
}
}
AdapterOrderUser.java
package my.anupamroy.smartcanteenapp.adapters;
import android.content.Context;
import android.text.Layout;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
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.util.ArrayList;
import java.util.Calendar;
import my.anupamroy.smartcanteenapp.R;
import my.anupamroy.smartcanteenapp.models.ModelOrderUser;
public class AdapterOrderUser extends RecyclerView.Adapter<AdapterOrderUser.HolderOrderUser>{
private Context context;
private ArrayList<ModelOrderUser> orderUserList;
public AdapterOrderUser(Context context, ArrayList<ModelOrderUser> orderUserList) {
this.context = context;
this.orderUserList = orderUserList;
}
#NonNull
#Override
public HolderOrderUser onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout
View view = LayoutInflater.from(context).inflate(R.layout.row_order_user,parent,false);
return new HolderOrderUser(view);
}
#Override
public void onBindViewHolder(#NonNull HolderOrderUser holder, int position) {
//get data
ModelOrderUser modelOrderUser=orderUserList.get(position);
String orderId = modelOrderUser.getOrderId();
String orderBy = modelOrderUser.getOrderBy();
String orderCost = modelOrderUser.getOrderCost();
String orderStatus = modelOrderUser.getOrderStatus();
String orderTime = modelOrderUser.getOrderTime();
String orderTo = modelOrderUser.getOrderTo();
//get shop info
loadShopInfo(modelOrderUser,holder);
//set data
holder.amountTv.setText("Amount: ₹" +orderCost);
holder.statusTv.setText(orderStatus);
holder.orderIdTv.setText("OrderID:"+orderId);
// change order status text color
if(orderStatus.equals("In Progress")){
holder.statusTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}
else if(orderStatus.equals("Completed")){
holder.statusTv.setTextColor(context.getResources().getColor(R.color.colorGreen));
}
else if(orderStatus.equals("Cancelled")){
holder.statusTv.setTextColor(context.getResources().getColor(R.color.colorRed));
}
//convert timestamp to proper format
Calendar calendar =Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(orderTime));
String formatedDate= DateFormat.format("dd/MM/yyy",calendar).toString();
holder.dateTv.setText(formatedDate);
}
private void loadShopInfo(ModelOrderUser modelOrderUser, final HolderOrderUser holder) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
ref.child(modelOrderUser.getOrderTo())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String shopName =""+dataSnapshot.child("shopName").getValue();
holder.shopNameTv.setText(shopName);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public int getItemCount() {
return orderUserList.size();
}
//view holder class
class HolderOrderUser extends RecyclerView.ViewHolder{
private TextView orderIdTv,dateTv,shopNameTv,amountTv,statusTv;
public HolderOrderUser(#NonNull View itemView) {
super(itemView);
//init views of layout
orderIdTv=itemView.findViewById(R.id.orderIdTv);
dateTv=itemView.findViewById(R.id.dateTv);
shopNameTv=itemView.findViewById(R.id.shopNameTv);
amountTv=itemView.findViewById(R.id.amountTv);
statusTv=itemView.findViewById(R.id.statusTv);
}
}
}
I am facing the following while executing don't know what is happening
java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
at com.google.firebase.database.DatabaseReference.child(DatabaseReference.java:96)
at my.anupamroy.smartcanteenapp.adapters.AdapterOrderUser.loadShopInfo(AdapterOrderUser.java:84)
at my.anupamroy.smartcanteenapp.adapters.AdapterOrderUser.onBindViewHolder(AdapterOrderUser.java:56)
at my.anupamroy.smartcanteenapp.adapters.AdapterOrderUser.onBindViewHolder(AdapterOrderUser.java:26)
Please help me out with this error
don't know why the code is throwing errors for me
please help me out
I am getting errors in lines number 84,56,26

JSON onResponse - List will not populate with data

I am getting a working app (kinda). It is meant to populate the screen from a request for JSON data. I thought what I have so far would work but I guess not.
onResponse does not seem to ever be called so the data is never assigned to a variable to be processed and I don't know how to fix this. Any and all help is very much appreciated.
Below is my relevant code:
My JSON data is:
{
"popular":[
{
"name":"Pizza",
"imageURL":"https://static4.depositphotos.com/1016418/315/i/600/depositphotos_3158962-stock-photo-pepperoni-pizza-isolated.jpg",
"rating":"4.8",
"deliveryTime":"45 min",
"deliveryCharges":"Free Delivery",
"price":"15",
"note":"Delicious"
},
{
"name":"Chick-Fil-A",
"imageURL":"https://media.istockphoto.com/photos/chicken-bacon-club-sandwich-picture-id585602032?k=6&m=585602032&s=612x612&w=0&h=DzlMVMOaqC25Zf78NPGzr9nLOf7wANEgv9u_vScu4d8=",
"rating":"5.0",
"deliveryTime":"15 min",
"deliveryCharges":"3",
"price":"7",
"note":"Classic"
},
{
"name":"Mac & Cheese",
"imageURL":"https://media.istockphoto.com/photos/homemade-baked-creamy-macaroni-and-cheese-picture-id483485720?k=6&m=483485720&s=612x612&w=0&h=u2Wb4hR0cIqNAm8q_4j-oFPrtC4hT_YXaq2srA2zmqI=",
"rating":"4.7",
"deliveryTime":"20 min",
"deliveryCharges":"1",
"price":"4",
"note":"Homestyle"
}
],
"recommended":[
{
"name":"Chicken Tikka Masala",
"imageURL":"https://media.istockphoto.com/photos/chicken-tikka-masala-curry-with-rice-and-naan-bread-picture-id1143530019?k=6&m=1143530019&s=612x612&w=0&h=aOCxTVcwi88NHCX9-xgNu7cmPX9rq5AGtEVYblNTnGc=",
"rating":"4.8",
"deliveryTime":"25 min",
"deliveryCharges":"2",
"price":"14",
"note":"Fan Favorite"
},
{
"name":"Strawberry Milkshake",
"imageURL":"https://thumbs.dreamstime.com/b/strawberry-milkshake-covered-whipped-cream-plastic-glass-isolated-white-background-44432579.jpg",
"rating":"4.5",
"deliveryTime":"10 min",
"deliveryCharges":"0",
"price":"4",
"note":"Chilly"
},
{
"name":"3 Tacos",
"imageURL":"https://previews.123rf.com/images/gdolgikh/gdolgikh1703/gdolgikh170300221/74432760-mexican-tacos-with-beef.jpg",
"rating":"4.6",
"deliveryTime":"17 min",
"deliveryCharges":"1",
"price":"12",
"note":"Hard or Soft Shell"
}
],
"allmenu":[
{
"name":"Pizza",
"imageURL":"https://static4.depositphotos.com/1016418/315/i/600/depositphotos_3158962-stock-photo-pepperoni-pizza-isolated.jpg",
"rating":"4.8",
"deliveryTime":"45 min",
"deliveryCharges":"Free Delivery",
"price":"15",
"note":"Delicious"
},
{
"name":"Chick-Fil-A",
"imageURL":"https://media.istockphoto.com/photos/chicken-bacon-club-sandwich-picture-id585602032?k=6&m=585602032&s=612x612&w=0&h=DzlMVMOaqC25Zf78NPGzr9nLOf7wANEgv9u_vScu4d8=",
"rating":"5.0",
"deliveryTime":"15 min",
"deliveryCharges":"3",
"price":"7",
"note":"Classic"
},
{
"name":"Mac & Cheese",
"imageURL":"https://media.istockphoto.com/photos/homemade-baked-creamy-macaroni-and-cheese-picture-id483485720?k=6&m=483485720&s=612x612&w=0&h=u2Wb4hR0cIqNAm8q_4j-oFPrtC4hT_YXaq2srA2zmqI=",
"rating":"4.7",
"deliveryTime":"20 min",
"deliveryCharges":"1",
"price":"4",
"note":"Homestyle"
},
{
"name":"Chicken Tikka Masala",
"imageURL":"https://media.istockphoto.com/photos/chicken-tikka-masala-curry-with-rice-and-naan-bread-picture-id1143530019?k=6&m=1143530019&s=612x612&w=0&h=aOCxTVcwi88NHCX9-xgNu7cmPX9rq5AGtEVYblNTnGc=",
"rating":"4.8",
"deliveryTime":"25 min",
"deliveryCharges":"2",
"price":"14",
"note":"Fan Favorite"
},
{
"name":"Strawberry Milkshake",
"imageURL":"https://thumbs.dreamstime.com/b/strawberry-milkshake-covered-whipped-cream-plastic-glass-isolated-white-background-44432579.jpg",
"rating":"4.5",
"deliveryTime":"10 min",
"deliveryCharges":"0",
"price":"4",
"note":"Chilly"
},
{
"name":"3 Tacos",
"imageURL":"https://previews.123rf.com/images/gdolgikh/gdolgikh1703/gdolgikh170300221/74432760-mexican-tacos-with-beef.jpg",
"rating":"4.6",
"deliveryTime":"17 min",
"deliveryCharges":"1",
"price":"12",
"note":"Hard or Soft Shell"
}
]
}
I have models for Allmenu, FoodData, Popular, and Recommended.
AllMenu:
package com.example.bearcateats.model;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class Allmenu {
#SerializedName("name")
#Expose
private String name;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("rating")
#Expose
private String rating;
#SerializedName("deliveryTime")
#Expose
private String deliveryTime;
#SerializedName("deliveryCharges")
#Expose
private String deliveryCharges;
#SerializedName("price")
#Expose
private String price;
#SerializedName("note")
#Expose
private String note;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(String deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getDeliveryCharges() {
return deliveryCharges;
}
public void setDeliveryCharges(String deliveryCharges) {
this.deliveryCharges = deliveryCharges;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
FoodData:
package com.example.bearcateats.model;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class FoodData {
#SerializedName("popular")
#Expose
private List<Popular> popular = null;
#SerializedName("recommended")
#Expose
private List<Recommended> recommended = null;
#SerializedName("allmenu")
#Expose
private List<Allmenu> allmenu = null;
public List<Popular> getPopular() {
return popular;
}
public void setPopular(List<Popular> popular) {
this.popular = popular;
}
public List<Recommended> getRecommended() {
return recommended;
}
public void setRecommended(List<Recommended> recommended) {
this.recommended = recommended;
}
public List<Allmenu> getAllmenu() {
return allmenu;
}
public void setAllmenu(List<Allmenu> allmenu) {
this.allmenu = allmenu;
}
}
Popular:
package com.example.bearcateats.model;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class Popular {
#SerializedName("name")
#Expose
private String name;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("rating")
#Expose
private String rating;
#SerializedName("deliveryTime")
#Expose
private String deliveryTime;
#SerializedName("deliveryCharges")
#Expose
private String deliveryCharges;
#SerializedName("price")
#Expose
private String price;
#SerializedName("note")
#Expose
private String note;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(String deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getDeliveryCharges() {
return deliveryCharges;
}
public void setDeliveryCharges(String deliveryCharges) {
this.deliveryCharges = deliveryCharges;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Recommended:
package com.example.bearcateats.model;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class Recommended {
#SerializedName("name")
#Expose
private String name;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("rating")
#Expose
private String rating;
#SerializedName("deliveryTime")
#Expose
private String deliveryTime;
#SerializedName("deliveryCharges")
#Expose
private String deliveryCharges;
#SerializedName("price")
#Expose
private String price;
#SerializedName("note")
#Expose
private String note;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(String deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getDeliveryCharges() {
return deliveryCharges;
}
public void setDeliveryCharges(String deliveryCharges) {
this.deliveryCharges = deliveryCharges;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Main:
package com.example.bearcateats;
import android.os.Bundle;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.bearcateats.adapters.PopularAdapter;
import com.example.bearcateats.adapters.RecommendedAdapter;
import com.example.bearcateats.model.Allmenu;
import com.example.bearcateats.model.FoodData;
import com.example.bearcateats.model.Popular;
import com.example.bearcateats.model.Recommended;
import com.example.bearcateats.retrofit.ApiInterface;
import com.example.bearcateats.retrofit.RetrofitClient;
import com.example.bearcateats.adapters.AllMenuAdapter;
import java.util.List;
public class MainActivity extends AppCompatActivity {
ApiInterface apiInterface;
RecyclerView popularRecyclerView, recommendedRecyclerView, allMenuRecyclerView;
PopularAdapter popularAdapter;
RecommendedAdapter recommendedAdapter;
AllMenuAdapter allMenuAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = RetrofitClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<FoodData>> call = apiInterface.getAllData();
call.enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
System.out.println("TEST!!!!!!!!!!!!!!");
List<FoodData> MenuList;
MenuList = response.body();
if(MenuList == null) {
System.out.println("MenuList!!!!!!!!!!!!!!");
}
List <FoodData> test1 = (List<FoodData>) MenuList.get(0);
List<Popular> popular = ((FoodData) test1).getPopular();
getPopularData(popular);
System.out.println("GET POPULAR RAN!!!!!!!!!!!!!!");
getRecommendedData(MenuList.get(0).getRecommended());
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Server is not responding.", Toast.LENGTH_SHORT).show();
}
});
}
private void getPopularData(List<Popular> popularList){
popularRecyclerView = findViewById(R.id.popular_recycler);
popularAdapter = new PopularAdapter(this, popularList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
popularRecyclerView.setLayoutManager(layoutManager);
popularRecyclerView.setAdapter(popularAdapter);
}
private void getRecommendedData(List<Recommended> recommendedList){
recommendedRecyclerView = findViewById(R.id.recommended_recycler);
recommendedAdapter = new RecommendedAdapter(this, recommendedList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recommendedRecyclerView.setLayoutManager(layoutManager);
recommendedRecyclerView.setAdapter(recommendedAdapter);
}
private void getAllMenu(List<Allmenu> allmenuList){
allMenuRecyclerView = findViewById(R.id.all_menu_recycler);
allMenuAdapter = new AllMenuAdapter(this, allmenuList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
allMenuRecyclerView.setLayoutManager(layoutManager);
allMenuRecyclerView.setAdapter(allMenuAdapter);
allMenuAdapter.notifyDataSetChanged();
}
}
FoodDetails
{
// now we will get data from intent and set to UI
ImageView imageView;
TextView itemName, itemPrice, itemRating;
RatingBar ratingBar;
String name, price, rating, imageUrl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_details);
Intent intent = getIntent();
name = intent.getStringExtra("name");
price = intent.getStringExtra("price");
rating = intent.getStringExtra("rating");
imageUrl = intent.getStringExtra("image");
imageView = findViewById(R.id.imageView5);
itemName = findViewById(R.id.name);
itemPrice = findViewById(R.id.price);
itemRating = findViewById(R.id.rating);
ratingBar = findViewById(R.id.ratingBar);
Glide.with(getApplicationContext()).load(imageUrl).into(imageView);
itemName.setText(name);
itemPrice.setText("$ "+price);
itemRating.setText(rating);
ratingBar.setRating(Float.parseFloat(rating));
}
}
Couple of silly mistakes are there. I have fixed all your bugs. Nothing wrong with your JSON or Response data classes. Correct response is received inside onResponse() callback. Issues are present other parts of your code. Just follow step by step.
Step-1
Replace below code while parsing response data from api call like:
call.enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
if (response.isSuccessful()){
if (response.body() != null){
List<Popular> popular = response.body().get(0).getPopular();
getPopularData(popular);
getRecommendedData(response.body().get(0).getRecommended());
}
}
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Server is not responding.", Toast.LENGTH_SHORT).show();
}
});
Step-2
Inside PopularAdapter class replace getItemCount() method as below:
#Override
public int getItemCount() {
//return 0; // Returning 0 will show nothing in RecyclerView.
return popularList.size();
}
Step-3:
Inside RecommendedAdapter class you have used wrong xml for ViewHolder. Replace like below:
#NonNull
#Override
public RecommendedViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//View view = LayoutInflater.from(context).inflate(R.layout.popular_recycler_items, parent, false);
View view = LayoutInflater.from(context).inflate(R.layout.recommended_recyvler_items, parent, false);
return new RecommendedViewHolder(view);
}
And also replace getItemCount() method like below:
#Override
public int getItemCount() {
return recommendedList.size();
}
UPDATE:-
Why are you calling same api inside onSuccess() of api call ? I have update your onCreate() method like below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = RetrofitClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<FoodData>> call = apiInterface.getAllData();
call.enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
getPopularData(response.body().get(0).getPopular());
getRecommendedData(response.body().get(0).getRecommended());
getAllMenu(response.body().get(0).getAllmenu());
}
}
/*
call.clone().enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
response.code();
getPopularData(response.body().get(0).getPopular());
getRecommendedData(response.body().get(0).getRecommended());
getAllMenu(response.body().get(0).getAllmenu());
}
}
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
response.code();
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});*/
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
I see your JSON in https://francescainfranca.github.io/menuJSON/index.json is an Single FoodData JSON Object and Not an JSONArray.
This is causing the following exception when we run the application. So either Change the JSON structure or Make the application use FoodData directly instead of List<FoodData>.
Also the Toast Message (Server is not responding) is being shown on run which you have added on Failure Response.
Hope this helps you. Thanks.

How to store data from REST API with Volley for Android

I try to get data from my Api, I can get data and convert it into an object class I created and show it but I can't store all objects instances in an list. Someone knows ?
I tried to add every element I got in a List then try to get elements from it after but doesn't work, the list stays empty.
This is what my API returns :
{"_id":"60683c5bcdfcb74689bc8382","questionId":3,"question":"Question 3","choices":"1-/-2-/-3-/-4","category":"Other","difficulty":"Easy"}
This is my "ApiTest activity" :
package com.jojo.jojozquizz;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.jojo.jojozquizz.model.Question;
import com.jojo.jojozquizz.model.QuestionBank;
import com.jojo.jojozquizz.tools.APIListener;
import org.json.JSONException;
import org.json.JSONObject;
public class ApiTests extends AppCompatActivity implements APIListener {
private TextView text;
public static final String TAG = "MyTag";
private QuestionBank mQuestionBank;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_api_tests);
mQuestionBank = new QuestionBank();
text = findViewById(R.id.api_text);
String url = "https://nextfor.studio/questions/test";
getQuestionFromApi(url);
}
private void getQuestionFromApi(String url) {
APIListener listener = this;
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, "onResponse: " + response.toString());
Question question = new Question();
question.setId(response.getInt("questionId"));
question.setQuestion(response.getString("question"));
question.setChoices(response.getString("choices"));
question.setCategory(response.getString("category"));
question.setDifficulty(response.getString("difficulty"));
listener.questionReceived(question);
} catch (JSONException e) {
Log.i(TAG, e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse: " + error.getMessage());
}
});
requestQueue.add(jsonObjectRequest);
}
#Override
public void questionReceived(Question q) {
mQuestionBank.addQuestion(q);
}
}
Question class :
package com.jojo.jojozquizz.model;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import java.io.Serializable;
import java.util.List;
#Entity(tableName = "questions")
public class Question implements Serializable {
#PrimaryKey()
#ColumnInfo(name = "id")
private long id;
#ColumnInfo(name = "question")
private String mQuestion;
#Ignore
private List<String> mChoiceList;
#ColumnInfo(name = "choices")
private String mChoices;
#ColumnInfo(name = "answer_index")
private int mAnswerIndex;
#ColumnInfo(name = "categorie")
private String mCategory;
#Ignore
private String mTrueAnswer;
#ColumnInfo(name = "difficulty")
private String mDifficulty;
public Question() {
}
public Question(int id, String mQuestion, List<String> mChoiceList, String mCategorie, String mDifficulty) {
this.id = id;
this.mQuestion = mQuestion;
this.mChoices = mChoiceList.get(0) + "-/-" + mChoiceList.get(1) + "-/-" + mChoiceList.get(2) + "-/-" + mChoiceList.get(3);
this.mAnswerIndex = 0;
this.mCategory = mCategorie;
this.mDifficulty = mDifficulty;
}
public Question(String mQuestion, List<String> mChoiceList, String mCategorie, String mDifficulty) {
this.mQuestion = mQuestion;
this.mChoices = mChoiceList.get(0) + "-/-" + mChoiceList.get(1) + "-/-" + mChoiceList.get(2) + "-/-" + mChoiceList.get(3);
this.mAnswerIndex = 0;
this.mCategory = mCategorie;
this.mDifficulty = mDifficulty;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getQuestion() {
return mQuestion;
}
public void setQuestion(String question) {
mQuestion = question;
}
public List<String> getChoiceList() {
return mChoiceList;
}
public void setChoiceList(List<String> choiceList) {
mChoiceList = choiceList;
}
public String getChoices() {
return mChoices;
}
public void setChoices(String choices) {
mChoices = choices;
}
public void setAnswerIndex(int mAnswerIndex) {
this.mAnswerIndex = mAnswerIndex;
}
public int getAnswerIndex() {
return mAnswerIndex;
}
public String getCategory() {
return mCategory;
}
public void setCategory(String categorie) {
mCategory = categorie;
}
public String getTrueAnswer() {
return mTrueAnswer;
}
public void setTrueAnswer(String trueAnswer) {
mTrueAnswer = trueAnswer;
}
public String getDifficulty() {
return mDifficulty;
}
public void setDifficulty(String difficulty) {
mDifficulty = difficulty;
}
}
QuestionBank (this is like a list of Questions) :
package com.jojo.jojozquizz.model;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class QuestionBank {
private List<Question> mQuestionList;
public int mNextQuestionIndex;
public QuestionBank() {
mQuestionList = new LinkedList<>();
mNextQuestionIndex = 0;
}
public QuestionBank(List<Question> questionList, boolean shuffle) {
mQuestionList = questionList;
if (shuffle)
Collections.shuffle(mQuestionList);
mNextQuestionIndex = 0;
}
public Question getQuestion() {
if (mNextQuestionIndex == mQuestionList.size())
mNextQuestionIndex = 0;
return mQuestionList.get(mNextQuestionIndex++);
}
public Question getQuestion(int i) {
return mQuestionList.get(i);
}
public void reShuffle() {
Collections.shuffle(mQuestionList);
}
public void addQuestion(Question question) {
mQuestionList.add(question);
}
public int returnListSize() {
return mQuestionList.size();
}
}
And APIListener :
package com.jojo.jojozquizz.tools;
import com.jojo.jojozquizz.model.Question;
public interface APIListener {
void questionReceived(Question q);
}
API calling is an asynchronous process. So getQuestionFromApi(url); might took some time, so if you try text.setText(mQuestionBank.getQuestion(0).getQuestion()); after getQuestionFromApi(url); line, it won't work. You could use LiveData to handle this case. Like:
class QuestionBank {
MutableLiveData<List<Question>> mQuestionList;
public int mNextQuestionIndex;
public QuestionBank() {
mQuestionList = new MutableLiveData<>(new LinkedList<>());
mNextQuestionIndex = 0;
}
public QuestionBank(List<Question> questionList, boolean shuffle) {
mQuestionList.setValue(questionList);
if (shuffle)
Collections.shuffle(mQuestionList.getValue());
mNextQuestionIndex = 0;
}
public Question getQuestion() {
if (mNextQuestionIndex == mQuestionList.getValue().size())
mNextQuestionIndex = 0;
return mQuestionList.getValue().get(mNextQuestionIndex++);
}
public Question getQuestion(int i) {
return mQuestionList.getValue().get(i);
}
public void reShuffle() {
Collections.shuffle(mQuestionList.getValue());
}
public void addQuestion(Question question) {
List<Question> tempQ = mQuestionList.getValue();
tempQ.add(question);
mQuestionList.setValue(tempQ);
}
public int returnListSize() {
return mQuestionList.getValue().size();
}
}
And inside onCreate() observe if any data has been added or not and then setText() to TextView. Like:
QuestionBank questionBank = new QuestionBank();
questionBank.mQuestionList.observe(getViewLifecycleOwner(), new Observer<List<Question>>() {
#Override
public void onChanged(List<Question> questions) {
if (!questions.isEmpty()){
textView.setText(questions.get(0).getQuestion());
Log.d("TAG==>>","New Question added Total size = "+questions.size());
}
}
});

Cannot access database on the main thread since it may potentially lock the UI for a long period of time error

Whenever I want to start my "NotenActivity", it Shows me this error:
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:209)
at androidx.room.RoomDatabase.query(RoomDatabase.java:237)
at com.example.mykolproject.persistance.dao.NoteDao_Impl.getnAll(NoteDao_Impl.java:121)
at com.example.mykolproject.NoteRepository.<init>(NoteRepository.java:23)
at com.example.mykolproject.NoteViewModel.<init>(NoteViewModel.java:20)
at java.lang.reflect.Constructor.newInstance0(Native Method) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200) 
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135) 
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103) 
at com.example.mykolproject.NotenActivity.onCreate(NotenActivity.java:130) 
at android.app.Activity.performCreate(Activity.java:7458) 
at android.app.Activity.performCreate(Activity.java:7448) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 
at android.os.Handler.dispatchMessage(Handler.java:112) 
at android.os.Looper.loop(Looper.java:216) 
at android.app.ActivityThread.main(ActivityThread.java:7625) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 
Here are my affected Activitys:
package com.example.mykolproject.persistance.dao;
import android.database.Cursor;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteStatement;
import com.example.mykolproject.persistance.entities.Note;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.List;
#SuppressWarnings("unchecked")
public final class NoteDao_Impl implements NoteDao {
private final RoomDatabase __db;
private final EntityInsertionAdapter __insertionAdapterOfNote;
private final EntityDeletionOrUpdateAdapter __deletionAdapterOfNote;
private final EntityDeletionOrUpdateAdapter __updateAdapterOfNote;
public NoteDao_Impl(RoomDatabase __db) {
this.__db = __db;
this.__insertionAdapterOfNote = new EntityInsertionAdapter<Note>(__db) {
#Override
public String createQuery() {
return "INSERT OR ABORT INTO `note_table`(`id`,`titlefach`,`noten`) VALUES (nullif(?, 0),?,?)";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
if (value.titlefach == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.titlefach);
}
if (value.getNoten() == null) {
stmt.bindNull(3);
} else {
stmt.bindString(3, value.getNoten());
}
}
};
this.__deletionAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
#Override
public String createQuery() {
return "DELETE FROM `note_table` WHERE `id` = ?";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
}
};
this.__updateAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
#Override
public String createQuery() {
return "UPDATE OR ABORT `note_table` SET `id` = ?,`titlefach` = ?,`noten` = ? WHERE `id` = ?";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
if (value.titlefach == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.titlefach);
}
if (value.getNoten() == null) {
stmt.bindNull(3);
} else {
stmt.bindString(3, value.getNoten());
}
stmt.bindLong(4, value.getId());
}
};
}
#Override
public void insert(Note note) {
__db.beginTransaction();
try {
__insertionAdapterOfNote.insert(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public void delete(Note note) {
__db.beginTransaction();
try {
__deletionAdapterOfNote.handle(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public void update(Note note) {
__db.beginTransaction();
try {
__updateAdapterOfNote.handle(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public List<Note> getnAll() {
final String _sql = "SELECT * FROM note_table";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
final Cursor _cursor = __db.query(_statement);
try {
final int _cursorIndexOfId = _cursor.getColumnIndexOrThrow("id");
final int _cursorIndexOfTitlefach = _cursor.getColumnIndexOrThrow("titlefach");
final int _cursorIndexOfNoten = _cursor.getColumnIndexOrThrow("noten");
final List<Note> _result = new ArrayList<Note>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Note _item;
final String _tmpTitlefach;
_tmpTitlefach = _cursor.getString(_cursorIndexOfTitlefach);
final String _tmpNoten;
_tmpNoten = _cursor.getString(_cursorIndexOfNoten);
_item = new Note(_tmpTitlefach,_tmpNoten);
final int _tmpId;
_tmpId = _cursor.getInt(_cursorIndexOfId);
_item.setId(_tmpId);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
}
package com.example.mykolproject;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import com.example.mykolproject.persistance.dao.NoteDao;
import com.example.mykolproject.persistance.entities.AppDatabase;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NoteRepository {
private NoteDao notenDao;
private LiveData<List<Note>> allNoten;
public NoteRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
notenDao = database.NoteDao();
allNoten = (LiveData<List<Note>>) notenDao.getnAll();
}
public void insert(LiveData<List<Note>> note) {
new InsertNoteAsyncTask(notenDao).execute((Runnable) note);
}
public void update(LiveData<List<Note>> note) {
new UpdateNoteAsyncTask(notenDao).execute((Runnable) note);
}
public void delete(LiveData<List<Note>> note) {
new DeleteNoteAsyncTask(notenDao).execute((Runnable) note);
}
public LiveData<List<Note>> getAllNoten() {
return getAllNoten();
}
private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private InsertNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.insert(noten[0]);
return null;
}
}
private static class UpdateNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private UpdateNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.update(noten[0]);
return null;
}
}
private static class DeleteNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private DeleteNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.delete(noten[0]);
return null;
}
}
}
package com.example.mykolproject;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NoteViewModel extends AndroidViewModel {
private NoteRepository repository;
private LiveData<List<Note>> allNoten;
public NoteViewModel(#NonNull Application application) {
super(application);
repository = new NoteRepository(application);
allNoten = repository.getAllNoten();
}
public void insert(Note note) {
repository.insert(allNoten);
}
public void update(Note note) {
repository.update(allNoten);
}
public void delete(Note note) {
repository.delete(allNoten);
}
public LiveData<List<Note>> getAllNotes() {
return allNoten;
}
}
package com.example.mykolproject;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NotenActivity extends AppCompatActivity {
public String TAG = "NotenActivity";
public static final String NOTEN_MESSAGE = "com.example.MyOLProject.NOTEN";
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
public static final int ADD_NOTE_REQUEST = 1;
public static final int EDIT_NOTE_REQUEST = 2;
private NoteViewModel noteViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_noten);
// final EditText editFach = findViewById(R.id.edit_fach);
recyclerView = (RecyclerView) findViewById(R.id.notenList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
Button btnAddNoten = findViewById(R.id.btn_addNote);
btnAddNoten.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "onClick: AddNoten");
startAddNoten();
}
});
ImageButton btnFach = findViewById(R.id.ibFach);
btnFach.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Fach");
startFach();
}
});
ImageButton btnHome = findViewById(R.id.ibHome);
btnHome.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Home");
startHome();
}
});
ImageButton btnHausaufgaben = findViewById(R.id.ibHausaufgaben);
btnHausaufgaben.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Hausaufgaben");
startHausaufgaben();
}
});
ImageButton btnKalender = findViewById(R.id.ibInfo);
btnKalender.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Kalender");
startKalender();
}
});
Button buttonAddNote = findViewById(R.id.btn_addNote);
buttonAddNote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
startActivityForResult(intent, ADD_NOTE_REQUEST);
}
});
RecyclerView recyclerView = findViewById(R.id.notenList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final NotenListAdapter adapter = new NotenListAdapter();
recyclerView.setAdapter(adapter);
noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
#Override
public void onChanged(#Nullable List<Note> noten) {
adapter.setNotes(noten);
}
});
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
noteViewModel.delete(adapter.getNoteAt(viewHolder.getAdapterPosition()));
Toast.makeText(NotenActivity.this, "Note deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
adapter.setOnItemClickListener(new NotenListAdapter.OnItemClickListener() {
#Override
public void onItemClick(Note note) {
Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
intent.putExtra(AddEditNoteActivity.EXTRA_ID, note.getId());
intent.putExtra(AddEditNoteActivity.EXTRA_TITLE, note.getTitleFach());
intent.putExtra(AddEditNoteActivity.EXTRA_DESCRIPTION, note.getNoten());
startActivityForResult(intent, EDIT_NOTE_REQUEST);
}
});
}
private void startAddNoten(){
Intent addNotenIntent = new Intent(this,AddNotenActivity.class);
startActivity(addNotenIntent);
}
private void startFach(){
Intent fachIntent = new Intent(this,FachActivity.class);
startActivity(fachIntent);
}
private void startHome(){
Intent homeIntent = new Intent(this,MainActivity.class);
startActivity(homeIntent);
}
private void startHausaufgaben(){
Intent hausaufgabenIntent = new Intent(this,HausaufgabenActivity.class);
startActivity(hausaufgabenIntent);
}
private void startKalender(){
Intent kalenderIntent = new Intent(this,InfoActivity.class);
startActivity(kalenderIntent);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_NOTE_REQUEST && resultCode == RESULT_OK) {
String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);
Note note = new Note(title, description);
noteViewModel.insert(note);
Toast.makeText(this, "Note saved", Toast.LENGTH_SHORT).show();
} else if (requestCode == EDIT_NOTE_REQUEST && resultCode == RESULT_OK) {
int id = data.getIntExtra(AddEditNoteActivity.EXTRA_ID, -1);
if (id == -1) {
Toast.makeText(this, "Note can't be updated", Toast.LENGTH_SHORT).show();
return;
}
String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);
Note note = new Note(title, description);
note.setId(id);
noteViewModel.update(note);
Toast.makeText(this, "Note updated", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Note not saved", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return true;
}
/* #Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_all_notes:
noteViewModel.deleteAllNotes();
Toast.makeText(this, "All notes deleted", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}*/
}
If you Need any other activities just let me know. My "NotenActivity" is like my MainActivity.
Thank you very much !
Try using some RxJava, that can probably help you out.
But since you're using Room, LiveData, and ViewModel you can probably try using this AppExecutor class. This usually helps me out when I'm doing Database and Network operations.
Also be careful when running on the UI/Main Thread, for Database operations with lots of data its always best practice to do it on a separate thread.
import android.os.Looper;
import android.support.annotation.NonNull;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class AppExecutors {
private static final Object LOCK = new Object();
private static AppExecutors sInstance;
private final Executor diskIO;
private final Executor mainThread;
private final Executor networkIO;
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
this.diskIO = diskIO;
this.networkIO = networkIO;
this.mainThread = mainThread;
}
public static AppExecutors getInstance() {
if (sInstance == null) {
synchronized (LOCK) {
sInstance = new AppExecutors(Executors.newSingleThreadExecutor(),
Executors.newFixedThreadPool(3),
new MainThreadExecutor());
}
}
return sInstance;
}
public Executor diskIO() {
return diskIO;
}
public Executor mainThread() {
return mainThread;
}
public Executor networkIO() {
return networkIO;
}
private static class MainThreadExecutor implements Executor {
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
#Override
public void execute(#NonNull Runnable command) {
mainThreadHandler.post(command);
}
}
}
//Then you can do something like this.
```AppExecutors.getInstance().getDiskIO.execute(()->database.NoteDao().getnAll());```
Maybe you could look on widely accepted solution of this problem, it could bring you to solution of your problem too...

Sorting data in List by specific value

I have an issue where my recyclerview adds new items at the end, whereas I want the latest items at the top upon user refresh. I've been scratching around all over the net and it essentially boils down to adding setreverseLayout or setStackFromEnd. This gives other complications such as the recycler view not scrolling to the top to the latest item.
I then had a thought of maybe ordering my data list by a specific value and then it should return it as I want it. Can this be done and would it resolve my issue? I want to sort it by value adopt_rownum desc.
My Custom Adapter
package com.example.admin.paws;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* Created by admin on 9/16/2016.
*/
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public Context context;
public List<MyData> my_data;
public CustomAdapter(Context context, List<MyData> my_data) {
this.context = context;
this.my_data = my_data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardnew,parent,false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String name = my_data.get(position).getName();
String age = my_data.get(position).getAge();
String gender = my_data.get(position).getGender();
String SubstAge = age.substring(0,age.indexOf("(") -1);
String NameAgeGender = name + ", " + SubstAge + ", " + gender;
holder.about.setText(my_data.get(position).getAbout());
holder.NameAgeGender.setText(NameAgeGender);
Glide.with(context).load(my_data.get(position).getPhoto_path()).into(holder.photo_path);
//activity_card_details vars
// final String about = my_data.get(position).getAbout();
final String adoptId = my_data.get(position).getId()+"";
final String photo_path_dtls = my_data.get(position).getPhoto_path();
final String listedDate = my_data.get(position).getDatetime_listed();
final String status = my_data.get(position).getStatus();
final String breed = my_data.get(position).getBreed();
final String source = my_data.get(position).getSource();
final String contact_info = my_data.get(position).getContact_info();
final String suburb = my_data.get(position).getSuburb();
final String city = my_data.get(position).getCity();
final String province = my_data.get(position).getProvince();
final String concat_location = suburb + ", " + city + ", " + province;
final String viewCounter = my_data.get(position).getViewCounter()+"";
//When click on photo
holder.photo_path.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context,CardDetailsActivity.class);
intent.putExtra("listedDate",listedDate);
intent.putExtra("adoptId",adoptId);
// intent.putExtra("about",about);
intent.putExtra("status",status);
intent.putExtra("breed",breed);
intent.putExtra("source",source);
intent.putExtra("contactinfo",contact_info);
intent.putExtra("location",concat_location);
intent.putExtra("photo_path_dtls",photo_path_dtls);
intent.putExtra("viewCounter",viewCounter);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return my_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
{
public TextView NameAgeGender;
public ImageView photo_path;
public TextView about;
private ViewHolder(View itemView) {
super(itemView);
about = (TextView) itemView.findViewById(R.id.about);
NameAgeGender = (TextView) itemView.findViewById(R.id.tvNameAgeGender);
// NameAgeGender.setTextColor(Color.parseColor("#9C9393"));
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Lato-Medium.ttf");
NameAgeGender.setTypeface(typeface);
//NameAgeGender.setBackgroundColor(Color.parseColor("#F35959"));
photo_path = (ImageView) itemView.findViewById(R.id.photo_path);
}
}
}
My DataList
package com.example.admin.paws;
public class MyData {
//the must be in the same order of the select column order
public int adopt_rownum
,viewCounter
,adopt_id;
private String
name
,type
,breed
,age
,gender
,size
,about
,photo_path
,source
,contact_info
,suburb
,city
,province
,datetime_listed
,status;
public MyData(
int adopt_rownum,
int viewCounter,
int adopt_id,
String name,
String type,
String breed,
String age,
String gender,
String size,
String about,
String photo_path,
String source,
String contact_info,
String suburb,
String city,
String province,
String datetime_listed,
String status)
{
this.adopt_rownum = adopt_rownum;
this.viewCounter = viewCounter;
this.adopt_id = adopt_id;
this.name = name;
this.type = type;
this.breed = breed;
this.age = age;
this.gender = gender;
this.size = size;
this.about = about;
this.photo_path = photo_path;
this.source = source;
this.contact_info = contact_info;
this.suburb = suburb;
this.city = city;
this.province = province;
this.datetime_listed = datetime_listed;
this.status = status;
}
//adopt_rownum used for filtering the records.
public int getAdopt_rownum() {
return adopt_rownum;
}
//viewcounter
public int getViewCounter() {
return viewCounter;
}
//adopt_id
public int getId() {
return adopt_id;
}
public void setId(int adopt_id) {
this.adopt_id = adopt_id;
}
//name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//type
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
//breed
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
//age
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
//gender
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.age = gender;
}
//size
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
//about
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
//photo path
public String getPhoto_path() {
return photo_path;
}
public void setPhoto_path(String photo_path) {
this.photo_path = photo_path;
}
//source
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
//contact_info
public String getContact_info() {
return contact_info;
}
public void setContact_info(String contact_info) {
this.contact_info = contact_info;
}
//suburb
public String getSuburb() {
return suburb;
}
public void setSuburb(String suburb) {
this.contact_info = suburb;
}
//city
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
//province
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
//datetime_listed
public String getDatetime_listed() {
return datetime_listed;
}
public void setDatetime_listed(String datetime_listed) {
this.datetime_listed = datetime_listed;
}
//status
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
The fragment that displays the results. Another question on the side, inside this fragment for load_data_from_server its giving me a warning that "This Async task should be static or leaks might occur". I have no idea what this means since I'm completely new to JAVA.
package com.example.admin.paws;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link feedFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link feedFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class feedFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public Activity FragActivity;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private List<MyData> data_list;
private CustomAdapter adapter;
RecyclerView recyclerView;
public String EndOfFeed;
private OnFragmentInteractionListener mListener;
public feedFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment fragment_feed.
*/
// TODO: Rename and change types and number of parameters
public static feedFragment newInstance(String param1, String param2) {
feedFragment fragment = new feedFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#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) {
setHasOptionsMenu(true);
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
final GridLayoutManager gridLayoutManager;
final SwipeRefreshLayout swipeRefreshLayout = rootView.findViewById(R.id.feedRefresh);
TextView tvEndOfFeed = rootView.findViewById(R.id.tvEndOfFeed);
tvEndOfFeed.setText(EndOfFeed);
//recycler view
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
data_list = new ArrayList<>();
load_data_from_server(0, "getFeed.php");
gridLayoutManager = new GridLayoutManager(getActivity(), 1); //2 nr of cards next to each other
recyclerView.setLayoutManager(gridLayoutManager);
//gridLayoutManager.setReverseLayout(true);
adapter = new CustomAdapter(getActivity(), data_list);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size() - 1) {
load_data_from_server(data_list.get(data_list.size() - 1).getAdopt_rownum(), "getFeed.php");
}
}
});
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
//this works but issue with the ordering of the adoptrownum
load_data_from_server(data_list.get(data_list.size() -1).getAdopt_rownum(), "refreshFeed.php");
swipeRefreshLayout.setRefreshing(false);
}
});
return rootView;
}
private void load_data_from_server(final int adopt_id, final String phpScript) {
AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {
#Override
protected Void doInBackground(Integer... integers) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.0.2.2/app_scripts/"+phpScript+"?adopt_rownum="+integers[0])
.build();
try {
Response response = client.newCall(request).execute();
JSONArray array = new JSONArray(response.body().string());
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
MyData data = new MyData(
object.getInt("ADOPT_ROWNUM"),
object.getInt("VIEWCOUNTER"),
object.getInt("ADOPT_ID"),
object.getString("NAME"),
object.getString("TYPE"),
object.getString("BREED"),
object.getString("AGE"),
object.getString("GENDER"),
object.getString("SIZE"),
object.getString("ABOUT"),
object.getString("PHOTO_PATH"),
object.getString("SOURCE"),
object.getString("CONTACT_INFO"),
object.getString("SUBURB"),
object.getString("CITY"),
object.getString("PROVINCE"),
object.getString("DATETIME_LISTED"),
object.getString("STATUS")
);
data_list.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
System.out.println("End of content"+e);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged();
}
};
task.execute(adopt_id);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
I added the Comparator as instructed below but the output is a bit weird...
public class MyComparator implements Comparator<MyData > {
#Override
public int compare(final MyData o1, final MyData o2) {
Log.d("APP", "compare Starting... ");
Integer val1 = o1.getAdopt_rownum();
Log.d("APP", "compare val1... "+val1);
Integer val2 = o2.getAdopt_rownum();
Log.d("APP", "compare val1... "+val2);
Log.d("APP", "compare val1 and val2 ="+val1.compareTo(val2));
return val1.compareTo(val2);
}
}
output
compare Starting...
compare val1... 2
compare val2... 1
compare val1 and val2 =1
...
compare Starting...
compare val1... 14
compare val2... 15
compare val2 and val2 =1
Below is how i implemented it in my fragment
private void load_data_from_server(final int adopt_id, final String phpScript) {
AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {
#Override
protected Void doInBackground(Integer... integers) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.0.2.2/app_scripts/"+phpScript+"?adopt_rownum="+integers[0])
.build();
try {
Response response = client.newCall(request).execute();
JSONArray array = new JSONArray(response.body().string());
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
MyData data = new MyData(
object.getInt("ADOPT_ROWNUM"),
object.getInt("VIEWCOUNTER"),
object.getInt("ADOPT_ID"),
object.getString("NAME"),
object.getString("TYPE"),
object.getString("BREED"),
object.getString("AGE"),
object.getString("GENDER"),
object.getString("SIZE"),
object.getString("ABOUT"),
object.getString("PHOTO_PATH"),
object.getString("SOURCE"),
object.getString("CONTACT_INFO"),
object.getString("SUBURB"),
object.getString("CITY"),
object.getString("PROVINCE"),
object.getString("DATETIME_LISTED"),
object.getString("STATUS")
);
data_list.add(data);
**Collections.sort(data_list,new MyComparator());**
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
//System.out.println("End of content"+e);
EndOfFeed = e+"";
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged();
}
};
task.execute(adopt_id);
}
You can sort list by a property using the following code:
Collections.sort(myList, new MyComparator());
public static class MyComparator implements Comparator<MyData > {
#Override
public int compare(final MyData o1, final MyData o2) {
return o1.getAdoptRownum().compareTo(o2.getAdoptRownum());
}
}
I usually declare comparators inside the relevant POJO class. Then you can call Collections.sort whenever you refresh your data.

Categories

Resources