пустой вид на ListActivity не работает

Я рву на себе волосы, пытаясь понять это. Из всех руководств, которые я прочитал, то, как я установил эту настройку, должно работать. У меня есть ListActivity, который использует пользовательский адаптер для отображения некоторых данных. Я хотел бы отобразить сообщение «элементы не найдены», если адаптер пуст.

Это мой макет:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 style="@style/BaseStyle"
 android:orientation="vertical"
 android:padding="5dip"
 >
      <ListView android:id="@android:id/list"
      style="@style/BaseStyle"
      />

      <TextView xmlns:android="http://schemas.android.com/apk/res/android" 
      android:id="@android:id/empty"
      style="@style/BaseStyle.Title"
      android:text="No Items Found"
      />

      <TextView xmlns:android="http://schemas.android.com/apk/res/android" 
      android:id="@+id/text"
      style="@style/BaseStyle.Title"
      android:layout_alignParentTop="true"
      />
 </RelativeLayout>

Это мой код:

 public class Main extends ListActivity {
 private CustomAdapter adapter;
 private String[] items = {};

 @Override     
 public void onCreate(Bundle icicle) {
      super.onCreate(icicle);
      setContentView(R.layout.main);

      adapter = new CustomAdapter();

      PopulateItems();

      for (String item : items)
           adapter.addItem(item);

      this.setListAdapter(adapter);
      adapter.notifyDataSetChanged();
 }

 private class CustomAdapter extends BaseAdapter {
 private String[] mData;
 private LayoutInflater mInflater;

 public CustomAdapter() {
      mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 }

 public void addItem(String item) {
      mData.add(item);
 }

 @Override
 public int getCount() {
      return mData.size();
 }

 @Override
 public Object getItem(int position) {
      return mData.get(position);
 }

 @Override
 public long getItemId(int position) {
      return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent)
 {
      ViewHolder holder;
      String item = (String)this.getItem(position);

      if (convertView == null)
      {         
           holder = new ViewHolder();

           convertView = mInflater.inflate(R.layout.main, parent, false);
           holder.text = (TextView)convertView.findViewById(R.id.text);
           convertView.setTag(holder);
      } else {
           holder = (ViewHolder)convertView.getTag();
      }
      TextView tvText = holder.text;
      tvText.setText(item);
 }

 static class ViewHolder {
      TextView text;
 }

Что происходит, так это то, что текст «No Items Found» отображается нормально, когда массив строк «items» не имеет данных. В методе PopulateItem() есть процесс, который заполняет массив данными, и если данные есть, текст «Нет элементов найдено» все еще можно увидеть в каждой строке листинга «под» данными. Таким образом, пустой текст в основном перекрывается данными.


person Kris B    schedule 06.09.2011    source источник


Ответы (2)


Я не уверен, что вы сделали какие-либо опечатки в своем вопросе для вашего кода. Похоже, вы вырезаете части своего кода, прежде чем публиковать его здесь.

getView() предназначен для создания представления для определенной строки в вашем ListView. Я предполагаю, что вы на самом деле раздули свой main.xml, который является вашим RelativeLayout, содержащим ListView, EmptyView и другой TextView.

Если ваш ListView отображает только строки, просто создайте экземпляр TextView и верните его в getView.

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
  String item = (String)this.getItem(position);

  if (convertView == null)
  {         
       convertView = new TextView(context);
  } 
  convertView.setText(item);
  return convertView
}

Передайте в Context через конструктор вашего пользовательского адаптера

Изменить: отображение нескольких видов текста в одной строке

Если быть строгим, проблема не в строке convertView = mInflater.inflate(). Ошибка в файле раздутом. Обычно проще раздуть другой XML-файл, если у вас есть более сложное представление для каждой строки в вашем списке. Более ранняя ошибка - это несколько, казалось бы, рекурсивное раздувание main.xml.

Чтобы обработать несколько текстовых представлений, сделайте следующее:

Создайте еще один файл xml для представления каждой строки в вашем списке, list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  .....
 >
  <TextView android:id="@+id/list_text_1"
    ....
  />

  <TextView android:id="@+id/list_text_2"
    ....
  />

  <TextView android:id="@+id/list_text_3"
    ....
  />
 </LinearLayout>

В вашей реализации getView в вашем адаптере

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
  String item = (String)this.getItem(position);

  if (convertView == null)
  {         
     convertView = mInflater.inflate(R.layout.list_item.xml, parent, false);
     //link list_text_1, list_text_2, list_text_3 as you need to the individual   
     // textviews
  } 
  else {
    // TODO linking up the textviews when convertView is not null
  }
  return convertView
}

