Android Как повторно использовать макет заголовка как пустой вид в ListView

Я боролся с этой проблемой на протяжении всей жизни моего проекта. У меня есть много списков в моем проекте, и большинство из них имеют заголовки. Я делаю отдельный файл макета и добавляю его в список с помощью addHeaderView(). Проблема в том, что когда данные (ArrayList, в моем случае) пустые, заголовок не отображается. После нескольких часов поиска способа повторного использования макета заголовка в качестве пустого представления я отказался и решил реплицировать макет кода и назначить его как пустой вид с помощью setEmptyView(). Проблема заключается в том, что многие заголовки содержат интерактивные представления, поэтому мне нужно удвоить всю мою интерактивную логику для каждого дублирующегося вида. Я пытался включить заголовок раньше, но не смог, в основном потому, что я до сих пор не совсем понимаю, как раздуты макетов и т.д.

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

вот код макета, который содержит представление списка списка:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
>
    <ListView
        android:id="@+id/lv_my_list"
        style="@style/ListStyle"
        android:headerDividersEnabled="false"
    />
    <include
        layout="@layout/my_list_header"
        android:id="@+id/my_list_empty"
    />
</LinearLayout>

стиль определяет ширину и высоту макета между прочим.

теперь у меня есть файл макета, который содержит представление заголовка

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:id="@+id/my_list_header"
>
    <Button 
        android:id="@+id/my_list_button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Click Me"
    />
</LinearLayout>

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

// set up the header
myListView = (ListView)findViewById(R.id.lv_my_list);
View header = View.inflate(this, R.layout.my_list_header, null);
Button b = (Button)header.findViewById(R.id.my_list_button);
b.setOnClickListener(this);
myListView.addHeaderView(header);

// set up the empty view        
LinearLayout ll = (LinearLayout)findViewById(R.id.my_list_empty);
b = (Button)ll.findViewById(R.id.my_list_button);
b.setOnClickListener(this);
meLocalListView.setEmptyView(ll);

Причина, по которой я завернул кнопку в макете, состоит в том, что я могу установить каждый экземпляр кнопки, чтобы использовать это как OnClickListener, а затем ссылаться на оба из них с одним id: R.id.my_list_button в моем методе onClick. Мне нужно проверить это намного больше, но, похоже, сейчас это работает. Я еще не реализовал его во всех моих списках, просто так, чтобы он не работал во всех ситуациях. Если у вас есть какие-либо предложения, сообщите мне, потому что это уже давно проблема для меня. Одна из проблем может заключаться в том, что если вы хотите создать экземпляр кнопки из идентификатора, вам, вероятно, придется снова пройти весь этот процесс, чтобы получить доступ к правильным идентификаторам?

Ответ 1

Если вы хотите показать заголовок ListView, когда список пуст, то вы действительно хотите показать сам список, а не отдельный пустой вид. Итак, самый простой способ - проверить, пуст ли ваш список, и установить список, если он еще не был:

getListView().setVisibility(View.VISIBLE);

Вы можете легко проверить это с помощью следующего кода:

public class TestListActivity extends ListActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_listview);

        // create the empty grid item mapping
        String[] from = new String[] {};
        int[] to = new int[] {};

        // prepare the empty list
        List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();

        // fill in the grid_item layout
        SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.test_listitem, from, to);

        View listHeader = 
                ((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.test_listheader, null, false);

        getListView().addHeaderView(listHeader);
        getListView().setAdapter(adapter);
    }
}

Список пуст, но заголовок виден.

Ответ 2

Мое решение - создать представление с макетом для заголовка, но установить фон таким же, как элементы списка.   Android: фон = "@андроид: рисуем /list _selector_background"

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