在每个viewpager片段中添加calback侦听器

时间:2017-09-02 09:33:30

标签: android android-fragments android-viewpager

我在viewpager中有2个片段,我想在两者中使用interface添加回调方法。我在viewpager adapter中启动片段时添加了接口侦听器,但只调用了最后一个片段。这就是为什么当我点击MainActivity's菜单选项时,即使 MyFragA 正在显示,也只会调用 MyFragB 中的Toast

两个碎片...只有活动调用MyFragB Toast在打开枯萎片段时显示

public class MyFragA extends Fragment implements FragmentCaller {

    private TextView myTxt;

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

    @Override
    public void CallFragment() {
        if(getActivity()!=null)
            Toast.makeText(getActivity(), "Activity calling MyFragA", Toast.LENGTH_SHORT).show();
    }
}
public class MyFragB extends Fragment implements FragmentCaller{

    private TextView myTxt;

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

    @Override
    public void CallFragment() {
        if(getActivity()!=null)
            Toast.makeText(getActivity(), "Activity calling MyFragB", Toast.LENGTH_SHORT).show();
    }
}

主要活动

public class MainActivity extends AppCompatActivity {

    TabLayout tabs;
    ViewPager viewpager;

    FragmentCaller fragListerner = null;
    public interface FragmentCaller {
        void CallFragment();
    }

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

        tabs = (TabLayout)findViewById(R.id.tabs);
        viewpager = (ViewPager)findViewById(R.id.viewpager);
        SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(this, getSupportFragmentManager());
        viewpager.setAdapter(adapter);
        tabs.setupWithViewPager(viewpager);

    } // onCreate ends



    public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {

        private Context mContext;

        public SimpleFragmentPagerAdapter(Context context, FragmentManager fm) {
            super(fm);
            mContext = context;
        }

        // This determines the fragment for each tab
        @Override
        public Fragment getItem(int position) {
            Fragment fragment = null;
            if (position == 0) {
                fragment = new MyFragA();
                fragListerner = (FragmentCaller) fragment;
                return fragment;
            } else if (position == 1){
                fragment = new MyFragB();
                fragListerner = (FragmentCaller)fragment;
                return fragment;
            }
            return null;
        }

        // This determines the number of tabs
        @Override
        public int getCount() {
            return 2;
        }

        // This determines the title for each tab
        @Override
        public CharSequence getPageTitle(int position) {
            // Generate title based on item position
            switch (position) {
                case 0:
                    return mContext.getString(R.string.fraga);
                case 1:
                    return mContext.getString(R.string.fragb);
                default:
                    return null;
            }
        }

    }

    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.callback, menu);
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        switch (item.getItemId()){
            case R.id.call:
                if(fragListerner!=null){
                    if(fragListerner instanceof MyFragA){
                        fragListerner.CallFragment();
                    }else if(fragListerner instanceof MyFragB){
                        fragListerner.CallFragment();
                    }
                }
                break;
        }

        return true;
    }  


}

2 个答案:

答案 0 :(得分:1)

我使用了来自here的rick的回答。

公共类MainActivity扩展了AppCompatActivity {

TabLayout tabs;
ViewPager viewpager;
public static int currentFrag=0;
SimpleFragmentPagerAdapter adapter;

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

    tabs = (TabLayout)findViewById(R.id.tabs);
    viewpager = (ViewPager)findViewById(R.id.viewpager);
    adapter = new SimpleFragmentPagerAdapter(this, getSupportFragmentManager());
    viewpager.setAdapter(adapter);
    tabs.setupWithViewPager(viewpager);
    viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            System.out.println("sammy_current_position: "+position);
            currentFrag = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

} // onCreate ends



public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {

    private Context mContext;

    public SimpleFragmentPagerAdapter(Context context, FragmentManager fm) {
        super(fm);
        mContext = context;
    }

    @Override
    public Fragment getItem(int position) {
        if (position == 0) {
            return new MyFragA();
        } else if (position == 1){
            return new MyFragB();
        }
        return null;
    }

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

    // This determines the title for each tab
    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        switch (position) {
            case 0:
                return mContext.getString(R.string.fraga);
            case 1:
                return mContext.getString(R.string.fragb);
            default:
                return null;
        }
    }

}

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.callback, menu);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {
    super.onOptionsItemSelected(item);
    switch (item.getItemId()){
        case R.id.call:
            if(currentFrag == 0) {
                MyFragA frag1 = (MyFragA)viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem());
                frag1.specialCase();
            }

            break;
    }

    return true;
}

}

答案 1 :(得分:0)

  

但只调用了最后一个片段

当然!因为在pos == 0您正在设置fragListerner = (FragmentCaller) fragment,然后再次在pos == 1重新设置 fragListerner = (FragmentCaller)fragment;。所以这个条件,fragListerner instanceof MyFragB永远都是真的!

        @Override
        public Fragment getItem(int position) {
            Fragment fragment = null;
            if (position == 0) {
                fragment = new MyFragA();
                fragListerner = (FragmentCaller) fragment;
                return fragment;
            } else if (position == 1){
                fragment = new MyFragB();
                fragListerner = (FragmentCaller)fragment;
                return fragment;
            }
            return null;
        }

因此,您正尝试从activityfragment

进行沟通

好的,如果您仍想使用接口,可以这样做:

为每个片段创建一个接口实例!并在getItem中分配两者,

@Override
        public Fragment getItem(int position) {
            Fragment fragment = null;
            if (position == 0) {
                fragment = new MyFragA();
                fragAListerner = (FragmentCaller) fragment;
                return fragment;
            } else if (position == 1){
                fragment = new MyFragB();
                fragBListerner = (FragmentCaller)fragment;
                return fragment;
            }
            return null;
        }

,有一种更简单的方法可以从它的父活动调用片段方法,如下所示,例如:

Fragment fragment = adapter.getItem(0); // MyFragA is at pos 0
fragment.<specific_function_name>(); 

,使用它的ID!

MyFragA fragment = (MyFragA) getFragmentManager().findFragmentById(R.id.MyFragAId);
fragment.<specific_function_name>(); 

,使用它的标签!

MyFragA fragment = (MyFragA) getFragmentManager().findFragmentByTag("MyFragATag");
fragment.<specific_function_name>();