First of all, I am completefy noob to android development and I am making this project for my college where I display items in a Recycler view, each Item has a delete button and it updates the product quantity, reloads the recycer view.
The recycler view is getting displayed the problem is with refreshing it when a item is deleted.
Adapter Class
public class ProductAdaptar extends RecyclerView.Adapter<ProductAdaptar.ProductAdaptarVH> {
private List<UserLoginResp> productListItems;
private Context context;
public ProductAdaptar() {
}
public void setData(List<UserLoginResp> productListItems) {
this.productListItems = productListItems;
notifyDataSetChanged();
}
@NonNull
@Override
public ProductAdaptarVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
return new ProductAdaptar.ProductAdaptarVH(LayoutInflater.
from(context).inflate(R.layout.row_products,parent,false));
}
@Override
public void onBindViewHolder(@NonNull ProductAdaptarVH holder, int position) {
UserLoginResp userLoginResp = productListItems.get(position);
String pName = userLoginResp.getProductName();
Log.e("Pname","" pName);
String pQuan = userLoginResp.getQuantity();
Log.e("Pquan","" pQuan);
String pPrice = userLoginResp.getProductPrice();
Log.e("Pprice","" pPrice);
String pBarcode = userLoginResp.getProductID();
Log.e("PBarcode","" pBarcode);
String userID = userLoginResp.getUserID();
Log.e("userid","" userID);
holder.pName.setText(pName);
holder.pQuan.setText(pQuan);
holder.pPrice.setText(pPrice);
holder.delProdcut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
delProduct(userID,pBarcode);
}
});
}
public void delProduct(String userID, String pBarcode){
Call<String> res = ApiClient.getUserPageService().deleteProduct(pBarcode,userID);
res.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful()){
new UserPage().getAllProducts(userID);
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("deletefailed","" t);
new UserPage().getAllProducts(userID);
}
});
}
@Override
public int getItemCount() {
return productListItems.size();
}
public static class ProductAdaptarVH extends RecyclerView.ViewHolder {
TextView pName;
TextView pQuan;
TextView pPrice;
Button delProdcut;
public ProductAdaptarVH(@NonNull View itemView) {
super(itemView);
pName=itemView.findViewById(R.id.pName);
pQuan=itemView.findViewById(R.id.pQuantity);
pPrice=itemView.findViewById(R.id.pPrice);
delProdcut=itemView.findViewById(R.id.delProduct);
}
}
}
User Page Activity
public class UserPage extends AppCompatActivity implements ProductAdaptar.deleteProduct {
Toolbar toolbar;
RecyclerView recyclerView;
String rfidNo;
ProductAdaptar productAdaptar;
Call<List<UserLoginResp>> productList;
List<UserLoginResp> productListsItems = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_page);
toolbar=findViewById(R.id.toolbar);
recyclerView=findViewById(R.id.recyclerview);
LinearLayoutManager manager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
productAdaptar = new ProductAdaptar(this::delProduct);
Intent intent =getIntent();
if(intent.getExtras()!=null){
rfidNo= intent.getStringExtra("rfid");
}
getAllProducts(rfidNo);
}
public void getAllProducts(String rfidno){
productAdaptar = new ProductAdaptar();
productList= ApiClient.getUserPageService().getCartItems(rfidno);
productList.enqueue(new Callback<List<UserLoginResp>>() {
@Override
public void onResponse(Call<List<UserLoginResp>> call, Response<List<UserLoginResp>> response) {
if (response.isSuccessful()) {
productListsItems = response.body();
productAdaptar.setData(productListsItems);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setAdapter(productAdaptar);
}
}
@Override
public void onFailure(Call<List<UserLoginResp>> call, Throwable t) {
Log.e("listfailed",t.getLocalizedMessage());
}
});
}
@Override
public void delProduct(UserLoginResp userLoginResp) {
Log.e("delted prodcut", userLoginResp.toString());
}
}
So, the api is working perfectly, the DB is getting updated the problem is that the Recycler View is failing to get refreshed, since I am calling the delProduct()
function which in turn calls the getAllProducts()
from Userpage Activity
its failing to refresh it.
The recycler view is getting displayed the problem is with refreshing it when a item is deleted.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.shopeasy, PID: 27509
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:159)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
at android.content.Context.obtainStyledAttributes(Context.java:675)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:842)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:809)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:633)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:259)
at com.example.shopeasy.UserPage$1.onResponse(UserPage.java:67)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$retrofit2-DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$$ExternalSyntheticLambda1.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:874)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:198)
at android.app.ActivityThread.main(ActivityThread.java:6729)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I am complete new to android coding so I can't seem to find a way to fix it.
CodePudding user response:
NEVER create an instance of an activity yourself.
Replace:
private Context context;
public ProductAdaptar() {
}
with:
private UserPage context;
public ProductAdaptar(UserPage activity) {
context = activity;
}
Then, replace all occurrences of new UserPage()
with context
, such as:
public void delProduct(String userID, String pBarcode){
Call<String> res = ApiClient.getUserPageService().deleteProduct(pBarcode,userID);
res.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful()){
context.getAllProducts(userID);
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("deletefailed","" t);
context.getAllProducts(userID);
}
});
}
Also, delete:
context = parent.getContext();
...and replace your call to the ProductAdaptar
constructor with one that takes the UserPage
activity as a parameter:
productAdaptar = new ProductAdaptar(this);