安卓应用程序集内容视图(R.layout.activity_main)与视图绑定-不尊重layout_gravity



我最终决定在这个月加入Kotlin,作为一个业余项目。我正在学习Udacity课程(使用Kotlin开发Android应用程序(。

我只是想用View绑定替换viewById(作为对我的测试(。这很好用。

但是,如果我从绑定中使用setContentView(视图(,为什么我的布局不再考虑重力?

我的主要活动的布局文件是线性的,具有中心垂直布局_gravity

<<?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:orientation="vertical"
android:layout_gravity="center_vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="30sp"
android:layout_gravity="center_horizontal"/>
<Button
android:id="@+id/roll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/roll"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>

当我在活动中使用旧的setContentView(R.layout.main_activity(时,它会按预期显示在屏幕中央的

class MainActivity : AppCompatActivity() {
@RequiresApi(Build.VERSION_CODES.P)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Let's do it the trad way without binding
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.roll_button)

带有重心的图像

如果我把它换成视图绑定,并替换如下所示的setContentView

var binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)

该应用程序仍在运行,但现在文本和按钮位于屏幕顶部。

图像顶部对齐

我只是在测试我是否可以在一般情况下实现这一点,因为我更喜欢在现实生活中使用它(任何减少nullPointer异常的东西(。但是,如果我连一个简单的例子都做不好,我就受够了。

有人知道我做错了什么吗?或者我错过了什么概念?

尝试将android:layout_gravity="center_horizontal"更改为android:layout_gravity="center",或者尝试使用RelativeLayout我听说这是最好的布局之一。

我遇到了同样的问题。我在查看视图绑定的文档,它指出:

"视图绑定不支持布局变量或布局表达式,因此它不能直接用于从XML声明动态UI内容布局文件">

我想知道它是否与此有关?我对此还很陌生,但这是迄今为止我能找到的唯一对我有意义的东西

更新:发现另一个问题在问同样的问题(如何使用线性布局的视图绑定?(

android:layout_gravity="center_vertical"更改为android:gravity="center",但布局编辑器中的预览没有居中显示时出现问题;为了弥补这一点,我添加了tools:layout_gravity="center_vertical",所以activity_main.xml现在在顶部显示了这一点:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
tools:layout_gravity="center_vertical"
android:orientation="vertical"
tools:context=".MainActivity">

可能不是最好的解决方案,但它可以向您显示预览,然后当您真正运行它时!

XMLlayout_前缀属性可用于父视图。如果在没有父级的情况下展开视图,则layout_*属性将不起作用。

活动的setContentView(int)通常委托给在扩展XML布局时隐式使用父容器布局的PhoneWindow#setContentView(int)。这就是为什么1 arg通胀在一项活动中起作用的原因。

视图绑定不隐式提供任何父布局。您需要显式地为它提供三个参数inflate(int, View, boolean)方法调用,其中第一个参数是布局id,第二个参数是父级,第三个参数控制膨胀时是否应将膨胀的布局添加到父级。

通常一个简单的用例是使用片段,其中onCreateView()回调为您提供了一个父容器布局,您可以只返回inflate(id, container, false)

PhoneWindow内容布局是延迟生成的,所以您有点像鸡和蛋的问题。调用setContentView()会生成内容布局,但在调用它时,您可能希望已经使用父内容布局扩展了视图绑定。

我的建议是将布局代码从你的活动中移除,而是使用片段。然后你可以在片段中使用视图绑定。

最新更新