Может ли кто-нибудь объяснить мне волшебство за FindViewById (1) или FindViewById (2)?

[UPDATE] – Просто хотел подтвердить всем, что я согласен, что ВСЕГДА плохая идея использовать жесткий кодированный номер. Мое любопытство заключалось в использовании API Карт, для которого указано постоянное значение 1, 2. Я бы чувствовал себя более комфортно, если бы нашел что-то вроде R.id.my_current_location_view.

Я вижу, что этот код уселся в этом вопросе и других вопросах. Как люди знают, что использовать findViewById (1) и т. Д.? Против findViewById (R.id.something);

Изменить положение кнопки «Мое местоположение» в Google Maps API

В этом вопросе, похоже, есть некоторая глубокая путаница. Мне интересно, каковы магические числа findViewById (1) .. Если вы нажмете на ссылку, вы увидите, что никто не поставил значение setId (1) в mapView, но каким-то образом люди знают, чтобы проверить родительский вид, а затем findViewById ( 1) и findViewById (2) ..

Я тоже задал вопрос, чтобы контекст не был потерян, но, похоже, никто не может это объяснить.

Это общая плохая идея использовать этот подход с жестко закодированными идентификаторами, особенно если вы не тот, кто их устанавливает, поскольку они могут быть изменены.

Однако, чтобы ответить на вопрос о том, чтобы использовать идентификатор, один из вариантов – сделать много угадывания и проверить работу с помощью отладчика Android Studio для ручного перемещения иерархии представлений. Это, скорее всего, займет много времени, поэтому гораздо проще использовать просто средство просмотра иерархии, которое доступно как в Android Studio, так и в Eclipse.

Вот как выглядит часть макета, которую мы интересуем. Я обрисовал полный макет, чтобы показать соответствующую часть.

Введите описание изображения здесь

Теперь мы можем разбить следующий код:

View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2); 
  1. findViewById(1) вернет LinearLayout (Red Outline), так как его id равен 1.
  2. getParent() вернет RelativeLayout , являющийся родителем LinearLayout (Blue Outline).
  3. findViewById(2) найдет дочерний View RelativeLayout с заданным идентификатором. На основе изображения мы видим, что ImageView (Green Outline), который мы хотим, имеет этот id.

Исходя из этого, интересно отметить, что мы могли бы просто использовать mapView.findViewById(2) чтобы получить доступ к ImageView напрямую и избежать других вызовов.

Не уверен, что это было в предыдущих версиях, но работает при использовании текущего MapFragment . Если это не работает в предыдущих версиях, это помогает доказать, что это плохая практика, поскольку она может меняться между версиями.

Просмотреть идентификаторы – это просто положительные, ненулевые целые числа.

Если вы установили идентификатор вида в XML, используя синтаксис @+id/name , целое число генерируется в R.java и вам нужно ссылаться на него как R.id.name в коде.

Если вы установили идентификатор вида в код с помощью setId(value) , вы можете получить представление с этим идентификатором из иерархии с findViewById(value) где значение id может быть жестко запрограммированным положительным, отличным от нуля целым числом, таким как 1 Или 2.

Как правило, при написании кода старайтесь избегать использования таких магических констант.

Они оба одинаковы, в первом случае вы поставляете идентификатор ресурса, который андроид строит в файле R самостоятельно, а во втором случае вы поставляете идентификатор ресурса, который андроид скомпилировал для вас.

Никакой разницы,

Сначала вам нужно установить id вида, используя setId(value) а затем вы можете получить представление, используя этот id используя findViewById(value)

Нашел этот пост, посмотрев на него: Ссылка

Документация для setid() говорит:

Устанавливает идентификатор для этого представления. Идентификатор не должен быть уникальным в иерархии этого представления. Идентификатор должен быть положительным числом.