我正在尝试使用 Kotlin 视图绑定向片段内的按钮添加单击侦听器。我正在方法中设置点击侦听器onCreateView()。当我这样做时,我得到一个空指针异常,因为按钮尚未创建。我认为 Kotlin 视图绑定负责视图初始化,因此按钮不应该为空?
这是我的代码:
class FragmentStart : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_start, container, false)
start_button.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.action_fragmentStart_to_fragmentQuestion,null)
)
return view
}
}
Run Code Online (Sandbox Code Playgroud)
这是例外情况:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Run Code Online (Sandbox Code Playgroud) java android nullpointerexception kotlin android-viewbinding
我想在同一个活动中使用 ViewBinding 和 DataBinding。如果这是可能的,您将如何在活动中实施它?
这是我到目前为止所尝试过的,
@Override
protected void onCreate(Bundle savedInstanceState) {
ActivityMainBinding viewBinding = ActivityMainBinding.inflate(getLayoutInflater();
View view = viewBinding.getRoot();
setContentView(view)
ActivityMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
}
Run Code Online (Sandbox Code Playgroud) 假设我有一个名为Activity_main.xml的布局,它有一个元素:
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Run Code Online (Sandbox Code Playgroud)
名为MainActivity.java 的活动。在其 onCreate 方法中,我使用 viewBinding 膨胀上述布局,并设置文本视图的文本:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.textView.setText("some text");
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我通过按
类似的方式重命名Activity_main.xml中 TextView 的 id ,那么 中的引用不会从 更改为Shift+F6@+id/text_view_newonCreatebinding.textView.setText("some text");binding.textViewNew.setText("some text");
这种行为是限制、错误还是我做错了什么?
我想使用视图绑定来绑定包含布局中的视图。我已经为包含的布局提供了 id“topBar”,但仍然无法访问其中的视图。我尝试使用 Android studio 自动修复来创建一个局部变量来查看其类型。它显示类型“android.widget .a”\n我使用的是Android Studio4.0。这是 Android Studio 中的错误吗?
\n我的活动
\n private ActivityWalletBinding viewBinding;\n private ViewTitleBinding topBarBinding;\n\n @Override\n protected void onCreate(@Nullable Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n viewBinding = ActivityWalletBinding.inflate(getLayoutInflater());\n setContentView(viewBinding.getRoot());\n viewBinding.topBar;\n android.widget . a = viewBinding.topBar; //Create local var using auto fix in android \nstudio \n}\nRun Code Online (Sandbox Code Playgroud)\n活动钱包.xml
\n<?xml version="1.0" encoding="utf-8"?>\n<LinearLayout\n xmlns:android="http://schemas.android.com/apk/res/android"\n android:layout_width="match_parent"\n android:layout_height="match_parent"\n android:orientation="vertical"\n >\n\n <include\n android:id="@+id/topBar"\n layout="@layout/view_title"/>\nRun Code Online (Sandbox Code Playgroud)\n视图标题.xml
\n<?xml version="1.0" encoding="utf-8"?>\n<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"\n android:layout_width="match_parent"\n android:layout_height="65dp"\n xmlns:tools="http://schemas.android.com/tools"\n android:background="@color/white"\n android:paddingTop="19dp"\n android:id="@+id/fl_tab">\n <RelativeLayout\n android:layout_width="match_parent"\n android:layout_height="match_parent"\n >\n <ImageView\n android:id="@+id/btn_back"\n …Run Code Online (Sandbox Code Playgroud) 我正在尝试将我的项目迁移到查看绑定,但在启动应用程序时出现异常。
我的主要活动包含一个 NavHostFragment,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
...
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
...
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
NavHostFragment 中默认加载的第一个片段的实现如下:
class ToolListFragment : Fragment(R.layout.fragment_tool_list) {
...
private var _binding: FragmentToolListBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentToolListBinding.inflate(layoutInflater, container, false)
return binding.root
}
...
}
Run Code Online (Sandbox Code Playgroud)
这是片段布局的相关部分:
<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="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ToolListFragment"
android:orientation="vertical"
android:background="@android:color/white">
<com.google.android.material.tabs.TabLayout …Run Code Online (Sandbox Code Playgroud) 我已经开始在我的片段和活动中使用视图绑定。片段的推荐模式是中的null绑定字段onDestroyView()。我还在自定义视图中使用视图绑定。我是否还需要清除该视图绑定字段?我想是这样,但没有onDestroyed()视图功能。有一个View.onDetachedFromWindow()函数,但我不确定这是否是null绑定字段的合适位置。
这是一个合理的担忧吗?如果是,我该如何实现呢?
**错误:任务“:app:dataBindingGenBaseClassesBetaDebug”执行失败。
不是有效的名称:switch
**
将 android studio 更新到版本 4.2.1 后无法运行构建。
buildFeatures { viewBinding true }
错误详细信息:
失败:构建失败并出现异常。
引起原因:java.lang.IllegalArgumentException:不是有效名称:在 com.squareup.javapoet.Util.checkArgument(Util.java:53) 处切换,在 com.squareup.javapoet.FieldSpec.builder(FieldSpec.java:91) 处切换android.databinding.tool.ext.Javapoet_extKt.fieldSpec(javapoet_ext.kt:60) 在 android.databinding.tool.writer.JavaFileGenerator.bindingFields(ViewBinderGenerateJava.kt:102) 在 android.databinding.tool.writer.JavaFileGenerator.access$ BindingFields(ViewBinderGenerateJava.kt:52) 在 android.databinding.tool.writer.JavaFileGenerator$typeSpec$1.invoke(ViewBinderGenerateJava.kt:81) 在 android.databinding.tool.writer.JavaFileGenerator$typeSpec$1.invoke(ViewBinderGenerateJava.kt: 52) 在 android.databinding.tool.ext.Javapoet_extKt.classSpec(javapoet_ext.kt:39) 在 android.databinding.tool.writer.JavaFileGenerator.typeSpec(ViewBinderGenerateJava.kt:73) 在 android.databinding.tool.writer.JavaFileGenerator .create(ViewBinderGenerateJava.kt:69) 在 android.databinding.tool.writer.ViewBinderGenerateJavaKt.toJavaFile(ViewBinderGenerateJava.kt:43) 在 android.databinding.tool.BaseDataBinder$generateAll$2.accept(BaseDataBinder.kt:82) 在 android .databinding.tool.BaseDataBinder$generateAll$2.accept(BaseDataBinder.kt:34) 在 android.databinding.tool.BaseDataBinder.generateAll(BaseDataBinder.kt:63) 在 com.android.build.gradle.internal.tasks.databinding。 DataBindingGenBaseClassesTask$CodeGenerator.run(DataBindingGenBaseClassesTask.kt:228) 位于 com.android.build.gradle.internal.tasks.databinding.DataBindingGenBaseClassesTask$writeBaseClasses$$inlined$recordTaskAction$1.invoke(BaseTask.kt:67) 位于 com.android. build.gradle.internal.tasks.Blocks.recordSpan(Blocks.java:51) 位于 com.android.build.gradle.internal.tasks.databinding.DataBindingGenBaseClassesTask.writeBaseClasses(DataBindingGenBaseClassesTask.kt:255) 位于 java.base/jdk。 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(本机方法) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
我试图了解片段中视图绑定的实现,我发现它与活动不同。
在一次活动中:
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
Run Code Online (Sandbox Code Playgroud)
在一个片段中:
private var _binding: ResultProfileBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,为什么片段中有bindingand ?_binding这条线是做什么的,它的目的是什么?
private val binding get() = _binding!!
Run Code Online (Sandbox Code Playgroud) 我被这个问题困住了。我已将项目等级升级到 7.0.1 和 Kotlin 1.5.30。升级之前一切正常。但升级后,我开始为每个项目收到以下错误。甚至,我也尝试过创建新项目。我也面临着同样的问题。请检查下图。

下面,我正在编写我的项目的所有文件。其中负责数据绑定和视图绑定。
项目基础build.gradle
buildscript {
ext.kotlin_version = '1.5.30'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Run Code Online (Sandbox Code Playgroud)
基于应用程序的 build.gradle 文件
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdk 30
defaultConfig {
applicationId "colour.moon"
minSdk 21
targetSdk 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 …Run Code Online (Sandbox Code Playgroud) 启用视图绑定后,使用:
android {
...
buildFeatures {
viewBinding = true
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用ViewBinding,问题是我们需要binding.在访问每个视图之前使用前缀。有没有一种方法可以省略这个前缀,并直接访问类中的视图?
所以而不是:
binding.textview1.text = viewModel.name
binding.button1.setOnClickListener { viewModel.userClicked() }
Run Code Online (Sandbox Code Playgroud)
直接使用:
textview1.text = viewModel.name
button1.setOnClickListener { viewModel.userClicked() }
Run Code Online (Sandbox Code Playgroud)
显然我们可以使用with(binding)和使用每个方法,但是有没有办法在全局范围内将其应用于整个类?
fun method = with(binding){
// now we can access the viewbinding
textview1.text = viewModel.name
button1.setOnClickListener { viewModel.userClicked() }
}
Run Code Online (Sandbox Code Playgroud)
是否有任何绑定设置,我们可以指定编译器从布局生成接口:
所以它会自动生成:
public interface Fragment1BindingInterface {
@NonNull
TextView getTextView1();
}
public final class Fragment1Binding implements ViewBinding, Fragment1BindingInterface {
@NonNull
private final RelativeLayout rootView;
@Override
@NonNull
private final TextView …Run Code Online (Sandbox Code Playgroud)