Android碎片,视图未被移除。

11

我开发了一个应用程序,在其中我有一个片段事务。

MainActivity 包含 Fragment View

MainActivity 在屏幕顶部有三个 Button,当我们从这个 Activity 移动到另一个 Fragment 时,这三个按钮保持不变,只有 MainActivityFragment 部分在我们点击其中之一后才会改变。

但是,我的问题是当我从这个 MainActivity 移动到 Fragment 时,如果我点击第一个按钮那就没问题,但是当我点击第二个按钮时,结果会用第一个 Fragment 覆盖屏幕,跳转到下一个 Fragment

因为它们在同一个 Activity 中,所以我不能通过 remove(fr).commit(); 来删除 Fragment

因为如果我这样做,它可能会使这个片段无法点击,也许片段被删除了,所以下一个按钮的点击将没有响应。

总体结果是,在我移动到 NewFragment 时,它显示了两个屏幕,即 FirstFragmentNewFragment 屏幕。那我如何在移动到 NewFragment 时删除 FirstFragment 屏幕?

MainActivity 中的三个按钮有以下代码来更改片段:

主要活动:

 public class MasterActivity extends Activity {                
   ImageView imgOne, imgTwo, imgThree;
   Fragment fr;                                              

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

    setContentView(R.layout.activity_master);             

    imgOne = (ImageView) findViewById(R.id.imgOne);       
    imgTwo = (ImageView) findViewById(R.id.imgTwo);       
    imgThree = (ImageView) findViewById(R.id.imgThree);


 imgOne.setOnClickListener(new View.OnClickListener() {                                                

       @Override                                                                                         
      public void onClick(View v) {                                                                     
     // TODO Auto-generated method stub                                                            
     fr = new FirstFragment();                                                                          

     FragmentManager fm = getFragmentManager();                                                    
     FragmentTransaction fragmentTransaction = fm.beginTransaction();                              
     fragmentTransaction.replace(R.id.fragment_place, fr);                                         
     fragmentTransaction.addToBackStack(null);                                                     
     //fragmentTransaction.remove(fr).commit();                                                    
     //getFragmentManager().beginTransaction().remove(fr).commit();                                  
     fragmentTransaction.commit();                                                                 
     }                                                                                                 
  });                                                                                                   

  imgTwo.setOnClickListener(new View.OnClickListener() {                                                

    @Override                                                                                         
    public void onClick(View v) {                                                                     
      // TODO Auto-generated method stub                                                            


     fr = new SecondFragment();                                                                           

     FragmentManager fm = getFragmentManager();                                                    
     FragmentTransaction fragmentTransaction = fm.beginTransaction();                              
     fragmentTransaction.replace(R.id.fragment_place, fr);                                         
     fragmentTransaction.addToBackStack(null);                                                     
     //fragmentTransaction.remove(fr).commit();                                                    
     // getFragmentManager().beginTransaction().remove(fr).commit();                                  
     fragmentTransaction.commit();                                                                 
    }                                                                                                 
 });    

以下是它的 XML 文件:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical" >

   <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="#000000"
    android:gravity="bottom"
    android:weightSum="3" >

    <ImageView
        android:id="@+id/imgOne"
        android:layout_width="0dp"
        android:layout_height="27dp"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:src="@drawable/img1" />

    <ImageView
        android:id="@+id/imgTwo"
        android:layout_width="0dp"
        android:layout_gravity="center"
        android:layout_height="27dp"
        android:layout_weight="1"
        android:src="@drawable/img2"/>
    <ImageView
        android:id="@+id/imgThree"
        android:layout_width="0dp"
        android:layout_gravity="center"
        android:layout_height="27dp"
        android:layout_weight="1"
        android:src="@drawable/img3" />
</LinearLayout>

 <fragment
     android:id="@+id/fragment_place"
    android:name="packagename.FirstFragment"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_weight="0.87"/>       
   <LinearLayout/>
 <LinearLayout/>

第一个片段:

public class FirstFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View r = inflater.inflate(R.layout.first_fratgment, container, false); 

        return r;
    }
}    

第二个碎片:

public class SecondFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View r = inflater.inflate(R.layout.second_fratgment, container, false); 

        return r;
    }
}    

但当点击一个名为Fragment的按钮时,它会显示第一个和第二个Fragment屏幕。

那么如何解决这个问题并在第二次点击时移除第一个视图?

我使用了这个:

fragmentTransaction.remove(fr).commit();

并且这个

getFragmentManager().beginTransaction().remove(fr).commit();

但它并没有起作用。


请发布您的NewFragment类。 - Ahmad Sanie
没问题,看到修改后的问题了。 - Joseph Mekwan
2
你不能在XML布局中声明一个嵌入式片段(使用fragment标签),然后对其进行事务处理(如替换)。因此,不要使用fragment标签,而是使用简单的FrameLayout,并在活动的onCreate()方法中手动添加片段。 - user
@Luksprog:谢谢,老兄……你太棒了……:)那个技巧很有用……谢谢谢谢谢谢….. - kiturk3
嗨 @Luksprog,现在它像魅力一样工作了...谢谢... - Joseph Mekwan
请查看此帖子的答案。 - Xcihnegn
7个回答

14

在Android中,布局中声明的Fragment会被特殊对待。请替换

 <fragment
     android:id="@+id/fragment_place"
     android:name="packagename.FirstFragment"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_weight="0.87"/> 

