Shajeel Afzal
Shajeel Afzal

Reputation: 5953

How to get the width of each child contained in the list_item using ArrayAdapter

I am creating a ListView which has some some static headers as shown in the following picture:

enter image description here

I want that the header columns (Date, Status, Latitude, and Longitude) adapts their width according to the width of their according column.

What i am trying is to get the Layout of the list item associated with the adapter so that i can find the width of its childs (but it seems to be impossible) in my ListActivity.

then i have tried in my custom ArrayAdapter's getView method to retrieve the width of each TextView associated with the list item as shown in the following code: (But it returns null, I think it can not return width before redering the textView.)

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    DispatchHolder holder = null;
    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new DispatchHolder();
        holder.tvcurrentDateTime = (TextView) row
                .findViewById(R.id.tvCurrentDateTimeLog);
        holder.tvAction = (TextView) row.findViewById(R.id.tvActionLog);
        holder.tvLatitude = (TextView) row.findViewById(R.id.tvlatitudeLog);
        holder.tvLongitude = (TextView) row
                .findViewById(R.id.tvlogitudeLog);

        row.setTag(holder);
    } else {
        holder = (DispatchHolder) row.getTag();
    }
    holder.tvcurrentDateTime.setText(data.get(position).getTime());
    int i = holder.tvcurrentDateTime.getWidth()    <------- Here it is return 0
    holder.tvAction.setText(data.get(position).getAction());
    holder.tvLatitude.setText(data.get(position).getLatitude());
    holder.tvLongitude.setText(data.get(position).getLogitude());

    return row;
}

I have searched on it but i could not find a way to do so.

Here is the related code:

My ListActivity:

public class Activity_Log extends ListActivity {

PickupStatusDao puDao;
LogAdapter adapter;
List<LogModel> listOfDispatch;
private Object mItem;
private View childView;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_log_xml);

    puDao = new PickupStatusDao(this);
    List<LogModel> lstResult = puDao.readAllLogData();
    adapter = new LogAdapter(this, R.layout.log_item_row, lstResult);

    setListAdapter(adapter);

}

}

My list_item (R.layout.log_item_row):

<?xml version="1.0" encoding="utf-8"?>

<TableLayout
    android:id="@+id/BodyTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TableRow
        android:id="@+id/tableRow2"
        style="@style/BodyRow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/tvCurrentDateTimeLog"
            style="@style/BodyText"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="this time"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tvActionLog"
            style="@style/BodyText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="this is action"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tvlogitudeLog"
            style="@style/BodyText"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="logitude"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tvlatitudeLog"
            style="@style/BodyText"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="latuide"
            android:textSize="20sp" />
    </TableRow>
</TableLayout>

List Activity Layout (R.layout.activity_log_xml)

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TableLayout
        android:id="@+id/HeaderTable"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TableRow style="@style/HeaderRow" >

            <TextView
                style="@style/HeaderText"
                android:layout_width="239dp"
                android:text="Date" />

            <TextView
                style="@style/HeaderText"
                android:layout_width="156dp"
                android:text="Status" />

            <TextView
                style="@style/HeaderText"
                android:layout_width="121dp"
                android:text="Latitude" />

            <TextView
                style="@style/HeaderText"
                android:layout_width="121dp"
                android:text="Longitude" />
        </TableRow>
    </TableLayout>

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </ListView>

</LinearLayout>

Upvotes: 0

Views: 1311

Answers (2)

Shajeel Afzal
Shajeel Afzal

Reputation: 5953

I have achieved this by XML android:layout_weight property, it works on all android devices with different densities, Here is the updated UI picture:

enter image description here

the updated XML of ListActivity (activity_log_xml.xml) and for list_item (log_item_row.xml) are as follows respectively:

<?xml version="1.0" encoding="utf-8"?>

<TableLayout
    android:id="@+id/HeaderTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TableRow
        style="@style/HeaderRow"
        android:weightSum="10" >

        <TextView
            android:id="@+id/dateHeaderTV"
            style="@style/HeaderText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:text="Date" />

        <TextView
            android:id="@+id/statusHeaderTV"
            style="@style/HeaderText"
            android:layout_width="0dp"
            android:layout_weight="4"
            android:text="Status" />

        <TextView
            android:id="@+id/latitudeHeaderTV"
            style="@style/HeaderText"
            android:layout_width="0dp"
            android:layout_weight="1.5"
            android:text="Latitude" />

        <TextView
            android:id="@+id/longitudeHeaderTV"
            style="@style/HeaderText"
            android:layout_width="0dp"
            android:layout_weight="1.5"
            android:text="Longitude" />
    </TableRow>
</TableLayout>

<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" >
</ListView>


<?xml version="1.0" encoding="utf-8"?>

<TableLayout
    android:id="@+id/BodyTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TableRow
        android:id="@+id/tableRow2"
        style="@style/BodyRow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="10" >

        <TextView
            android:id="@+id/tvCurrentDateTimeLog"
            style="@style/BodyText"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:text="this time" />

        <TextView
            android:id="@+id/tvActionLog"
            style="@style/BodyText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:text="this is action" />

        <TextView
            android:id="@+id/tvlogitudeLog"
            style="@style/BodyText"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.5"
            android:text="logitude" />

        <TextView
            android:id="@+id/tvlatitudeLog"
            style="@style/BodyText"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.5"
            android:text="latuide" />
    </TableRow>
</TableLayout>

Upvotes: 1

Kevin Coppock
Kevin Coppock

Reputation: 134684

Unfortunately, this just isn't something you can do efficiently with an AdapterView. Since they tie together an arbitrarily long data source, but only display a small subset of the data at any one time, there is no efficient way to determine what the maximum width of the data will be without measuring a view for each piece of data.

I would suggest maybe doing some work when initializing the data source to find the average length of the text that will be displayed, and setting each column to some value that makes sense for the data. Or, just use the same values for each column (be that some combination of layout_weights or some hardcoded values).

Upvotes: 1

Related Questions