ArrayAdapter and ViewGroup.GetChildAt not working properly

0

I have a Listview with a custom layout for each row. The custom layout consists of a LinearLayout, having two other LinearLayouts as children (L1 and L2). L1 contains the basic information of the row while L2 contains visual signals which provide relevant information to the user. The end result looks like this:

ListView Layout

The colourful squares are simple TextViews that have a drawable object set as backgroud. The L2 xml looks like this:

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/hasReceipt"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:background="@drawable/blank" />

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/warehouseMonitor"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:background="@drawable/blank" />


    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swapDeliver"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:background="@drawable/blank" />

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swapReturn"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:background="@drawable/blank" />

The condition for "lighting up" a signal is checked in the overriden getView function of the ArrayAdapter. The appropriate View is cast from the ViewGroup hierarchy as shown in the example below:

 public View getView(int position, View convertView, ViewGroup parent) {

    View view = super.getView(position, convertView, parent);
    ViewGroup mainViewGroup = (ViewGroup) view;
    ViewGroup visualSignalsGroup = (ViewGroup) mainViewGroup.getChildAt(1); // L2

    TextView tvOrder = (TextView) visualSignalsGroup.getChildAt(0);
    TextView tvPayment = (TextView) visualSignalsGroup.getChildAt(1);
    TextView tvReceipt = (TextView) visualSignalsGroup.getChildAt(3);
    TextView tvWarehouseMonitor = (TextView) visualSignalsGroup.getChildAt(4);
    TextView tvSwapDeliver = (TextView) visualSignalsGroup.getChildAt(5);
    TextView tvSwapReturn = (TextView) visualSignalsGroup.getChildAt(6);

    if (checkCondition(position)){
        tvReceipt.setBackgroundDrawable(hasReceipt);
    } else {
        tvReceipt.setBackgroundDrawable(blank);
    }

}

If I want to add more visual signals, I add more TextViews in L2 and calling getChildAt with the appropriate index. Everything works well up to index 5. The light blue signal on the right in the picture, is index 6. The condition for lighting it up is true only for the first row. While debbuging, the breakpoint is hit only for the first row. As you can see, it is visible in other rows as well and I really cannot explain this behaviour as the default state is "blank" and the breakpoint is only hit once.

I paste below the full code of the array adapter:

public class StableArrayAdapter extends DArrayAdapter {


HashMap<String, Customers.Customer> mcusMap = new HashMap<String, Customers.Customer>();
Context context = getContext();

static Customers customers;
public static ArrayList<String> customerNames;


Drawable order = context.getResources().getDrawable(R.drawable.order);
Drawable paymentCompleted = context.getResources().getDrawable(R.drawable.payment_completed);
Drawable blank = context.getResources().getDrawable(R.drawable.blank);
Drawable hasReceipt = context.getResources().getDrawable(R.drawable.has_receipt);
Drawable warehouseMonitor = context.getResources().getDrawable(R.drawable.warehouse_monitor);
Drawable swapDeliver = context.getResources().getDrawable(R.drawable.swap_deliver);
Drawable swapReturn = context.getResources().getDrawable(R.drawable.swap_return);


public StableArrayAdapter(Context context, int listViewLayout, int textViewID, ArrayList<String> customerNames) {
    super(context, listViewLayout, textViewID, customerNames);
    customers = Customers.getCustomers(context);
    StableArrayAdapter.customerNames = customers.customerNames;
    int i = 0;
    for (Customers.Customer customer : customers.list.values()) {
        mIdMap.put(customer.name, i);
        mcusMap.put(customer.name, customer);
        i++;
    }

}


private static ArrayList<String> init() {
    ArrayList<String> customerNames = new ArrayList<String>();
    Object[] customerArray = customers.list.values().toArray();
    for (Object customer : customerArray) {
        customerNames.add(((Customers.Customer) customer).name);
    }
    StableArrayAdapter.customerNames = customerNames;
    return customerNames;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);
    ViewGroup mainVewGroup = (ViewGroup) view;
    ViewGroup vgRowTextViewGroup = (ViewGroup) mainVewGroup.getChildAt(0);
    ViewGroup visualSignalsGroup = (ViewGroup) mainVewGroup.getChildAt(1);

