2016-11-13 152 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