'How to update listview in Fragment with custom adapter

I am giving product id with barcode scanner. I can add product to listView but when i try to increase or decrease amount of the product. It doesn't update UI. I used Toast message to see weather list is updated, it updates list but doesn't update UI

I have tried to use runOnUiThread() but i couldn't find any solution. How to update UI can you please help me

custom_lisView_row

BaseActivity which keeps MainFragment on it

public class BaseActivity extends AppCompatActivity {

    public static final String MAIN_FRAGMENT = "mainFragment";
    public static final String PRODUCTS = "products";

    FragmentManager fragmentManager;

    Dialog dialog ;

    public static ArrayList<MyProduct>  myProductList = new ArrayList<>();
    public static MyTablet myTablet = new MyTablet();

    Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);

        //Initialize fragment manager
        fragmentManager = getSupportFragmentManager();
  
        fragmentManager.beginTransaction().replace(R.id.fl_BaseActivity, new MainFragment()).commit();

        //Create database
        mDatabase = FirebaseDatabase.getInstance().getReference();

        dialog = new Dialog(this);

        //Runs when i enter product id
        initScanner();
    }

    public void updateMyProductList(MyProduct myProduct){

        for(int i= 0 ; i< myProductList.size() ; i++ ){

            MyProduct temp = myProductList.get(i);

            if (temp.getId().equals(myProduct.getId())) {
                temp.setAmount(temp.getAmount() + myProduct.getAmount());
                myProductList.set(i, temp);
                return;
            }
        }
        myProductList.add(myProduct);
        updateMainFragment();
    }

    private void initScanner() {
      
      mDatabase.child(PRODUCTS).child(finalData).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
          @Override
          public void onComplete(@NonNull Task<DataSnapshot> task) {

              MyProduct myProduct = task.getResult().getValue(MyProduct.class);
              myProduct.setAmount(1);
              dialog.setContentView(R.layout.custom_product_dialog);
              dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
              dialog.setCancelable(false);

              
              TextView tv_addBasket_product_dialog = dialog.findViewById(R.id.tv_addBasket_product_dialog);
            

              tv_addBasket_product_dialog.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      updateMyProductList(myProduct);
                      dialog.dismiss();
                  }
              });

              dialog.show();
          }
      };
    }
    public void updateMainFragment() {
        if (isExist(MAIN_FRAGMENT)) {
            Fragment fragment = findFragment(MAIN_FRAGMENT);

            ((MainFragment) fragment).updateMyList();
        }

    }

    //Add fragments to BaseActivity
    public void addFragments(Fragment fragment, String tag) {

        fragmentManager.beginTransaction().add(R.id.fl_BaseActivity, fragment, tag).commit();
    }
    //Replace fragments to BaseActivity
    public void replaceFragments(Fragment fragment, String tag) {

        fragmentManager.beginTransaction().replace(R.id.fl_BaseActivity, fragment, tag).commit();
    }

    //Remove fragment from BaseActivity
    public void removeFragment(String tag) {

        Fragment fragmentB = fragmentManager.findFragmentByTag(tag);
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (fragmentB != null) {
            fragmentTransaction.remove(fragmentB);
            fragmentTransaction.commit();
        }
    }

    // finds fragment and returns it
    // It may return null first check fragment is exist. use isExist() method
    public Fragment findFragment(String tag) {
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        return fragment;
    }

    //Check fragment exist in BaseActivity
    public boolean isExist(String tag) {
        Fragment fragmentB = fragmentManager.findFragmentByTag(tag);
        if (fragmentB != null) {
            return true;
        }
        return false;
    }

}

MainFragment

public class MainFragment extends Fragment {
    
    ListView lv_MainFragment;

    public MyProductListAdapter myListAdapter;
    public static ArrayList<MyProduct>  myProductList;

    Activity mActivity;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        mActivity = getActivity();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myProductList = BaseActivity.myProductList;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);

        lv_MainFragment = view.findViewById(R.id.lv_MainFragment);

        myListAdapter = new MyProductListAdapter(mActivity.getApplicationContext(), R.layout.custom_product_list_row, myProductList);
        lv_MainFragment.setAdapter(myListAdapter);


        return view;
    }

    public void updateMyList() {

        myProductList = BaseActivity.myProductList;
        myListAdapter.notifyDataSetChanged();

    }

}

MyProductListAdapter

public class MyProductListAdapter extends ArrayAdapter<MyProduct> {


    private Context mContext;
    private ArrayList<MyProduct> list;

  
    AppCompatButton acb_DecreaseAmount_productListRow, acb_IncreaseAmount_productListRow;


    public MyProductListAdapter(Context context, int resource, ArrayList<MyProduct> objects) {
        super(context, resource, objects);

        this.mContext = context;
        this.list = objects;
    }

    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View view = convertView;

        if (view == null) {

            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.custom_product_list_row, parent, false);

        
            tv_ProductAmount_productListRow = view.findViewById(R.id.tv_ProductAmount_productListRow);
        
            acb_DecreaseAmount_productListRow = view.findViewById(R.id.acb_DecreaseAmount_productListRow);
            acb_IncreaseAmount_productListRow = view.findViewById(R.id.acb_IncreaseAmount_productListRow);

            tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));

            acb_IncreaseAmount_productListRow.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    double productPrice = list.get(position).getPrice();
                    int productAmount = list.get(position).getAmount();
                    productAmount++;

                    list.get(position).setAmount(productAmount);

                    Toast.makeText(mContext, String.valueOf(productAmount), Toast.LENGTH_SHORT).show();

                    tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
                }
            });

            acb_DecreaseAmount_productListRow.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    int productAmount = list.get(position).getAmount();

                    if (productAmount > 1) {
                        double productPrice = list.get(position).getPrice();

                        productAmount--;

                        list.get(position).setAmount(productAmount);

                        Toast.makeText(mContext, String.valueOf(productAmount), Toast.LENGTH_SHORT).show();

                        tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));      
                    }
                }
            });

        }

        return view;
    }

}



Solution 1:[1]

Hej Metehan,

your use case sounds perfect for a RecyclerView with a ListAdapter. You just submit a new list of products to the adapter and it will handle the updating and notifying for you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Daniel Knauf