web-dev-qa-db-ja.com

ナビゲーションフラグメントの変更で消えるファブアイコン

3つの異なるフラグメントにナビゲートする3つのアイテム(フラグメントは1回だけ作成され、それらのインスタンスはmainactivityのonSavedInstanceState()に保存されます)とその上にフローティングアクションボタンがある下部のナビゲーションビューがあります。

各フラグメントにアクセスしたときにファブの描画可能なアイコンを変更したいので、各下部ナビゲーションアイコンを選択したときに、スイッチケースでファブのsetImageResource().setImageDrawable()の両方を試しました。

/**
 * used to handle switching between fragments when a new navigation item is selected
 */
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()) {
        case R.id.nav_tasks:
            .........
    loadFragment(tasksFragment);
            mFab.setOnClickListener(mFabClickListenerTasks);
            mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_add_task));
    //2 tabs in 1 fragment
            if (mTabLayout.getSelectedTabPosition() == 1)
                mFab.hide();
            else mFab.show();
            break;
        case R.id.nav_employees:
            .......
            loadFragment(employeesFragment);
            mFab.setOnClickListener(mFabClickListenerEmployees);
            mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_add_employee2));
            mFab.show();


            break;
        case R.id.nav_departments:
            .......
            loadFragment(departmentsFragment);
            mFab.setOnClickListener(mFabClickListenerDepartments);
           mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_add_department));
            mFab.show();


            break;

    }

    item.setChecked(true);

    return true;
}
void loadFragment(Fragment fragment) {
    if (activeFragment == fragment)
        return;

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.hide(activeFragment).show(fragment);
    activeFragment = fragment;
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

    if (activeFragment instanceof TasksFragment)
        mFab.setImageResource(R.drawable.ic_add_task);
    else if(activeFragment instanceof DepartmentsFragment)
        mFab.setImageResource(R.drawable.ic_add_department);
    else if(activeFragment instanceof EmployeesFragment)
        mFab.setImageResource(R.drawable.ic_add_employee2);

    transaction.commit();
}

3つのフラグメントは主に3つのリサイクラービューです。recyclerviewがスクロールするとファブも非表示になります。

ファブドローアブルは、下部のナビゲーションからフラグメントをトラバースするときに正しく設定されますが、スクロールするとこの状態が保存され、後で元に戻ります。

これにより、別のフラグメントに移動するときにファブドローアブルが削除され、アイコンドローアブルがない状態でファブが空のままになります。どうすればこれを解決できますか?

11
Moamen Mohamed

これはFloatingActionButtonクラスのバグです。show()を呼び出すと、imageMatrixScaleが0に設定されます。setImageResource()を呼び出すと、空白が表示されます。 show()を呼び出す前に機能します。

このバグはデザインライブラリ28.0.0で導入され、v27.1.1で機能していました。 27.1.1にダウングレード

編集: Google Issuetracker

13
MrStahlfelge

アクティビティがonPauseに入ってからonResumeに入ると、同じ問題が発生します。setImageResourceFloatingActionButtonを呼び出していました。 FABアイコンが消えていました。私の解決策は、setImageResourceの直後に次の呼び出しを行うことでした

mFloatingActionButton.hide();        
mFloatingActionButton.show();
19
Ziad Halabi

私の場合、多くの理由でデザインライブラリをダウングレードすることはできませんでした。 MrStahlfelgeの答えは、私が解決策を見つけるのに役立ちました。

public class MyNewFab  extends FloatingActionButton {

    private Matrix imageMatrix;

    ...  

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        imageMatrix = getImageMatrix();
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        setImageMatrix(imageMatrix);
    }
}

これは私のために働きます。それが同じ問題に直面している他の人たちを助けることを願っています。

3

この問題はMaterialComponents 1.1.0で修正されているようですが、現在アルファ版です。

試してみました:

implementation com.google.Android.material:material:1.1.0-alpha10

0
Alex Styl