web-dev-qa-db-ja.com

findFragmentByIdはnullを返します

フラグメントのIDでfindFragmentById()を呼び出すと、nullが返されます。コードを見せてください。

activity_main.xml

_<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent">

        <fragment Android:name="com.madduck.test.app.fragment.MainFragment"
                  Android:id="@+id/main_fragment"
                  Android:layout_width="match_parent"
                  Android:layout_height="match_parent" />

        <fragment Android:name="com.madduck.test.app.fragment.LoginFragment"
                  Android:id="@+id/login_fragment"
                  Android:layout_width="match_parent"
                  Android:layout_height="match_parent" />
</LinearLayout>
_

MainActivity.Java

_private static final int LOGIN = 0;
private static final int MAIN = 1;
private static final int FRAGMENT_COUNT = MAIN +1;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT]

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

    FragmentManager fm = getSupportFragmentManager();
    fragments[LOGIN] = fm.findFragmentById(R.id.login_fragment);
    fragments[MAIN] = fm.findFragmentById(R.id.main_fragment);

    FragmentTransaction transaction = fm.beginTransaction();
    for (Fragment f : fragments) {
        if (f != null)
            transaction.hide(f);
        else
            Log.e(TAG, "???");
    }

    transaction.commit();
}
_

問題は、fm.findFragmentById(R.id.login_fragment);を呼び出すとnullが取得されますが、fm.findFragmentById(R.id.main_fragment);を呼び出すとフラグメントが取得されることです。

29
Kar0t

私の間違いを見つけました。

MainActivity.Javaで_Android.support.v4.app.Fragment;_をインポートし、LoginFragment.Javaで_Android.app.Fragment;_をインポートしていました。同じものに変更し、fm.findFragmentById(R.id.login_fragment)が正しいフラグメントを返すようになりました。

34
Kar0t

答え Kar0t はまったく問題ありませんが、これは誰かを助けるかもしれません。私の場合、フラグメント内にフラグメントがあり、間違ったFragmentManagerを取得していました。私は電話しなければなりませんでした:

getChildFragmentManager()

そして、いつものようにフラグメントを見つけます。

fm.findFragmentById(R.id.fragment)
83
codeskraps

特定の質問に実際には関係ありませんが、nullでのfindFragmentByIdの受信に関連します。コミット直後にfindFragmentByIdを呼び出すと、nullまたは最後のフラグメント(コミット前)が返されます。コミットが非同期要求を行うためです。

ドキュメントから:

このトランザクションのコミットをスケジュールします。コミットはすぐには行われません。メインスレッドでの作業として、次回スレッドの準備ができたときに実行されるようにスケジュールされます。

フラグメントを追加した後にステータスバーのテキストの色を変更するなど、すぐにfindFragmentByIdが必要な場合は、executePendingTransactions()の後にcommit()を呼び出します

getSupportFragmentManager().executePendingTransactions();
//call findFragmentById 
4
Pavel Poley

コトリン

私も子供のかけらにいたので問題がありました。私が使用できます:

    supportFragmentManager.fragments.forEach {
        it.childFragmentManager.fragments.forEach { fragment ->
            if (fragment is HomeFragment) {
                //do something
            } 
        }

しかし、ある同僚はそれを次のように最適化しました。

     if( findNavController(R.id.nav_Host_fragment).currentDestination?.id == R.id.homeFragment) {
       // do something
   }
0
Barbara K