用后退按钮上的另一个替换片段

Replace Fragment with another on back button

我试图覆盖后退按钮,因为当我按下时它会关闭我的应用程序,我有不同的片段:

我有我的 Main Activity:它管理我的 Fragments(因为有一个导航抽屉)。

我找到了很多关于这个的帖子,但我无法实现它们:

以片段 B 为例:

@Override
public void onBackPressed(){
    FragmentManager fm = getSupportFragmentManager();
    Fragment f = fm.findFragmentById(R.id.fragmentb); // get the fragment that is currently loaded in placeholder
    Object tag = f.getTag();
    // do handling with help of tag here
    // call super method
    super.onBackPressed();
}

它说不能解析onBackPressed()和getSupportFragmentManager(),我想我没有正确使用该方法,所以怎么办?

Activity:

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {

    private static String TAG = MainActivity.class.getSimpleName();
    private Toolbar mToolbar;
    private FragmentDrawer drawerFragment;

    //Initialisation de l activite avec les donnees necessaires
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        drawerFragment = (FragmentDrawer)getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
        drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
        drawerFragment.setDrawerListener(this);
        // Affichage de la navigation
        displayView(0);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //Ajout des items
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onDrawerItemSelected(View view, int position) {
        displayView(position);
    }

    private void displayView(int position) {
        Fragment fragment = null;
        String title = getString(R.string.app_name);
        switch (position) {
            case 0:
                fragment = new Accueil();
                title = getString(R.string.title_accueil);
                break;
            case 1:
                fragment = new NosOffres();
                title = getString(R.string.title_nosoffres);
                break;
            case 2:
                fragment = new DemandeGratuite();
                title = getString(R.string.title_demandegratuite);
                break;
            case 3:
                fragment = new ContactezNous();
                title = getString(R.string.title_contact);
                break;
            case 4:
                fragment = new Actualites();
                title = getString(R.string.title_actu);
                break;
            case 5:
                fragment = new MentionsLegales();
                title = getString(R.string.title_mentions);
                break;
            default:
                break;
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.container_body, fragment);
            fragmentTransaction.commit();
            // libelle du toolbar
            TextView titlet;
            titlet = (TextView) findViewById(R.id.main_toolbar_title);
            titlet.setText(title);
            titlet.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/GothamBook.ttf"));
        }
    }
}

@jujyfruits

我试过了但是没用:

    @Override
    public void onBackPressed(){
        Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.demande_gratuite);
        if (myFragment != null && myFragment.isVisible()) {
            AlertDialog alertDialog = new AlertDialog.Builder(this).create();
            alertDialog.setTitle("Reset...");
            alertDialog.setMessage("test");
            alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            });
            alertDialog.show();
        }
        super.onBackPressed();
    }
}

@AutonomousApps

public class MainActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {

    private static String TAG = MainActivity.class.getSimpleName();
    private Toolbar mToolbar;
    private FragmentDrawer drawerFragment;

    //Initialisation de l activite avec les donnees necessaires
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        drawerFragment = (FragmentDrawer)getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
        drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
        drawerFragment.setDrawerListener(this);
        // Affichage de la navigation
        displayView(0);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //Ajout des items
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onDrawerItemSelected(View view, int position) {
        displayView(position);
    }

    private void displayView(int position) {
        Fragment fragment = null;
        String title = getString(R.string.app_name);
        switch (position) {
            case 0:
                fragment = new Accueil();
                title = getString(R.string.title_accueil);
                break;
            case 1:
                fragment = new NosOffres();
                title = getString(R.string.title_nosoffres);
                break;
            case 2:
                fragment = new DemandeGratuite();
                title = getString(R.string.title_demandegratuite);
                break;
            case 3:
                fragment = new ContactezNous();
                title = getString(R.string.title_contact);
                break;
            case 4:
                fragment = new Actualites();
                title = getString(R.string.title_actu);
                break;
            case 5:
                fragment = new MentionsLegales();
                title = getString(R.string.title_mentions);
                break;
            default:
                break;
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.container_body, fragment);
            fragmentTransaction.addToBackStack("name");
            fragmentTransaction.commit();
            // libelle du toolbar
            TextView titlet;
            titlet = (TextView) findViewById(R.id.main_toolbar_title);
            titlet.setText(title);
            titlet.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/GothamBook.ttf"));
        }
    }

    @Override
    public void onBackPressed(){
        FragmentManager mgr = getSupportFragmentManager();
        if (mgr.getBackStackEntryCount() == 0) {
            super.onBackPressed();
        }else{
             mgr.popBackStack();
        }
    }

