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
Related
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);
}
}
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());
}
}
});
I am a beginner at coding in Java. I am creating a notes app with lots of other features. And one of the features are, storing the user's bank card details in a RecyclerView. I did this by making an SQLite CRUD. All of the Create, Read, Update and Delete works. And I protected this page with a Pattern lock.
And when we are in the Input Pattern page, we can see a clickable text called Click HERE if you forgot your pattern, That works. And when you click on that clickable text, the app shows an Alert Dialog, titled are you sure? and the message is If you change your pattern, all your data will be deleted then there are two buttons Yes and No. No does nothing, it just cancel the forgot pattern thing. But the problem is with the Yes button.
When we click it, It should delete all bank cards or delete all data. Please suggest a way to delete all data from the SQLite Database. I tried lots of ways to do this.
HERE IS MY INPUT PATTERN ACTIVITY
package com.ixidev.simplenotepad;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ixidev.simplenotepad.model.Note;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
public class ProgramActivity extends AppCompatActivity {
FloatingActionButton fab, fabChangePattern, fabexit;
RecyclerView mRecyclerViewBC;
CardsDatabaseHelper cardsDatabaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_program);
mRecyclerViewBC = findViewById(R.id.recyclerViewBC);
cardsDatabaseHelper = new CardsDatabaseHelper(this);
showRecord();
fabexit = findViewById(R.id.exitProgram);
fab = findViewById(R.id.addFabButtonBC);
fabChangePattern = findViewById(R.id.ChangePattern);
fabexit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ProgramActivity.this, MainActivity.class);
startActivity(intent);
}
});
fabChangePattern.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ProgramActivity.this, CreatePasswordActivity.class);
startActivity(intent);
}
});
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ProgramActivity.this, AddBankCardActivity.class);
intent.putExtra("BCeditMode", false);
startActivity(intent);
}
});
}
private void showRecord() {
CardAdapter cardAdapter = new CardAdapter(ProgramActivity.this, cardsDatabaseHelper.getAllBCdata(ConstantsCard.BC_C_ADD_TIMESTAMP + " DESC"));
mRecyclerViewBC.setAdapter(cardAdapter);
}
#Override
protected void onResume() {
super.onResume();
showRecord();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == event.KEYCODE_BACK) {
moveTaskToBack(true);
}
return super.onKeyDown(keyCode, event);
}
}
HERE IS MY DATABASE HELPER CLASS
package com.ixidev.simplenotepad;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class CardsDatabaseHelper extends SQLiteOpenHelper {
public CardsDatabaseHelper(#Nullable Context context) {
super(context, ConstantsCard.BC_DB_NAME, null, ConstantsCard.BC_DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(ConstantsCard.BC_CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + ConstantsCard.BC_TABLE_NAME);
onCreate(db);
}
public long insertInfo(String number, String cvv, String expiry, String image, String addTimestamp, String updateTimestamp) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ConstantsCard.BC_C_NUMBER, number);
values.put(ConstantsCard.BC_C_CVV, cvv);
values.put(ConstantsCard.BC_C_EXPIRY, expiry);
values.put(ConstantsCard.BC_C_IMAGE, image);
values.put(ConstantsCard.BC_C_ADD_TIMESTAMP, addTimestamp);
values.put(ConstantsCard.BC_C_UPDATE_TIMESTAMP, updateTimestamp);
long id = db.insert(ConstantsCard.BC_TABLE_NAME, null, values);
db.close();
return id;
}
public void updateInfo(String BCid, String number, String cvv, String expiry, String image, String addTimestamp, String updateTimestamp) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ConstantsCard.BC_C_NUMBER, number);
values.put(ConstantsCard.BC_C_CVV, cvv);
values.put(ConstantsCard.BC_C_EXPIRY, expiry);
values.put(ConstantsCard.BC_C_IMAGE, image);
values.put(ConstantsCard.BC_C_ADD_TIMESTAMP, addTimestamp);
values.put(ConstantsCard.BC_C_UPDATE_TIMESTAMP, updateTimestamp);
db.update(ConstantsCard.BC_TABLE_NAME, values, ConstantsCard.BC_C_ID + " = ?", new String[]{BCid});
db.close();
}
public void deleteInfo(String BCid) {
SQLiteDatabase db = getWritableDatabase();
db.delete(ConstantsCard.BC_TABLE_NAME, ConstantsCard.BC_C_ID + " = ? ", new String[]{BCid});
db.close();
}
public void testDelete() {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(ConstantsCard.BC_TABLE_NAME,null,null);
db.execSQL("delete from "+ ConstantsCard.BC_TABLE_NAME);
db.execSQL("TRUNCATE table " + ConstantsCard.BC_TABLE_NAME);
db.close();
}
public void delete(String BCid)
{
String[] args={BCid};
getWritableDatabase().delete("texts", "_ID=?", args);
}
public ArrayList<CardModel> getAllBCdata(String orderByBC) {
ArrayList<CardModel> ArrayListCard = new ArrayList<>();
String selectQuery = "SELECT * FROM " + ConstantsCard.BC_TABLE_NAME + " ORDER BY " + orderByBC;
SQLiteDatabase BCdb = this.getWritableDatabase();
Cursor CardCursor = BCdb.rawQuery(selectQuery, null);
if (CardCursor.moveToNext()) {
do {
CardModel cardModel = new CardModel(
""+CardCursor.getInt(CardCursor.getColumnIndex(ConstantsCard.BC_C_ID)),
""+CardCursor.getString(CardCursor.getColumnIndex(ConstantsCard.BC_C_IMAGE)),
""+CardCursor.getString(CardCursor.getColumnIndex(ConstantsCard.BC_C_NUMBER)),
""+CardCursor.getString(CardCursor.getColumnIndex(ConstantsCard.BC_C_CVV)),
""+CardCursor.getString(CardCursor.getColumnIndex(ConstantsCard.BC_C_EXPIRY)),
""+CardCursor.getString(CardCursor.getColumnIndex(ConstantsCard.BC_C_ADD_TIMESTAMP)),
""+CardCursor.getString(CardCursor.getColumnIndex(ConstantsCard.BC_C_UPDATE_TIMESTAMP))
);
ArrayListCard.add(cardModel);
} while (CardCursor.moveToNext());
}
BCdb.close();
return ArrayListCard;
}
}
HERE IS MY ADAPTER CLASS
package com.ixidev.simplenotepad;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.arch.core.executor.TaskExecutor;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.Holder> {
private Context CardContext;
private ArrayList<CardModel> CardArrayList;
CardsDatabaseHelper cardsDatabaseHelper;
public CardAdapter(Context cardContext, ArrayList<CardModel> cardArrayList) {
CardContext = cardContext;
CardArrayList = cardArrayList;
cardsDatabaseHelper = new CardsDatabaseHelper(CardContext);
}
#NonNull
#Override
public Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewBC = LayoutInflater.from(CardContext).inflate(R.layout.bc_row, parent, false);
return new Holder(viewBC);
}
#Override
public void onBindViewHolder(#NonNull Holder holder, int position) {
CardModel cardModel = CardArrayList.get(position);
final String BCid = cardModel.getBCid();
final String BCimage = cardModel.getImageBC();
final String BCnumber = cardModel.getNumber();
final String BCcvv = cardModel.getCvv();
final String BCexpiry = cardModel.getExpiryBC();
final String addTimeStampBC = cardModel.getAddTimeStampBC();
final String updateTimeStampBC = cardModel.getUpdateTimeStampBC();
holder.profileIvBC.setImageURI(Uri.parse(BCimage));
holder.number.setText(BCnumber);
holder.cvv.setText(BCcvv);
holder.expiryBC.setText(BCexpiry);
holder.editButtonBC.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editDialog(
""+position,
""+BCid,
""+BCnumber,
""+BCcvv,
""+BCexpiry,
""+BCimage,
""+addTimeStampBC,
""+updateTimeStampBC
);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
deleteDialog(
""+BCid
);
return false;
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(CardContext, "Clicked", Toast.LENGTH_SHORT).show();
cardsDatabaseHelper.testDelete();
cardsDatabaseHelper.delete(BCid);
}
});
}
private void deleteDialog(final String BCid) {
AlertDialog.Builder builderBC = new AlertDialog.Builder(CardContext);
builderBC.setTitle("Delete?");
builderBC.setMessage("Are you sure you want to delete this document?");
builderBC.setCancelable(false);
builderBC.setIcon(R.drawable.ic_action_delete);
builderBC.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
cardsDatabaseHelper.deleteInfo(BCid);
((ProgramActivity)CardContext).onResume();
Toast.makeText(CardContext, "Successfully deleted!", Toast.LENGTH_SHORT).show();
}
});
builderBC.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builderBC.create().show();
}
private void editDialog(String position, String BCid, String BCnumber, String BCcvv, String BCexpiry, String BCimage, String addTimeStampBC, String updateTimeStampBC) {
AlertDialog.Builder BCbuilder = new AlertDialog.Builder(CardContext);
BCbuilder.setTitle("Edit?");
BCbuilder.setMessage("Are you sure you want to edit this Bank Card?");
BCbuilder.setCancelable(false);
BCbuilder.setIcon(R.drawable.ic_action_edit);
BCbuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(CardContext, EditBankCardActivity.class);
intent.putExtra("BCID", BCid);
intent.putExtra("NUMBER", BCnumber);
intent.putExtra("CVV", BCcvv);
intent.putExtra("EXPIRYBC", BCexpiry);
intent.putExtra("IMAGE", BCimage);
intent.putExtra("BC_ADD_TIMESTAMP", addTimeStampBC);
intent.putExtra("BC_UPDATE_TIMESTAMP", updateTimeStampBC);
intent.putExtra("BCeditMode", true);
CardContext.startActivity(intent);
}
});
BCbuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
BCbuilder.create().show();
}
#Override
public int getItemCount() {
return CardArrayList.size();
}
class Holder extends RecyclerView.ViewHolder {
ImageView profileIvBC;
TextView number, cvv, expiryBC;
ImageButton editButtonBC;
public Holder(#NonNull View itemView) {
super(itemView);
profileIvBC = itemView.findViewById(R.id.profileIvBC);
number = itemView.findViewById(R.id.number);
cvv = itemView.findViewById(R.id.cvv);
expiryBC = itemView.findViewById(R.id.expiry);
editButtonBC = itemView.findViewById(R.id.editBtnBC);
}
}
}
HERE IS MY MODEL CLASS
package com.ixidev.simplenotepad;
public class CardModel {
String BCid, imageBC, number, cvv, expiryBC, addTimeStampBC, updateTimeStampBC;
public CardModel(String BCid, String imageBC, String number, String cvv, String expiryBC, String addTimeStampBC, String updateTimeStampBC) {
this.BCid = BCid;
this.imageBC = imageBC;
this.number = number;
this.cvv = cvv;
this.expiryBC = expiryBC;
this.addTimeStampBC = addTimeStampBC;
this.updateTimeStampBC = updateTimeStampBC;
}
public String getBCid() {
return BCid;
}
public void setBCid(String BCid) {
this.BCid = BCid;
}
public String getImageBC() {
return imageBC;
}
public void setImageBC(String imageBC) {
this.imageBC = imageBC;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getCvv() {
return cvv;
}
public void setCvv(String cvv) {
this.cvv = cvv;
}
public String getExpiryBC() {
return expiryBC;
}
public void setExpiryBC(String expiryBC) {
this.expiryBC = expiryBC;
}
public String getAddTimeStampBC() {
return addTimeStampBC;
}
public void setAddTimeStampBC(String addTimeStampBC) {
this.addTimeStampBC = addTimeStampBC;
}
public String getUpdateTimeStampBC() {
return updateTimeStampBC;
}
public void setUpdateTimeStampBC(String updateTimeStampBC) {
this.updateTimeStampBC = updateTimeStampBC;
}
}
And here is my CONSTANTS class
package com.ixidev.simplenotepad;
public class ConstantsCard {
public static final String BC_DB_NAME = "MY_BANK_CARDS";
public static final int BC_DB_VERSION = 1;
public static final String BC_TABLE_NAME = "MY_BANK_CARDS_TABLE";
public static final String BC_C_ID = "BC_ID";
public static final String BC_C_NUMBER = "BC_NUMBER";
public static final String BC_C_CVV = "BC_CVV";
public static final String BC_C_EXPIRY = "BC_EXPIRY";
public static final String BC_C_IMAGE = "BC_IMAGE";
public static final String BC_C_ADD_TIMESTAMP = "BC_ADD_TIMESTAMP";
public static final String BC_C_UPDATE_TIMESTAMP = "BC_UPDATE_TIMESTAMP";
public static final String BC_CREATE_TABLE = "CREATE TABLE " + BC_TABLE_NAME + "("
+ BC_C_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ BC_C_NUMBER + " TEXT,"
+ BC_C_CVV + " TEXT,"
+ BC_C_EXPIRY + " TEXT,"
+ BC_C_IMAGE + " TEXT,"
+ BC_C_ADD_TIMESTAMP + " TEXT,"
+ BC_C_UPDATE_TIMESTAMP + " TEXT"
+ ");";
}
I am trying to load the result of an API call into a recyclerView. I created a data model to hold the array of results (strings) to be used in populating the recyclerView Adapter. But once the JSON file is parsed, the application crashes on the call to "setValues" of the data model but the result displays accurately on the logcat.
my code is below:
MainActivity
package com.limitless.googlebooks;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.NetworkInterface;
import java.util.ArrayList;
import static android.text.TextUtils.isEmpty;
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String> {
private EditText bookImput;
private RecyclerView recyclerView;
private ProgressBar progressBar;
private static Books books;
ArrayList<Books> booksArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bookImput = findViewById(R.id.bookInput);
progressBar = findViewById(R.id.progressBar);
recyclerView = findViewById(R.id.bookRecyclerView);
booksArray = new ArrayList<>();
BooksAdapter adapter = new BooksAdapter(booksArray);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
if(LoaderManager.getInstance(this).getLoader(0) != null){
LoaderManager.getInstance(this).initLoader(0,null, this);
}
}
public void searchBooks(View view) {
String queryText = bookImput.getText().toString();
InputMethodManager methodManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if(methodManager != null){
methodManager.hideSoftInputFromWindow(view.getWindowToken(),
methodManager.HIDE_NOT_ALWAYS);
}
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = null;
if(connectivityManager != null){
networkInfo = connectivityManager.getActiveNetworkInfo();
}
if(networkInfo != null && !isEmpty(queryText) && networkInfo.isConnected()){
Bundle queryBundle = new Bundle();
queryBundle.putString("queryString", queryText);
LoaderManager.getInstance(this).restartLoader(0, queryBundle, this);
progressBar.setVisibility(View.VISIBLE);
}else {
if(isEmpty(queryText)){
Toast.makeText(this, R.string.emptyquery, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
}
}
#NonNull
#Override
public Loader<String> onCreateLoader(int id, #Nullable Bundle args) {
String queryString = "";
if(args != null){
queryString = args.getString("queryString");
}
return new BookLoader(this, queryString);
}
#Override
public void onLoadFinished(#NonNull Loader<String> loader, String data) {
try{
JSONObject jsonObject = new JSONObject(data);
JSONArray itemsArray = jsonObject.getJSONArray("items");
int i = 0;
String title = null;
String authors = null;
String publisher = null;
String date = null;
while(i < itemsArray.length() && title == null && authors == null && date == null){
JSONObject book = itemsArray.getJSONObject(i);
JSONObject volumeInfo = book.getJSONObject("volumeInfo");
try{
title = volumeInfo.getString("title");
authors = volumeInfo.getString("authors");
publisher = volumeInfo.getString("publisher");
date = volumeInfo.getString("publishedDate");
} catch (JSONException e) {
e.printStackTrace();
}
i++;
}
if(title != null && authors != null && date != null){
books.setBookName(title);
books.setAuthorsName(authors);
books.setPublisher(publisher);
books.setPublishedDate(date);
booksArray.add(books);
}else {
books.setBookName(String.valueOf(R.string.no_results));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");;
}
}catch (JSONException e){
books.setBookName(String.valueOf(R.string.error));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");
e.printStackTrace();
}
}
#Override
public void onLoaderReset(#NonNull Loader<String> loader) {
}
}
Data Model
package com.limitless.googlebooks;
public class Books {
private String bookName;
private String authorsName;
private String publisher;
private String publishedDate;
public Books(String bookName, String authorsName, String publisher, String publishedDate) {
this.bookName = bookName;
this.authorsName = authorsName;
this.publisher = publisher;
this.publishedDate = publishedDate;
}
public Books(){}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthorsName() {
return authorsName;
}
public void setAuthorsName(String authorsName) {
this.authorsName = authorsName;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
}
Adapter Class
package com.limitless.googlebooks;
import android.content.Context;
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 java.util.ArrayList;
public class BooksAdapter extends RecyclerView.Adapter<BooksAdapter.BooksHolder>{
ArrayList<Books> booksArrayList;
public BooksAdapter(ArrayList<Books> booksArray){
this.booksArrayList = booksArray;
}
#NonNull
#Override
public BooksHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
View itemView = LayoutInflater.from(context).inflate(R.layout.booklist, parent, false);
return new BooksHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull BooksHolder holder, int position) {
Books books = booksArrayList.get(position);
holder.bind(books);
}
#Override
public int getItemCount() {
return booksArrayList.size();
}
public class BooksHolder extends RecyclerView.ViewHolder {
private TextView bookName;
private TextView authorsName;
private TextView publisher;
private TextView publishedDate;
public BooksHolder(#NonNull View itemView) {
super(itemView);
bookName = itemView.findViewById(R.id.bookTitle);
authorsName = itemView.findViewById(R.id.authorsName);
publisher = itemView.findViewById(R.id.publisher);
publishedDate = itemView.findViewById(R.id.publishedDate);
}
public void bind(Books books){
bookName.setText(books.getBookName());
authorsName.setText(books.getAuthorsName());
publisher.setText(books.getPublisher());
publishedDate.setText(books.getPublishedDate());
}
}
}
In your MainActivity:
These
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String> {
....
private static Books books;
ArrayList<Books> booksArray;
Becomes:
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String> {
....
private Books books;
private ArrayList<Books> booksArray;
private BooksAdapter adapter;
In onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
........
adapter = new BooksAdapter(booksArray);
........
........
}
Now in onLoadFinished():
This:
if(title != null && authors != null && date != null){
books.setBookName(title);
books.setAuthorsName(authors);
books.setPublisher(publisher);
books.setPublishedDate(date);
booksArray.add(books);
}else {
books.setBookName(String.valueOf(R.string.no_results));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");;
}
}catch (JSONException e){
books.setBookName(String.valueOf(R.string.error));
books.setAuthorsName("");
books.setPublisher("");
books.setPublishedDate("");
e.printStackTrace();
}
Becomes:
if(title != null && authors != null && date != null){
books = new Books(title,authors,publisher,date);
booksArray.add(books);
adapter.notifyDataSetChanged();
}else {
books = new Books(String.valueOf(R.string.no_results),"","","");
//if you want to add them to array add them, if not then don't
booksArray.add(books);
adapter.notifyDataSetChanged();
}
}catch (JSONException e){
books = new Books(String.valueOf(R.string.error),"","","");
//if you want to add them to array add them, if not then don't
booksArray.add(books);
adapter.notifyDataSetChanged();
e.printStackTrace();
}
This is my MainActivity.java :
package example.com.getdata;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public static final String JSON_URL = "http://172.31.131.52:8081/application/status";
private Button buttonGet;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonGet = (Button) findViewById(R.id.button2);
}
private void sendRequest(){
StringRequest stringRequest = new StringRequest(JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.getMessage(),Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showJSON(String json) {
Product product = new Product(json);
ArrayList<JSONObject> listItems= product.parseJSON();
listView = (ListView) findViewById(R.id.list_view);
CustomList customerList = new CustomList(this,R.layout.list_view_layout,R.id.textViewName, listItems);
//customerList.notifyDataSetChanged();
listView.setAdapter(customerList);
}
public void clickHere(View v) {
sendRequest();
}
}
Product.java
package example.com.getdata;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import static com.android.volley.VolleyLog.TAG;
public class Product {
public String productName;
public String description;
public int priceInDollars;
//public int productID;
public static final String KEY_Name = "productName";
public static final String KEY_Desc = "description";
//public static final String KEY_ID= "ProductID";
public static final String KEY_Price ="priceInDollars" ;
private JSONArray users = null;
private String json;
public Product(String json){
this.json =json;
}
protected ArrayList<JSONObject> parseJSON(){
JSONArray jsonArray=null;
ArrayList<JSONObject> aList=new ArrayList<JSONObject>();
try {
jsonArray = new JSONArray(json);
Log.d("Debugging...", jsonArray.toString());
if(jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
productName = jo.getString(KEY_Name);
description = jo.getString(KEY_Desc);
priceInDollars = jo.getInt(KEY_Price);
aList.add(jsonArray.getJSONObject(i));
// productID = jo.getInt(KEY_ID);
}
return aList;
}
else {
Log.d(TAG, "parseJSON: Null condition");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
CustomList.java
package example.com.getdata;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class CustomList extends ArrayAdapter<String> {
private ArrayList<JSONObject> list;
private int vg;
private Activity context;
public CustomList(Activity context,int vg, int id, ArrayList<JSONObject> list ) {
super(context,R.layout.list_view_layout, id);
this.vg = vg;
this.context = context;
this.list=list;
// this.productID=productID;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View listViewItem = inflater.inflate(vg, parent, false);
TextView textViewName = (TextView) listViewItem.findViewById(R.id.textViewName);
TextView textViewDescription = (TextView) listViewItem.findViewById(R.id.textViewDescription);
TextView textViewPrice = (TextView) listViewItem.findViewById(R.id.textViewPrice);
// TextView textViewID = (TextView) listViewItem.findViewById(R.id.textViewID);
try {
textViewName.setText(list.get(position).getString("productName"));
textViewDescription.setText(list.get(position).getString("description"));
textViewPrice.setText(list.get(position).getString("priceInDollars"));
}
catch (JSONException e) {
e.printStackTrace();
}
// textViewID.setText(productID);
return listViewItem;
}
}
I have tried and searched for answers online and I am still not able to figure out the problem. I am unable to see the list of objects. Through debugging, I am sure that the objects are read into the json objects, still I am not able to display the objects in a listView.
Any help is appreciated.
You need to crate constructor with all variables of Product class and put all values in Product class object and add into ArrayList .
See Product Class :
public class Product {
public String productName;
public String description;
public int priceInDollars;
//public int productID;
public static final String KEY_Name = "productName";
public static final String KEY_Desc = "description";
//public static final String KEY_ID= "ProductID";
public static final String KEY_Price ="priceInDollars" ;
private JSONArray users = null;
private String json;
public Product(String productName, String json, JSONArray users, int priceInDollars, String description) {
this.productName = productName;
this.json = json;
this.users = users;
this.priceInDollars = priceInDollars;
this.description = description;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static String getKEY_Name() {
return KEY_Name;
}
public static String getKEY_Price() {
return KEY_Price;
}
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
public JSONArray getUsers() {
return users;
}
public void setUsers(JSONArray users) {
this.users = users;
}
public static String getKEY_Desc() {
return KEY_Desc;
}
public int getPriceInDollars() {
return priceInDollars;
}
public void setPriceInDollars(int priceInDollars) {
this.priceInDollars = priceInDollars;
}
}
And When your are parsing your data you need to change like below code:
protected ArrayList<Product> parseJSON(){
JSONArray jsonArray=null;
ArrayList<Product> aList=new ArrayList<Product>();
try {
jsonArray = new JSONArray(json);
Log.d("Debugging...", jsonArray.toString());
if(jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
String productName = jo.optString(KEY_Name);
String description = jo.optString(KEY_Desc);
String priceInDollars = jo.optInt(KEY_Price);
Product product = new Product(productName,json,
jsonArray.getJSONObject(i),priceInDollars,description);
aList.add(product);
// productID = jo.getInt(KEY_ID);
}
return aList;
}
else {
Log.d(TAG, "parseJSON: Null condition");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
Also you need to change in Adapter class where you have passes ArrayList<JsonArray> in this case you have to pass ArrayList<Product>.
You missed
#override
public int getCount()
{
return list.size();
}
and make sure you either "setAdapter" on your listview after getting the json or call "notifydatasetchanged" method
Use
super(context,R.layout.list_view_layout, list);
instead of
super(context,R.layout.list_view_layout, id);
Make sure getCount() is properly implemented in Adapterclass:
#Override
public int getCount(){
return list.size();
}
Extend the CustomList class as:
type JSONObject
instead of
type String