gpt4 book ai didi

android - 无法将数据传递给 Android (Kotlin) 中的另一个 fragment

转载 作者:行者123 更新时间:2023-12-02 13:33:49 24 4
gpt4 key购买 nike

我有一个问题。我正在为 MQTT 客户端的 Android 应用程序,我需要在不同的 fragment 中为 MqttAndroidClient() 方法使用相同的参数。我已经尝试通过 putExtra() Intent 将它们传递到包中,从而创建类的对象。 bundle 和 putExtra 将数据发送到另一个 fragment it shows in the debug mode , 但在目标 fragment 中 I get nulls .当我尝试接收实例化第一个 fragment 的值时,它向我发送了没有任何值的 lateinit 变量。我不知道我还能做些什么。我考虑过使用 setter 和 getter 来获取它,但我不确定这是解决方案。

我发送数据的第一个 fragment :

ConnectFragment.kt

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.dzichkovskii.mqttsrm.R
import kotlinx.android.synthetic.main.fragment_connect.*
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*
import java.io.Serializable

class ConnectFragment : Fragment(){
companion object{
const val SUCCESS_TEXT = "Connection established successfully"
const val FAILURE_TEXT = "Connection wasn't established. Error happened."
const val BLANK_TEXT = "Your inputs cannot be empty. Please, write the correct address or ID."
const val CONNECTION_FAILURE = "Something went wrong. Probably you have no internet. Try later"
const val SENDING_NAME_ADDRESS = "mqttAndroidClientAddress"
const val SENDING_NAME_ID = "mqttAndroidClientId"
const val TAG = "ConnectFragment"
}
lateinit var mqttAndroidClient: MqttAndroidClient

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment_connect, container, false)

//I will leave this values just in case I would need to test the connection
//val testClientId = MqttClient.generateClientId()
//val testAddress = "tcp://broker.hivemq.com:1883"

root.findViewById<Button>(R.id.btn_connect).setOnClickListener {
mqttAndroidClient = connect(context, view)

}

return root
}
private fun connect(context: Context?,
view: View?): MqttAndroidClient {

// val inputAddress = view?.findViewById(R.id.tv_broker_address_input) as EditText
// val inputId = view?.findViewById(R.id.tv_client_id_input) as EditText
// val inputPort = view.findViewById(R.id.tv_broker_port_input) as EditText
//
//Making the string the user needs to put more friendly
// val addressStringSimplification = "tcp://" + inputAddress.text.toString() +
// ":" + inputPort.text.toString()

val addressStringSimplification = "tcp://broker.hivemq.com:1883"
val testClientId = MqttClient.generateClientId()

mqttAndroidClient = MqttAndroidClient(context?.applicationContext, addressStringSimplification, testClientId/*inputId.text.toString()*/)

val intent = Intent(this.context, SubscribeFragment::class.java)

val bundle = Bundle()
bundle.putString("testBundle", addressStringSimplification) //bundle here
val subscribeFragment = SubscribeFragment()
subscribeFragment.arguments = bundle

intent.putExtra(SENDING_NAME_ADDRESS, addressStringSimplification) //Intents here
intent.putExtra(SENDING_NAME_ID, testClientId)

// if (inputAddress.isBlank() || inputId.isBlank()
// || inputPort.isBlank() || addressStringSimplification == "tcp://:"){
// displayErrorMessage(BLANK_TEXT, view, this)
// return
// }
// else {
try {
val token = mqttAndroidClient.connect()
token.actionCallback = object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {

Log.d(TAG, "Connection is successful")

Toast.makeText(context, SUCCESS_TEXT, Toast.LENGTH_SHORT).show()
hideKeyboard()
return
}

override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {

Log.d(TAG, "Connection didn't established")

Toast.makeText(context, FAILURE_TEXT, Toast.LENGTH_SHORT).show()
displayErrorMessage(FAILURE_TEXT, view, this@ConnectFragment)
return
}
}
} catch (e: MqttException) {

Log.d(TAG, "Exception caught")

displayErrorMessage(CONNECTION_FAILURE, view, this)
}
return mqttAndroidClient
}
// tv_error.visibility = View.INVISIBLE
}

/**
* This extension function makes strings look less ugly.
*/
private fun EditText.isBlank() = this.text.toString().isBlank()
//}

fun displayErrorMessage(errorString: String, view: View?, fragment: Fragment){
val errorTextView = view?.rootView?.findViewById(R.id.tv_error) as TextView
errorTextView.text = errorString
errorTextView.visibility = View.VISIBLE
fragment.hideKeyboard()
}

