簡體   English   中英

正確使用Fragments和TabListener

[英]Using Fragments and TabListener the right way

我的問題是關於帶有標簽的片段。 我有一個活動,基本上是一個空的布局,我動態地添加了一些片段。 一旦開始活動,我便向其中添加了一個帶有列表視圖的片段,當我單擊列表中的某個項目時,便刪除了具有列表視圖的片段,並添加了另一個包含有關該列表的詳細信息的片段。 現在也可以看到一些標簽。 單擊這些選項卡之一將顯示列表視圖中有關該項目的其他詳細信息。

我確實有可用的代碼,但似乎我完全將其修改了。

這是其中的一些內容:

活動:

// 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的書以了解有關片段的更多信息,但是我找不到包含不同片段一起工作的更復雜的示例,也找不到如何處理或覆蓋后退按鈕。 例如,單擊后退按鈕后,如果fragment1、2或3可見,則始終顯示fragment4。 如果有人在書中找到一個,您能告訴我這一章(名稱)/頁面嗎? 如果沒有,那么在下一次更新中,普通人會提供一個。

注意2:在項目中使用了全局變量,例如fSpeed,tabSpeed,...

注意3:如果您需要更多代碼或說明,請在評論中讓我知道。 感謝您的幫助!

我自己編寫的方法changeFragment()是錯誤的方法嗎?

您正在添加一個片段,而不是替換一個片段。 要替換片段,請使用replace() ,而不要使用add()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM