Каждая переменная в Java является ссылкой. Поэтому, когда вы делаете
SomeClass s2 = s1;
, вы просто указываете s2
на тот же объект, что и s1
. Фактически вы назначаете значение ссылки s1 (которое указывает на экземпляр SomeClass
) на s2. Если вы измените s1
, будет также изменен s2
(потому что он указывает на тот же объект).
Существует исключение, примитивные типы: int, double, float, boolean, char, byte, short, long
. Они хранятся по значению. Поэтому при использовании =
вы присваиваете значение только, но не можете указывать на один и тот же объект (потому что это не ссылки). Это означает, что
int b = a;
устанавливает значение b
в значение a
. Если вы измените a
, b
не изменится.
В конце дня все назначается по значению, это всего лишь значение ссылки, а не значение объекта (с исключение примитивных типов, как указано выше).
Итак, в вашем случае, если вы хотите сделать копию s1
, вы можете сделать это следующим образом:
SomeClass s1 = new SomeClass("first");
SomeClass s2 = new SomeClass(s1.getText());
Кроме того, вы можете добавить конструктор копирования к SomeClass
, который принимает экземпляр в качестве аргумента и копирует его в свой собственный экземпляр.
class SomeClass {
private String text;
// all your fields and methods go here
public SomeClass(SomeClass copyInstance) {
this.text = new String(copyInstance.text);
}
}
С помощью этого вы можете легко скопировать объект:
SomeClass s2 = new SomeClass(s1);
Кажется, исправлено в SupportLibrary 25.1.0 :) Edit: Кажется, что исправлено, что состояние выбора сохраняется при вращении экрана.
private void setSelectedItem(int actionId) {
Menu menu = viewBottom.getMenu();
for (int i = 0, size = menu.size(); i < size; i++) {
MenuItem menuItem = menu.getItem(i);
((MenuItemImpl) menuItem).setExclusiveCheckable(false);
menuItem.setChecked(menuItem.getItemId() == actionId);
((MenuItemImpl) menuItem).setExclusiveCheckable(true);
}
}
Единственный минус решения использует MenuItemImpl
, который является «внутренним» для библиотеки (хотя и общедоступным).
Теперь возможно, что версия 25.3.0 для вызова setSelectedItemId()
\ o /
Попробуйте мое решение из https://stackoverflow.com/a/40778162/2571249
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bottomNavigationView.setOnNavigationItemSelectedListener(this);
Menu menu = bottomNavigationView.getMenu();
this.onNavigationItemSelected(menu.findItem(R.id.action_favorites));
}
Это, вероятно, будет добавлено в ближайшие обновления. Но в то же время для достижения этой цели вы можете использовать отражение.
Создайте пользовательский вид, простирающийся от BottomNavigationView и получив доступ к некоторым его полям.
public class SelectableBottomNavigationView extends BottomNavigationView {
public SelectableBottomNavigationView(Context context) {
super(context);
}
public SelectableBottomNavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SelectableBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setSelected(int index) {
try {
Field f = BottomNavigationView.class.getDeclaredField("mMenuView");
f.setAccessible(true);
BottomNavigationMenuView menuView = (BottomNavigationMenuView) f.get(this);
try {
Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE);
method.setAccessible(true);
method.invoke(menuView, index);
} catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
И затем используйте его в своем xml.
<com.your.app.SelectableBottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemBackground="@color/primary"
app:itemIconTint="@drawable/nav_item_color_state"
app:itemTextColor="@drawable/nav_item_color_state"
app:menu="@menu/bottom_navigation_menu"/>
Просто добавление другого способа выполнения выбора программно - это, вероятно, было намерением в первую очередь или, возможно, это было добавлено позже.
Menu bottomNavigationMenu = myBottomNavigationMenu.getMenu();
bottomNavigationMenu.performIdentifierAction(selected_menu_item_id, 0);
performIdentifierAction
принимает Menu
id и флаг.
Я не хочу изменять код. Если это так, я рекомендовал вам попробовать BottomNavigationViewEx .
Вам просто нужно заменить вызов методом setCurrentItem(index);
и getCurrentItem()
.
[/g1]
Я сделал ошибку Google о том, что нет надежного способа выбрать страницу в BottomNavigationView: https://code.google.com/p/android/issues/detail?id=233697
У NavigationView, похоже, была аналогичная проблема, которую они исправили добавлением нового метода setCheckedItem ().
Чтобы программно щелкнуть элемент BottomNavigationBar, который вам нужно использовать:
View view = bottomNavigationView.findViewById(R.id.menu_action_item);
view.performClick();
Это правильно упорядочивает все элементы с их метками.
Выше API 25 вы можете использовать setSelectedItemId (menu_item_id), но в соответствии с API 25 вы должны сделать по-другому, пользовательское меню, чтобы получить дескриптор, а затем setChecked to Checked specific item
Отражение - плохая идея.
Направьте этот gist . Существует метод, который выполняет выбор, но также вызывает обратный вызов:
@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;
}
callOnClick()
вместо performClick()
, поэтому мне не нужно отключать звук, который в любом случае не работает с performClick()
.
– arekolek
14 March 2017 в 16:08
Из API 25.3.0 был введен метод setSelectedItemId(int id)
, который позволяет отмечать элемент как выбранный, как если бы он был использован.
Из документов:
Установите выбранный идентификатор элемента меню. Это ведет себя так же, как постукивание по элементу.
blockquote>Пример кода:
BottomNavigationView bottomNavigationView; bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationView); bottomNavigationView.setOnNavigationItemSelectedListener(myNavigationItemListener); bottomNavigationView.setSelectedItemId(R.id.my_menu_item_id);
ВАЖНО
Вы ДОЛЖНЫ уже добавить все элементы в меню и установить прослушиватель перед вызовом setSelectedItemId, чтобы BottomNavigationView мог выполнять поведение соответствующего кода. Если вы вызываете setSelectedItemId перед добавлением пунктов меню и установкой слушателя, ничего не произойдет.
setSelectedItemId()
функция NOT работает внутри Activity.onCreate()
, но работает внутри Activity.onResume()
.
– Andy H.
4 May 2017 в 21:07
onTabSelected
, очевидно, что ничего не сделаете. Прочтите документы - & gt; Установите выбранный идентификатор элемента меню. Это ведет себя так же, как постукивание по элементу. Это от разработчиков Android
– Ricardo
27 September 2017 в 09:57
Добавьте android:enabled="true"
в элементы BottomNavigationMenu.
Затем установите bottomNavigationView.setOnNavigationItemSelectedListener(mListener)
и установите его как выбранное, выполнив bottomNavigationView.selectedItemId = R.id.your_menu_id
Для тех, кто все еще использует SupportLibrary & lt; 25.3.0
Я не уверен, является ли это полным ответом на этот вопрос, но моя проблема была очень похожа - мне пришлось обработать кнопку back
и привести пользователя на предыдущую вкладку, где он был , Итак, может быть, мое решение будет полезно для кого-то:
private void updateNavigationBarState(int actionId){
Menu menu = bottomNavigationView.getMenu();
for (int i = 0, size = menu.size(); i < size; i++) {
MenuItem item = menu.getItem(i);
item.setChecked(item.getItemId() == actionId);
}
}
Пожалуйста, имейте в виду, что если пользователь нажимает другую вкладку навигации BottomNavigationView
, не будет очищать выбранный элемент в данный момент, поэтому вам нужно позвонить этому метод в вашем onNavigationItemSelected
после обработки действия навигации:
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.some_id_1:
// process action
break;
case R.id.some_id_2:
// process action
break;
...
default:
return false;
}
updateNavigationBarState(item.getItemId());
return true;
}
Что касается сохранения состояния экземпляра, я думаю, что вы можете играть с тем же action id
навигационного представления и найти подходящее решение.
Menu menu = bottomNavigationView.getMenu();
копию меню, поэтому объект bottomNavigationView
не затрагивается?
– 最白目
16 February 2017 в 09:14