2

私の問題は、タブ付きのフラグメントに関するものです。基本的に空のレイアウトを持つアクティビティが 1 つあり、フラグメントを動的に追加します。アクティビティを開始するとすぐに、リストビューを含むフラグメントを追加し、リストの項目をクリックすると、リストビューを含むフラグメントを削除し、それに関する詳細を含む別のフラグメントを追加します。また、いくつかのタブが表示されるようになりました。これらのタブのいずれかをクリックすると、リストビューのアイテムに関するその他の詳細が表示されます。

動作するコードはありますが、完全にハッキングしているようです。

ここにいくつかのビットがあります:

アクティビティ:

// In onCreate:
@Override
  protected void onCreate(Bundle savedInstanceState) {
    // Check that the activity is using the layout version with
    // the fragment_container FrameLayout
    if (findViewById(R.id.fragment_container) != null) {
      // However, if we're being restored from a previous state,
      // then we don't need to do anything and should return or else
      // we could end up with overlapping fragments.
      if (savedInstanceState != null) {
        return;
      }
      // Create an instance of FList
      fList = new FList();
      // Add the fragment to the 'fragment_container' FrameLayout
      getFragmentManager().beginTransaction().add(R.id.fragment_container,fList).commit();
    }
  }



// After clicking on an item of the listview changeFragment() is called
public void changeFragment() {
  FragmentTransaction ft = getFragmentManager().beginTransaction();
  fSpeed = new FSpeed();
  ft.add(R.id.fragment_container, fSpeed);

  // this might be necessary
  if (actionBar != null)
    actionBar.selectTab(tabSpeed);
  ft.commit();
}

// In the activity I also setup the ActionBar with tabs
private void setupActionBar() {
  tabSpeed = actionBar.newTab();
  // and a few more tabs...
  tabSpeed.setTabListener(this);
  actionBar.addTab(tabSpeed);
  // But the tabs are not visible because of the navigation mode
  actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
}

// Here is the tabListener - very hacky!
@Override
  public void onTabSelected(Tab tab, FragmentTransaction ft)
    if (fm == null)
      fm = getFragmentManager();
    Fragment f = null;
    switch (tab.getPosition()) {
    case 0:
      if (fSpeed == null)
        fSpeed = new FSpeed();
      f = findFragment(fSpeed);
      if (f != null) {
        ft.setCustomAnimations(R.anim.fragment_alpha_0_1, R.anim.fragment_alpha_1_0);
        ft.remove(f);
        ft.add(R.id.fragment_container, fSpeed);
      } else {
        Log.d(TAG, "fSpeed is " + f);
        return;
      }
      break;
      case 1:
        // more tabs - similar code
    }

// the findFragment() method
private Fragment findFragment(Fragment selectedFragment) {
  if (fm.findFragmentById(R.id.fragment_container) == fSpeed && selectedFragment != fSpeed)
    return fSpeed;
  // more ifs for other fragments
  else
    return null;
}

これはすべてうまくいきましたが、タブ間でx回切り替えた後、おかしくなり始めました。たとえば、fListが表示され、タブアイコンが消えました...バグを追跡してnullチェックを追加することはできましたが、間違っていたと思います仕方。これが、TabListener を次のように変更した理由です。

// Still in activity
public static class MyTabListener<T extends Fragment> implements TabListener {
  private Fragment mFragment;
  private final Activity mActivity;
  private final String mTag;
  private final Class<T> mClass;
  /**
  * * Constructor used each time a new tab is created. 
  * * * @param
  * activity * The host Activity, used to instantiate the fragment 
  * * @param
  * tag * The identifier tag for the fragment 
  * * @param clz * The
  * fragment's Class, used to instantiate the fragment
  */
  public MyTabListener(Activity activity, String tag, Class<T> clz) {
    mActivity = activity;
    mTag = tag;
    mClass = clz;
    }

  /* The following are each of the ActionBar.TabListener callbacks */
  public void onTabSelected(Tab tab, FragmentTransaction ft) {
    // Check if the fragment is already initialized
    if (mFragment == null) {
      // If not, instantiate and add it to the activity
      mFragment = Fragment.instantiate(mActivity, mClass.getName());
      ft.add(R.id.fragment_container, mFragment, mTag);
    } else {
    // If it exists, simply attach it in order to show it
      ft.attach(mFragment);
    }
  }

public void onTabUnselected(Tab tab, FragmentTransaction ft) {
  if (mFragment != null) {
    ft.detach(mFragment);
  }
}

// The tabs are now assigned to MyTabListener
tabSpeed.setTabListener(new MyTabListener<FSpeed>(this, "speed", FSpeed.class));

ここから問題が始まりました。新しい TabListener を使用してリストビューの項目をクリックすると、onTabSelected と onTabUnSelected が順番に際限なく呼び出されます。

質問:

私の質問は、リストビューの項目をクリックした後、リストビューのあるフラグメントから別のフラグメントに移動する方法です (それでも同じアクティビティを使用します)。自分で書いたメソッド changeFragment() は間違ったアプローチですか? それでも MyTabListener を使用したいと思います。

注 1: フラグメントについて詳しく知るために Commonsware の本を購入しましたが、さまざまなフラグメントが連携して動作するより複雑な例を見つけることができず、戻るボタンの処理方法やオーバーライド方法もわかりませんでした。たとえば、フラグメント 1、2、または 3 が表示されている場合に戻るボタンをクリックすると、常にフラグメント 4 が表示されます。誰かが本の中でそれを見つけたら、その章(名前)/ページを教えてもらえますか? ない場合は、次の更新かそこらで提供することは、Common の非常に親切なことです。

注 2: fSpeed、tabSpeed などのグローバル変数がプロジェクトで使用されました。

注 3: さらにコードや説明が必要な場合は、コメントでお知らせください。助けてくれてありがとう!

4

1 に答える 1

0

自分で書いたメソッド changeFragment() は間違ったアプローチですか?

フラグメントを置き換えるのではなく、フラグメントを追加しています。フラグメントを置き換えるにはreplace()、 ではなくを使用しますadd()

于 2012-11-01T07:31:28.720 に答える