ViewBinding无法使用布局文件中的视图



我正在构建一个简历生成器应用程序。为此,我必须使用视图绑定。在我的应用程序中,everting运行良好,我能够创建具有特定布局的变量的视图绑定对象。但当我从绑定变量调用视图时,它在.kt文件中工作,但在运行应用程序时不工作。Binding对象显示视图。但当我运行应用程序时,它并没有像代码中所说的那样工作。

class EducationActivity : AppCompatActivity() {
private lateinit var binding : ActivityEducationBinding
private lateinit var toolbar : Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityEducationBinding.inflate(layoutInflater)
setContentView(R.layout.activity_education)
toolbar = findViewById(R.id.toolbar_eduction_activity)
setUpToolbar()
}
private fun setUpToolbar(){
setSupportActionBar(toolbar)
val actionBar = supportActionBar
if (actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setHomeAsUpIndicator(R.drawable.ic_back_button_action_bar)
actionBar.setDisplayShowTitleEnabled(false)
}
toolbar.setNavigationOnClickListener { onBackPressed() }
}

上面的代码使用的是:setSupportActionBar(工具栏(

但当我使用时,设置SupportActionBar(binding.toolbarEducationActivity(。它在运行应用程序时不起作用。没有任何错误。我不明白这个问题。提前感谢!

问题是您的布局被夸大了两次:

binding = ActivityEducationBinding.inflate(layoutInflater)
setContentView(R.layout.activity_education)

inflate调用扩展布局XML,构建视图层次结构,并将对该层次结构的引用存储在binding对象中。

然后,具有布局引用的setContentView调用将扩展到另一个完全分离的视图层次结构并显示它。

所以你有两组视图,一组是可见的,另一组不是。binding中的那些是没有显示的——用户看不到它们,也无法与它们交互,所以它们几乎毫无用处。这就是为什么当您尝试在binding中设置视图时,事情不起作用。

相反,使用findViewById是在"活动"的view层次结构(即显示的内容(上隐式调用它。通过这种方式,您可以获得实际屏幕上的Toolbar的引用,而不是binding中的杂散引用。所以,当你用它设置东西时,你实际上看到它在工作!


因此,要解决此问题,您需要确保对布局进行一次充气,然后让所有内容都使用它。有两种常见的方法:

// inflate your Binding class, and pass the resulting layout to setContentView to display
binding = ActivityEducationBinding.inflate(layoutInflater)
// this root property is the inflated view hierarchy
setContentView(binding.root)

// use setContentView with a layout resource, and let it inflate the views as normal
setContentView(R.layout.activity_education)
// now that the 'view' property for the Activity has been set with the inflated layout,
// you can grab that and -bind- its views to the properties in your Binding class
binding = ActivityEducationBinding.bind(view)

bind调用基本上与inflate相同,只是您跳过了膨胀步骤,因为您已经有了膨胀的布局。


您可以使用任何一种方法-我更喜欢第一种方法,因为您只通过引用适当的绑定类指定布局资源一次。然后你只要把你充气的东西传给setContentView就可以了。对于第二种方法,您必须确保使用的Binding类与传递到setContentView中的布局资源ID匹配。没什么大不了的,有时一个比另一个更方便!

然而,重要的是,在这两种情况下,你只东西充气一次。然后一切都在使用同一组视图,没有什么奇怪的事情发生。如果你发现自己不止一次膨胀,而且你没有一个非常具体的原因,那就是一个警告信号!

为什么在viewBinding中使用findViewByID?

你的代码应该像这个

->KOTLIN

class EducationActivity : AppCompatActivity() {
private lateinit var binding : ActivityEducationBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityEducationBinding.inflate(layoutInflater)
setContentView(binding.root)
setUpToolbar()
}
private fun setUpToolbar(){
setSupportActionBar(binding.toolbar)
val actionBar = supportActionBar
if (actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setHomeAsUpIndicator(R.drawable.ic_back_button_action_bar)
actionBar.setDisplayShowTitleEnabled(false)
}
binding.toolbar.setNavigationOnClickListener { onBackPressed() }
}

如果这有帮助,请将其标记为答案。

希望这能有所帮助!:(

最新更新