如何避免这些乏味的 findViewById() 调用?
How to avoid these tedious findViewById() calls?
我有一个包含两个 TextView 的简单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_tile_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample text"
android:textSize="18dp"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/tv_tile_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="20.0"
android:textSize="26dp"
android:textStyle="bold" />
</LinearLayout>
我在我的应用程序的某些地方包含了这个布局。在我的最后一个案例中,我不得不包括这 4 次。要在包含的各个布局中为这两个文本视图查找和设置文本,我必须找到一个布局的 id,然后从那里找到两个文本视图的 id。并对所有包含的布局重复 3 次。这导致一些丑陋和可怕的维护代码:
@Override
public void setStatsValues(String today, String week, String month, String total) {
// this is so tedious.
View layoutDay = findViewById(R.id.layout_stats_day);
View layoutWeek = findViewById(R.id.layout_stats_week);
View layoutMonth = findViewById(R.id.layout_stats_month);
View layoutTotal = findViewById(R.id.layout_stats_total);
TextView tvDayTitle = layoutDay.findViewById(R.id.tv_tile_title);
TextView tvWeekTitle = layoutWeek.findViewById(R.id.tv_tile_title);
TextView tvMonthTitle = layoutMonth.findViewById(R.id.tv_tile_title);
TextView tvTotalTitle = layoutTotal.findViewById(R.id.tv_tile_title);
TextView tvDayValue = layoutDay.findViewById(R.id.tv_tile_value);
TextView tvWeekValue = layoutWeek.findViewById(R.id.tv_tile_value);
TextView tvMonthValue = layoutMonth.findViewById(R.id.tv_tile_value);
TextView tvTotalValue = layoutTotal.findViewById(R.id.tv_tile_value);
tvDayTitle.setText("Today");
tvWeekTitle.setText("Week");
tvMonthTitle.setText("Month");
tvTotalTitle.setText("Total");
tvDayValue.setText(today);
tvWeekValue.setText(week);
tvMonthValue.setText(month);
tvTotalValue.setText(total);
}
我怎样才能避免这种怪事?
您可以使用 View Binding:
添加你的build.gradle:
android {
...
buildFeatures {
viewBinding true
}
}
创建布局activity_test.xml
:
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/text1"/>
<TextView
android:id="@+id/text2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
然后在你的 Activity
:
科特林
private lateinit var binding: ActivityTestBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTestBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.text1.text = "Hello"
binding.text2.text = "....."
}
Java
private ActivityTestBinding binding;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
binding = ActivityTestBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
binding.text1.setText("hello");
}
您可以使用 View Binding 自动执行所有 findViewById
操作 - 它会生成一个以您的布局命名的“绑定”class,并且每个 View
具有 id
的布局获得参考。
所以在你的情况下你可以做到 dayBinding.tv_tile_value.setText("today")
如果你不想这样做,你可以将所有重复的代码重构为一个函数,比如
private void setTheThings(int layoutResId, String title, String value) {
View layout = findViewById(layoutResId)
layout.findViewById<TextView>(R.id.tv_tile_title).setText(title)
layout.findViewById<TextView>(R.id.tv_tile_value).setText(value)
}
(或任何要投射到 TextView 的内容)然后为每个布局 ID 调用它
实际上,您自己正在使代码变得乏味。无需先到父级再到子级等查找视图。
而不是:
View layoutDay = findViewById(R.id.layout_stats_day);
View layoutWeek = findViewById(R.id.layout_stats_week);
View layoutMonth = findViewById(R.id.layout_stats_month);
View layoutTotal = findViewById(R.id.layout_stats_total);
TextView tvDayTitle = layoutDay.findViewById(R.id.tv_tile_title);
TextView tvWeekTitle = layoutWeek.findViewById(R.id.tv_tile_title);
TextView tvMonthTitle = layoutMonth.findViewById(R.id.tv_tile_title);
TextView tvTotalTitle = layoutTotal.findViewById(R.id.tv_tile_title);
TextView tvDayValue = layoutDay.findViewById(R.id.tv_tile_value);
TextView tvWeekValue = layoutWeek.findViewById(R.id.tv_tile_value);
TextView tvMonthValue = layoutMonth.findViewById(R.id.tv_tile_value);
TextView tvTotalValue = layoutTotal.findViewById(R.id.tv_tile_value);
你可以这样做(只是不同的 id,我的意思是为每个视图使用不同的 id):
TextView tvDayTitle = findViewById(R.id.tv_day_title);
TextView tvWeekTitle = findViewById(R.id.tv_week_title);
TextView tvMonthTitle = findViewById(R.id.tv_month_title);
TextView tvTotalTitle = findViewById(R.id.tv_total_title);
我有一个包含两个 TextView 的简单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_tile_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample text"
android:textSize="18dp"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/tv_tile_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="20.0"
android:textSize="26dp"
android:textStyle="bold" />
</LinearLayout>
我在我的应用程序的某些地方包含了这个布局。在我的最后一个案例中,我不得不包括这 4 次。要在包含的各个布局中为这两个文本视图查找和设置文本,我必须找到一个布局的 id,然后从那里找到两个文本视图的 id。并对所有包含的布局重复 3 次。这导致一些丑陋和可怕的维护代码:
@Override
public void setStatsValues(String today, String week, String month, String total) {
// this is so tedious.
View layoutDay = findViewById(R.id.layout_stats_day);
View layoutWeek = findViewById(R.id.layout_stats_week);
View layoutMonth = findViewById(R.id.layout_stats_month);
View layoutTotal = findViewById(R.id.layout_stats_total);
TextView tvDayTitle = layoutDay.findViewById(R.id.tv_tile_title);
TextView tvWeekTitle = layoutWeek.findViewById(R.id.tv_tile_title);
TextView tvMonthTitle = layoutMonth.findViewById(R.id.tv_tile_title);
TextView tvTotalTitle = layoutTotal.findViewById(R.id.tv_tile_title);
TextView tvDayValue = layoutDay.findViewById(R.id.tv_tile_value);
TextView tvWeekValue = layoutWeek.findViewById(R.id.tv_tile_value);
TextView tvMonthValue = layoutMonth.findViewById(R.id.tv_tile_value);
TextView tvTotalValue = layoutTotal.findViewById(R.id.tv_tile_value);
tvDayTitle.setText("Today");
tvWeekTitle.setText("Week");
tvMonthTitle.setText("Month");
tvTotalTitle.setText("Total");
tvDayValue.setText(today);
tvWeekValue.setText(week);
tvMonthValue.setText(month);
tvTotalValue.setText(total);
}
我怎样才能避免这种怪事?
您可以使用 View Binding:
添加你的build.gradle:
android {
...
buildFeatures {
viewBinding true
}
}
创建布局activity_test.xml
:
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/text1"/>
<TextView
android:id="@+id/text2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
然后在你的 Activity
:
科特林
private lateinit var binding: ActivityTestBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTestBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.text1.text = "Hello"
binding.text2.text = "....."
}
Java
private ActivityTestBinding binding;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
binding = ActivityTestBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
binding.text1.setText("hello");
}
您可以使用 View Binding 自动执行所有 findViewById
操作 - 它会生成一个以您的布局命名的“绑定”class,并且每个 View
具有 id
的布局获得参考。
所以在你的情况下你可以做到 dayBinding.tv_tile_value.setText("today")
如果你不想这样做,你可以将所有重复的代码重构为一个函数,比如
private void setTheThings(int layoutResId, String title, String value) {
View layout = findViewById(layoutResId)
layout.findViewById<TextView>(R.id.tv_tile_title).setText(title)
layout.findViewById<TextView>(R.id.tv_tile_value).setText(value)
}
(或任何要投射到 TextView 的内容)然后为每个布局 ID 调用它
实际上,您自己正在使代码变得乏味。无需先到父级再到子级等查找视图。
而不是:
View layoutDay = findViewById(R.id.layout_stats_day);
View layoutWeek = findViewById(R.id.layout_stats_week);
View layoutMonth = findViewById(R.id.layout_stats_month);
View layoutTotal = findViewById(R.id.layout_stats_total);
TextView tvDayTitle = layoutDay.findViewById(R.id.tv_tile_title);
TextView tvWeekTitle = layoutWeek.findViewById(R.id.tv_tile_title);
TextView tvMonthTitle = layoutMonth.findViewById(R.id.tv_tile_title);
TextView tvTotalTitle = layoutTotal.findViewById(R.id.tv_tile_title);
TextView tvDayValue = layoutDay.findViewById(R.id.tv_tile_value);
TextView tvWeekValue = layoutWeek.findViewById(R.id.tv_tile_value);
TextView tvMonthValue = layoutMonth.findViewById(R.id.tv_tile_value);
TextView tvTotalValue = layoutTotal.findViewById(R.id.tv_tile_value);
你可以这样做(只是不同的 id,我的意思是为每个视图使用不同的 id):
TextView tvDayTitle = findViewById(R.id.tv_day_title);
TextView tvWeekTitle = findViewById(R.id.tv_week_title);
TextView tvMonthTitle = findViewById(R.id.tv_month_title);
TextView tvTotalTitle = findViewById(R.id.tv_total_title);