3

我有一个活动和两个片段,其中包含viewpagertablayout。 现在我可以通过执行谷歌的指南回调界面从片段与活动进行交流。但是我怎样才能通过从活动到?如果活动(外部事件)中发生某些事情,我想更新片段。我设法与使用ViewPager从活动到片段的通信

MyFragmentPagerAdapter a = (MyFragmentPagerAdapter) viewPager.getAdapter(); 
Frag1 frag = (Frag1) a.getItem(0); 

得到Frag1片段,但是当我呼吁断枝public方法,我得到一个IllegalStateException异常:片段未连接到活动可能是因为的getItem(0)返回Frag1的新实例,这是不附然而......有没有人能为整个Viewpager提供一个干净的解决方案 - >片段沟通活动?

你的某些代码:

在活动

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

     ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager); 
     if (viewPager != null) { 
      viewPager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager())); 
     } 

     TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs); 
     if (tabLayout != null) { 
      tabLayout.setupWithViewPager(viewPager); 
     } 
} 

活动布局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:orientation="vertical" 
    tools:context="com.MainActivity"> 

    <android.support.design.widget.TabLayout 
     android:id="@+id/sliding_tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/viewpager" 
     android:layout_width="match_parent" 
     android:layout_height="0px" 
     android:layout_weight="1"/> 
</LinearLayout> 

MyFragmentPagerAdapter:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter { 

    final int PAGE_COUNT = 2; 
    private String tabTitles[] = new String[] { "tab1", "tab2" }; 

    public MyFragmentPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     switch (position) { 
      case 0: 
       return Frag1.newInstance(position + 1); 
      case 1: 
       return Frag2.newInstance(position + 1); 
      default: 
       return null; 
     } 
    } 

    @Override 
    public int getCount() { 
     return PAGE_COUNT; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return tabTitles[position]; 
    } 
} 

Frag1:

public class Frag1 extends Fragment { 
    public static final String ARG_PAGE = "ARG_PAGE"; 

    private int mPage; 

    private onFrag1InteractionListener mListener; 

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

    /** 
    * Use this factory method to create a new instance of 
    * this fragment using the provided parameters. 
    * 
    * @return A new instance of fragment Frag1. 
    */ 
    public static Frag1 newInstance(int page) { 
     Frag1 fragment = new Frag1(); 
     Bundle args = new Bundle(); 
     args.putInt(ARG_PAGE, page); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (getArguments() != null) { 
      mPage = getArguments().getInt(ARG_PAGE); 
     } 
    } 

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


    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof onFrag1InteractionListener) { 
      mListener = (onFrag1InteractionListener) context; 
     } else { 
      throw new RuntimeException(context.toString() 
        + " must implement onFrag1InteractionListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 

    public interface onFrag1InteractionListener { 
     // TODO: Update argument type and name 
     void onFrag1Interaction(Action action); 
    } 
+0

扩展AppCompatActivity而不是Activity然后检查发生了什么? – Nitesh

+0

活动已扩展AppCompatActivity – Zuop

+0

你是什么意思的外部事件?假设你想在刷标签时更新片段。像这样 – Nitesh

回答

1

你需要建立一些事件监听器哪里的逻辑与它想要的事件活动的片段寄存器。该片段应该在创建时注册并注销破坏。

然后,当事件发生时,活动会遍历已注册侦听器的列表并通知其事件。

我给出了一个详细的例子this answer

您可以使用事件总线库来简化活动和片段之间的一些连线。

+0

我按照你的答案的链接指示,并解决了它。 。虽然我觉得实现一个接口来从Fragment - > Activity进行通信,然后另外还有另一个接口来从Activity - > Fragment – Zuop

+0

进行通信,我觉得很奇怪我的例子没有在活动上实现一个接口,但这样做对于单元测试和重用。很多谷歌的例子都是像导航抽屉这样做的。 –

+0

噢好吧..我一定误解了你的答案,但是现在它可以工作。 尽管你说过“定义一个监听器接口,我通常将其作为活动内的一个内部接口”链接:) – Zuop