572

onBackPressed()Android アクティビティで実装する方法と同様に、Android フラグメントで実装できる方法はありますか?

フラグメントのライフサイクルにはonBackPressed(). onBackPressed()Android 3.0 フラグメントでオーバーライドする別の方法はありますか?

4

56 に答える 56

97

これは私のために働いた:https://stackoverflow.com/a/27145007/3934111

@Override
public void onResume() {
    super.onResume();

    if(getView() == null){
        return;
    }

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
                // handle back button's click listener
                return true;
            }
            return false;
        }
    });
}
于 2015-03-20T12:53:32.533 に答える
68

この種の機能が必要な場合は、アクティビティでそれをオーバーライドしてYourBackPressedから、すべてのフラグメントにインターフェイスを追加する必要があります。これは、戻るボタンが押されるたびに関連するフラグメントを呼び出します。

編集:以前の回答を追加したいと思います。

今日これを行う場合は、ブロードキャストを使用します。他のパネルがマスター/メインコンテンツパネルと一致して更新されることを期待している場合は、順序付けられたブロードキャストを使用します。

LocalBroadcastManagerサポートライブラリでこれを支援できます。ブロードキャストを送信してonBackPressed、気になるフラグメントをサブスクライブするだけです。メッセージングは​​より分離された実装であり、より適切に拡張できると思います。そのため、これが私の公式の実装推奨事項になります。Intent'sアクションをメッセージのフィルターとして使用するだけです。新しく作成ACTION_BACK_PRESSEDしたものを送信し、アクティビティから送信して、関連するフラグメントでリッスンします。

于 2011-08-10T19:20:17.933 に答える
30

addToBackStack以下のように、フラグメント間を移行しているときに追加するだけです。

fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("tag").commit();

と書くaddToBackStack(null)と勝手に処理してくれますが、 tag をつけた場合は手動で処理する必要があります。

于 2013-10-20T13:33:37.520 に答える
25

Navigation コンポーネントを使用すると、次のように実行できます。

ジャワ

public class MyFragment extends Fragment {

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // This callback will only be called when MyFragment is at least Started.
    OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
        @Override
        public void handleOnBackPressed() {
            // Handle the back button event
        }
    });
    requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

    // The callback can be enabled or disabled here or in handleOnBackPressed()
}
...
}

コトリン

class MyFragment : Fragment() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // This callback will only be called when MyFragment is at least Started.
    val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
        // Handle the back button event
    }

    // The callback can be enabled or disabled here or in the lambda
}
...
}
于 2020-02-25T00:20:56.807 に答える
21

この質問といくつかの回答は 5 年以上前のものなので、私の解決策を共有させてください。これは、@oyenigun からの回答に対するフォローアップと最新化です。

更新: この記事の最後に、Activity をまったく含まない抽象的な Fragment 拡張機能を使用した代替実装を追加しました。これは、異なるバック動作を必要とするネストされたフラグメントを含む、より複雑なフラグメント階層を持つすべての人に役立ちます。

私が使用する一部のフラグメントには、ポップアップする小さな情報ビューなど、戻るボタンで閉じたい小さなビューがあるため、これを実装する必要がありましたが、これは、の動作をオーバーライドする必要がある人には適していますフラグメント内の戻るボタン。

まず、インターフェイスを定義します

public interface Backable {
    boolean onBackPressed();
}

私が呼び出すこのインターフェイスBackable(私は命名規則に固執しています) にはonBackPressed()、値を返す必要がある単一のメソッドがありbooleanます。戻るボタンの押下が戻るイベントを「吸収」したかどうかを知る必要があるため、ブール値を適用する必要があります。戻るtrueということは、それが完了したことを意味し、それ以上のアクションは必要falseありません。このインターフェイスは、独自のファイルにする必要があります (できれば、 という名前の別のパッケージ内にありますinterfaces)。クラスをパッケージに分割することをお勧めします。

次に、一番上のフラグメントを見つけます

Fragmentバックスタックの最後のオブジェクトを返すメソッドを作成しました。私はタグを使用しています... ID を使用している場合は、必要な変更を加えてください。ナビゲーション状態などを処理するユーティリティ クラスにこの静的メソッドがありますが、もちろん、最適な場所に配置してください。啓蒙のために、私は自分のものを というクラスに入れましたNavUtils

