OnCreateView не вызывается с помощью фрагмента в ViewPager

Я использую ViewPager из ACL, чтобы показать пару Fragment . Сначала эти фрагменты, где все ListFragment s содержат список. Я пытаюсь имитировать таблицу с двумя столбцами, поэтому каждый элемент в списке содержит другой список из двух объектов. Я хочу, чтобы каждая ячейка была долго-кликабельной (не весь элемент списка), поэтому я реализовал свой собственный ColumnLayout (возможно, его следует назвать CellLayout). Каждый элемент списка содержит два столбца ColumnLayouts, которые являются long-clickable и реализуют getContextMenuInfo() чтобы возвращать информацию о том, какой объект был долго нажат. Этот метод ищет ViewPager, запрашивает текущий фрагмент, а затем вызывает фрагмент, чтобы вернуть идентификатор объекта из долгого щелчка. Чтобы получить правильную строку, необходимо сделать фрагмент:

 getListView().getPositionForView(v) 

И вот тут проблема. Иногда getListView() бросает IllegalStateException говорящий «Content view еще не созданный». Т.е. onCreateView(...) не был вызван. Это происходит иногда, когда приложение возобновляется. Сегодня мне удалось повторно создать проблему, включив опцию «Не сохранять действия» в настройках> Параметры разработчика на моем Galaxy Nexus. Я запустил приложение, нажмите «Домой», а затем снова откройте приложение из меню последних приложений, и теперь, если я долгое время нажимаю любую из ячеек в своем списке, это исключение вызывается. По некоторым выводам отладки мне удалось проверить, что onCreateView никогда не вызывался. Что странно, потому что весь ViewPager с его фрагментом и его ListView и его элементы ячейки нарисованы!

Мне сказали # android-dev, что ListFragment в ACL не поддерживает настраиваемые макеты, поэтому я повторно выполнил мой ListFragment android.support.v4.app.Fragment без использования ListFragment но это не помогло.

Краткое описание: У меня есть настраиваемый макет, который обрабатывает событие длительного нажатия макета с целью создания объекта MenuInfo содержащего информацию об entitiy в нажатой ячейке. Чтобы найти объект, содержащийся в макете, в конечном итоге вызывается listview.getPositionForView(View v) , иногда вызывающий IllegalStateException .

Здесь мой собственный макет (возможно, есть более простой способ получить ViewPager чем копать в иерархии представлений):

 package org.remotestick; import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.ContextMenu.ContextMenuInfo; import android.view.View; import android.widget.LinearLayout; public class ColumnLayout extends LinearLayout { public ColumnLayout(Context context, AttributeSet attrs) { super(context, attrs); } public ColumnLayout(Context context) { super(context); } @Override protected ContextMenuInfo getContextMenuInfo() { int itemTypeId = getChildAt(0).getId(); int positionTypeId = getId(); View currentView = this; ViewPager viewPager = null; while(currentView.getParent() != null) { currentView = (View) currentView.getParent(); if(currentView.getId() == R.id.pager) { viewPager = (ViewPager) currentView; break; } else if (currentView.getId() == R.id.rootLayout) break; } if(viewPager == null) return null; WorkspaceAdapter adapter = (WorkspaceAdapter) viewPager.getAdapter(); Pair<Integer, Integer> itemIdAndListPosition = adapter.getItemIdFromWorkspace(viewPager.getCurrentItem(), this, itemTypeId, (positionTypeId == R.id.leftColumn)); if(itemIdAndListPosition == null) return null; else return new MatrixAdaptableContextMenuInfo(itemTypeId, itemIdAndListPosition.first, itemIdAndListPosition.second); } public static class MatrixAdaptableContextMenuInfo implements ContextMenuInfo { public final int itemTypeId; public final Integer itemId; public final Integer positionInList; public MatrixAdaptableContextMenuInfo(int itemTypeId, Integer itemId, Integer positionInList) { this.itemTypeId = itemTypeId; this.itemId = itemId; this.positionInList = positionInList; } } } 

И вот (фрагмент) Fragment :

 public class EntityTableFragment extends Fragment implements TelldusEntityChangeListener { protected static final String ARG_TITLE = "title"; protected MatrixAdapter mAdapter; protected ProgressViewer mProgressViewer; protected MatrixFilter mFilter; protected Handler mHandler = new Handler(); protected RemoteStickData db; public boolean onAttach = false; public boolean onCreateView = false; private ListView listView; public static EntityTableFragment newInstance(String title) { EntityTableFragment f = new EntityTableFragment(); Bundle args = new Bundle(); args.putString(ARG_TITLE, title); f.setArguments(args); return f; } @Override public void onAttach(SupportActivity activity) { super.onAttach(activity); onAttach = true; try { mProgressViewer = (ProgressViewer) activity; mAdapter = new MatrixAdapter(getActivity(), mProgressViewer, new ArrayList<List<MatrixEntity>>(), null); TelldusLiveService.addListener(this); } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement ProgressViewer"); } db = new RemoteStickData(getActivity()); } @Override public void onDetach() { super.onDetach(); TelldusLiveService.removeListener(this); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); listView.setAdapter(mAdapter); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.list, null); listView = (ListView) view.findViewById(R.id.list); return view; } @Override public String toString() { return getArguments().getString(ARG_TITLE); } public Pair<Integer, Integer> getIdAndPositionForView(View v, boolean isLeft) { if(listView == null) throw new IllegalStateException("Listview not yet created"); int positionForView = listView.getPositionForView(v); if(isLeft) return new Pair<Integer, Integer>(mAdapter.getItem(positionForView).get(0).getId(), positionForView); else return new Pair<Integer, Integer>(mAdapter.getItem(positionForView).get(1).getId(), positionForView); } 

Разве не странно, что при возобновлении приложения (если действие было уничтожено), ViewPager с его фрагментами и его ListView и его пользовательскими макетами нарисованы. Но я получаю IllegalStateException говоря, что представление не было создано, если я долгое время IllegalStateException любую из ячеек в списке?

Edit / Фактически, Log.d(Constants.TAG, "onCreateView!!!!"); Вывод в onCreateView показывает, что методы вызывается два раза при первом запуске приложения (по одному для каждого фрагмента в ViewPager), но затем он никогда не вызывается снова, когда приложение возобновляется !? Это ошибка или что я могу сделать неправильно?

Solutions Collecting From Web of "OnCreateView не вызывается с помощью фрагмента в ViewPager"

Жизненно важной частью, по-видимому, был FragmentPagerAdapter (который я не включил). Отладка показывает, что getItem() не вызывается при восстановлении активности. Фрагменты воссоздаются другими способами. Это означало, что моя реализация FragmentPagerAdapter имела неправильные ссылки на фрагменты в FragmentManager .

Поэтому вместо этого, когда мне нужно найти фрагмент, я использую findFragmentByTag()FragmentManager ), используя makeFragmentName() чтобы получить соответствующее имя тега. Это метод, используемый FragmentPagerAdapter при добавлении фрагмента. Не уверен, что это безопасный подход или нет.