Когда я впервые начал программировать на Android, меня действительно смутили LayoutInflater
и findViewById
. Иногда мы использовали один, а иногда другой.
LayoutInflater
используется для создания нового View
(или Layout
) объекта из одного из ваших XML-макетов.
findViewById
просто дает вам ссылку на вид, который уже был создан. Вы можете подумать, что вы еще не создали ни одного представления, но всякий раз, когда вы вызываете setContentView
в onCreate
, макет действия вместе с его подпредставлениями раздувается (создается) за кулисами.
Так что, если представление уже существует, используйте findViewById
. Если нет, то создайте его с помощью LayoutInflater
.
* +1025 * Пример
Вот мини-проект, который я сделал, который показывает как LayoutInflater
, так и findViewById
в действии. Без специального кода макет выглядит следующим образом.
Синий квадрат - это пользовательский макет, вставленный в основной макет с помощью include
(подробнее см. здесь ). Он был раздут автоматически, потому что он является частью представления содержимого. Как видите, в коде нет ничего особенного.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Теперь давайте надуем (создадим) еще одну копию нашего пользовательского макета и добавим ее.
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
Чтобы надуть новый макет представления, все, что я сделал, это сказал инфлятору имя моего xml-файла (my_layout
), родительский макет, к которому я хочу добавить его (mainLayout
), и что я не Я на самом деле не хочу его добавлять (false
). (Я мог бы также установить родительский элемент на null
, но тогда параметры макета корневого представления моей пользовательской компоновки будут игнорироваться.)
Здесь снова в контексте.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// inflate the main layout for the activity
setContentView(R.layout.activity_main);
// get a reference to the already created main layout
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.activity_main_layout);
// inflate (create) another copy of our custom layout
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
// make changes to our custom layout and its subviews
myLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorAccent));
TextView textView = (TextView) myLayout.findViewById(R.id.textView);
textView.setText("New Layout");
// add our custom layout to the main layout
mainLayout.addView(myLayout);
}
}
Обратите внимание, как findViewById
используется только после того, как макет уже накачан.
Дополнительный код
Вот XML для примера выше.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- Here is the inserted layout -->
<include layout="@layout/my_layout"/>
</LinearLayout>
my_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorPrimary">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="5dp"
android:textColor="@android:color/white"
android:text="My Layout"/>
</RelativeLayout>
Когда вам нужен LayoutInflater
- Чаще всего большинство людей используют его в
RecyclerView
. (См. Эти RecyclerView
примеры для списка или сетки .) Вы должны надуть новый макет для каждого видимого элемента в списке или сетке.
- Вы также можете использовать инфлятор, если у вас есть сложный макет, который вы хотите добавить программно (как мы это делали в нашем примере). Вы можете сделать все это в коде, но сначала гораздо проще определить его в xml, а затем просто накачать.