public static Fragment getCurrentFragment(Activity activity) {
    FragmentManager fragmentManager = activity.getFragmentManager();
    if (fragmentManager.getBackStackEntryCount() > 0) {
        String lastFragmentName = fragmentManager.getBackStackEntryAt(
                fragmentManager.getBackStackEntryCount() - 1).getName();
        return fragmentManager.findFragmentByTag(lastFragmentName);
    }
    return null;
}

バック スタック カウントが 0 より大きいことを確認してください。そうしないArrayOutOfBoundsExceptionと、実行時に がスローされる可能性があります。0 より大きくない場合は、null を返します。後で null 値を確認します...

第三に、フラグメントで実装する

Backable戻るボタンの動作をオーバーライドする必要があるフラグメントにインターフェイスを実装します。実装方法を追加します。

public class SomeFragment extends Fragment implements 
        FragmentManager.OnBackStackChangedListener, Backable {

...

    @Override
    public boolean onBackPressed() {

        // Logic here...
        if (backButtonShouldNotGoBack) {
            whateverMethodYouNeed();
            return true;
        }
        return false;
    }

}

オーバーライドには、onBackPressed()必要なロジックを入れます。戻るボタンがバック スタックをポップしないようにする場合 (デフォルトの動作)、戻るイベントが吸収されたことを示す trueを返します。それ以外の場合は false を返します。

最後に、アクティビティで...

メソッドをオーバーライドして、次のonBackPressed()ロジックを追加します。

@Override
public void onBackPressed() {

    // Get the current fragment using the method from the second step above...
    Fragment currentFragment = NavUtils.getCurrentFragment(this);

    // Determine whether or not this fragment implements Backable
    // Do a null check just to be safe
    if (currentFragment != null && currentFragment instanceof Backable) {

        if (((Backable) currentFragment).onBackPressed()) {
            // If the onBackPressed override in your fragment 
            // did absorb the back event (returned true), return
            return;
        } else {
            // Otherwise, call the super method for the default behavior
            super.onBackPressed();
        }
    }

    // Any other logic needed...
    // call super method to be sure the back button does its thing...
    super.onBackPressed();
}

バック スタックで現在のフラグメントを取得し、null チェックを行って、それがBackableインターフェイスを実装しているかどうかを判断します。含まれている場合は、イベントが吸収されたかどうかを判断します。もしそうなら、私たちは終わったのでonBackPressed()戻ることができます。それ以外の場合は、通常のバック プレスとして扱い、スーパー メソッドを呼び出します。

アクティビティを含まない 2 番目のオプション

場合によっては、アクティビティでこれをまったく処理したくない場合があり、フラグメント内で直接処理する必要があります。しかし、バック プレス API では Fragments を使用できないと誰が言いますか? フラグメントを新しいクラスに拡張するだけです。

Fragment を拡張し、インターフェースを実装する抽象クラスを作成しView.OnKeyListnerます...

import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;

public abstract class BackableFragment extends Fragment implements View.OnKeyListener {

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        view.setFocusableInTouchMode(true);
        view.requestFocus();
        view.setOnKeyListener(this);
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                onBackButtonPressed();
                return true;
            }
        }

        return false;
    }

    public abstract void onBackButtonPressed();
}

ご覧のとおり、拡張BackableFragmentするフラグメントは、インターフェイスを使用してバック クリックを自動的にキャプチャしView.OnKeyListenerます。onBackButtonPressed()標準ロジックを使用して、実装されたメソッド内から抽象メソッドを呼び出すだけでonKey()、戻るボタンの押下を識別できます。戻るボタン以外のキークリックを登録する必要がある場合は、フラグメントでsuperオーバーライドするときに必ずメソッドを呼び出してください。そうしないと、抽象化で動作がオーバーライドされます。onKey()

使い方は簡単で、拡張して実装するだけです:

public class FragmentChannels extends BackableFragment {

    ...

    @Override
    public void onBackButtonPressed() {
        if (doTheThingRequiringBackButtonOverride) {
            // do the thing
        } else {
            getActivity().onBackPressed();
        }
    }

    ...
}

