Intereting Posts
Как обрабатывать изменение ориентации экрана, когда диалог выполнения и фоновый поток активны? Как включить Spongy Castle JAR в Android? Всегда показывать заголовок маркера карты в Android Android Wear Включить подключение ADB через WiFi TCP / IP Установить inputType для EditText? Проблема с материалами Inline Datepicker для Android Является ли GCM (теперь FCM) бесплатным для любого ограничения? SharedUserId: безопасно менять, когда приложение уже находится на рынке? Сравнение использования распознавания речи в Android: по Intent или on-thread? Обнаруживать, если я в режиме выпуска или отладки в android Android: как я могу сказать, отображается ли мягкая клавиатура или нет? Изменение цвета строки состояния при входе в контекстный режим действия Комната Android: каждая переменная привязки в запросе должна иметь соответствующий метод Ограничения квоты на Android Geocoder Пользовательская версияName значение AndroidManifest.xml в коде

Может ли ListView содержать фрагменты

Как и в, могут ли ЭЛЕМЕНТЫ ListView быть фрагментами. Я знаю, что вы можете назначить TextView XML в ListView для изменения способа его просмотра, но можете ли вы добавить фрагменты в ListView.

Например: у меня есть фрагмент. XML для упомянутого фрагмента содержит ImageView, пару текстовых элементов большого стиля и текстовый TextView небольшого размера. Код класса Fragment получает Bundle, а затем на основе содержимого заполняет TextViews и ImageView соответственно. И XML-фрагмент фрагмента, и код фрагмента работают без проблем (я могу показать индивидуальный фрагмент просто отлично). У меня есть FragmentActivity, в котором я хочу отобразить вышеупомянутый список фрагментов. Вот код, который я использую, чтобы попытаться заполнить ListView внутри представления FragmentActivity:

ArrayList<Fragment> fragList = new ArrayList<Fragment>(); Fragment fragment = Fragment.instantiate(this, TileItem.class.getName()); Bundle bundle = new Bundle(); bundle.putInt("key", 0); fragment.setArguments(bundle); fragList.add(fragment); ArrayAdapter<Fragment> adapter = new ArrayAdapter<Fragment>(this, R.layout.tile_item, fragList); listItems.setAdapter(adapter); 

Вот мой образ мышления об этом. Я делаю ArrayList of Fragments для хранения всех моих экземпляров. Затем я создаю фрагмент, создаю Bundle, добавляю данные в Bundle (так, чтобы Fragment мог правильно маршировать данные в его представлениях), добавьте Bundle в Fragment, а затем, наконец, добавьте фрагмент в ArrayList. После этого я создаю ArrayAdapter, добавляю макет элемента, который я хочу использовать, и список Фрагментов, которые я сделал; Затем установите ListView для чтения из моего адаптера.

Любой, кто запускает этот код, скорее всего, получит NPE @, создающий экземпляр массива ArrayAdapter. Что дает? Возможно ли это? Прежде чем я продолжаю ломать голову над этим, может кто-то сказать мне, если я просто трачу свое время? Есть ли способ лучше? Я подумывал об использовании ScrollView, но так много функций ListView нужно было бы переделать, и я ненавижу ненависть-ненависть, изобретая колесо, когда это не нужно.

Спасибо всем, кто читает, и особенно благодарю вас за ваши мысли, если вы решите оставить их. Я попытался найти правильный ответ на этот вопрос, но все, что мне кажется, это вопросы / веб-страницы, касающиеся использования ListView INSIDE из фрагмента; Не используя фрагменты КАК ЭЛЕМЕНТЫ ListView

Изменить: я принял приведенные ниже предложения и начал расследование. Из того, как выглядят вещи, я должен использовать пользовательский адаптер, который раздувает фрагменты, а не просто строит из XML (из-за отсутствия лучшего способа описать процесс). Однако моя текущая реализация бросает NPE при попытке установить Адаптер.

Вот мой код адаптера (сокращенный для краткости):

 public class AdapterItem extends ArrayAdapter<Fragment> { Context c; List<Fragment> f; public AdapterItem(Context c, List<Fragment> f) { super(c, R.layout.tile_item, f); this.c = c; this.f = f; } @Override public View getView(int pos, View v, ViewGroup vg) { LayoutInflater i = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return i.inflate(R.layout.tile_item, vg, false); } 

}

И вот как я его реализую:

 ArrayList<Fragment> fragList = new ArrayList<Fragment>(); Fragment fragment = Fragment.instantiate(this, TileItem.class.getName()); Bundle bundle = new Bundle(); bundle.putInt("key", 0); fragment.setArguments(bundle); fragList.add(fragment); AdapterItem adapter = new AdapterItem(this, fragList); adapter.add(fragment); listItems.setAdapter(adapter); 

Так что прошло несколько дней, и я уверен, что эта нить была похоронена. Тем не менее, я думал, что добавлю одно последнее обновление на случай, если кто-то захочет попробовать это, и поиск в Google приведет их сюда. Поэтому в моей реализации я получаю NPE, когда ListView получает адаптер. Хирург-ракетовед не считает, что это, скорее всего, адаптер, а не ListView, бросающий ошибку. Для жизни я не могу понять, почему, хотя …

