web-dev-qa-db-ja.com

BottomNavigationViewからアニメーション/シフトモードを削除しますandroid

bottomNavigationViewがあるアプリケーションを構築しています。アクティビティに到達するまで、すべて正常に動作します。

ナビゲーションは次のとおりです。

enter image description here

問題は、このデフォルトのアニメーションがあるため、アクティブな要素を常に他の要素よりも高く押すことです。

もう一つの例:

enter image description here

だから私の質問は、このデフォルトのアニメーションを取り除く方法であり、それらを切り替えるときにすべてのアイテムが整列されますか?

私のコード:

public class MainActivity extends AppCompatActivity {
    private BottomNavigationView bottomNavigationView;
    private Fragment fragment;
    private FragmentManager fragmentManager;
    private FragmentTransaction transaction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupBottomBar();
    }

    private void setupBottomBar() {
        bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottomBar);
        fragmentManager = getSupportFragmentManager();
        fragment = new CardDeckFragment();
        transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.activity_main, fragment).commit();
        bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()){
                    case R.id.action_card_deck:{
                        Toast.makeText(MainActivity.this, "Card Deck Selected", Toast.LENGTH_SHORT).show();
                        fragment = new CardDeckFragment();
                        break;
                    }
                    case R.id.action_favorites:{
                        Toast.makeText(MainActivity.this, "Favorites Selected", Toast.LENGTH_SHORT).show();
                        fragment = new FavoritesFragment();
                        break;
                    }
                    case R.id.action_favorites_another:{
                        Toast.makeText(MainActivity.this, "Image Selected", Toast.LENGTH_SHORT).show();
                        fragment = new ImageFragment();
                        break;
                    }
                    case R.id.action_profile:{
                        Toast.makeText(MainActivity.this, "Profile Selected", Toast.LENGTH_SHORT).show();
                        fragment = new ProfileFragment();
                        break;
                    }
                    case R.id.action_menu:{
                        Toast.makeText(MainActivity.this, "Menu Selected", Toast.LENGTH_SHORT).show();
                        fragment = new MenuFragment();
                        break;
                    }
                }

                transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.activity_main, fragment).commit();
                return true;
            }
        });



    }
}

そして私のレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/activity_main"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context="com.realtimegaming.androidnative.testproject.MainActivity">

    <Android.support.design.widget.BottomNavigationView
        Android:id="@+id/bottomBar"
        Android:layout_alignParentBottom="true"
        Android:background="@color/brown"
        Android:layout_gravity="bottom"
        Android:gravity="bottom"
        Android:layout_marginTop="?attr/actionBarSize"
        app:itemBackground="@color/colorPrimary"
        app:menu="@menu/bottom_navigation_main"
        app:itemIconTint="@color/white"
        Android:fitsSystemWindows="true"
        Android:animateLayoutChanges="false"
        Android:splitMotionEvents="false"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"/>
</RelativeLayout>
32
user7157256

[OK]を私はそれが他の誰かを助ける場合の方法を見つけました。そのため、デフォルトでは、BottomNavigationViewは、3つ以上のアイテムがある場合、shiftingmode = trueを追加します。

現時点では、既存のAPIを使用して変更することはできません。シフトモードを無効にする唯一の方法は、リフレクションを使用することです。

したがって、このヘルパーを使用してこれを取り除くことができます。

class BottomNavigationViewHelper {

    static void removeShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView, false);
            shiftingMode.setAccessible(false);
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                item.setShiftingMode(false);
                // set once again checked value, so view will be updated
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
        } catch (IllegalAccessException e) {
            Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
        }
    }
}

そして、次のように使用します:

BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottomBar);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

これが私と同じ問題を抱えている人の助けになることを願っています!!!

BottomNavigationViewでメニュー項目を変更するたびに、このメソッドを実行する必要があることに注意してください。

UPDATE

異なる stackoverflow question ごとに、proguard構成ファイル(例:proguard-rules.pro)も更新する必要があります。上記のコードはリフレクションを使用し、proguardがmShiftingModeフィールドを難読化すると機能しません。

-keepclassmembers class Android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}
74
user7157256