是否可以在不在 Fragment 中编写样板代码的情况下将 androidx-navigation 与 onClick-databinding 一起使用?
Is it possible to use androidx-navigation with onClick-databinding without writing boilercode in Fragment?
我想通过使用数据绑定而不是在代码中实现 onClick
处理程序来实现 androidx-navigation
我有一个带有实时数据元素的列表片段 selectedItemId
,我想在按下编辑按钮时打开一个对应的详细片段。有没有类似的可能
<layout>
<data>
<!-- assuming that com.example.MyGeneratedNavigation was
generated from .../res/navigation/my_navigation.xml -->
<variable name="myNavigation" type"com.example.MyGeneratedNavigation" />
<variable name="selectedItemId" type"..." />
</data>
<LinearLayout ...>
<Button android:id="@+id/edit"
android:onClick="@{() -> myNavigation.onShowDetails(selectedItemId)}" />
</LinearLayout>
</layout>
如果不在 List-fragment 中实现 onClick-handler 是否可行?
[@ABr回答后更新]
建议的解决方案不会触发按钮事件。为了进一步调查,我创建了自己的静态函数来调试它是否被调用
<layout ...>
<data>
<import type="de.k3b.androidx.navigationdemo.R" />
<import type="de.k3b.androidx.navigationdemo.GalleryFragment" />
</data>
<RelativeLayout ...>
<Button ...
android:onClick="@{view -> GalleryFragment.myNavigate(view,
R.id.action_gallery_to_editProperties)}"
/>
</RelativeLayout>
</layout>
public class GalleryFragment extends Fragment {
public static final String TAG = "GalleryFragment";
public static void myNavigate(Object view, @IdRes int id) {
// this gets never called neither with `Object view` nor with `View view`
Log.d (TAG, "myNavigate clicked");
// Navigation.findNavController(view).navigate(id);
}
}
不幸的是,语句 Log.d
从未被调用。
如果我在 java 代码中重命名静态方法 myNavigate
而不是在布局中重命名,我将按预期得到编译错误,因此数据绑定在语法上是正确的。
我使用这个导航图
<navigation 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/nav_gallery"
app:startDestination="@id/galleryFragment">
<fragment
android:id="@+id/galleryFragment"
android:name="de.k3b.androidx.navigationdemo.GalleryFragment"
android:label="fragment_gallery"
tools:layout="@layout/fragment_gallery" >
<action
android:id="@+id/action_gallery_to_editProperties"
app:destination="@id/editPropertiesFragment" />
</fragment>
<fragment
android:id="@+id/editPropertiesFragment"
android:name="de.k3b.androidx.navigationdemo.EditPropertiesFragment"
android:label="fragment_edit_properties"
tools:layout="@layout/fragment_edit_properties" />
</navigation>
还有这些build.gradle
全球build.gradle
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
应用build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "de.k3b.androidx.navigationdemo"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding.enabled=true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'android.arch.navigation:navigation-fragment:1.0.0'
implementation 'android.arch.navigation:navigation-ui:1.0.0'
}
当然可以。首先,您应该在导航图中创建一个您计划前往的方向的连接 move.Then 您可以使用以下导入和 onclick。
请注意,我不确定您是否可以在此方法中传递参数!!!!!!
<layout>
<data>
<import type="com.rf.comm.R"/>
<import type="androidx.navigation.Navigation"/>
<!-- assuming that com.example.MyGeneratedNavigation was
generated from .../res/navigation/my_navigation.xml -->
<variable name="myNavigation" type"com.example.MyGeneratedNavigation" />
<variable name="selectedItemId" type"..." />
</data>
<LinearLayout ...>
<Button android:id="@+id/edit"
android:onClick="@{view -> Navigation.findNavController(view).navigate(R.id.createServiceFragment)}" />
</LinearLayout>
</layout>
我想通过使用数据绑定而不是在代码中实现 onClick
处理程序来实现 androidx-navigation
我有一个带有实时数据元素的列表片段 selectedItemId
,我想在按下编辑按钮时打开一个对应的详细片段。有没有类似的可能
<layout>
<data>
<!-- assuming that com.example.MyGeneratedNavigation was
generated from .../res/navigation/my_navigation.xml -->
<variable name="myNavigation" type"com.example.MyGeneratedNavigation" />
<variable name="selectedItemId" type"..." />
</data>
<LinearLayout ...>
<Button android:id="@+id/edit"
android:onClick="@{() -> myNavigation.onShowDetails(selectedItemId)}" />
</LinearLayout>
</layout>
如果不在 List-fragment 中实现 onClick-handler 是否可行?
[@ABr回答后更新]
建议的解决方案不会触发按钮事件。为了进一步调查,我创建了自己的静态函数来调试它是否被调用
<layout ...>
<data>
<import type="de.k3b.androidx.navigationdemo.R" />
<import type="de.k3b.androidx.navigationdemo.GalleryFragment" />
</data>
<RelativeLayout ...>
<Button ...
android:onClick="@{view -> GalleryFragment.myNavigate(view,
R.id.action_gallery_to_editProperties)}"
/>
</RelativeLayout>
</layout>
public class GalleryFragment extends Fragment {
public static final String TAG = "GalleryFragment";
public static void myNavigate(Object view, @IdRes int id) {
// this gets never called neither with `Object view` nor with `View view`
Log.d (TAG, "myNavigate clicked");
// Navigation.findNavController(view).navigate(id);
}
}
不幸的是,语句 Log.d
从未被调用。
如果我在 java 代码中重命名静态方法 myNavigate
而不是在布局中重命名,我将按预期得到编译错误,因此数据绑定在语法上是正确的。
我使用这个导航图
<navigation 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/nav_gallery"
app:startDestination="@id/galleryFragment">
<fragment
android:id="@+id/galleryFragment"
android:name="de.k3b.androidx.navigationdemo.GalleryFragment"
android:label="fragment_gallery"
tools:layout="@layout/fragment_gallery" >
<action
android:id="@+id/action_gallery_to_editProperties"
app:destination="@id/editPropertiesFragment" />
</fragment>
<fragment
android:id="@+id/editPropertiesFragment"
android:name="de.k3b.androidx.navigationdemo.EditPropertiesFragment"
android:label="fragment_edit_properties"
tools:layout="@layout/fragment_edit_properties" />
</navigation>
还有这些build.gradle
全球build.gradle
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
应用build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "de.k3b.androidx.navigationdemo"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding.enabled=true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'android.arch.navigation:navigation-fragment:1.0.0'
implementation 'android.arch.navigation:navigation-ui:1.0.0'
}
当然可以。首先,您应该在导航图中创建一个您计划前往的方向的连接 move.Then 您可以使用以下导入和 onclick。
请注意,我不确定您是否可以在此方法中传递参数!!!!!!
<layout>
<data>
<import type="com.rf.comm.R"/>
<import type="androidx.navigation.Navigation"/>
<!-- assuming that com.example.MyGeneratedNavigation was
generated from .../res/navigation/my_navigation.xml -->
<variable name="myNavigation" type"com.example.MyGeneratedNavigation" />
<variable name="selectedItemId" type"..." />
</data>
<LinearLayout ...>
<Button android:id="@+id/edit"
android:onClick="@{view -> Navigation.findNavController(view).navigate(R.id.createServiceFragment)}" />
</LinearLayout>
</layout>