2015-11-12 50 views
7

MainActivity替換()不與多片段正常工作

package example.antonio.activitydemo; 

import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.support.v4.app.*; 

public class MainActivity extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     final FragmentManager fragmentManager = getSupportFragmentManager(); 

     Button button = (Button) findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       FirstFragment fragment = new FirstFragment(); 
       FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

       fragmentTransaction.add(R.id.container, fragment); 
       fragmentTransaction.commit(); 
      } 
     }); 

     Button button2 = (Button) findViewById(R.id.button2); 
     button2.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       SecondFragment fragment = new SecondFragment(); 
       FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

       fragmentTransaction.replace(R.id.container, fragment); 
       fragmentTransaction.commit(); 
      } 
     }); 
    } 
} 

FirstFragment

package example.antonio.activitydemo; 

import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.ViewGroup; 
import android.view.View; 

public class FirstFragment extends Fragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) { 
     return inflater.inflate(R.layout.first_fragment, container, false); 
    } 
} 

SecondFragment

package example.antonio.activitydemo; 

import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.ViewGroup; 
import android.view.View; 

public class SecondFragment extends Fragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) { 
     return inflater.inflate(R.layout.second_fragment, container, false); 
    } 
} 

他們的XML文件:

main_activity.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/container" 
    android:orientation="vertical"> 

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

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

</LinearLayout> 

first_fragment.xml

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="#000000"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="First!" 
     android:textColor="#ffffff"/> 


</FrameLayout> 

second_fragment.xml就像前面的一個,只有android:text="Second!"

這裏是奇怪的事情,當我點擊4次Start1按鈕,然後我得到4個字First!,直到這裏一切正常。以下如果我點擊Start2按鈕,我期望的是刪除4個以前的片段,並添加一個新的片段,出現Second!。這是我從文檔中理解的:

替換已添加到容器的現有片段。這與爲所有當前添加的片段調用remove(Fragment)相同的containerViewId,然後使用此處給出的相同參數添加(int,Fragment,String)基本相同。

但這裏是我所得到的:

After I click 4 times <code>Start1</code> button After I click <code>Start2</code> button

我試圖讀取源代碼,也許我發現這裏是「問題」,我想知道你在想什麼如果是我在某個地方犯了錯誤。

這裏是片斷BackStackRecord.javarun()方法:

case OP_REPLACE: { 
        Fragment f = op.fragment; 
        int containerId = f.mContainerId; 
        if (mManager.mAdded != null) { 
         for (int i = 0; i < mManager.mAdded.size(); i++) { 
          Fragment old = mManager.mAdded.get(i); 
          if (FragmentManagerImpl.DEBUG) { 
           Log.v(TAG, 
             "OP_REPLACE: adding=" + f + " old=" + old); 
          } 
          if (old.mContainerId == containerId) { 
           if (old == f) { 
            op.fragment = f = null; 
           } else { 
            if (op.removed == null) { 
             op.removed = new ArrayList<Fragment>(); 
            } 
            op.removed.add(old); 
            old.mNextAnim = op.exitAnim; 
            if (mAddToBackStack) { 
             old.mBackStackNesting += 1; 
             if (FragmentManagerImpl.DEBUG) { 
              Log.v(TAG, "Bump nesting of " 
                + old + " to " + old.mBackStackNesting); 
             } 
            } 
            mManager.removeFragment(old, mTransition, mTransitionStyle); 
           } 
          } 
         } 
        } 

,這裏是從FragmentManager.java的片段:

public void removeFragment(Fragment fragment, int transition, int transitionStyle) { 
     if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); 
     final boolean inactive = !fragment.isInBackStack(); 
     if (!fragment.mDetached || inactive) { 
      if (false) { 
       // Would be nice to catch a bad remove here, but we need 
       // time to test this to make sure we aren't crashes cases 
       // where it is not a problem. 
       if (!mAdded.contains(fragment)) { 
        throw new IllegalStateException("Fragment not added: " + fragment); 
       } 
      } 
      **if (mAdded != null) { 
       mAdded.remove(fragment); 
      }** 
      if (fragment.mHasMenu && fragment.mMenuVisible) { 
       mNeedMenuInvalidate = true; 
      } 
      fragment.mAdded = false; 
      fragment.mRemoving = true; 
      moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED, 
        transition, transitionStyle, false); 
     } 
    } 

正如你所看到的, removeFragment方法從mAdded中刪除分部,但在run()方法中,i索引沒有被修改,它從它離開的地方重新啓動,以這種方式它可能會丟失一些元素...

+1

我認爲這是一個錯誤,其他人發現相同的問題:https://code.google.com/p/android/issues/detail?id=83178&can=1&q=fragment%20replace&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars – zer0uno

+0

嘗試調用getSupportFragmentManager();直接從每個按鈕的onclick正文,而不是最終 – Olu

+0

已完成,同樣的問題。 – zer0uno

回答

0

您無法使用linearlayout作爲容器來實現此方案。

如果您嘗試使用片段作爲linearlayout中的容器,則可以實現此目的。請詢問進一步的澄清

Android - fragment .replace() doesn't replace content - puts it on top

此鏈接,否則使用按鈕下面的代碼單擊操作,

Button button = (Button) findViewById(R.id.button); 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      FirstFragment fragment = new FirstFragment(); 
      FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 

      fragmentTransaction.add(R.id.container, fragment).addToBackStack(null); 
      fragmentTransaction.commit(); 
     } 
    }); 

    Button button2 = (Button) findViewById(R.id.button2); 
    button2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      SecondFragment fragment = new SecondFragment(); 
      FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
      for(int i=0; i < getSupportFragmentManager().getBackStackEntryCount(); i++) 
       getSupportFragmentManager().popBackStack(); 
      fragmentTransaction.replace(R.id.container, fragment); 
      fragmentTransaction.commit(); 
     } 
    }); 

希望這將幫助你..謝謝