#android #android-fragments #android-support-library
#Android #android-фрагменты #android-support-library
Вопрос:
Во-первых, я использую библиотеку совместимости с Android версии 4 rev.3 для моего 1.6 (Donut)
При первом создании ListFragment он отображает неопределенный индикатор выполнения, пока вы не используете setListAdabpter(). Согласно документации ListFragment.onCreateView, если я хочу использовать пользовательский макет:
Если вы переопределяете этот метод своим собственным пользовательским контентом, рассмотрите возможность включения стандартного макета {@link android.R.layout#list_content} в свой файл макета, чтобы сохранить все стандартное поведение ListFragment. В частности, в настоящее время это единственный способ отображения встроенного неопределенного состояния выполнения.
Проблема в том, что когда я захожу в свой файл макета и пытаюсь: <include layout="@android:layout/list_content" ...>
он (eclipse) сообщает мне, что
Ресурс не является общедоступным. (в ‘layout’ со значением ‘@android:layout / list_content’).
Я полагаю, что это означает list_content.xml
, что в моем исходном коде V4 не существует. что правильно, потому что, согласно документам, оно появилось в API v11.
Я просто предположил, что он будет существовать в источнике библиотеки совместимости, не знаю, так ли это…
Единственным другим решением, которое я вижу, было бы извлечь исходный код Android API V11, скопировать и вставить list_content.xml
. Однако на данный момент я хотел бы избежать этого взлома. это единственное решение?
Комментарии:
1. @Yuyo В итоге я не использовал пользовательский макет (на самом деле лень), но, как сказали мы с антонитом, вы можете просто скопировать
list_content.xml
его в свой проект. На самом деле это не хакерство, это лучший способ сделать это, если вы не хотите начинать писать строки кода для достижения того же эффекта.
Ответ №1:
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 и включением этого кода инициализации представления, я думаю, ясно, какой из них будет считаться «хакерством» 😉
Ответ №2:
Я был разочарован, увидев, что макет 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 в моем пользовательском макете.
Комментарии:
1. Я поддержал, поскольку казалось, что это будет единственный способ сохранить представление «Загрузка / неопределенный прогресс» по умолчанию с setListShown(false). К сожалению, оказывается, что ListFragment из библиотеки поддержки просто не поддерживает это представление прогресса в сочетании с представлением для пустого списка (@id / android:empty). Реализация здесь даже пытается найти пользовательское пустое представление, если оно не создано по умолчанию.
2. Разве мы не можем просто использовать container вместо вызова findViewById . Вот где мы говорим Android, чтобы он уже поместил ListView.
Ответ №3:
Одним из возможных способов включения default @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 по умолчанию, сохраняя при этом пользовательский макет для него.