スーパー クラスのonBackButtonPressed()メソッドは抽象的であるため、拡張したら を実装する必要がありますonBackButtonPressed()voidフラグメント クラス内でアクションを実行するだけでよく、プレスの吸収をアクティビティに中継する必要がないため、返されます。戻るボタンで行っていることが処理を必要としない場合は、Activity メソッドを呼び出すようにしてくださいonBackPressed()。そうしないと、戻るボタンが無効になります...そして、それは望ましくありません!

警告 ご覧のとおり、これによりキー リスナーがフラグメントのルート ビューに設定され、フォーカスする必要があります。このクラスを拡張するフラグメント (または同じものを持つ他の内部フラグメントまたはビュー) に関連する編集テキスト (または他のフォーカスを盗むビュー) がある場合は、それを個別に処理する必要があります。EditTextを拡張して、バック プレスへのフォーカスを失うことに関する良い記事があります。

誰かがこれが役立つことを願っています。ハッピーコーディング。

于 2017-01-19T11:41:59.113 に答える
15

解決策は簡単です:

  1. すべてのフラグメントが拡張する基本フラグメント クラスがある場合は、このコードをそのクラスに追加します。そうでない場合は、そのような基本フラグメント クラスを作成します。
/* 
* called when on back pressed to the current fragment that is returned
*/
public void onBackPressed()
{
    // add code in super class when override
}
  1. Activity クラスで、次のようにオーバーライドonBackPressedします。
private BaseFragment _currentFragment;

@Override
public void onBackPressed()
{
      super.onBackPressed();
     _currentFragment.onBackPressed();
}
  1. Fragment クラスに、目的のコードを追加します。
@Override
public void onBackPressed()
{
    setUpTitle();
}
于 2014-07-08T10:59:51.680 に答える
8

EventBus を使用する場合は、おそらくはるかに単純なソリューションです。

あなたのフラグメントで:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    EventBus.getDefault().register(this);
}

@Override
public void onDetach() {
    super.onDetach();
    EventBus.getDefault().unregister(this);
}


// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
    getSupportFragmentManager().popBackStack();
}

Activity クラスでは、以下を定義できます。

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
    super.onBackPressed();
}

@Override
public void onBackPressed() {
    EventBus.getDefault().post(new BackPressedMessage(true));
}

BackPressedMessage.java は単なる POJO オブジェクトです

これは非常にクリーンで、インターフェースや実装の手間がありません。

于 2015-04-01T06:54:10.813 に答える
8

以下のようにプロジェクトにインターフェースを追加する必要があります。

public interface OnBackPressed {

     void onBackPressed();
}

次に、このインターフェースをフラグメントに実装する必要があります。

public class SampleFragment extends Fragment implements OnBackPressed {

    @Override
    public void onBackPressed() {
        //on Back Pressed
    }

}

また、以下のように、アクティビティの onBackPressed イベントの下で、この onBackPressed イベントをトリガーできます。

public class MainActivity extends AppCompatActivity {
       @Override
        public void onBackPressed() {
                Fragment currentFragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
                if (currentFragment instanceof OnBackPressed) {  
                    ((OnBackPressed) currentFragment).onBackPressed();
                }
                super.onBackPressed();
        }
}
于 2017-01-12T11:25:52.717 に答える
7
public class MyActivity extends Activity {

    protected OnBackPressedListener onBackPressedListener;

    public interface OnBackPressedListener {
        void doBack();
    }

    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }

    @Override
    public void onBackPressed() {
        if (onBackPressedListener != null)
            onBackPressedListener.doBack();
        else
            super.onBackPressed();
    } 

    @Override
    protected void onDestroy() {
        onBackPressedListener = null;
        super.onDestroy();
    }
}

フラグメントに次を追加します。mainactivity のインターフェイスを実装することを忘れないでください。

public class MyFragment extends Framgent implements MyActivity.OnBackPressedListener {
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
         ((MyActivity) getActivity()).setOnBackPressedListener(this);
    }

@Override
public void doBack() {
    //BackPressed in activity will call this;
}

}
于 2016-08-02T07:06:58.507 に答える
5
@Override
public void onResume() {
    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button
                replaceFragmentToBackStack(getActivity(), WelcomeFragment.newInstance(bundle), tags);

                return true;
            }

            return false;
        }
    });
}
于 2018-03-21T10:20:03.717 に答える
4

