我试图使用数据绑定(确切地说是方法引用)对多个按钮进行工作事件处理,但是似乎不能使它工作。看来onCLick侦听器找不到引用的方法。不知道为什么会这样。以下是相关的代码段以及我不断收到的错误:
主要活动:
class MainActivity : AppCompatActivity(), EntryScreenFragment.FragInterface, ImageChoiceFragment.FragInterface,
AccelerometerDisplayFragment.FragInterface, JSONPostChooserFragment.FragInterface {
companion object {
const val MY_REQUEST_CODE_1 = 24215
const val MY_REQUEST_CODE_2 = 31345
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.my_toolbar))
val fragment = EntryScreenFragment()
fragment.listener = this
addNewFragment(fragment)
supportActionBar?.setHomeAsUpIndicator(R.mipmap.ic_launcher_round)
supportActionBar?.setHomeButtonEnabled(true)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun screenshotAccelerometer(): Boolean {
if (isExternalStorageWritable()) checkAndAskForPermissionToWrite()
return true
}
override fun imageChoiceButtonclick1(input: String) {
val fragment = ImageDisplayFragment.newInstanceWithText(getString(R.string.url_1), input)
addNewFragment(fragment)
}
override fun imageChoiceButtonclick2(input: String) {
val fragment = ImageDisplayFragment.newInstanceWithText(getString(R.string.url_2), input)
addNewFragment(fragment)
}
override fun imageChoiceButtonclick3(input: String) {
val fragment = ImageDisplayFragment.newInstanceWithText(getString(R.string.url_3), input)
addNewFragment(fragment)
}
override fun entryScreenButtonClickImages() {
val fragment = ImageChoiceFragment()
fragment.listener = this
addNewFragment(fragment)
}
override fun entryScreenButtonClickAccelerometer() {
val fragment = AccelerometerDisplayFragment()
fragment.listener = this
addNewFragment(fragment)
}
override fun entryScreenButtonClickJSON() {
// val fragment=JSONLoaderFragment()
val fragment = JSONPostChooserFragment()
fragment.listener = this
addNewFragment(fragment)
}
override fun entryScreenButtonClickNoXML() {
val fragment = NoXMLFragment()
addNewFragment(fragment)
}
override fun entryScreenButtonClickCheckForInternet() {
return checkAndAskForPemissionToAccessNetworkState()
}
override fun entryScreenButtonClickImageBind() {
val fragment =ImageBindFragment()
addNewFragment(fragment)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.test_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
android.R.id.home -> {
val mgr = supportFragmentManager
if (!mgr.popBackStackImmediate())
finish()
}
R.id.action_settings -> {
}
else -> {
}
}
return super.onOptionsItemSelected(item)
}
override fun createChosenPostFragment(data: PostEntity) {
val fragment = ChosenJSONPostFragment.newInstance(data)
addNewFragment(fragment)
}
override fun onStart() {
super.onStart()
}
override fun onResume() {
super.onResume()
}
override fun onPause() {
super.onPause()
}
fun addNewFragment(f: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.setCustomAnimations(R.anim.anim_entry_1, R.anim.anim_exit_1, R.anim.anim_entry_1, R.anim.anim_exit_1)
transaction.add(R.id.fragment_container, f).addToBackStack(UUID.randomUUID().toString()) //potential error
transaction.commit()
}
private fun checkAndAskForPermissionToWrite() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), MY_REQUEST_CODE_1)
} else {
if (isExternalStorageWritable())
return
}
}
private fun checkAndAskForPemissionToAccessNetworkState() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_NETWORK_STATE), MY_REQUEST_CODE_2)
} else {
//what to do with permission
openWifi()
}
return
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
MY_REQUEST_CODE_1 -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
//what to do with permission
if (isExternalStorageWritable())
return
}
}
MY_REQUEST_CODE_2 -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
openWifi()
}
}
else -> {
//...
Toast.makeText(this, "Permission not granted", Toast.LENGTH_LONG).show()
}
}
}
fun openWifi() {
if (isNetworkAvailable())
else {
val bar = Snackbar.make(findViewById(R.id.EntryScreenCoordinatorLayout), getString(R.string.internet_check_snackbar_text), Snackbar.LENGTH_LONG)
bar.show()
bar.setAction(getString(R.string.internet_check_snackbar_action)) { startActivity(Intent(Settings.ACTION_WIFI_SETTINGS)) }
}
}
private fun isNetworkAvailable(): Boolean {
val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
return activeNetwork?.isConnectedOrConnecting == true
}
fun isExternalStorageWritable(): Boolean {
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
}
} 片段:
class EntryScreenFragment : Fragment() {
interface FragInterface {
fun entryScreenButtonClickImages()
fun entryScreenButtonClickAccelerometer()
fun entryScreenButtonClickJSON()
fun entryScreenButtonClickNoXML()
fun entryScreenButtonClickCheckForInternet()
fun entryScreenButtonClickImageBind()
}
var listener: FragInterface? = null
lateinit var binding: FragmentEntryScreenBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding=DataBindingUtil.inflate(inflater,R.layout.fragment_entry_screen,container,false)
binding.handlers= EntryScreenEventHandlers()
binding.handlers.listener=listener
binding.root.isClickable=true
return binding.root
}
} 片段的XML:
<layout>
<data>
<variable
name="handlers"
type="com.example.robert.testapp.EntryScreenEventHandlers" />
</data>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/EntryScreenCoordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorWhite"
android:orientation="vertical">
<Button
android:id="@+id/EntryScreenButtonToImages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:onClick="@{handlers::entryScreenButtonClickImages}"
android:text="Make Fragment"
app:layout_behavior="com.example.robert.testapp.ButtonSnackbarBehaviour" />
<Button
android:id="@+id/EntryScreenAccelerometerButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:onClick="@{handlers::entryScreenButtonClickAccelerometer}"
android:text="Accelerometer screen"
app:layout_behavior="com.example.robert.testapp.ButtonSnackbarBehaviour" />
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/EntryScreenButtonToJSONLoader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{handlers::entryScreenButtonClickJSON}"
android:text="@string/entry_screen_load_json_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/EntryScreenButtonToNoXmlFragment"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/EntryScreenButtonToNoXmlFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{handlers::entryScreenButtonClickNoXML"
android:text="@string/entry_screen_to_no_xml_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/EntryScreenButtonToJSONLoader"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/EntryScreenButtonInternetCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{handlers::entryScreenButtonClickCheckForInternet"
android:text="@string/entry_screen_internet_check_button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/EntryScreenButtonImageBind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{handlers::entryScreenButtonClickImageBind"
android:text="@string/entry_screen_image_bind_button"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
事件处理类:
class EntryScreenEventHandlers {
var listener : EntryScreenFragment.FragInterface? = null
fun entryScreenButtonClickImages(){listener?.entryScreenButtonClickImageBind()}
fun entryScreenButtonClickAccelerometer(){listener?.entryScreenButtonClickAccelerometer()}
fun entryScreenButtonClickJSON(){listener?.entryScreenButtonClickJSON()}
fun entryScreenButtonClickNoXML(){listener?.entryScreenButtonClickNoXML()}
fun entryScreenButtonClickCheckForInternet(){listener?.entryScreenButtonClickCheckForInternet()}
fun entryScreenButtonClickImageBind() {listener?.entryScreenButtonClickImageBind()}
}
最后是错误消息:
[kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: Found data binding errors.
****/ data binding error ****msg:Listener class android.view.View.OnClickListener with method onClick did not match signature of any method handlers::entryScreenButtonClickImages
file:C:\Users\Robert\Desktop\AP_projects\app\src\main\res\layout\fragment_entry_screen.xml
loc:22:31 - 22:68
****\ data binding error ****
at android.databinding.tool.processing.Scope.assertNoError(Scope.java:112)
at android.databinding.annotationprocessor.ProcessDataBinding.doProcess(ProcessDataBinding.java:101)
at android.databinding.annotationprocessor.ProcessDataBinding.process(ProcessDataBinding.java:65)
at org.jetbrains.kotlin.kapt3.ProcessorWrapper.process(annotationProcessing.kt:133)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$200(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.runContributingProcs(JavacProcessingEnvironment.java:627)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1033)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1198)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068)
at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:89)
at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:46)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:226)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:181)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:93)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:97)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:107)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:84)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:374)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:64)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:101)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:365)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:130)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:161)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:63)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:108)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:52)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$1$2.invoke(CompileServiceImpl.kt:395)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$1$2.invoke(CompileServiceImpl.kt:97)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:909)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:97)
at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:939)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:908)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:394)
at sun.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)