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