onDestroyView() を使用するのはどうですか?

@Override
public void onDestroyView() {
    super.onDestroyView();
}
于 2015-05-23T17:15:48.627 に答える
4

次の手順に従ってください。

常にフラグメントを追加している間、

fragmentTransaction.add(R.id.fragment_container, detail_fragment, "Fragment_tag").addToBackStack(null).commit();

次に、メイン アクティビティでオーバーライドします。onBackPressed()

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
    getSupportFragmentManager().popBackStack();
} else {
    finish();
}

アプリで戻るボタンを処理するには、

Fragment f = getActivity().getSupportFragmentManager().findFragmentByTag("Fragment_tag");
if (f instanceof FragmentName) {
    if (f != null) 
        getActivity().getSupportFragmentManager().beginTransaction().remove(f).commit()               
}

それでおしまい!

于 2016-07-21T14:43:24.233 に答える
4

非常に短くて甘い答え:

getActivity().onBackPressed();

私の場合のシナリオ全体の説明:

MainActivity に FragmentA があり、FragmentA から FragmentB を開いています (FragmentB は FragmentA の子またはネストされたフラグメントです)

 Fragment duedateFrag = new FragmentB();
 FragmentTransaction ft  = getFragmentManager().beginTransaction();
 ft.replace(R.id.container_body, duedateFrag);
 ft.addToBackStack(null);
 ft.commit();

FragmentB から FragmentA に移動したい場合は、単に FragmentB を挿入できますgetActivity().onBackPressed();

于 2016-12-23T09:55:32.243 に答える
4

フラグメント内のコールバックを使用すると、onBackPressed を処理してカスタムの戻るナビゲーションを提供することがより簡単になりました。

class MyFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val onBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (true == conditionForCustomAction) {
                    myCustomActionHere()
                } else  NavHostFragment.findNavController(this@MyFragment).navigateUp();    
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(
        this, onBackPressedCallback
    )
    ...
}

何らかの条件に基づいてデフォルトの戻るアクションが必要な場合は、次を使用できます。

 NavHostFragment.findNavController(this@MyFragment).navigateUp();
于 2019-11-04T06:48:19.857 に答える
3

戻るボタンを押したときにアクティビティが終了するように、ft.addToBackStack() メソッドを実装しないでください。

proAddAccount = new ProfileAddAccount();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, proAddAccount);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
于 2014-01-04T15:25:39.283 に答える
3

フラグメントをアクティビティに登録して、バック プレスを処理できます。

interface BackPressRegistrar {
    fun registerHandler(handler: BackPressHandler)
    fun unregisterHandler(handler: BackPressHandler)
}

interface BackPressHandler {
    fun onBackPressed(): Boolean
}

利用方法:

フラグメント内:

private val backPressHandler = object : BackPressHandler {
    override fun onBackPressed(): Boolean {
        showClosingWarning()
        return false
    }
}

override fun onResume() {
    super.onResume()
    (activity as? BackPressRegistrar)?.registerHandler(backPressHandler)
}

override fun onStop() {
    (activity as? BackPressRegistrar)?.unregisterHandler(backPressHandler)
    super.onStop()
}

活動中:

class MainActivity : AppCompatActivity(), BackPressRegistrar {


    private var registeredHandler: BackPressHandler? = null
    override fun registerHandler(handler: BackPressHandler) { registeredHandler = handler }
    override fun unregisterHandler(handler: BackPressHandler) { registeredHandler = null }

    override fun onBackPressed() {
        if (registeredHandler?.onBackPressed() != false) super.onBackPressed()
    }
}
于 2019-04-19T19:32:06.970 に答える
1

遅すぎることはわかっていますが、先週同じ問題がありました。答えはどれも私を助けませんでした。その後、コードをいじっていましたが、すでにフラグメントを追加していたので、これはうまくいきました。

アクティビティで を設定しOnPageChangeListenerViewPager、ユーザーが 2 番目のアクティビティにいるときがわかるようにします。彼が 2 番目のアクティビティにいる場合は、true次のようにブール値を作成します。

    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setCurrentItem(0);
    mViewPager.addOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            // TODO Auto-generated method stub
                mSectionsPagerAdapter.instantiateItem(mViewPager, position);
                if(position == 1)
                    inAnalytics = true;
                else if(position == 0)
                    inAnalytics = false;
        }

        @Override
        public void onPageScrolled(int position, float arg1, int arg2) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }
    });

