2016-11-13 137 views
9

我想用新的Fragment替換舊的Fragment,但我仍然看到在舊片段中仍然可見的舊Fragment的按鈕。用另一個片段替換一個片段

在舊的,點擊一個按鈕 enter image description here

FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
Fragment newFragment = GenericMood.newInstance("a","b"); 

// Replace whatever is in the fragment_container view with this fragment, 
// and add the transaction to the back stack if needed 
transaction.replace(R.id.allmoods, newFragment); 
transaction.addToBackStack(null); 
transaction.commitAllowingStateLoss(); 

我可以取代舊Fragment用新的,但是從R.id.allmoods Fragment按鈕仍然可見在新的頂部Fragment

enter image description here

我試着用下面這個代碼中給出。

FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
Fragment newFragment = GenericMood.newInstance("a","b"); 

// Replace whatever is in the fragment_container view with this fragment, 
// and add the transaction to the back stack if needed 
transaction.replace(((ViewGroup)getView().getParent()).getId(), newFragment); 
transaction.addToBackStack(null); 
transaction.commitAllowingStateLoss(); 

XML文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/allmoods" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@color/colorPrimary" 
    tools:context="com.moodoff.Moods"> 
    <Button 
     android:text="Button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="64dp" 
     android:id="@+id/btn_btn" 
     android:height="80dp" 
     android:width="100dp" 
     android:onClick="putmeoff" 
     android:layout_marginLeft="17dp" 
     android:layout_marginStart="17dp"/> 
</RelativeLayout> 

這是應該替換上面的片段:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:id="@+id/genericmood" 
    android:layout_height="match_parent" 
    android:background="@color/colorPrimary" 
    tools:context="com.moodoff.GenericMood"> 
    <!-- TODO: Update blank fragment layout --> 


    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="#000000" 
     android:layout_gravity="fill_horizontal" 
     android:id="@+id/floatingButtons" 
     > 
     <android.support.design.widget.FloatingActionButton 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="1dp" 
      android:layout_marginRight="14dp" 
      app:backgroundTint="#ffffff" 
      android:layout_alignParentTop="true" 
      android:layout_alignParentRight="true" 
      android:layout_alignParentEnd="true" 
      android:src="@drawable/cameraicon" 
      android:id="@+id/btn_camera" 
      app:fabSize="mini" 
      /> 
    </RelativeLayout> 
</FrameLayout> 

兩個不起作用。該怎麼辦? 更新:用適當的容器替換後,按鈕已經消失,但新的片段沒有正確實例化。我得到一個純白色的空白屏幕。 enter image description here

my activity_alltabs.xml looks like this: 

<?xml version="1.0" encoding="utf-8"?> 
    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:id="@+id/main_content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:fitsSystemWindows="true" 
     tools:context="com.moodoff.AllTabs"> 

     <android.support.design.widget.AppBarLayout 
      android:id="@+id/appbar" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:theme="@style/AppTheme.AppBarOverlay"> 

      <android.support.design.widget.TabLayout 
       android:id="@+id/tabs" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:background="@android:color/background_dark" /> 

     </android.support.design.widget.AppBarLayout> 

     <android.support.v4.view.ViewPager 
      android:id="@+id/container" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

    </android.support.design.widget.CoordinatorLayout> 
+0

你可以添加你的XML文件。片段xml專用 –

+0

@masoudvali:完成 – Santanu

+0

給你的活動xml – Sayem

回答

3

在你活動的onCreate功能,你應該叫setContentView(R.layout.main),那麼當你想加載一個片段,您在R.layout.main選擇ViewParent。該片段將成爲該ViewParent的孩子。所以ID傳入FragmentTransaction.replace,是在R.layout.main ViewParent的ID。

它是有道理的,因爲FragmentTransaction.replace函數只會替換該容器中的現有片段,您的allmoods RelativeLayout中的按鈕將保留。 R.layout.main中的所有內容都將保留。這就是Activity如何保持靜態內容,如抽屜或工具欄。

當你加載你的「新片段」時,你將使用相同的ID。因此,「新片段」取代R.layout.main內的ViewParent的新孩子「舊片段」。

這裏是Fragments API guide

更新:

當你調用你的活動的onCreate功能FragmentTransaction.replace,這可以再造一個現有的片段。確保savedInstanceState(傳遞給onCreate的Bundle)爲null。如果savedInstanceState不爲空,那麼該片段可能已經存在,您可以像這樣找到它;

