2017-08-01 212 views
3

我有一个ViewPager活动,ViewPager的每个页面都有一个片段。如何替换片段内的片段?

在我的Screen3Fragment里面我有一个LinearLayout(lly_fragments),我在其中显示一些其他片段。我开始显示片段Screen3_1

public class Screen3Fragment extends Fragment { 

    private FragmentManager manager; 
    private FragmentTransaction transaction; 


    public static Screen3Fragment newInstance() { 
     final Screen3Fragment mf = new Screen3Fragment(); 
     return mf; 
    } 

    public Screen3Fragment() { 
    } 

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

     View v = inflater.inflate(R.layout.fragment_screen3, container, false); 
     Screen3_1Fragment frag31 = new Screen3_1Fragment(); 
     manager = getChildFragmentManager(); 
     transaction = manager.beginTransaction(); 
     transaction.add(R.id.lly_fragments,frag31,"frag31"); 
     transaction.addToBackStack("frag31"); 
     transaction.commit(); 
     return v; 
    } 

} 

这工作正常没有问题。从frag31(它位于Screen3Fragment内部)开始,我想调用fragt32,因为我做了以下操作。

public class Screen3_1Fragment extends Fragment { 

    private ImageButton imgbt_timer; 
    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 

     View v = inflater.inflate(R.layout.fragment_screen3_1,container,false); 
     imgbt_timer = (ImageButton) v.findViewById(R.id.bT_scr31_timer); 
     imgbt_timer.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       getChildFragmentManager().beginTransaction() 
              .replace(R.id.lly_fragments, new Screen3_2Fragment(), "frag32") 
              .commit(); 
      } 
     }); 


     return v; 
    } 
} 

正如我在其他的答案读,行transaction.replace应该做的伎俩并更换由给定frag32现有frag31同一给定容器内lly_fragments

但是,我得到java.lang.IllegalArgumentException: No view found for id.....我不知道为什么。

+0

看看View.invalidate()。 https://developer.android.com/reference/android/view/View.html#invalidate() 不知道,但也许这可能有所帮助。 –

+0

使用片段管理器,而不是子片段管理器。我想如果你使用子管理器,你应该在父代片段中使用view id。 –

+0

@FlorescuGeorgeCătălin,谢谢,我将不胜感激更详细的答案,我应该在哪里使用它?在我的'Screen3Fragment' ??中,在我的'Screen3_1Fragment' ??在他们两个??中,为什么?我读到,当使用片段内的片段时,您称为儿童管理器 – codeKiller

回答

0

getFragmentManager()将始终返回来自父级的属性,大多数情况下是活动。 getChildFragmentManager()将返回父项属性(在你的情况下,Screen3Fragment属性)。应该在片段中添加片段时使用它。

在你的情况,应Screen3Fragment使用getFragmentManager()添加和Screen3_1Fragment应该使用getChildFragmentManager()因为Screen3_1FragmentScreen3Fragment孩子加入。 Screen3Fragment是父项。

我强烈建议您始终使用getFragmentManager()add方法,而不是replace,因为您的父母将是相同的。

getChildFragmentManager()可以在片段中添加ViewPager时使用。

+0

ok,'Screen3Fragment'是Screen3_1Fragment和Screen3_2Fragment的父项,所以它不需要添加或替换。 – codeKiller

+0

根据您的实施情况,我不知道您是如何做到的。 –

+0

好的,我会玩弄它,并接受它,如果我得到它的工作。谢谢! – codeKiller

0

您可以使用回调,如下: 为我工作,我希望我的回答可以帮助你

1)创建一个接口

public interface ChangeFragmentListener { 

    void onChangeFragmentLicked(int fragment); 
} 

2)实施界面和交易方式:

 public class MainActivity extends AppCompatActivity implements ChangeFragmentListener { 


     FragmentTransaction fragmentTransaction; 
     Fragment1 fragment1; 
     Fragment2 fragment2; 


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

      fragment1 = new Fragment1(); 
      fragment1.setChangeFragmentListener(this); 

      fragment2 = new Fragment2(); 
      fragment2.setChangeFragmentListener(this); 

      initListeners(); 
     } 

    void changeToFrag1() { 
      fragmentTransaction = getFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.activity_main_fragment_container,fragment1, ""); 
      fragmentTransaction.commit(); 
     } 

     void changeToFrag2() { 
      fragmentTransaction = getFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.activity_main_fragment_container, fragment2, ""); 
      fragmentTransaction.commit(); 
     } 

@Override 
    public void onChangeFragmentLicked(int fragment) { 
     switch (fragment){ 
      case 1: 
       changeToFrag1(); 
       break; 

      case 2: 
       changeToFrag2(); 
       break; 
     } 
    } 

3)从接口创建对象来处理回调:

public class Fragment1 extends Fragment { 

    private ChangeFragmentListener changeFragmentListener; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.fragment_fragment1, container, false); 

     view.findViewById(R.id.fragment1_textView).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       changeFragmentListener.onChangeFragmentLicked(2); 
      } 
     }); 

     return view; 
    } 

    public Fragment1 setChangeFragmentListener(ChangeFragmentListener changeFragmentListener) { 
     this.changeFragmentListener = changeFragmentListener; 
     return this; 
    } 
}