戻るボタンが押されるたびにブール値を確認し、現在のアイテムを最初のフラグメントに設定します。

@Override
public void onBackPressed() {
    if(inAnalytics)
        mViewPager.setCurrentItem(0, true);
    else 
        super.onBackPressed();
}
于 2016-05-31T10:16:36.140 に答える
1

アクティビティ A があり、B、C、D のような 3 つのフラグメントを作成する場合は単純です。フラグメント B または C にいて、onBackPressed毎回フラグメント D に移動したい場合は、onBackPressed()メソッドをオーバーライドするだけです。また、任意のフラグメントにジャンプするときに、 メイン アクティビティ A でそのフラグメントを認識したタグまたはそのフラグメントの名前を渡します。

私はあなたがそれを簡単に理解できるその例を挙げています....

if (savedInstanceState == null) {

   getSupportFragmentManager().beginTransaction().add(R.id.container, new C_fragment(),"xyz").commit();

}

または、フラグメント B からフラグメント C に移動しており、バック プレスでフラグメント D に移動したい場合は、以下のように

btn.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {

        getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, new C_frament(), "xyz").commit();
        ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Fragment C");
    }
});

次に、メイン アクティビティの onBackPressed() メソッドをオーバーライドする必要があります....以下のように..

@Override
public void onBackPressed() {
    FragmentManager fragmentManager =getSupportFragmentManager();
    if (((C_fragment) getSupportFragmentManager().findFragmentByTag("xyz")) != null && ((C_fragment) getSupportFragmentManager().findFragmentByTag("xyz")).isVisible()) {
        Fragment fragment = new D_Fragment();
        fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
        getSupportActionBar().setTitle("D fragment ");
    } else {
        super.onBackPressed();
    }
}
于 2015-05-04T07:04:03.157 に答える
1

次のように別のアプローチを使用しました。

  • アクティビティとそのフラグメントの間で通信するためのOtto イベント バス
  • 呼び出しフラグメントが定義する にラップされたカスタムバックアクションを含むアクティビティ内のスタックRunnable
  • onBackPressed制御アクティビティで呼び出されると、最新のカスタムバックアクションがポップされ、その が実行されますRunnable。スタックに何もない場合、デフォルトsuper.onBackPressed()が呼び出されます

サンプル コードを使用した完全なアプローチは、この他の SO の質問に対する回答としてここに含まれています。

于 2015-11-23T12:39:19.537 に答える
0

mainActivity で、コールバック用のインターフェイスを実装します

protected mainActivity.OnBackPressedListener onBackPressedListener;

public interface OnBackPressedListener {
    void doBack();
}

public void setOnBackPressedListener(mainActivity.OnBackPressedListener onBackPressedListener) {
    this.onBackPressedListener = onBackPressedListener;
}

@Override
public void onBackPressed() {
    if (onBackPressedListener != null) {
        onBackPressedListener.doBack();
    } else { 
        super.onBackPressed();
    }
}

フラグメントでは、次のように mainActivity に書き込む intefrace OnBackPressedListener を実装します

implements mainActivity.OnBackPressedListener

mainActivity は私の基本アクティビティであり、フラグメントの onCreateView メソッドに次のコードを記述します

((mainActivity) getActivity()).setOnBackPressedListener(this);

OnBackPressedListener インターフェイス メソッド doBack を実装します。

@Override
public void doBack() {
    //call base fragment 
}

doBack() メソッドを使用して、バックプレスで呼び出したいフラグメントを呼び出します

于 2017-08-29T03:30:49.773 に答える
-1

私は同じ問題を抱えていたので、そのための新しいリスナーを作成し、フラグメントで使用しました。

1 - アクティビティには、リスナー インターフェースとリスナーのリストが必要です。

2 - リスナーを追加および削除するためのメソッドを実装する必要があります

3 - onBackPressed メソッドをオーバーライドして、いずれかのリスナーがバック プレスを使用しているかどうかを確認する必要があります。

public class MainActivity ... {