Во всяком случае, я думаю, что у меня есть идея. Во-первых, небольшая история: некоторое время назад я пытался сделать FragmentTransactions внутри FragmentDialog. Каждый раз, когда я пытался это сделать, я получал NPE. В конце концов, благодаря большому количеству исследований, я обнаружил, что причина связана с тем, как создаются Фрагменты. Когда вызывается фрагмент, ему нужен контекст из его родителя. Поскольку родительский элемент диалогового окна – это начальная операция, сам диалог не соответствовал требуемым критериям. Я считаю, что при попытке добавить фрагменты в ListView это тоже так. Поскольку ListView не соответствует соглашению с созданием фрагмента, он бросает NPE и, таким образом, оставляет меня зависанием и возвращается к соглашениям. D @ mn … Я действительно надеялся, что смогу это сделать. Использование фрагментов вместо простого XML упростило бы организацию / поиск по списку. О, ну … думаю, это невозможно сделать, если кто-то задается вопросом.

Solutions Collecting From Web of "Может ли ListView содержать фрагменты"

Я бы сказал, что это невозможно сделать, поскольку размещение фрагмента в ListView означает, что фрагмент можно умножить на несколько контейнеров. Когда вы используете FragmentManager для создания фрагмента, он помечен идентификатором, что упрощает перезагрузку и переупорядочивание по ориентации и другим изменениям конфигурации. Он также поощряет использование нескольких конфигураций устройств.

Фрагмент – это действительно подмножество Activity. Имеете ли вы когда-либо действие как часть списка? Определенно нет (должен быть ответ!) !!!

Кроме того, не очень полезно прикрепить () и отсоединить () фрагмент непрерывно по мере их перемещения и выхода из вида (ячейки возвращаются). Это все дорогостоящие операции, с которыми ListView не справляется. Списки должны прокручиваться быстро.

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

  1. Переопределите класс « View » и сделайте свой собственный рисунок и настройте его.
  2. Создайте новый класс, в котором вы предоставите контекст и набор данных, необходимые для того, чтобы вернуть вам представление, которое должен показать список – это то, что я обычно делаю.
  3. У вас есть класс Utils для создания вашего видео в другом месте (глупо).

Просто не используйте фрагменты в списках. Не тот прецедент, к которому они стремятся. НТН.

Оказывается, вы можете создать ListView где каждый элемент в listView является Fragment . Трюк обертывает Фрагмент в FrameLayout .

ОБНОВЛЕНИЕ 9/16/2014

Несмотря на то, что можно создать ListView который содержит Fragments , это не похоже, что это хорошая идея. Кажется, это определенно является краеугольным камнем в мире Android, и там есть драконы. Для простого фрагмента, подобного тому, который приведен в приведенном ниже примере, все работает красиво, но если у вас есть сложный проект, в котором много чего происходит, то это, вероятно, не путь. Мой новый подход заключается в том, чтобы вывести весь код, связанный с графическим интерфейсом, в представление, которое расширяет FrameLayout и вставляет его в ListView – это работает FrameLayout и больше соответствует тому, как Android ожидает использования. Если вам нужна функциональность Fragment в других частях вашего кода, вы можете просто использовать этот новый View там тоже.

Вернемся к исходному ответу …

Я добавил новый пример ManyFragments в пример приложения AnDevCon 14 Fragments, если вы хотите попробовать его. По существу это происходит с BaseAdapter , который в моем примере выглядит так:

  BaseAdapter adapter = new BaseAdapter() { @Override public int getCount() { return 10000; } @Override public Object getItem(int i) { return new Integer(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { if (view!=null){ ManyListItemFragment fragment = (ManyListItemFragment) view.getTag(); fragment.setCount(i); } else { FrameLayout layout = new FrameLayout(getActivity()); layout.setLayoutParams(frameLayoutParams); int id = generateViewId(); layout.setId(id); ManyListItemFragment fragment = new ManyListItemFragment(); fragment.setCount(i); getChildFragmentManager() .beginTransaction() .replace(id,fragment) .commit(); view = layout; view.setTag(fragment); } return view; } }; 

В случае, если вам любопытно здесь generateViewId ():

 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static int generateViewId() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { for (;;) { final int result = sNextGeneratedId.get(); // aapt-generated IDs have the high byte nonzero; clamp to the range under that. int newValue = result + 1; if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0. if (sNextGeneratedId.compareAndSet(result, newValue)) { return result; } } } else { return View.generateViewId(); } } private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1); 

Вам не нужно использовать фрагменты.

Напишите пользовательский ViewAdapter и раздуйте более сложный макет (или, возможно, несколько более сложных макетов, если вам нужно по-настоящему выглядеть), затем заполните поля макета по мере необходимости.

[Кроме того, для людей, которые ответили в комментариях, используйте ответы, а не комментарии, если вы действительно отвечаете на вопрос! Если только потому, что вы получаете больше очков репутации таким образом!]