Fragment f = getFragmentManager().findFragmentByTag(YOUR_FRAGMENT_TAG); 

更新2:

Here is a guide,應該幫助你。它看起來像你可以使用FragmentPagerAdapter來簡化你的片段交易。

+0

謝謝。但事情是,我有一個標籤活動ALLTabs.java。在其中一個選項卡(讓我們說第一個)中,我創建了一個顯示一些按鈕的片段。點擊該片段中的一個按鈕後,一個新片段將替換該片段,但是我看到舊片段中新片段中的按鈕。 – Santanu

+0

確保在加載每個片段時將相同的ID傳遞到FragmentTransaction.replace。另外...我會編輯別的東西的答案。 – Mike

+0

如何確保第一個片段正在加載該片段ID,因爲我只用了一次從第一個片段導航到第二個片段。我使用了正確的容器ID。 – Santanu

3

爲了理解片段轉換的流程,首先,你必須知道它在活動中的結構。 讓我們來看看: a)活動:在一切的底部(MainActivity)

activity_main.xml中: -

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <FrameLayout 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
</RelativeLayout> 

這裏@ + ID /容器是佈局在我們做的片段內容轉變。

B)片段A:最初添加到MainActivity容器的片段。

FragmentManager fm = getFragmentManager(); 
FragmentTransaction ft = fm.beginTransaction(); 
//Instance of fragment 
Fragment newFragment = FragmentA.newInstance("a","b"); 
//It will replace the fragment content view to container of main activity 
ft.replace(R.id.container, newFragment); 
//FragmentA is added to back stack with it's name as a tag 
ft.addToBackStack(FragmentA.class.getSimpleName()); 
ft.commitAllowingStateLoss(); 

B)FragmentB:與FragmentB

替換FragmentA這背後
FragmentManager fm = getFragmentManager(); 
FragmentTransaction ft = fm.beginTransaction(); 
//Instance of fragment 
Fragment newFragment = FragmentB.newInstance("a","b"); 
//It will replace the fragment content view to container of fragment A which  // is previously replaced to main activity container 
ft.replace(R.id.container, newFragment); 
//FragmentB is added to back stack with it's name as a tag 
ft.addToBackStack(FragmentB.class.getSimpleName()); 
ft.commitAllowingStateLoss(); 

所以主要的是要替換/添加片段內容視圖的活動容器視圖。

+0

謝謝。它的增加,但我沒有看到任何新的替換片段中的內容。它是一個純白色的屏幕。 – Santanu

0

問題是傳遞給replace方法的容器ID是要替換的片段的ID,而不是片段容器的ID。這似乎解釋了爲什麼一些原始片段控件在替換之後仍然存在 - 整個片段沒有被替換。

請更改它以獲取片段容器視圖ID,它將起作用!這裏是代碼:

transaction.replace(((ViewGroup)(getView()。getParent()))。getId(),fragment);

我找到了獲取片段的容器視圖ID的答案,Get fragment的容器視圖ID。

1

試試這一次, 1.如果您是通過在按鈕的任何值單擊 在活動

Category category=new Category(); 
      Bundle bundle=new Bundle(); 
      bundle.putString("heading",heading); 
      bundle.putInt("position",position1+1); 
      bundle.putString("url",url); 
      bundle.putString("sku",sku); 
      bundle.putBoolean("flag",flag); 
      category.setArguments(bundle); 

      FragmentManager fragmentManager = getSupportFragmentManager(); 
      final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
      fragmentTransaction.replace(R.id.fragmentCategories,category); 
      fragmentTransaction.commit(); 

在片段

Bundle bundle=getArguments(); 
    if(getArguments()!=null) { 
     position = bundle.getInt("position"); 
     heading = bundle.getString("heading"); 
     url = bundle.getString("url"); 
     sku=bundle.getString("sku"); 
     flag=bundle.getBoolean("flag"); 

     tvHeading.setText(heading); 

     video_chapter = handler.getContent_Aspects(position); 
     adapter = new Chapter_content_Adapter(getActivity(), video_chapter, url, heading, position); 
     gvChapter.setAdapter(adapter); 
    } 

2.如果簡單地調用片段

FragmentManager fragmentManager = getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentCategories=fragmentManager.findFragmentById(R.id.fragmentCategories); 
    fragmentTransaction.commit(); 
0

只要使按鈕setVisibility(View.GONE)在當這個片段開始交易時你的活動。

1

請嘗試下面的代碼。

