ICS 4.0.3 上的 ActionBar 和 Fragments

Posted

技术标签:

【中文标题】ICS 4.0.3 上的 ActionBar 和 Fragments【英文标题】:ActionBar and Fragments on ICS 4.0.3 【发布时间】:2012-10-02 09:02:02 【问题描述】:

我正在尝试开发一个 android 应用,但 ActionBar 出现了一些问题。

我需要类似于 Android 版 Instagram 或 Twitter 的东西:我有一个带有 3 个选项卡的操作栏,这些选项卡有一些按钮;每个按钮都有一个 OnClick(),它使用 FragmentTransaction(和方法 replace())将实际片段替换为新片段(例如“FragmentN”)。

我的第一个问题是,当我从 ActionBar 中选择一个选项卡时,所选选项卡不会替换“FragmentN”,而是将自己置于顶部,因此我继续看到两个片段,一个在另一个之上。

我还有另一个问题,但我认为它与前一个问题有关......但是我用一个例子来解释你。 我从 ActionBar 中选择选项卡 A,然后从该选项卡中按下按钮 3,以便“FragmentA3”替换“FragmentA”。之后,我从 ActionBar 中选择 tabC。 现在我总是从 ActionBar 中再次选择选项卡 A,但我没有再次看到“FragmentA”,而是看到了我之前选择的“FragmentA3”。

我该如何解决这些问题? 非常感谢。

编辑:这是我的代码。

主活动

    import android.os.Bundle;
    import android.annotation.SuppressLint;
    import android.annotation.TargetApi;
    import android.app.ActionBar;
    import android.app.ActionBar.Tab;
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentTransaction;


    @SuppressLint("NewApi")
    @TargetApi(11)
    public class ABActivity extends Activity 
@Override
     public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    ActionBar actionBar = getActionBar(); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    //TAB 1
    Tab tab = actionBar.newTab(); 
    tab.setIcon(R.drawable.p);
    String label1 = "one";
    TabListener<Tab1Fragment> tl1 = new TabListener<Tab1Fragment>(this,
            label1, Tab1Fragment.class);
    tab.setTabListener(tl1);
    actionBar.addTab(tab);

    //TAB2
    tab = actionBar.newTab(); 
    tab.setIcon(R.drawable.m);
    String label2 = "two";
    TabListener<Tab2Fragment> tl2 = new TabListener<Tab2Fragment>(this,
            label2, Tab2Fragment.class);
    tab.setTabListener(tl2);
    actionBar.addTab(tab);

    //TAB3       
    tab = actionBar.newTab(); 
    tab.setIcon(R.drawable.s);
    String label3 = "three";
    TabListener<Tab3Fragment> tl3 = new TabListener<Tab3Fragment>(this,
            label3, Tab3Fragment.class);
    tab.setTabListener(tl3);
    actionBar.addTab(tab);
     

   private class TabListener<T extends Fragment> implements   ActionBar.TabListener 
  private Fragment mFragment;
  private final Activity mActivity;
  private final String mTag;
  private final Class<T> mClass;

  public TabListener(Activity activity, String tag, Class<T> clz) 
  
      mActivity = activity;
      mTag = tag;
      mClass = clz;
  

  public void onTabSelected(Tab tab, FragmentTransaction ft) 
  
     if (mFragment == null) 
          mFragment = Fragment.instantiate(mActivity, mClass.getName());
          ft.add(android.R.id.content, mFragment, mTag);
       else 
          ft.attach(mFragment);
      

      

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

  public void onTabReselected(Tab tab, FragmentTransaction ft) 
   

Tab1片段

   import android.annotation.SuppressLint;
   import android.app.Fragment;
   import android.app.FragmentTransaction;
   import android.os.Bundle;
   import android.view.LayoutInflater;
   import android.view.View;
   import android.view.ViewGroup;
   import android.widget.Button;
   import android.widget.LinearLayout;

   public class Tab1Fragment extends Fragment 
 Fragment f;
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 

    return (LinearLayout) inflater.inflate(R.layout.tab1, container, false);
  

      @Override
       public void onActivityCreated (Bundle savedInstanceState)

super.onActivityCreated(savedInstanceState);
f=this;

