Instantly share code, notes, and snippets.
Forked from NikolaDespotoski/RichBottomNavigationView.java
Last active
December 20, 2016 01:55
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Nkzn/b40a294fa50db8369f169140d0c12878 to your computer and use it in GitHub Desktop.
Saving and restoring BottomNavigationView state (No Shadow settings)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.os.Build; | |
import android.os.Parcel; | |
import android.os.Parcelable; | |
import android.support.annotation.CallSuper; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.RequiresApi; | |
import android.support.design.widget.BottomNavigationView; | |
import android.support.design.widget.NavigationView; | |
import android.support.v4.os.ParcelableCompat; | |
import android.support.v4.os.ParcelableCompatCreatorCallbacks; | |
import android.support.v7.view.menu.MenuItemImpl; | |
import android.support.v7.view.menu.MenuView; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import static android.support.design.widget.TabLayout.Tab.INVALID_POSITION; | |
public class StateBottomNavigationView extends BottomNavigationView { | |
private ViewGroup mBottomItemsHolder; | |
private int mLastSelection = INVALID_POSITION; | |
public StateBottomNavigationView(Context context) { | |
super(context); | |
} | |
public StateBottomNavigationView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
public StateBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
} | |
public int getSelectedItem() { | |
return mLastSelection = findSelectedItem(); | |
} | |
@CallSuper | |
public void setSelectedItem(int position) { | |
if (position >= getMenu().size() || position < 0) return; | |
View menuItemView = getMenuItemView(position); | |
if (menuItemView == null) return; | |
MenuItemImpl itemData = ((MenuView.ItemView) menuItemView).getItemData(); | |
itemData.setChecked(true); | |
boolean previousHapticFeedbackEnabled = menuItemView.isHapticFeedbackEnabled(); | |
menuItemView.setSoundEffectsEnabled(false); | |
menuItemView.setHapticFeedbackEnabled(false); //avoid hearing click sounds, disable haptic and restore settings later of that view | |
menuItemView.performClick(); | |
menuItemView.setHapticFeedbackEnabled(previousHapticFeedbackEnabled); | |
menuItemView.setSoundEffectsEnabled(true); | |
mLastSelection = position; | |
} | |
@Override | |
protected Parcelable onSaveInstanceState() { | |
Parcelable superState = super.onSaveInstanceState(); | |
BottomNavigationState state = new BottomNavigationState(superState); | |
mLastSelection = getSelectedItem(); | |
state.lastSelection = mLastSelection; | |
return state; | |
} | |
@Override | |
protected void onRestoreInstanceState(Parcelable state) { | |
if (!(state instanceof BottomNavigationState)) { | |
super.onRestoreInstanceState(state); | |
return; | |
} | |
BottomNavigationState bottomNavigationState = (BottomNavigationState) state; | |
mLastSelection = bottomNavigationState.lastSelection; | |
dispatchRestoredState(); | |
super.onRestoreInstanceState(bottomNavigationState.getSuperState()); | |
} | |
private void dispatchRestoredState() { | |
if (mLastSelection != 0) { //Since the first item is always selected by the default implementation, dont waste time | |
setSelectedItem(mLastSelection); | |
} | |
} | |
private View getMenuItemView(int position) { | |
View bottomItem = mBottomItemsHolder.getChildAt(position); | |
if (bottomItem instanceof MenuView.ItemView) { | |
return bottomItem; | |
} | |
return null; | |
} | |
private int findSelectedItem() { | |
int itemCount = getMenu().size(); | |
for (int i = 0; i < itemCount; i++) { | |
View bottomItem = mBottomItemsHolder.getChildAt(i); | |
if (bottomItem instanceof MenuView.ItemView) { | |
MenuItemImpl itemData = ((MenuView.ItemView) bottomItem).getItemData(); | |
if (itemData.isChecked()) return i; | |
} | |
} | |
return INVALID_POSITION; | |
} | |
@Override | |
protected void onFinishInflate() { | |
super.onFinishInflate(); | |
mBottomItemsHolder = (ViewGroup) getChildAt(0); | |
} | |
static class BottomNavigationState extends BaseSavedState { | |
public int lastSelection; | |
@RequiresApi(api = Build.VERSION_CODES.N) | |
public BottomNavigationState(Parcel in, ClassLoader loader) { | |
super(in, loader); | |
lastSelection = in.readInt(); | |
} | |
public BottomNavigationState(Parcelable superState) { | |
super(superState); | |
} | |
@Override | |
public void writeToParcel(@NonNull Parcel dest, int flags) { | |
super.writeToParcel(dest, flags); | |
dest.writeInt(lastSelection); | |
} | |
public static final Parcelable.Creator<NavigationView.SavedState> CREATOR | |
= ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks<NavigationView.SavedState>() { | |
@Override | |
public NavigationView.SavedState createFromParcel(Parcel parcel, ClassLoader loader) { | |
return new NavigationView.SavedState(parcel, loader); | |
} | |
@Override | |
public NavigationView.SavedState[] newArray(int size) { | |
return new NavigationView.SavedState[size]; | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment