Fragment ViewPager 中的后退按钮实现

Back Button Implementation in Fragment ViewPager

我在一个ViewPager里面有3个Fragments。我想为每个 Fragment 实现不同的后退按钮功能。目前,我已经在每个片段中创建了与我希望后退按钮执行的操作相对应的方法。我使用以下方法在 activity 中实现了一个接口:

@Override
public void onCameraBack(int i) {
    currFrag = i;
}

这里的思路是三个片段,每个片段在自己的onStart()方法中调用这个方法。片段 0 传递 0,片段 1 传递 1,片段 2 传递 2。因此,持有 activity 知道哪个片段可见。现在我试图获取对该片段的引用,以便能够调用我在其中实现的后退按钮方法。我试过使用这个:

@Override
public void onBackPressed() {
    if (currFrag == 0) {

    }
    else if (currFrag == 1) {
        FragmentBTesting fragmentBTesting= new FragmentBTesting();
        fragmentBTesting.FragmentBBack();
    }
}`

但这不起作用。我不能使用 findFragmentbyId 方法,因为我的片段在 XML 中没有片段标签,它们会填满整个屏幕并且它们的视图是使用 linearLayouts 定义的。我的问题是如何获取片段的实例以便调用其 FragmentBack() 方法。

这是我的全部 activity

  public class FragmentActivityTesting extends FragmentActivity implements FragmentATesting.logoutListener,FragmentBTesting.onCameraBack {
ViewPager viewPager = null;
SessionManager session = new SessionManager(MyApp.getContext());
int currFrag;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fragment_activity_testing);
    viewPager = (ViewPager) findViewById(R.id.pic_pager);
    setStatusBarColor();
    FragmentManager fragmentManager = getSupportFragmentManager();
    viewPager.setAdapter(new MyAdapter(fragmentManager));
    viewPager.setCurrentItem(1);
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("CLOSE_ALL");
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    };
    registerReceiver(broadcastReceiver, intentFilter);

}
@TargetApi(21)
public void setStatusBarColor() {
    Window window = this.getWindow();
    // clear FLAG_TRANSLUCENT_STATUS flag:
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

    if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 21) {
        window.setStatusBarColor(this.getResources().getColor(R.color.green));

    }

}

@Override
public void logout() {
    session.logOut();
    Intent a = new Intent(this,MainActivity.class);
    startActivity(a);
    Intent intent = new Intent("CLOSE_ALL");
    this.sendBroadcast(intent);
    finish();
}
@Override
public void onBackPressed() {
    if (currFrag == 0) {

    }
    else if (currFrag == 1) {
        FragmentBTesting fragmentBTesting= new FragmentBTesting();
        fragmentBTesting.FragmentBBack();
    }
}


@Override
public void onCameraBack(int i) {
    currFrag = i;
}
}

class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int position) {
    Fragment fragment = null;
    if (position ==0) {
        fragment = new FragmentATesting();
    }
    else if (position == 1) {
        fragment = new FragmentBTesting();
    }
    else if (position == 2) {
        fragment = new FragmentCTesting();
    }
    return fragment;
}

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

}

为什么不告诉 activity 你当前在哪个片段上,为什么不告诉它在按下后退时执行什么?

在你的activity中你可以有一个字段来保存回调字段(作为一个Runnable,我知道很讨厌。如果你愿意,你可以制作自己的界面),setter,然后是 onBackPressed 实现。这是我的有效代码片段。我使用的是 Guava 的 Optional class,但如果你喜欢那种东西,你可以 null 代替它。

这是应该实现 ActivityWithHomeButton

的 Activity
private Optional<? extends Runnable> backButtonListener = Optional.absent();

@Override
public void onBackPressed() {
    // Check if there is a custom back button
    if (backButtonListener.isPresent()) {
        backButtonListener.get().run();
        backButtonListener = Optional.absent();
    } else {
        super.onBackPressed();
    }
}

@Override
public void setBackButtonListener(Optional<? extends Runnable> backButtonListener) {
    this.backButtonListener = backButtonListener;
}

这是我在activity

中实现的接口
public interface ActivityWithHomeButton {
    void setBackButtonListener(Optional<? extends Runnable> runnable);
}

当然还有片段的用法

parent.setBackButtonListener(Optional.of(new Runnable() {
        @Override
        public void run() {
            // do back button stuff
        }
    }));

您可以将其放在片段中的任何位置。您还需要在不再需要时清除后退按钮侦听器 (onPause)。你可以这样做

parent.setBackButtonListener(Optional.<Runnable>absent());

其中 parent 可以使用此处详述的标准 activity 片段通信模式 (http://developer.android.com/training/basics/fragments/communicating.html) 实现。此代码进入您的片段

private ActivityWithHomeButton parent;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        parent = (ActivityWithHomeButton) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement ActivityWithHomeButton");
    }
}

希望对您有所帮助!