从 BottomNavigationView android 移除 Animation/Shifting 模式
Remove Animation/Shifting mode from BottomNavigationView android
我正在构建一个应用程序,其中有一个 BottomNavigationView。一切正常,直到我到达 Activity.
导航是这样的:
问题是它有这个默认动画,所以它每次都会将活动元素推得比其他元素高。
另一个例子:
所以我的问题是如何摆脱这个默认动画,并且当我在它们之间切换时每个项目都对齐?
我的代码:
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>
好的,我找到了一种方法,以防对其他人有所帮助。所以默认情况下 BottomNavigationView 添加 shiftingmode = true 当它超过 3 个项目时。
此时您无法通过现有的 API 更改它,禁用 shift 模式的唯一方法是使用反射。
所以我们可以使用这个助手来摆脱这个:
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 中的菜单项时都需要执行此方法。
更新
根据不同的 ,您还需要更新 proguard 配置文件(例如 proguard-rules.pro),上面的代码使用反射,如果 proguard 混淆了 mShiftingMode 字段,将无法工作。
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {
boolean mShiftingMode;
}
我正在构建一个应用程序,其中有一个 BottomNavigationView。一切正常,直到我到达 Activity.
导航是这样的:
问题是它有这个默认动画,所以它每次都会将活动元素推得比其他元素高。
另一个例子:
所以我的问题是如何摆脱这个默认动画,并且当我在它们之间切换时每个项目都对齐?
我的代码:
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>
好的,我找到了一种方法,以防对其他人有所帮助。所以默认情况下 BottomNavigationView 添加 shiftingmode = true 当它超过 3 个项目时。
此时您无法通过现有的 API 更改它,禁用 shift 模式的唯一方法是使用反射。
所以我们可以使用这个助手来摆脱这个:
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 中的菜单项时都需要执行此方法。
更新
根据不同的
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {
boolean mShiftingMode;
}