WANTED: TableLayout-подобный ListView - PullRequest
9 голосов
/ 01 апреля 2011

Мой вопрос может быть таким: «Как создать однострочный горизонтальный LinearLayout с двумя однострочными текстовыми представлениями без переноса текста, где левый TextView всегда занимает 1/3 доступной ширины экрана, правый TextView всегда занимает 2 / 3 доступной ширины экрана, а текстовые метки усекаются с ... когда они слишком длинные для отображения? " (Если этот вопрос достаточно ясен, и читатель - это вы - уже имеет в виду решение, которым он готов поделиться, дальнейшее чтение проблемы и описание вопроса могут быть излишними.)

ListView, заполненный четырьмя такими LinearLayouts, будет выглядеть примерно так:

medium length text ---- short text
short text         ---- text that is too loooooooooooooo...
loooooooooooooo... ---- short text
loooooooooooooo... ---- text that is too loooooooooooooo...
В этом макете, в первой строке , левая и правая текстовые метки были достаточно короткими, чтобы отображаться полностью, во второй строке , левая метка была достаточно короткой, чтобы отобразить ее полностью, в то время как текст правой метки был слишком длинным и, таким образом, был усечен, а начало текста правой метки выровнено по вертикали с правый текст первой строки, визуально создавая столбец, как если бы это было в TableLayout, в третьей строке , текст левой метки был слишком длинным и был усечен для выравнивания по вертикали с левой текст второй и первой строк, а текст правой метки начинался по вертикали с правым текстом второй и первой строк , а в четвертой строке текст левой метки был слишком длинным и, таким образом, отображался аналогично левому тексту третьей строки, а текст правой метки был слишком длинным и таким образом отображался аналогично правому тексту второй строки.

Из различных публикаций о стековом потоке и в других местах я понял, что хотя использование TableLayout с ArrayAdapter в некоторой степени возможно, есть и недостатки, и, вероятно, это неправильный подход.

Я, конечно, пробовал много комбинаций параметров макета, но пока что ничего не приблизилось к цели. Я пытаюсь найти решение, которое будет работать на экранах разных размеров, поэтому указание определенной ширины в пикселях, вероятно, не будет работать очень хорошо.

Возможно, следующий простой пример кода (со скриншотом) является хорошей отправной точкой для решения и требует лишь небольших изменений.

(Форматировщик кода stackoverflow сходит с ума по поводу этого кода. Поэтому, пожалуйста, простите за любое прикольное форматирование.)

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>

(Обратите внимание, что, хотя TextView действительно имеет атрибут ellipsize, изменять его, по-видимому, не нужно, поскольку установка singleLine в значение true усекает и уже эллипсизирует метки. Я могу ошибаться.)

Ниже приведен скриншот этого кода в действии:
image

Любой совет, конечно, приветствуется.

Ответы [ 4 ]

6 голосов
/ 01 апреля 2011

Я думаю, этот урок поможет вам. Попробуйте это ..

Ваш row.xml должен выглядеть так:

<?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>

Вам нужен этот тип макета, верно? Поправь меня, если я не ошибаюсь. See the output when i tried the above layout file.

3 голосов
/ 23 апреля 2011

hackbod представляет еще один красивый аргумент о том, почему ListViews не могут размещать строки, такие как TableViews, в ответе на вопрос Есть ли в Android таблица, подобная Adapter для ListView .

3 голосов
/ 01 апреля 2011

Вы можете использовать TableLayout и заставить его вести себя как ListView (по крайней мере, визуально). Вот мой ответ.

2 голосов
/ 20 января 2014

Лучшее, что я могу придумать, это иметь row.xml, который выглядит примерно так. Это не идеальный вариант, но он будет сохранять строки с фиксированной шириной, которые будут масштабироваться при изменении размеров, но не на основе текста. Это даст вам 80% макета таблицы с преимуществами ListView.

<?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="0dp"
    android:layout_weight=1
    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="0dp"
    android:layout_weight=3
    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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...