1

各「ビュー」が Fragment を拡張する 5 つの異なるビュー間をユーザーがスライドできるように、ViewPager を使用しています。

FragmentPagerAdapter を拡張し、getItem() を実装する独自のアダプターがあります。

@Override public Fragment getItem(int position) {
   switch(position) {
      case 0: 
          return new TextDescriptionFragment();
      // Handle the 4 other cases the same way
   }
}

これは正常に機能し、ユーザーは 5 つの異なるビュー間をスワイプできます。しかし、ここで問題が発生します。最初の 4 つのビューにはそれぞれ、ユーザーが操作できる Button や EditText などのビューが含まれています。

そして、最後のページ (ページ番号 5) に、前の 4 ページ (フラグメント) のすべてのビューからのすべてのユーザー入力値を表示します。それ、どうやったら出来るの?

前のフラグメントからユーザー入力値を読み取る方法が見つかりません。ビューはもう存在しないかもしれません (ただし、ユーザーが戻ると再作成されます)。

そして、既存のフラグメントを取得できないようです。

4

2 に答える 2

1

各フラグメントが埋めるデータを保持するカスタム オブジェクトを持つことを検討します。何かのようなもの:

public class FillerData implements Parcelable {
    private String page0$data0;
    private String page0$data1;
    private String page0$data2;

    // getters and setters if you wish

    // implement Parcelable interface as this object will be managed by host activity
}

親アクティビティによって管理されるそのようなオブジェクトは 1 つだけで、親アクティビティはこのオブジェクトを公開するためのインターフェイスを実装します。

public static interface FillerDataExposer {
    public FillerData exposeFiller();
}

public class MyFragmentHostActivity extends FragmentActivity implements FillerDataExposer {
    private static final String FILLER_KEY = "FILLER_KEY";
    private FillerData myFillerData;

    protected void onCreate(Bundle savedInstance) {
        .......
        if(savedInstance != null) {
            myFillerData = (FillerData) savedInstance.getParcelable(FILLER_KEY);
        } else {
            myFillerData = new FillerData();
        }
    }

    protected void onSaveInstanceState(Bundle savedInstance) {
        super.onSaveInstanceState();
        savedInstance.putExtra(FILLER_KEY, myFillerData);
    }

    public FillerData exposeFiller() {
        return this.myFillerData;
    }
}

これで、各フラグメントは、親アクティビティを介して集中化されたデータ フィラー オブジェクトにアクセスできるようになります。FillerDataExposerコードの重量を減らすために、すべてのフラグメントは、実装 (実際には親アクティビティ)へのアクセスを提供する基本フラグメント クラスから拡張できます。

public abstract class AbstractFillerFragment extends Fragment {
    protected FillerDataExposer dataExposer;

    public void onAttach(Activity act) {
        super.onAttach(act);
        // make sure no ClassCastExceptions
        this.dataExposer = (FillerDataExposer) act;
    }
}

満たされたデータのみを記録する必要があるフラグメントは、次のようになります。

public class Page1Fragment extends AbstractFillerFragment {

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = // inflate XML resource ...
        yourEditText = (EditText) view.findViewById(...);
        // other relevant code ....
    }

    public void onViewCreated(View view, Bundle savedInstanceState) {
       yourEditText.setText(dataExposer.exposeFiller.setPageX$DataY());
       // some code for EditText.addTextChangedListener(new TextWatcher() could look like:
        yourEditText.addTextChangedListener(new TextWatcher() {

          public void afterTextChanged(Editable s) {

            dataExposer.exposeFiller().setPage1$Data0(s.toString());

          }

          public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

          public void onTextChanged(CharSequence s, int start, int before, int count) {}
       });
    }
}

保存されているすべてのデータにアクセスする必要があるフラグメントは、次のようになります。

public class FinalFragment extends AbstractFillerFragment {
    public void collectAllData() {
        DataFiller allDataCollectedObject = dataExposer.exposeFiller();
        // by calling get...() you should have access to collected data.
    }
}

これはスケッチにすぎませんが、イメージは得られます。アイデアは、アクティビティの再起動全体で管理されるアクティビティ内の単一のオブジェクトを保持し、インターフェイスを介してアクセスできるようにすることで、フラグメントからアクティビティへのパターンを尊重します。

それが理にかなっていることを願っています...

于 2013-07-30T14:00:22.870 に答える
0

2つの解決策が頭に浮かびます。

1 つ目は、最初の 4 つのフラグメントの onpause() メソッドが呼び出されたときにユーザー入力データを保存することです。データをプリファレンスに保存してから、5 番目のフラグメントから取得することができます。

2 番目のアプローチは、スワイプ中にフラグメントを永続化することです。この方法では、スワイプがより高速かつクリーンになり、スワイプが発生するたびにフラグメントを再作成する必要があります。

yourcustomviewpager.setOffscreenPageLimit(5);

Android ドキュメントのsetOffscreenPageLimit について:

アイドル状態でビュー階層の現在のページの両側に保持するページ数を設定します。この制限を超えるページは、必要に応じてアダプターから再作成されます。これは最適化として提供されます。サポートする必要のあるページ数が事前にわかっている場合、またはページに遅延読み込みメカニズムを配置している場合は、この設定を調整すると、ページング アニメーションとインタラクションの滑らかさが感じられるというメリットがあります。一度にアクティブにできるページの数が少ない場合 (3 ~ 4 ページ)、ユーザーがページを行ったり来たりするときに、新しく作成されたビュー サブツリーのレイアウトに費やす時間が少なくなります。特にページのレイアウトが複雑な場合は、この制限を低く抑える必要があります。この設定のデフォルトは 1 です。

于 2013-07-30T13:36:31.387 に答える