【问题标题】:Share and accessing radio button text value between two kotlin files在两个 kotlin 文件之间共享和访问单选按钮文本值
【发布时间】:2020-09-23 12:38:43
【问题描述】:

我有一个以 2 个单选按钮开头的应用程序。

当我单击其中一个时,我可以在当前文件中恢复其文本值。但是当我尝试在另一个文件中访问这个值时,即使我点击另一个按钮,它也不会改变!

MainActivity.kt

class MainActivity : AppCompatActivity() {
public var rbt= "French"
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.layout_activity_main)

    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

    val assistantFragment = AimyboxAssistantFragment()

    supportFragmentManager.beginTransaction().apply {

        replace(R.id.assistant_container, assistantFragment)
        commit()
    }

}
// Get the selected radio button text using radio button on click listener
fun radio_button_click(view: View){
    // Get the clicked radio button instance
    val radio: RadioButton = findViewById(radio_group.checkedRadioButtonId)
    rbt=radio.text.toString()
    Toast.makeText(applicationContext,"On click : ${rbt}",
        Toast.LENGTH_SHORT).show()
}
override fun onBackPressed() {
    val assistantFragment = (supportFragmentManager.findFragmentById(R.id.assistant_container)
            as? AimyboxAssistantFragment)
    if (assistantFragment?.onBackPressed() != true) super.onBackPressed()
}

}

我想要访问单选按钮文本值的另一个文件 (AimyboxApplication.kt):

class AimyboxApplication : Application(), AimyboxProvider {

companion object {
    private const val AIMYBOX_API_KEY = ""
}

override val aimybox by lazy { createAimybox(this) }

private fun createAimybox(context: Context): Aimybox {
    val unitId = UUID.randomUUID().toString()
    val textToSpeech = GooglePlatformTextToSpeech(context, Locale.getDefault())
    val speechToText = GooglePlatformSpeechToText(context, Locale.getDefault())
    //speechToText.toString()
    var rbt = MainActivity().rbt

    if (rbt=="English"){
        println("English")
    }
    if (rbt=="French"){
        println("French")
    }
    // Do something
}

}

layout_activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ImageView
        android:layout_width="wrap_content"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:layout_marginBottom="100dp"
        android:src="@mipmap/logo"/>

<RadioGroup
    android:id="@+id/radio_group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="100dp"
    android:checkedButton="@+id/fr">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="100dp"
        android:padding="18dp"
        android:text="@string/prompt"
        android:textSize="22sp" />

    <RadioButton
        android:id="@+id/en"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="English"
        android:onClick="radio_button_click"/>

    <RadioButton
        android:id="@+id/fr"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="French"
        android:onClick="radio_button_click"/>


</RadioGroup>

<FrameLayout
    android:id="@+id/assistant_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


</FrameLayout>

当我启动应用程序时,即使我点击了英文单选按钮,它总是打印我“法语”!

谢谢。

【问题讨论】:

  • 您在粘贴的代码中留下了 API 密钥,以防万一出现问题

标签: android android-studio android-layout kotlin android-fragments


【解决方案1】:

考虑以下几点:

  1. createAimybox 方法和此代码MainActivity().rbt 中,此代码将 创建MainActivity 的新实例,并且在那个活动中你有 预定义public var rbt= "French"。这就是为什么,它正在打印 French 值。
  2. AimyboxApplication 类将在活动开始之前被调用,因为它是应用程序,而且这个类只会被调用一次。所以现在即使你改变了MainActivity里面的值,应用程序类的方法也不会被自动触发(也是不同的对象MainActivity),你必须放一些逻辑。但不建议在应用程序级别使用此类逻辑,因为它会发生变化。

编辑:

让我给你一个简单的解决方案:

首先添加这个LanguagePref 类。

import android.content.Context
import android.content.SharedPreferences
const val LANGUAGE_PREFERENCE = "preferenceData"
const val LANGUAGE_DATA = "languageData"

public enum class LANGUAGE_ENUM(languageCode:String){
     ENGLISH("English"),
     FRENCH("French")
}