Это, вероятно, хорошее время, чтобы ввести шаблон просмотра, учитывая, что вам нужно раздуть файл xml. Страница 11/19 файла PDF, связанного с этим ответ дает довольно хорошее объяснение шаблона ViewHolder.

Наконец, прочитайте больше примеров ListView и обратите внимание, когда они используют инфлятор в getView и что они на самом деле надувают.

person yjw    schedule 06.09.2011
comment
Я относительно новичок в разработке для Android, но, судя по тому, что я читал, если у вас есть представление с идентификатором @android:id/empty, это представление будет отображаться, если нет данных. Я не включил весь свой код, но это те части кода, которые относятся к макету. Единственные места, где я вызываю main.xml, — это когда я использую setContentView, в onCreate и в методе getView. Редактировать: я написал это поздно ночью, поэтому у меня была опечатка. В getView я думаю, что упускаю место, где я создаю экземпляр переменной tvText. - person Kris B; 06.09.2011
comment
ваше понимание @android:id/empty верно. Он будет отображаться до тех пор, пока содержимое пусто, и Android будет скрывать это представление, пока у вас нет содержимого. Из вашего описания похоже, что у вас есть иерархия, в которой у вас есть списки внутри вашего списка. Это означает, что любая строка, которая не заполнена данными, будет считаться пустой и показывать пустое представление... следовательно, в каждой строке не найдено элементов. - person yjw; 06.09.2011
comment
Итак, я запутался и, возможно, я упускаю что-то очевидное, но я вижу, что элементы не найдены один раз, если адаптер пуст, как я и ожидал. Проблема в том, что когда есть данные, я вижу сообщение «Нет найденных элементов» И данные вместе в каждой строке. Похоже, что данные накладываются поверх сообщения No Items Found в каждой строке. - person Kris B; 07.09.2011
comment
Хорошо, я думаю, что знаю, где моя проблема. Это в этой строке кода: convertView = mInflater.inflate(R.layout.main, parent, false); Я, вероятно, не должен использовать это, и мне просто нужно использовать код yjw. yjw, как бы вы изменили свой код, чтобы настроить таргетинг на несколько TextView? - person Kris B; 07.09.2011
comment
Я обновил свой ответ. Надеюсь, это достаточно ясно. Пингуйте меня, если у вас есть какие-либо вопросы! - person yjw; 07.09.2011
comment
Спасибо за обновления. В своем исходном посте я использую шаблон ViewHolder и расширяю макет main.xml. Может быть, вам нужно прокрутить мой код вниз, чтобы увидеть все это? Итак, моя первоначальная проблема все еще остается: я вижу сообщение «Нет найденных элементов», когда нет данных (как и ожидалось), но когда есть данные, я вижу ОБА «Нет найденных элементов» И данные друг над другом. Я думал, что раздувание main.xml приводит к отображению всего TextView, даже пустого TextView, в чем и заключается мое замешательство. - person Kris B; 07.09.2011
comment
Привет, я в замешательстве. Вы все еще сталкиваетесь с этой проблемой после того, как опробовали мое решение для множественного просмотра текста? Обратите внимание, что ключ не создает другой макет .xml и не раздувает файл .xml, содержащий ListView, внутри вашей реализации getView(). - person yjw; 07.09.2011

Поскольку ваше текстовое представление с пустым идентификатором по-прежнему отображается, сначала установите видимость этого представления как невидимое, а если список пуст, сделайте его видимым только,
посмотрите на параметр android:visibility="invisible".
> и в коде, если список пуст yourtextview.setVisibility(View.VISIBILE)

person sat    schedule 06.09.2011
comment
Не надо такой сложности. ListView должен автоматически делать пустое представление невидимым, когда обнаруживает, что список не пуст. - person yjw; 06.09.2011
comment
У меня сложилось впечатление, что если у вас есть представление с идентификатором android:id=@android:id/empty, то оно будет отображать это представление, если список пуст. Вот что меня смущает. Попробую настроить видимость. - person Kris B; 06.09.2011