включение list_content в макет списка, чтобы сохранить функциональность ListFragment

Во-первых, я использую The Android Compatibility Library V4 rev.3 для своего 1.6 (пончик).

Когда вы впервые создаете ListFragment, он отображает неопределенный индикатор прогресса, пока вы не используете setListAdabpter(). Согласно документации ListFragment.onCreateView, если я хочу использовать пользовательский макет:

Если вы переопределяете этот метод своим собственным контентом, рассмотрите возможность включения стандартного макета {@link android.R.layout#list_content} в файл макета, чтобы сохранить все стандартное поведение ListFragment. В частности, в настоящее время это единственный способ отобразить встроенное неопределенное состояние выполнения.

Проблема в том, что когда я захожу в свой файл макета и пытаюсь: <include layout="@android:layout/list_content" ...> он (затмение) говорит мне, что

Ресурс не публичный. (в 'layout' со значением '@android:layout/list_content').

Я понимаю, что это означает, что list_content.xml не существует в моем исходном коде V4. что правильно, потому что согласно документам он появился в API v11.

Я просто предположил, что он будет существовать в исходном коде библиотеки совместимости, не знаю, существует ли он...

Единственное другое решение, которое я вижу, - это копать исходный код Android API V11, копировать и вставлять list_content.xml. Однако сейчас я хотел бы избежать этого хакерства. это единственное решение?


person code shogan    schedule 22.10.2011    source источник
comment
вы нашли решение этого? у меня та же проблема.   -  person Yuyo    schedule 04.01.2012
comment
@Yuyo В итоге я не использовал собственный макет (на самом деле лень), но, как мы с Антонитом сказали, вы можете просто скопировать list_content.xml в свой проект. На самом деле это не хакерство, это лучший способ сделать это, если вы не хотите начинать писать строки кода для достижения того же эффекта.   -  person code shogan    schedule 28.03.2012


Ответы (3)


ListFragment, включенный в библиотеку совместимости, похоже, не использует этот макет (list_content), как настоящий. Это может быть связано с тем, что он предлагается в виде jar-файла, и ресурсы невозможно упаковать. Вот содержимое его onCreateView:

ListFragment из библиотеки совместимости:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    final Context context = getActivity();

    FrameLayout root = new FrameLayout(context);

    // ------------------------------------------------------------------

    LinearLayout pframe = new LinearLayout(context);
    pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
    pframe.setOrientation(LinearLayout.VERTICAL);
    pframe.setVisibility(View.GONE);
    pframe.setGravity(Gravity.CENTER);

    ProgressBar progress = new ProgressBar(context, null,
            android.R.attr.progressBarStyleLarge);
    pframe.addView(progress, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

    root.addView(pframe, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    // ------------------------------------------------------------------

    FrameLayout lframe = new FrameLayout(context);
    lframe.setId(INTERNAL_LIST_CONTAINER_ID);

    TextView tv = new TextView(getActivity());
    tv.setId(INTERNAL_EMPTY_ID);
    tv.setGravity(Gravity.CENTER);
    lframe.addView(tv, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    ListView lv = new ListView(getActivity());
    lv.setId(android.R.id.list);
    lv.setDrawSelectorOnTop(false);
    lframe.addView(lv, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    root.addView(lframe, new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    // ------------------------------------------------------------------

    root.setLayoutParams(new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

    return root;
}

ListFragment из Android 4.0:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(com.android.internal.R.layout.list_content, container, false);
}

Учитывая выбор между копированием файла макета из исходного кода APIv11 и включением этого кода инициализации представления, я думаю, ясно, какой из них будет считаться «хакерским»;)

person antonyt    schedule 16.03.2012

Я был разочарован, увидев, что макет list_content недоступен при использовании библиотеки поддержки. Мой подход состоял в том, чтобы просто повторно использовать метод onCreateView по умолчанию для ListFragment и добавить его как часть моего пользовательского макета:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View listContent = super.onCreateView(inflater, container,
            savedInstanceState);

    View v = inflater.inflate(R.layout.my_custom_layout, container,
            false);

    FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.my_list_container);

    listContainer.addView(listContent);

    return v;
}

Я добавил FrameLayout, где ListView раньше был в моем пользовательском макете.

person argenkiwi    schedule 23.10.2013
comment
Я проголосовал за, так как казалось, что это единственный способ сохранить представление загрузки/неопределенного хода выполнения по умолчанию с помощью setListShown(false). К сожалению, оказывается, что ListFragment из библиотеки поддержки просто не поддерживает это представление прогресса в сочетании с представлением для пустого списка (@id/android:empty). Реализация здесь даже пытается найти собственное пустое представление, если представление по умолчанию не создано. - person tangobravo; 20.10.2014
comment
Разве мы не можем просто использовать контейнер вместо вызова findViewById. Именно здесь мы говорим Android уже поместить ListView. - person wheredidthatnamecomefrom; 29.11.2014

Одним из возможных обходных путей для включения @android.R.layout/list_content по умолчанию в пользовательский макет при использовании библиотеки совместимости является создание фиктивного ListFragment:

package com.example.app;

import android.support.v4.app.ListFragment;

public class ListContentFragment extends ListFragment {
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        //Supress default list and empty text behavior
        //super.onViewCreated(view, savedInstanceState);
    }
}

Затем включите этот фрагмент (вместо рекомендуемого макета list_content) в свой собственный макет:

...
<fragment class="com.example.app.ListContentFragment"
    android:layout_weight   ="1" 
    android:layout_width    ="fill_parent"
    android:layout_height   ="0dip" />
...

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

person esteewhy    schedule 19.04.2012