    TextView rowText = (TextView) vgRowTextViewGroup.getChildAt(0);


    TextView tvOrder = (TextView) visualSignalsGroup.getChildAt(0);
    TextView tvPayment = (TextView) visualSignalsGroup.getChildAt(1);
    TextView tvReceipt = (TextView) visualSignalsGroup.getChildAt(3);
    TextView tvWarehouseMonitor = (TextView) visualSignalsGroup.getChildAt(4);
    TextView tvSwapDeliver = (TextView) visualSignalsGroup.getChildAt(5);
    TextView tvSwapReturn = (TextView) visualSignalsGroup.getChildAt(6);

    Customers.Customer customer = mcusMap.get(customerNames.get((position)));

    if (customer.longitude == 0 || customer.latitude == 0) {
        rowText.setBackgroundColor(0xfffface4);
    } else {
        rowText.setBackgroundColor(0xffffffff);
    }

    if (customer.hasOrders) tvOrder.setBackgroundDrawable(order);
    else tvOrder.setBackgroundDrawable((blank));


    if (Routing.Current != null && Routing.Current.trdrLines.containsKey(Integer.parseInt(mcusMap.get(customerNames.get(position)).trdr))) {
        RoutingTrdrLine line = Routing.Current.trdrLines.get(Integer.parseInt(mcusMap.get(customerNames.get(position)).trdr));
        if (line.paymentStatus > 0) {
            tvPayment.setBackgroundDrawable(paymentCompleted);
        } else {
            tvPayment.setBackgroundDrawable(blank);
        }

        if (line.receipt > 0 && line.receiptPayment == 0) {
            tvReceipt.setBackgroundDrawable(hasReceipt);
        } else {
            tvReceipt.setBackgroundDrawable(blank);
        }

        if (line.warehouseMonitorObject != null && line.warehouseMonitorObject.WarehouseMonitorStatus == 0) {
            tvWarehouseMonitor.setBackgroundDrawable(warehouseMonitor);
        } else {
            tvWarehouseMonitor.setBackgroundDrawable(blank);
        }

        if (line.swapDeliverItems != null) {
            Boolean delivered = false;
            for (SwapDeliverItem item :
                    line.swapDeliverItems) {
                if (item.Delivered == 1) {
                    delivered = true;
                    break;
                }
            }

            if (!delivered) {
                tvSwapDeliver.setBackgroundDrawable(swapDeliver);
            } else {
                tvSwapDeliver.setBackgroundDrawable(blank);
            }
        }

        if (line.swapReturnItems != null) {
            Boolean returned = false;
            for (SwapReturnItem item :
                    line.swapReturnItems) {
                if (item.Returned == 1) {
                    returned = true;
                    break;
                }
            }

            if (!returned) {
                tvSwapReturn.setBackgroundDrawable(swapReturn);
            } else {
                tvSwapReturn.setBackgroundDrawable(blank);
            }
        }

    } else {
        tvPayment.setBackgroundDrawable(blank);
    }

    //todo change view depending on


    return view;
}

}

android
asked on Stack Overflow Mar 27, 2020 by Saloom • edited Mar 28, 2020 by Saloom

1 Answer

1

These if statements do not have an else case that resets the state of what they set:

if (line.swapDeliverItems != null) {
if (line.swapReturnItems != null) {

The state of the TextViews is only reset if the field is non-null - it should always be reset.

answered on Stack Overflow Mar 28, 2020 by Ryan M • edited Mar 28, 2020 by Ryan M

User contributions licensed under CC BY-SA 3.0