Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WANTED: TableLayout-Like ListView

My question might be, "How does one create a single-line horizontal LinearLayout with two single-line non-wrapping TextViews, where the left TextView always occupies 1/3 of the available screen width, the right TextView always occupies 2/3 of the available screen width, and the text labels truncate with ... when they are too long to display?" (If that question is clear enough and the reader -- that's you -- already has in mind a solution they are willing to share, further reading of the problem and question description may be unnecessary.)

A ListView populated with four such LinearLayouts would then look something like this:

medium length text ---- short text
short text         ---- text that is too loooooooooooooo...
loooooooooooooo... ---- short text
loooooooooooooo... ---- text that is too loooooooooooooo...
In this mock-up, in the first row, the left and right text labels were short enough to display completely, in the second row, the left label was short enough to display completely, while the text of the right label was too long and was thus truncated, and the start of the text of the right label aligned vertically with the right text of the first row, visually creating a column as if this were in a TableLayout, in the third row, the text of the left label was too long and was truncated so as to vertically align with the left text of the second and first rows, and the text of the right label started vertically aligned with the right text of the second and first rows, and in the fourth row, the text of the left label was too long and thus was displayed similarly to the left text of the third row, and the text of the right label was too long and thus was displayed similarly to the right text of the second row.

From various posts on stackoverflow and other places, I gather that while using a TableLayout with an ArrayAdapter is somewhat possible, there are downsides, and it is probably not ever the right approach to take.

I've certainly tried many combinations of layout parameters, but nothing has yet come very close to the goal. I'm trying to figure out a solution that will work on many different screen sizes, so specifying specific pixel widths probably wouldn't work very well.

Perhaps the following simple code example (with screenshot) is a good starting point for the solution, and just needs some small modifications.

(The stackoverflow code formatter was freaking out about this code. So, please forgive any funky formatting.)

public class TableLayoutLikeListView extends ListActivity
{
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list);

    List<Datum> data = new ArrayList<Datum>();
    data.add(new Datum("short", "short"));
    data.add(new Datum("short", "loooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnng"));
    data.add(new Datum("loooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnng", "short"));
    data.add(new Datum("loooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnng",
        "loooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnng"));
    setListAdapter(new MyAdapter(this, R.layout.row, data));
  }
}
class Datum
{
  String left, right;

  Datum(String left, String right)
  {
    this.left = left;
    this.right = right;
  }
}

class MyAdapter extends ArrayAdapter<Datum>
{
  List<Datum> data;
  int textViewResourceId;

  MyAdapter(Context context, int textViewResourceId, List<Datum> data)
  {
    super(context, textViewResourceId, data);
    this.data = data;
    this.textViewResourceId = textViewResourceId;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent)
  {
    if (convertView == null)
    {
      LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      convertView = inflater.inflate(textViewResourceId, null);
    }
    Datum datum = data.get(position);
    if (datum != null)
    {
      TextView leftView = (TextView) convertView.findViewById(R.id.left);
      TextView rightView = (TextView) convertView.findViewById(R.id.right);
      if (leftView != null)
      {
        leftView.setText(datum.left);
      }
      if (rightView != null)
      {
        rightView.setText(datum.right);
      }
    }
    return convertView;
  }
}

list.xml: 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ListView
        android:id="@+id/android:list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:weightSum="3">
    <TextView
        android:id="@+id/left"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:singleLine="true" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="----" />
    <TextView
        android:id="@+id/right"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:singleLine="true" />
</LinearLayout>

(Note that while TextView does have the ellipsize attribute, it doesn't appear necessary to alter, as setting singleLine to true truncates and ellipsizes the labels already. I may be wrong about this.)

Following is a screenshot of this code in action:

Any advice is of course appreciated.

like image 757
Thane Anthem Avatar asked Apr 01 '11 05:04

Thane Anthem


1 Answers

I think this tutorial will help you. Try this..

Your row.xml should look like :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:gravity="left|center"
android:layout_width="wrap_content"
android:paddingBottom="10px"
android:paddingTop="10px"
android:paddingLeft="3px">
 <TextView
    android:id="@+id/TextView01"
    android:layout_width="70dip"
    android:layout_height="wrap_content"
    android:gravity="left"
    android:singleLine="true"
    android:textSize="15dip"
    android:textStyle="bold"
    android:textColor="#d08021"
    android:paddingLeft="20dip">
 </TextView>
 <TextView

    android:id="@+id/TextView02"
    android:layout_width="200dip"
    android:layout_height="wrap_content"
    android:gravity="left"
    android:singleLine="true"
    android:layout_marginLeft="10dip"
    android:textSize="15dip"
    android:textStyle="bold"
    android:textColor="#7f0000">
 </TextView>

</LinearLayout>

You need this type of layout right ? Correct me if i am not wrong. See the output when i tried the above layout file.

like image 160
Kartik Domadiya Avatar answered Sep 29 '22 19:09

Kartik Domadiya