fun Fragment.hideKeyboard() {
view?.let { activity?.hideKeyboard(it) }
}
fun Context.hideKeyboard(view: View) {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}

这是我接收数据的另一个 fragment :

SubscribeFragment.kt

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.dzichkovskii.mqttsrm.R
import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.fragment_subscribe.view.*
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.IMqttActionListener
import org.eclipse.paho.client.mqttv3.IMqttToken
import org.eclipse.paho.client.mqttv3.MqttException

class SubscribeFragment : Fragment() {

companion object {
const val TAG = "SubscribeFragment"
const val BLANK_TEXT = "Your inputs cannot be empty. Please, write the correct address or ID."
const val ON_SUCCESS = "You subscribed successfully."
const val ON_FAILURE = "You didn't subscribed to the topic. Probably this topic doesn't exist."
const val CONNECTION_ERROR = "The topic don't exist or you have connection problems. " +
"Check your internet connection or change the topic's name"
const val GETTING_NAME_ADDRESS = "mqttAndroidClientAddress"
const val GETTING_NAME_ID = "mqttAndroidClientId"
}

private var checkedOption: Int = 0 //Default value of qos

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {

val root = inflater.inflate(R.layout.fragment_subscribe, container, false)

return root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

view.chip_group?.setOnCheckedChangeListener { _, checkedId: Int ->
val chip: Chip? = view.findViewById(checkedId)
val qos = chip?.text.toString().toInt()
checkedOption = qos

Log.d(TAG, "Checked option passed with value $checkedOption")
}

view.findViewById<Button>(R.id.btn_subscribe).setOnClickListener {
subscribe()
}
}

private fun subscribe(){

val connectFragment = ConnectFragment()

val mqttAndroidClient = connectFragment.mqttAndroidClient //Instantiation of the class here

val address = this@SubscribeFragment.arguments?.getString("testBundle") // Bundle here
val id = activity?.intent?.getStringExtra(GETTING_NAME_ID) // Intent string here

//val mqttAndroidClient = MqttAndroidClient(context, address, id)

val inputTopic = view?.findViewById(R.id.et_topic) as EditText
val topic = inputTopic.text.toString()

if (inputTopic.isBlank()){
displayErrorMessage(BLANK_TEXT, view, this)
}

try {
Log.d(TAG, "Checked option in subscribe method is $checkedOption")
mqttAndroidClient.subscribe(topic, checkedOption, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken) {
Toast.makeText(context, ON_SUCCESS, Toast.LENGTH_SHORT).show()
Log.d(TAG, "Connected successfully")
}
override fun onFailure(
asyncActionToken: IMqttToken,
exception: Throwable
) {
Toast.makeText(context, ON_FAILURE, Toast.LENGTH_SHORT).show()
Log.d(TAG, "Didn't connected")
}
})
} catch (e: MqttException) {
displayErrorMessage(CONNECTION_ERROR, view, this)
}
}
private fun EditText.isBlank() = this.text.toString().isBlank()
}

感谢您的回答!

最佳答案

首先要创建一个 fragment ,你应该有一个 newInstance 方法,这个方法应该除了你想传递给 fragment 的参数,在你的例子中是 SubscriberFragment companion object

应该有以下功能
class SubscribeFragment: Fragment() {
companion object {
const val SENDING_NAME_ADDRESS = "mqttAndroidClientAddress"
const val SENDING_NAME_ID = "mqttAndroidClientId"

// Use this function to create instance of your fragment
fun newInstance(addressStringSimplification: String,
testClientId: String): MyFragment {
val args = Bundle()
args.putString(SENDING_NAME_ADDRESS , addressStringSimplification)
args.putString(SENDING_NAME_ID , testClientId)
val fragment = SubscribeFragment()
fragment.arguments = args
return fragment
}
}
}

在此之后,当您的 fragment 被加载时,参数被传送到 onCreate 方法,您可以按如下方式提取它们。

@Override
public void onCreate(Bundle savedInstanceState) {
var sendingName = getArguments().getInt(SENDING_NAME_ADDRESS);
var sendingId = getArguments().getString(SENDING_NAME_ID);
}

现在是最重要的部分,您似乎认为执行 SubscriberFragment() 足以加载不是案件。当你想启动 SubscriberFragment 时,你应该执行以下操作

// create instance of SubscriberFragment with newInstance function and pass the argguments you want
var someFragment = SubscribeFragment.newInstance(addressStringSimplification,testClientId);
var transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, someFragment); // give your fragment container id in first parameter
transaction.addToBackStack(null);
transaction.commit();

关于android - 无法将数据传递给 Android (Kotlin) 中的另一个 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59908070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com