A)創建活動如下:

MainActivity

import android.app.FragmentTransaction; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 

public class MainActivity extends AppCompatActivity implements ShowNextFragment{ 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    FragmentA fragmentA=new FragmentA(); 
    FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction(); 
    fragmentTransaction.replace(R.id.container,fragmentA); 
    fragmentTransaction.addToBackStack("A"); 
    fragmentTransaction.commitAllowingStateLoss(); 

} 

@Override 
public void showFragment() { 
    FragmentB fragmentB=new FragmentB(); 
    FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction(); 
    fragmentTransaction.replace(R.id.container,fragmentB); 
    fragmentTransaction.addToBackStack("B"); 
    fragmentTransaction.commitAllowingStateLoss(); 
} 
} 

B)創建2個片段如下:

片段A

import android.app.Fragment; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 


public class FragmentA extends Fragment { 
private ShowNextFragment showNextFragment; 



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

     showNextFragment=(ShowNextFragment)getActivity(); 
     Log.e("CAllback","Set"); 
    }catch (ClassCastException e){ 
     Log.e("Error","Please Implement ShowFragment Interface"); 
    } 
    return inflater.inflate(R.layout.fragment_a,container,false); 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (showNextFragment!=null){ 
       showNextFragment.showFragment(); 
      } 
     } 
    }); 

} 
} 

片段B

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

public class FragmentB extends Fragment { 



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

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 


} 
} 

C)創建的接口如下

public interface ShowNextFragment { 
void showFragment(); 
} 

d)作爲創建以下個XML:

ⅰ)activity_main

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

    </RelativeLayout> 

ⅱ)fragment_a

<?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:background="@color/colorcyan" 
android:orientation="vertical"> 

<Button 
    android:id="@+id/button" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Show Fragment B" /> 
</LinearLayout> 

III)fragment_b

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@color/colorgreen" 
android:orientation="vertical"> 

<TextView 

    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Fragment B" 
    android:layout_centerVertical="true" 
    android:layout_alignRight="@+id/btn_camera" 
    android:layout_alignEnd="@+id/btn_camera" /> 

<android.support.design.widget.FloatingActionButton 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:backgroundTint="#ffffff" 
    android:src="@android:drawable/ic_dialog_email" 
    android:id="@+id/btn_camera" 
    app:fabSize="mini" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" /> 
</RelativeLayout> 
5

我以前的片段工作,希望這會幫助你,給你一個更好地瞭解流程。首先,你的MainActivity.xml文件將是這樣的:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    tools:context="com.example.activity.HomeActivity"> 


    //This frameLayout will contain all your fragments view. 
    <FrameLayout 
     android:id="@+id/container_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
    </FrameLayout> 

</RelativeLayout> 

接下來,創建兩個片段以及它們的XML如下提到:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:clickable="true" // important to have this 
    tools:context=".fragments.frament1"> 

    <Button 
     android:id="@+id/btn" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom"/> 

</RelativeLayout> 

下一個片段看起來完全一樣,上面提到的。這裏是Fragment1.class

public class Fragment1 extends Fragment implements View.OnClickListener { 
Button btn; 

    public Fragment1() { 
    // Required empty public constructor 
} 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment1, container, false); 
     view.setBackgroundColor(Color.WHITE); 

     //Perform required conditions and return view 
     button = (Button) view.findViewById(R.id.btn); 
     button.setOnClickListener(this); 

     return view; 
     } 

     public void onClick(View v) { 

      switch(v.getId()) 
      { 
       case R.id.btn: 
       //replace current fragment on button click 

       Fragment fragment2= new Fragment2(); 

       getFragmentManager().beginTransaction(). 
       replace(R.id.container_view, fragment2). 
       addToBackStack("frags").commit(); 

       break; 
      } 
     } 
} 

而且Fragment2情況如下:

public class Fragment2 extends Fragment{ 
String TAG = "Fragment2"; 


    public Fragment2() { 
     // Required empty public constructor 
    } 

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

      View view = inflater.inflate(R.layout.fragment2,container,false); 
      view.setBackgroundColor(Color.WHITE); 
     return view; 
    } 
} 

正如我前面提到的,XML文件將是一樣的。這裏更重要的是,主要活動將包含一個佈局,當用戶切換片段時,該佈局將採用片段視圖。因此,我們使用替換方法,它將用我們指定的片段視圖替換先前的視圖。

+0

我的activity_alltabs.xml如下所示: – Santanu