这是我在片段之间导航时使用的:

MainActivity.java:

@Override
public void onBackPressed() {
    // note: you can also use 'getSupportFragmentManager()'
    FragmentManager mgr = getFragmentManager();
    if (mgr.getBackStackEntryCount() == 0) {
        // No backstack to pop, so calling super
        super.onBackPressed();
    } else {
        mgr.popBackStack();
    }
}

编辑第二个: 请注意,如果您还没有处理它,您只想调用 super.onBackPressed()(例如,弹出片段管理器的后栈)。

为此,您必须将新片段添加到 FragmentManager 的后台堆栈 (addToBackStack())。例如(也在MainActivity.java):

private void displayView(int position) {
    Fragment fragment = ...; // YOUR CODE HERE
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.container_body, fragment);

        // ADD THIS LINE
        fragmentTransaction.addToBackStack("name"); // name can be null

        fragmentTransaction.commit();
        // libelle du toolbar
        TextView titlet;
        titlet = (TextView) findViewById(R.id.main_toolbar_title);
        titlet.setText(title);
        titlet.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/GothamBook.ttf"));
    }
}

编辑第三个 (7/28): 在您的 onCreate(Bundle) 方法中,您通过调用 displayView(int) 方法来执行您的第一个片段事务。 displayView(int) 总是 将其片段事务添加到后台堆栈。这不是你想要的。 第一个片段交易应该使用fragmentTransaction.**add**(int, Fragment)并且应该调用addToBackStack(String) 之后的每个事务第一个应该调用 fragmentTransaction.**replace**(int, Fragment) 并且 应该 调用 addToBackStack(String)。这样做的原因是你第一个交易基本上是"adding"一个片段(你的UI)到一个空容器(它不是"replacing"另一个分段)。当这个事务在后台时,这意味着空容器状态在后台是。因此,当您弹出最后一笔交易时,它会显示空白 UI.

编辑第一个: 当您调用 addToBackStack(String name) on a FragmentTransaction object (which you obtain by calling getFragmentManager().beginTransaction()), then you are adding a FragmentTransaction to your FragmentManagers 'backstack'. What my code does is check the size of the backstack by calling getFragmentManager.getBackStackEntryCount(). If that number is greater than zero, then we know we have FragmentTransactions on the backstack. In such a case, you can call getFragmentManager.popBackStack() 时,这会将最后一个事务从后台堆栈中弹出——换句话说,将您的应用程序返回到最后一个片段那是在展出。

如果 backstack entry county 等于 0,那么这意味着你在你的片段 A,你应该改为调用 super.onBackPressed(),这将导致应用程序退出。

onBackPressed()getSupportFragmentManager() 是 Activity class 中的方法,而不是 Fragment,因此您必须在 Activity 而不是分段。 如果你只想为一个片段实现一种特定的行为,你可以检查当前可见的片段是什么,然后实现你的行为。像这样:

@Override
public void onBackPressed(){
    MyFragment myFragment =   (MyFragment)getFragmentManager().findFragmentByTag("YOUR_FRAGMENT");
    if (myFragment != null && myFragment.isVisible()) {
       // the code for whatever behaviour you want goes here
    }
    else
       super.onBackPressed();
}

另一种可能更简单的方法是在添加片段时激活的 Activity 中使用一些标志,然后从 onBackPressed().

中读取

编辑对 BENJY 编辑的回应

请注意,您并没有完全使用我发布的代码。您使用的 findFragmentById() 并不适用于所有情况,我无法判断它是否适合您的代码。 您应该使用适用于任何类型的片段事务的 findFragmentByTag。 只需在您进行交易时向您的片段添加一个标签,如下所示:

 getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment(), "FRAGMENT_TAG")
                    .commit();

然后,当您尝试取回 onBackPressed() 中的片段时,您会发现它正在寻找该标签:

PlaceholderFragment myFragment = (PlaceholderFragment) getSupportFragmentManager()
   .findFragmentByTag("FRAGMENT_TAG");

进行此更改必须有效。

我知道这个回答太迟了,但是无论谁来这里,都可能得到帮助,我通过下面实现了这个。

如果您想更改在点击设备后退按钮时保持 activity 的片段,上面提到的所有代码都可以在删除下面的行时使用。

super.onBackPressed()