ActionBar and Fragments on ICS 4.0.3

2019-07-22 20:35发布

I'm trying to develop an Android app and I have some problems with the ActionBar.

I need something similar to Instagram or Twitter for Android: I have an Action Bar with 3 tabs and these tabs have some buttons; every button has an OnClick() that replaces the actual fragment with a new one (for example ''FragmentN'') using FragmentTransaction (and the method replace()) .

My first problem is that when I select a tab from the ActionBar, the selected tab doesn't replace "FragmentN" but it places itself on top so I continue seeing both fragment, one above the other.

I have also another problem but I think it's linked to the previous...however I explain you with an example. I select tab A from the ActionBar and from this tab I press button 3 so "FragmentA3" replaces "FragmentA". After this, I select tabC from the ActionBar. Now I select, always from the ActionBar, the tab A again but instead of seeing again "FragmentA" I see "FragmentA3" that I choose previously.

How can I solve these problems? Thank you very much.

EDIT: This is my code.

MainActivity

    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) {
  }} }

Tab1Fragment

   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();
   } });
}
 }

Nuova

   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_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">


<Button
    android:id="@+id/butt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button" />

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    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_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      android:gravity="center">

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

2条回答
男人必须洒脱
2楼-- · 2019-07-22 21:03

In your Tab1Fragment in onClick method you replace mFragment instance with newly created nuovo

Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

(It looks like mFragment now reffer to another object(nuovo), but i may be wrong -- I'll check it tommorow)

So, at first replace this line transaction.replace(android.R.id.content, nuovo);

with

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

Then modify your public void onTabSelected(Tab tab, FragmentTransaction ft) with the following code:

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);
  }
查看更多
Anthone
3楼-- · 2019-07-22 21:09

Use the method detach and attach wherever necessary on the fragment on changing the tab. For example,

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);
        }
    }

You can see the full source in Android samples in the following path android-sdk -> samples -> android-16 -> ApiDemos -> src -> com -> example -> android -> apis -> app -> FragmentTabs.java

查看更多
登录 后发表回答