MikeOx
MikeOx

Reputation: 177

How update UI (ListView) when DB data recieved or button pressed

I have a ListView that represents an order list, and a listAdapter that sets recieved data from DB to the listView, and I want to dynamically do:

*(with paint I mean setBackground color of item)

**(Order have an attribute "state" to know if they are Started or not)

Currently I'm doing this only when buttons are pressed, and I want to also update UI and repaint items when orders are received and if one order is started paint it

some code of OrdersActivity:

private void updateOrders() {
        if (!listItemIsSelected) {
            orderAdapter.clear();
            orderAdapter.notifyDataSetChanged();
            populateListView();
        } else {
            debugLog("item is selected, list not updated");
        }
    }
    
    private void populateListView() {
        try {
            // Read items from server
            Log.d("LSO", "Reading from Database");
            ListObtainer listObtainer = new ListObtainer(this);
            listObtainer.getTmOfsDTOList(user, orderAdapter); // this method returns list of objects from DB and populates adapter
        } catch (Exception e) {
            e.printStackTrace();
        }
        configureAdapter();
    }

    private void configureAdapter() {

    // Configure listview
    listView = (ListView) findViewById(R.id.lvOrdenes);
    listView.setAdapter(orderAdapter);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            try {
                OrderRO orderRO = (OrderRO) parent.getItemAtPosition(position);
                listItemIsSelected = true;
                lastChildSelected = currentChildSelected;
                currentChildSelected = (View) listView.getChildAt(position);
                uptadteUI();

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    });
}
private void uptadteUI() {

    try {

        if (lastChildSelected != null) {
            lastChildSelected.setBackgroundColor(getResources().getColor(R.color.transparent));
        }
        if (orderIsStarted) {  // Block scroll, disable start, paint item
            disableIniciarOrden();
            disableBotonSalir();
            enableTerinarOrden();
            currentChildSelected.setBackgroundColor(getResources().getColor(R.color.light_orange));
            listView.setEnabled(false);
        } else {// if there is no started order
            listView.setEnabled(true);
            enableBotonSalir();
            disableTerminarOrden();
            if (listItemIsSelected) {  // enable start, paint item
                enableIniciarOrden();
                currentChildSelected.setBackgroundColor(getResources().getColor(R.color.light_green));
            }
        }
    } catch (Exception e) {
        Log.e("error", "error updating UI" + e);
    }
}

   public class UpdateOrdersAsync extends AsyncTask {
        @Override
        protected Object doInBackground(Object[] params) {
            while (updateService == true) {
                try {
                    Thread.sleep(180000);

                } catch (InterruptedException e) {
                    e.printStackTrace();

                }
                publishProgress();

            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Object[] values) {
            //super.onProgressUpdate(values);
            debugLog(". . . calling list update");
            updateOrders();
        }
    }

This looks to me very dirty and I have a problem: if the DB changed and Adapter is updated I can receive an Order already started and I don't know how to paint it from activity, I'm new using custom adapters and I'm confused on what I should do, I can paint the started orders directly in adapter but this breaks the logic I already did in activity(posted code) because I don't know from the activity which orders are started(check the attribute of one item from activity).

Sorry if the question is difficult to understand or poorly explained, It's difficult to me to transmit my problem

Upvotes: 0

Views: 106

Answers (4)

Khalid Taha
Khalid Taha

Reputation: 3313

first, you have to fill the data source that ListView gets the data from, and then, call the method:

listView.getAdapter().notifyDataSetChanged();

then the list will get all the new data filled in the data source

Upvotes: 0

Ricardo Vieira
Ricardo Vieira

Reputation: 1818

So, you want to update the list of items on a ListView when you receive more information, correct? I have modified your code a bit to enhance readability.

Lets say you have a list with the items :

List<Items> listItems = new List<Items>;
listItems.add(item1);
listItems.add(item2);
listItems.add(item3);

with an adapter associated to it. Then you just associated the adapter to your listView like :

ArrayAdapter<String> orderAdapter = new ArrayAdapter<String>(this,android.R.layout.listem_item, listItems);
listView.setAdapter(orderAdapter);

Now you have all your items. Lets say those items change like this :

listItems.remove(item1); // you remove item1
listItems.add(item4); // and you add item4

Now you want to inform the adapter that you have changed the base data.
You can do it like :

listView.getAdapter().notifyDataSetChanged();

What I strongly recommend is that you associate the background color to the Model instace of the row instead of the its view. This way, if the view gets re-drawn, the information will still be store inside the Model.

public class OrderRo
    ...
    String color = "red";
    boolean isOrderStarted = false;
    ...

    ...
    public boolean isOrderStarted(){
        return isOrderStarted;
    }

    public void setIsOrderStarted(boolean isOrderStarted){
        this.isOrderStarted = isOrderStarted;
    }

    public String getColor(){
        return this.color;
    }

    public void setColor(String color){
        this.color = color;
    }
    ....

and

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            try {
                OrderRO orderRO = listView.getAdapter().getItem(position);
                orderRO.setColor("orange");
                orderRO.setIsOrderStarted(true);
                uptadteUI(orderRO, (View) listView.getChildAt(position));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
private void uptadteUI(OrderRO order, View selectChild) {
    try {
        if (selectChild != null) {
            selectChild.setBackgroundColor(getResources().getColor(R.color.transparent));
        }
        if (order.isOrderStarted()) {  // Block scroll, disable start, paint item
            disableIniciarOrden();
            disableBotonSalir();
            enableTerminarOrden();
            selectChild.setBackgroundColor(getResources().getColor(R.color.light_orange));
            listView.setEnabled(false);
        } else {// if there is no started order
            listView.setEnabled(true);
            enableBotonSalir();
            disableTerminarOrden();
            if (listItemIsSelected) {  // enable start, paint item
                enableIniciarOrden();
                selectChild.setBackgroundColor(getResources().getColor(R.color.light_green));
            }
        }
    } catch (Exception e) {
        Log.e("error", "error updating UI" + e);
    }
}

Upvotes: 1

faranjit
faranjit

Reputation: 1637

Add status attribute to OrderRO class like started, pressed etc. In your adapter, where inflate the listview items check this status and set view color. On onItemClick method change item status and call adapter.notifyDataSetChanged().

Upvotes: 0

Jake
Jake

Reputation: 26

I think you should keep state in your OrderRO class.And when state is changed,call notifyDataSetChanged.In getView method,paint view with different colors according to the state in OrderRO.

Upvotes: 0

Related Questions