Fragment
を表示するには、ACLのViewPager
を使用しています。最初に、これらのフラグメントはすべてListFragment
にリストが含まれています。私は2列テーブルを模倣しようとしているので、リストの各要素には2つのオブジェクトの別のリストが含まれています。私は各セルをリスト項目全体ではなく、クリック可能にしたいので、独自のColumnLayoutを実装しました(たぶんCellLayoutと呼ばれるべきです)。各リスト項目には、2つのColumnLayoutsが含まれています。これらはLongClickableで、どのエンティティが長押しされたかに関する情報を返すためにgetContextMenuInfo()
を実装しています。このメソッドは、ViewPagerを検索し、現在のフラグメントを尋ねてから、そのフラグメントを呼び出して、長押しされたビューからエンティティIDを返します。正しい行を取得するには、フラグメントにする必要があります。ViewPagerのフラグメントでonCreateViewが呼び出されていません
ここで問題が発生します。 getListView()
がIllegalStateException
「コンテンツビューがまだ作成されていません」とスローすることがあります。私。 onCreateView(...)
が呼び出されていません。これは、アプリが再開されたときにのみ発生します。今日は、私のGalaxy Nexusで[設定]> [デベロッパーオプション]の[アクティビティを保存しない]オプションを有効にして問題を再現しました。私は、アプリを起動し、ホームを押して、最近のアプリメニューからアプリを再度開いて、今度はリストビュー内のセルのどれかを長押しするとこの例外がスローされます。いくつかのデバッグ出力によって、私はonCreateViewが一度も呼び出されていないことを確認することができました。 FragmentとそのListViewとそのセル項目を持つViewPager全体がすべて描画されるので、これは奇妙です。
ACL内のListFragment
がカスタムレイアウトをサポートしていないことが#android-devに伝えられたので、ListFragment
を使わずにandroid.support.v4.app.Fragment
を再実装しましたが、それは役に立たなかった。
短い要約:私は押され、細胞内entitiyについての情報を含むMenuInfo
オブジェクトを作成する目的のために長押しレイアウトのイベントを処理するカスタムレイアウトを持っています。レイアウトに含まれるエンティティを見つけるには、最終的に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);
}
アプリを再開すると(アクティビティが破棄された場合)、そのフラグメントとそのListViewとカスタムレイアウトを持つViewPagerがすべて描画されるのはむしろ奇妙なことではありませんか?しかし、私はIllegalStateException
を得て、リストビュー内のセルのどれかを長押しするとビューが作成されていないと言っていますか?/
編集は実は、onCreateView
でLog.d(Constants.TAG, "onCreateView!!!!");
出力は、メソッドが、私はアプリ(ViewPagerの各フラグメントに1つ)を起動しますが、アプリケーションが再開されたとき、それが再び呼び出されることはありませんだ2回の最初の時間に呼び出されることを示しています! ?それはバグですか、何が間違っているのでしょうか?