    /**
     * Back press listener list. Used for notifying fragments when onBackPressed called
     */
    private Stack<BackPressListener> backPressListeners = new Stack<BackPressListener>();


    ...

    /**
     * Adding new listener to back press listener stack
     * @param backPressListener
     */
    public void addBackPressListener(BackPressListener backPressListener) {
        backPressListeners.add(backPressListener);
    }

    /**
     * Removing the listener from back press listener stack
     * @param backPressListener
     */
    public void removeBackPressListener(BackPressListener backPressListener) {
        backPressListeners.remove(backPressListener);
    }


    // Overriding onBackPressed to check that is there any listener using this back press
    @Override
    public void onBackPressed() {

        // checks if is there any back press listeners use this press
        for(BackPressListener backPressListener : backPressListeners) {
            if(backPressListener.onBackPressed()) return;
        }

        // if not returns in the loop, calls super onBackPressed
        super.onBackPressed();
    }

}

4 - フラグメントは、バック プレス用のインターフェイスを実装する必要があります

5 - バックプレスのリスナーとしてフラグメントを追加する必要があります

6 - フラグメントがこのバック プレスを使用する場合、onBackPressed から true を返す必要があります。

7 - 重要 - リスト onDestroy からフラグメントを削除する必要があります

public class MyFragment extends Fragment implements MainActivity.BackPressListener {


    ...

    @Override
    public void onAttach(Activity activity) {
        super.onCreate(savedInstanceState);

        // adding the fragment to listener list
        ((MainActivity) activity).addBackPressListener(this);
    }

    ...

    @Override
    public void onDestroy() {
        super.onDestroy();

        // removing the fragment from the listener list
        ((MainActivity) getActivity()).removeBackPressListener(this);
    }

    ...

    @Override
    public boolean onBackPressed() {

        // you should check that if this fragment is the currently used fragment or not
        // if this fragment is not used at the moment you should return false
        if(!isThisFragmentVisibleAtTheMoment) return false;

        if (isThisFragmentUsingBackPress) {
            // do what you need to do
            return true;
        }
        return false;
    }
}

最新のフラグメントから開始できるように、ArrayList の代わりに使用される Stack があります。バックスタックにフラグメントを追加する際にも問題が発生する可能性があります。したがって、バックプレスを使用しているときにフラグメントが表示されるかどうかを確認する必要があります。そうしないと、フラグメントの 1 つがイベントを使用し、バック プレスで最新のフラグメントが閉じられません。

これでみんなの問題が解決することを願っています。

于 2014-03-20T09:21:37.350 に答える
-1

フラグメントを使用findFragmentByIdしてキャストし、onBackpressed を処理するメソッドを呼び出すだけです。このサンプルは、これが注文プロセスの最初のステップであるかどうか、または終了注文を確認するダイアログ フラグメントをポップアップするかどうかを確認する方法を示しています。

@Override
    public void onBackPressed() {
        //check if first fragment in wizard is loaded, if true get abandon confirmation before going back
        OrderFragment frag =(OrderFragment)getSupportFragmentManager().findFragmentById(R.id.fragContainer);
        if (frag==null || (frag!=null && frag.getOrderStage()<1)){
            AlertDialogFragment.show(getSupportFragmentManager(), R.string.dialog_cancel_order,R.string.dialog_cancel_order_msg, R.string.dialog_cancel_order_pos,R.string.dialog_order_quiz_neg, DIALOG_ID_CANCEL);
        }else {
            super.onBackPressed();
        }
    }
于 2014-06-20T09:58:41.267 に答える
-3

その問題に対する私の解決策は次のとおりです。

アクティビティ A:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == REQUEST_CODE)
    {
        if(resultCode == Activity.RESULT_OK)
        {
            tvTitle.setText(data.getExtras().getString("title", ""));
        }
    }
}

アクティビティ B:

@Override
public void onBackPressed() 
{
    setResult(Activity.RESULT_OK, getIntent());

    super.onBackPressed();
}

アクティビティ b はフラグメントを保持します。

断片的に:

private void setText(String text)
    {
        Intent intent = new Intent();
        intent.putExtra("title", text);
        getActivity().setIntent(intent);
    }

そのようにして、アクティビティAのインテントオブジェクト「データ」はフラグメントから文字列を取得します

于 2013-12-04T16:15:38.630 に答える