在每个 ViewPager 片段中添加回调侦听器



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

两个碎片...打开枯萎片段时,仅显示调用 MyFragBToast

的活动
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;
}  

}

我从这里使用了里克的答案。

公共类 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;
}

}

但只调用了最后一个片段

当然!因为在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;
}

因此,您正在尝试从activity进行通信fragment

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

为每个片段创建一个接口实例! 并在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>(); 

最新更新