使用FrameLayout或您选择的任何ViewGroup子类,并以编程方式处理所有事务。其他部分看起来对我很好。

使用FrameLayout或您选择的任何ViewGroup子类,并以编程方式处理所有事务。其他部分看起来对我很好。


5

最好使用viewGroup或者layout/FrameLayout代替片段(在Activity中通过按钮点击进行片段导航)。因为片段有自己的生命周期,而片段会持有它们的视图或者在活动中进行片段转换时不会被销毁。

虽然如果你还是想使用片段,可以先加载第一个按钮点击的片段,并通过删除先前添加的片段(附加到第一个按钮点击的片段)来处理其他两个按钮的点击事件。

这可以通过以下方式实现:

getSupportFragmentManager().beginTransaction().remove(YOUR_FIRST_FRAGMENT).commit();

接下来您可以编写一段代码在这个位置添加片段,

getFragmentManager().beginTransaction().replace(YOUR_FIRST_FRAGMENT, new YourSecondButtonFragment()).commit();

因此,您也可以通过更改连接到第二个按钮的片段来实现第三个按钮的点击。

希望这能帮到您。


1

在XML中硬编码的片段是无法替换的。请使用FramLayout作为片段容器。

在您的XML中进行替换

<fragment
     android:id="@+id/fragment_place"
     android:name="packagename.FirstFragment"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_weight="0.87"/>       
   <LinearLayout/>

带有。
<FrameLayout
     android:id="@+id/contentFragment"
     android:layout_width="match_parent"
     android:layout_height="0px"
     android:layout_weight="2" />

现在,请按照以下代码风格实现你的目标:
首先将onClickListeners设置为所有的imageviews: 例如:imgOne.setOnClickListener(this);
            @Override
            public void onClick(View v) {
                Fragment fragment = null;
                switch (v.getId()) {
                    case R.id.imgOne:
                        fragment = new Fragment1();
                        break;
                    case R.id.imgTwo:
                        fragment = new Fragment2();
                        break;
                }
                if (fragment != null) {
                    FragmentManager fm = getSupportFragmentManager();
                    fm.beginTransaction().replace(R.id.contentFragment, fragment).commit();                        
                } else {
                    Log.e(LOG_TAG, "Error in fragment transaction.");
                }
            }

希望这有所帮助。

0

进行必要的更改。使用此活动和xml文件替换您自己的文件。 如果这样做,它应该可以稳定运行。

public class MasterActivity extends Activity {                
ImageView imgOne, imgTwo, imgThree;
Fragment fr;                                              

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

setContentView(R.layout.activity_master);             

imgOne = (ImageView) findViewById(R.id.imgOne);       
imgTwo = (ImageView) findViewById(R.id.imgTwo);       
imgThree = (ImageView) findViewById(R.id.imgThree);

getFragmentManager().beginTransaction().add(R.id.fragment_place, new FirstFragment()).commit();


imgOne.setOnClickListener(new View.OnClickListener() {                                                
    @Override                                                                                         
    public void onClick(View v) {    
        getFragmentManager().beginTransaction().replace(R.id.fragment_place, new FirstFragment()).commit();
    }                                                                                                 
});                                                                                                   

imgTwo.setOnClickListener(new View.OnClickListener() {
    @Override                                                                                         
    public void onClick(View v) {                                                                     
        getFragmentManager().beginTransaction().replace(R.id.fragment_place, new SecondFragment()).commit();                                                               
    }
});  

XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000000"
android:gravity="bottom"
android:weightSum="3" >

<ImageView
    android:id="@+id/imgOne"
    android:layout_width="0dp"
    android:layout_height="27dp"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:src="@drawable/img1" />

<ImageView
    android:id="@+id/imgTwo"
    android:layout_width="0dp"
    android:layout_gravity="center"
    android:layout_height="27dp"
    android:layout_weight="1"
    android:src="@drawable/img2"/>
<ImageView
    android:id="@+id/imgThree"
    android:layout_width="0dp"
    android:layout_gravity="center"
    android:layout_height="27dp"
    android:layout_weight="1"
    android:src="@drawable/img3" />
</LinearLayout>

 <FrameLayout
 android:id="@+id/fragment_place"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_weight="0.87"/>       
 <LinearLayout/>
 <LinearLayout/>

0
当我移动到NewFragment时,如何删除第一个片段屏幕?
你可以通过隐藏旧的(第一个)Fragmentsource来实现。
getSupportFragmentManager().beginTransaction().hide(getSupportFragmentManager()
                      .findFragmentById(R.id.the_id_of_my_first_fragment));

你也可以通过相同的方法source将它(第一个片段)获取回来。

getSupportFragmentManager().beginTransaction().show(getSupportFragmentManager()
                      .findFragmentById(R.id.the_id_of_my_first_fragment));

这种方法可以提高灵活性,而不需要重新更改应用程序的架构和逻辑,同时只需一行工作。

我总是晚到派对(:


0
你可以使用:getSupportFragmentManager().beginTransaction().remove(fragment).commit(); 希望这能帮到你。

-1

在您的按钮点击事件中复制并粘贴代码。

fr = new FirstFragment();  
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);                                         
fragmentTransaction.commit();

这是已完成的工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接