为什么使用 View Binding 会改变布局?
Why using View Binding is changing the layout?
实际代码:
我的主Activity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val rollButton = binding.rollButton
rollButton.setOnClickListener { rollDice() }
setContentView(binding.root)
}
private fun rollDice() {
val randomDiceRoll = Random.nextInt(6) + 1
Toast.makeText(this, randomDiceRoll.toString(), Toast.LENGTH_SHORT).show()
binding.resultText.text = randomDiceRoll.toString()
}
我的 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/result_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/count"
android:textSize="30sp" />
<Button
android:id="@+id/roll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/roll" />
</LinearLayout>
在 android 工作室中预览:
设备中的实际布局:
如果我将 setContentView(binding.root)
更改为 setContentView(R.layout.activity_main)
,Android Studio 和设备的布局将变得相同,但是当然,按钮不再起作用...
为什么会这样?为什么 ActivityMainBinding.inflate(layoutInflater)
改变布局?如何解决这个问题?
谢谢
也许您应该在线性布局中将 android:layout_height 设置为 match_parent 并在其中对齐内部视图。
If I change setContentView(binding.root) to setContentView(R.layout.activity_main), the layout of Android Studio and the device become the same
很可能是由于视图像这样膨胀时 container
没有传递给膨胀器造成的。
您可以尝试以下方法:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
和
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = ActivityMainBinding.bind(findViewById(R.id.root))
val rollButton = binding.rollButton
rollButton.setOnClickListener { rollDice() }
由于截图表明问题来自the Udacity course on Andorid, there is a good explanation on the course knowledge hub (link accessible only to the course users). In short, the explanation is the two things mentioned in the setContentView
docs and the ViewBinding
docs。
首先是当使用 setContentView
时
layout parameters of the specified view are ignored
而ViewBinding
的缺点是
it doesn't support layout variables or layout expressions, so it can't
be used to declare dynamic UI content straight from XML layout files
android:gravity
和android:layout_gravity
有区别:
android:gravity
设置 View Content 的引力(或 child,以防应用于 ViewGroup
)。
- 同时
android:layout_gravity
设置应用它的 View 的重力,相对于其父级。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:layout_gravity="center_horizontal"
android:textSize="30sp"/>
</LinearLayout>
在 LinearLayout 添加 android:gravity = "center"
解决问题。
实际代码:
我的主Activity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val rollButton = binding.rollButton
rollButton.setOnClickListener { rollDice() }
setContentView(binding.root)
}
private fun rollDice() {
val randomDiceRoll = Random.nextInt(6) + 1
Toast.makeText(this, randomDiceRoll.toString(), Toast.LENGTH_SHORT).show()
binding.resultText.text = randomDiceRoll.toString()
}
我的 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/result_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/count"
android:textSize="30sp" />
<Button
android:id="@+id/roll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/roll" />
</LinearLayout>
在 android 工作室中预览:
设备中的实际布局:
如果我将 setContentView(binding.root)
更改为 setContentView(R.layout.activity_main)
,Android Studio 和设备的布局将变得相同,但是当然,按钮不再起作用...
为什么会这样?为什么 ActivityMainBinding.inflate(layoutInflater)
改变布局?如何解决这个问题?
谢谢
也许您应该在线性布局中将 android:layout_height 设置为 match_parent 并在其中对齐内部视图。
If I change setContentView(binding.root) to setContentView(R.layout.activity_main), the layout of Android Studio and the device become the same
很可能是由于视图像这样膨胀时 container
没有传递给膨胀器造成的。
您可以尝试以下方法:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
和
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = ActivityMainBinding.bind(findViewById(R.id.root))
val rollButton = binding.rollButton
rollButton.setOnClickListener { rollDice() }
由于截图表明问题来自the Udacity course on Andorid, there is a good explanation on the course knowledge hub (link accessible only to the course users). In short, the explanation is the two things mentioned in the setContentView
docs and the ViewBinding
docs。
首先是当使用 setContentView
时
layout parameters of the specified view are ignored
而ViewBinding
的缺点是
it doesn't support layout variables or layout expressions, so it can't be used to declare dynamic UI content straight from XML layout files
android:gravity
和android:layout_gravity
有区别:
android:gravity
设置 View Content 的引力(或 child,以防应用于ViewGroup
)。- 同时
android:layout_gravity
设置应用它的 View 的重力,相对于其父级。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:layout_gravity="center_horizontal"
android:textSize="30sp"/>
</LinearLayout>
在 LinearLayout 添加 android:gravity = "center"
解决问题。