public class LanguagePref(val context: Context) {
    private val mPreferences: SharedPreferences by lazy {
        context.getSharedPreferences(
            LANGUAGE_PREFERENCE,
            Context.MODE_PRIVATE
        )
    }
    private val mEditor: SharedPreferences.Editor by lazy { mPreferences.edit() }

    public fun saveLanguage(
        langauage: String
    ) {
        mEditor
            .putString(LANGUAGE_DATA, langauage)
            .apply()
    }

    public fun getLanaguage(): String {
        return mPreferences.getString(LANGUAGE_DATA, LANGUAGE_ENUM.ENGLISH.name)!!
    }
}

现在在按钮单击事件中的主要活动中,您可以像这样保存语言:

val languagePref =LanguagePref(this)
languagePref.saveLanguage(LANGUAGE_ENUM.ENGLISH.name)
//languagePref.saveLanguage(LANGUAGE_ENUM.FRENCH.name)//For FRENCH language

您还应该在MainActivity 中使用aimyboxcreateAimybox,而不是在应用程序级别:

 override val aimybox by lazy { createAimybox(this) }

    private fun createAimybox(context: Context): Aimybox {
        val unitId = UUID.randomUUID().toString()

        val textToSpeech = GooglePlatformTextToSpeech(context, Locale.ENGLISH)
        val speechToText = GooglePlatformSpeechToText(context, Locale.ENGLISH)

        val dialogApi = AimyboxDialogApi(AIMYBOX_API_KEY, unitId)
        var rbt = LanguagePref(this).getLanaguage()

        if (rbt==LANGUAGE_ENUM.ENGLISH.name){
            println("English")
        }
        if (rbt==LANGUAGE_ENUM.FRENCH.name){
            println("French")
        }
        return Aimybox(Config.create(speechToText, textToSpeech, dialogApi))
    }

因为不会再次调用应用程序级代码。 Aimybox 文档中也提到了它。你可以通过(CTRL+ Right click)aimyboxAimyboxApplication类里面查看它,它会打开这个界面:

/**
 * Implement the interface in your Activity or Application to start using Aimybox components
 * */
interface AimyboxProvider {
    /**
     * Main class of the Aimybox library. You should have only one instance of the class for correct behavior.
     * */
    val aimybox: Aimybox
    /**
     *
     * */
    fun getViewModelFactory() = AimyboxAssistantViewModel.Factory.getInstance(aimybox)
}

如果您查看评论,则说明Activity or Application

/**
 * Implement the interface in your Activity or Application to start using Aimybox components
 * */

【讨论】:

  • 感谢@keyur 的回复。那你有什么建议呢?
  • 这取决于您想要做什么。请说明你到底想做什么。
  • 我想做的很简单。启动应用程序时,我通过点击一个单选按钮来选择语言,然后我想在方法 createAimybox() 中精确地获取在文件 AimyboxApplication.kt 中单击的单选按钮的文本值
【解决方案2】:

Keyur 对值的看法是正确的,您没有访问您存储的那个,您正在使用默认值 ("French") 创建一个全新的活动,所以这就是您读入的内容。

您有几个选项,具体取决于您的应用的设置方式。最简单的方法是在设置语言时直接调用createAimybox(),并将语言作为参数传递。如果您在活动之间执行此操作(而不是将其保存在应用程序中),您应该在 Intent 包中将数据作为额外内容传递。

将它存储在SharedPreferences 中并告诉目标获取当前值可能是一个更好的选择 - 这样createAimybox 函数就可以查找当前设置是什么,并且它将在应用会话之间持续存在也一样,如果这很重要的话。

我猜是因为aimyboxlazy 属性,它在用户设置他们的语言后被初始化,但在应用程序关闭并重新启动之前它会永久固定。因此,如果您希望用户能够在不重新启动应用的情况下更改语言,则需要以不同的方式进行操作。

【讨论】:

  • 是的@cactustictacs。我是安卓新手。你能告诉我在设置语言后在哪里以及如何直接调用 createAimybox() 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多