正确使用Fragments和TabListener

时间:2012-10-31 17:33:00

标签: android android-fragments

我的问题是关于带标签的片段。我有一个基本上有空布局的活动,我动态地添加片段。一旦我开始活动,我就会添加一个带有listview的片段,当我点击列表中的某个项目时,我会删除带有listview的片段,并添加另一个片段及其详细信息。现在也可以看到一些标签。单击其中一个选项卡可显示列表视图中有关该项目的其他详细信息。

我确实有工作代码,但似乎我完全是在破解它。

以下是它的一些内容:

的活动:

// 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是可见的,标签图标消失了,...我可以跟踪错误并添加一些空检查,但我认为我走错了路。这就是我用以下方法更改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。如果有人在书中找到了一个,请告诉我章节(姓名)/页面?如果不存在,那么在下一次更新中提供一个人就会很普通。

注2:项目中使用了全局变量,如fSpeed,tabSpeed,...

注3:如果您需要更多代码或说明,请在评论中告诉我。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

  

我自己编写的方法changeFragment()是错误的方法吗?

您正在添加片段,而不是替换片段。要替换片段,请使用replace(),而不是add()