Button butt = (Button) getActivity().findViewById(R.id.butt);
butt.setOnClickListener(new View.OnClickListener() 

@SuppressLint("NewApi")
public void onClick(View v) 
 Fragment nuovo = new Nuova();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

transaction.replace(android.R.id.content, nuovo);
transaction.addToBackStack("nuovo");

 transaction.commit();
    );

 

诺瓦

   import android.app.Fragment;
   import android.os.Bundle;
   import android.view.LayoutInflater;
   import android.view.View;
   import android.view.ViewGroup;
   import android.widget.LinearLayout;

   public class Nuova extends Fragment 

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 

        return (LinearLayout) inflater.inflate(R.layout.nuova, container, false);
     

tab1.xml

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab1"
android:layout_
android:layout_
android:orientation="vertical"
android:gravity="center">


<Button
    android:id="@+id/butt"
    android:layout_
    android:layout_
    android:text="Button" />

<TextView
    android:id="@+id/textView1"
    android:layout_
    android:layout_
    android:layout_gravity="center"
    android:text="one" />

    </LinearLayout>

nuova.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/nuovo"
      android:layout_
      android:layout_
      android:orientation="vertical"
      android:gravity="center">

<TextView
    android:id="@+id/textView1"
    android:layout_
    android:layout_
    android:layout_gravity="center"
    android:text="nuova" />
 </LinearLayout>

【问题讨论】:

你应该发布一些代码。不幸的是,没有代码来查看“我该如何解决这些问题?”的唯一答案。是“修复你的代码”。 【参考方案1】:

在更改选项卡时,在片段上的任何必要位置使用分离和附加方法。 例如,

public void onTabSelected(Tab tab, FragmentTransaction ft) 
        if (mFragment == null) 
            mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
            ft.add(android.R.id.content, mFragment, mTag);
         else 
            ft.attach(mFragment);
        
    

您可以在以下路径android-sdk -&gt; samples -&gt; android-16 -&gt; ApiDemos -&gt; src -&gt; com -&gt; example -&gt; android -&gt; apis -&gt; app -&gt; FragmentTabs.java中查看Android示例中的完整源代码

【讨论】:

这正是我正在做的......我认为在 TabListener 中需要修改一些东西,但我不知道是什么。我发布了我的代码!【参考方案2】:

在 onClick 方法中的 Tab1Fragment 中,将 mFragment 实例替换为新创建的 nuovo

替换已添加到容器中的现有片段。这本质上与为所有当前添加的片段调用 remove(Fragment) 相同,这些片段使用相同的 containerViewId 添加,然后使用此处给出的相同参数调用 add(int, Fragment, String)。

(看起来 mFragment 现在引用另一个对象(nuovo),但我可能错了——我明天会检查它)

所以,首先替换这一行 transaction.replace(android.R.id.content, nuovo);

transaction.replace(android.R.id.content, nuovo, "nuovoTag");

然后使用以下代码修改您的 public void onTabSelected(Tab tab, FragmentTransaction ft):

Fragment fr = getFragmentManager().findFragmentByTag("nuovoTag");
if (fr != null)
  ft.remove(fr);

  if (mFragment == null) 
      mFragment = Fragment.instantiate(mActivity, mClass.getName());
      ft.add(android.R.id.content, mFragment, mTag);
   else 
      ft.attach(mFragment);
  

【讨论】:

谢谢,但最后我以另一种方式修改了 onTabSelected,所以我解决了重叠问题(第一个),但我还有第二个......我需要回到原来的碎片,但我找不到方法!这是我的 onTabSelected public void onTabSelected(Tab tab, FragmentTransaction ft) if (mFragment == null) mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); else if(mFragment.getTag().equals(getFragmentManager().findFragmentById(android.R.id.content).getTag())) ft.show(mFragment);否则 ft.detach(getFragmentManager().findFragmentById(android.R.id.content)); if (mFragment == null) mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); else ft.attach(mFragment);

以上是关于ICS 4.0.3 上的 ActionBar 和 Fragments的主要内容,如果未能解决你的问题,请参考以下文章

像在 ICS 中一样在 android 2.x 中创建下拉菜单的最佳方法

关于 Lazarus 上的 ICS

创建javascript ICS以添加到ios上的日历

Android ICS 上的 GCM 通知不起作用

如何自定义ActionBar上的后退按钮

更改后退按钮上的颜色(在ActionBar上)