#android #android-studio #android-layout #kotlin #android-fragments
#Android #android-studio #android-макет #kotlin #android-фрагменты
Вопрос:
У меня есть приложение, которое начинается с 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>
Когда я запускаю приложение, оно всегда выводит меня на «французский», даже если я нажал на английскую кнопку переключения!!
Спасибо.
Комментарии:
1. Вы оставили ключ API во вставленном коде, на всякий случай, если это проблема
Ответ №1:
Рассмотрим эти вещи:
- В
createAimybox
методе и этом кодеMainActivity().rbt
этот код создаст новый экземплярMainActivity
, и в этом заданном вами действииpublic var rbt= "French"
. Вот почему этоFrench
значение для печати. 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
Также вы должны использовать aimybox
и createAimybox
внутри MainActivity
, а не на уровне приложения:
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)
aimybox
внутри AimyboxApplication
класса, и он откроет этот интерфейс:
/**
* 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
* */
Комментарии:
1. Спасибо @keyur за ваш ответ. Итак, что вы предлагаете?
2. То, что вы хотите сделать, зависит от ваших требований. Пожалуйста, объясните, что именно вы хотите сделать.
3. то, что я хочу сделать, просто. При запуске приложения я выбираю язык, нажимая на один переключатель, а затем я хочу получить текстовое значение переключателя, нажатого в файле AimyboxApplication.kt точно в методе createAimybox ()
Ответ №2:
Keyur прав в отношении значения, вы не получаете доступ к тому, которое вы сохранили, вы создаете совершенно новое действие со значением по умолчанию ( "French"
), так что это то, что вы читаете.
У вас есть несколько вариантов, в зависимости от того, как настроено ваше приложение. Проще всего просто вызвать createAimybox()
напрямую, когда язык установлен, и передать язык в качестве параметра. Если вы делаете это между действиями (вместо того, чтобы хранить его в приложении), вы должны передавать данные в качестве дополнительных в Intent
пакете.
Возможно, было бы лучше сохранить его SharedPreferences
и указать цели захватить текущее значение — таким образом createAimybox
, функция может просто посмотреть, какова текущая настройка, и она будет сохраняться и между сеансами приложения, если это важно.
Я предполагаю, что aimybox
lazy
это свойство инициализируется после того, как пользователь устанавливает свой язык, но затем оно навсегда фиксируется до тех пор, пока приложение не будет закрыто и перезапущено. Поэтому, если вы хотите, чтобы пользователь мог менять язык без перезапуска приложения, вам нужно будет действовать по-другому.
Комментарии:
1. да @cactustictacs. я новичок в Android. можете ли вы сказать мне, где и как я могу вызвать createAimybox() напрямую, когда язык установлен?