使用ViewPager从活动到片段进行通信

使用ViewPager从活动到片段进行通信

本文介绍了使用ViewPager从活动到片段进行通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于包含viewpagertablayout,我有一个活动和两个片段.现在,我可以通过实现Google的指南回调接口,将片段从Activity传达到Activity.但是,我该如何从活动到片段进行另一种交流?如果活动中发生了某些事件(外部事件),我想更新片段.我设法用

I have one Activity and two Fragments for a tablayout containing a viewpager.Now I can communicate from the fragment to the Activity by implementing the google's guide callback interface. But how can I communicate the other way from activity to fragment? If something happens in the Activity (external events) I want to update the Fragment. I managed to get the Frag1 fragment with

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

但是当我在frag上调用公共方法时,我得到了一个IllegalStateException:片段未附加到Activity上,可能是因为getItem(0)返回了Frag1的新实例,而该实例尚未附加...有人可以提供清理整个Viewpager的解决方案->片段通信的活动性?

but when I call public methods on frag I get a IllegalStateException: Fragment not attached to Activity probably because getItem(0) returns a new instance of Frag1 and this is not attached yet... is there anyone who can provide a clean solution for this whole Viewpager -> Activity to Fragment communication?

一些适合您的代码:

活动中:

@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);
    }

推荐答案

您需要设置一些事件侦听器逻辑,在该逻辑中,片段为所需的事件向活动注册.该片段应在创建时注册,而在销毁时注销.

You need to set up some event listener logic where the fragment registers with the activity for the event it wants. The fragment should register on creation and unregister on destruction.

然后,当事件发生时,活动将遍历已注册的侦听器列表,并将事件通知给他们.

Then when the event occurs, the activity goes through the list of registered listeners and notifies them of the event.

我在此答案中给出了详细的示例.

I give a detailed example in this answer.

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

You can use an event bus library to simplify some of the wiring between the activity and the fragments.

这篇关于使用ViewPager从活动到片段进行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 20:57