更新
画面の向きと関係があると思いました。実際、デバイスの向きを変更せずにさまざまなアクションを実行すると、問題は発生せず、ウィジェットは正しく評価されます。向きを変えるとすぐに、元のアクティビティに戻ると、すべてのウィジェットが null になります。
元の投稿
Fragments または FragmentPagerAdapter のライフサイクルに問題があります。何が問題の原因なのかよくわかりません。
私は Fragments を初めて使用することに注意してください。何かを誤解したり忘れたりしたに違いありませんが、既存の投稿で答えを見つけることができませんでした。また、互換パッケージと、ActionBarSherlock および ViewPageIndicator の両方のライブラリを使用していることにも注意してください。
とにかく、ここに私の状況があります:
- 2 つのフラグメントを含む ViewPager を表示することを目標とする SherlockFragmentActivity A があり、両方のフラグメントは SherlockFragment を継承します。これまでのところ、すべて正常に動作し、両方のフラグメントに関連付けられたビューは正しく、ウィジェットでやりたいことは何でもできます。
- ActionBar で、ユーザーは SherlockActivity B を表示する項目をクリックして、データを入力して検証するか、入力をキャンセルすることができます。アクティビティ A で結果が期待されるため、アクティビティ B は startActivityForResult() で開始されます。
アイデアは、ユーザーがアクティビティ B によって表示されるフォームを入力して検証する場合、アクティビティ A の onActivityResult() の ViewPager の両方のフラグメントのコンテンツを更新することです。
しかし、ユーザーがフォームを検証した場合に onActivityResult() でフラグメントのビューを更新しようとすると、両方のフラグメントのすべてのウィジェットが null になります。Fragments が最初に提示されたときは null ではありませんでしたが、現在は null であり、初期値を取得する方法がわかりません。アクティビティのライフサイクルを試してみましたが、成功しませんでした。
私のコードの最も重要な部分は次のとおりです。
アダプター
public class TabGameSetPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments;
public TabGameSetPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return App.getApplication().getString(R.string.lblGamesTitle);
case 1:
return App.getApplication().getString(R.string.lblSynthesisTitle);
default:
return "Unknown[" + position + "]";
}
}
ポケットベルを使ったアクティビティ
public class TabGameSetActivity extends SherlockFragmentActivity implements IRefreshableGameSetContainer {
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
private GameSetGamesFragment gameSetGamesFragment = GameSetGamesFragment.newInstance();
private GameSetSynthesisFragment gameSetSynthesisFragment = GameSetSynthesisFragment.newInstance();
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.simple_titles);
// initialize the pager
this.initialisePaging();
}
catch (Exception e) {
AuditHelper.handleActivityException(this, e);
}
}
private void initialisePaging() {
this.gameSetGamesFragment = GameSetGamesFragment.newInstance();
this.gameSetSynthesisFragment = GameSetSynthesisFragment.newInstance();
List<Fragment> fragments = newArrayList();
fragments.add(this.gameSetGamesFragment);
fragments.add(this.gameSetSynthesisFragment);
this.mPagerAdapter = new TabGameSetPagerAdapter(super.getSupportFragmentManager(), fragments);
this.mPager = (ViewPager) super.findViewById(R.id.pager);
this.mPager.setAdapter(this.mPagerAdapter);
this.mPager.setCurrentItem(this.startPage-1);
TitlePageIndicator indicator = (TitlePageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(mPager);
indicator.setFooterIndicatorStyle(IndicatorStyle.Triangle);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
if (requestCode == RequestCodes.ADD_GAME) {
if (resultCode == ResultCodes.AddGame_Ok) {
this.refresh();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void refresh() {
this.gameSetGamesFragment.refresh();
this.gameSetSynthesisFragment.refresh();
}
}
特に、両方のフラグメントで refresh() メソッドの呼び出しを処理する onActivityResult() を参照してください。
欠片の一つ
public class GameSetGamesFragment extends SherlockFragment implements IRefreshableGameSetContainer {
private View mViewTabGameSet;
private LinearLayout playersLayout;
private LinearLayout gamesLayout;
private ScoresRow playerScoresRow;
private PlayersRow playersRow;
public static GameSetGamesFragment newInstance() {
return new GameSetGamesFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
this.mViewTabGameSet = inflater.inflate(R.layout.tablegameset, null);
this.playersLayout = (LinearLayout)this.mViewTabGameSet.findViewById(R.id.playersLayout);
this.gamesLayout = (LinearLayout)this.mViewTabGameSet.findViewById(R.id.gamesLayout);
this.playerScoresRow = new ScoresRow(this.getActivity(), App.getBizService().getPlayers());
this.playersRow = new PlayersRow(this.getActivity(), App.getBizService().getPlayers());
this.playersLayout.addView(this.playersRow);
this.playersLayout.addView(this.playerScoresRow);
this.progressDialog = new ProgressDialog(this.getActivity());
this.refreshGameRows();
return this.mViewTabGameSet;
}
protected void refreshGameRows() {
this.gamesLayout.removeAllViews();
for (View rowToDisplay : rowsToDisplay) {
this.gamesLayout.addView(rowToDisplay);
}
...
}
@Override
public void refresh() {
this.refreshGameRows();
}
}
すべてのコードをここに記載したわけではありませんが、最も重要なビットが存在します。ご覧のとおり、フラグメントの onCreateView() メソッドは refreshGameRows() を呼び出し、フラグメントの refresh() メソッドも呼び出します。したがって、UI レンダリングに関しては、どちらの方法も基本的に同じことを行います。
ただし、TabGameSetActivity クラスの onActivityResult() でメソッド refresh() が呼び出されると、すべてのフラグメント ウィジェットが null になります: gamesLayout、mViewTabGameSet... onCreateView() が以前に呼び出され、適切にすべてのオブジェクト。
現在、例外がスローされているため、UI は更新されていません。最初のアクティビティとそのすべての子フラグメントも再作成されるように、デバイスの向きを変更する必要があります。しかし、これをエンドユーザーに出荷する方法はありません:/
そのため、どんな助けでも大歓迎です。
前もって感謝します。