android - 具有两个片段的视图模型不起作用
问题描述
我正在开发一个应用程序,用户可以在他们的个人资料中添加他们的地址,现在我想在我从个人资料片段接收到的坐标上添加一个 viewModel 观察者,比如我的片段 A 并将此信息提供给地图片段,所以我可以在该位置创建一个新标记。显然我没有在我的片段 B 中获得观察者的任何信息。这就是我的代码:
这是配置文件的第一个片段:
class ProfilFoto : Fragment() {
lateinit var mDatabase : DatabaseReference
var mAuth = FirebaseAuth.getInstance()
var user = FirebaseAuth.getInstance().currentUser
var DISPLAY_NAME : String? = null
private var model: Communicator?=null
@SuppressLint("SetTextI18n", "ResourceType")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// setContentView(R.layout.fragment_notifications)
val rootView: View = inflater.inflate(R.layout.fragment_profil_foto, container, false)
model= activity?.let { ViewModelProviders.of(it).get(Communicator::class.java) }
val loca = rootView.findViewById<View>(R.id.locationtext) as TextView
var uid = user!!.uid
val userHashMap = HashMap<String, Any>()
mDatabase = FirebaseDatabase.getInstance().getReference("User").child(uid)
val speicherButton = rootView.findViewById<Button>(R.id.speichern)
speicherButton.setOnClickListener {
val location = rootView.findViewById<View>(R.id.locationPerson) as EditText
val loc = location.text.toString()
if (!loc.isEmpty()) {
Log.e("Location", loc)
val locationAddress = GeocodingLocation()
locationAddress.getAddressFromLocation(loc,
getActivity()?.getApplicationContext(), GeocoderHandler())
model!!.setMsgCommunicator(locationAddress.toString())
//userHashMap["Adresse"] = loc
mDatabase.child("Adresse").setValue(loc)
.addOnSuccessListener {
Log.e("Telefon", loc)
}
.addOnFailureListener {
Log.e("Telefon2", "failed")
}
// mDatabase.updateChildren(userHashMap)
}
}
mDatabase.addValueEventListener(object : ValueEventListener {
override fun onCancelled(error: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
return rootView
}
private class GeocoderHandler : Handler() {
override fun handleMessage(message: Message) {
val locationAddress: String?
locationAddress = when (message.what) {
1 -> {
val bundle: Bundle = message.getData()
bundle.getString("address")
}
else -> null
}
if (locationAddress != null) {
Log.e("Handler", locationAddress)
}
}
}
}
这是应该出现消息的地图片段:
class MapsFragment : Fragment() {
private val callback = OnMapReadyCallback { googleMap ->
val model= activity?.let { ViewModelProviders.of(it).get(Communicator::class.java) }
if (model != null) {
model.message.observe(this, { t ->
//txt.text = o!!.toString()
Log.e("Marker", t.toString())
var latlong = t.toString().split(",")
var lat = parseFloat(latlong[0])
var long = parseFloat(latlong[1])
googleMap.addMarker(
MarkerOptions()
.position(LatLng(lat.toDouble(), long.toDouble()))
.title("Der Neue")
)
})
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView : View = inflater.inflate(R.layout.fragment_maps, container, false)
...
return rootView
}
这是我正在使用的通信器类:
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class Communicator : ViewModel(){
val message =MutableLiveData<Any>()
fun setMsgCommunicator(msg:String){
message.setValue(msg)
}
}
也许重要的是还显示我从中获取坐标的 GeoLocator:
private const val TAG = "GeocodingLocation"
public class GeocodingLocation {
lateinit var mDatabase : DatabaseReference
var user = FirebaseAuth.getInstance().currentUser
fun getAddressFromLocation(locationAddress: String,
context: Context?, handler: Handler?) {
val thread: Thread = object : Thread() {
override fun run() {
val geocoder = Geocoder(context, Locale.getDefault())
var result: String? = null
var uid = user!!.uid
mDatabase = FirebaseDatabase.getInstance().getReference("User").child(uid)
try {
val addressList: List<*>? = geocoder.getFromLocationName(locationAddress, 1)
if (addressList != null && addressList.size > 0) {
val address: Address = addressList[0] as Address
val sb = StringBuilder()
sb.append(address.getLatitude()).append("\n")
mDatabase.child("Latitude").setValue(address.latitude)
.addOnSuccessListener {
Log.e("Telefon", address.latitude.toString())
}
.addOnFailureListener {
Log.e("Telefon2", "failed")
}
sb.append(address.getLongitude()).append("\n")
mDatabase.child("Longtitude").setValue(address.longitude)
.addOnSuccessListener {
Log.e("Telefon", address.longitude.toString())
}
.addOnFailureListener {
Log.e("Telefon2", "failed")
}
result = sb.toString()
}
} catch (e: IOException) {
Log.e(TAG, "Unable to connect to Geocoder", e)
} finally {
val message: Message = Message.obtain()
message.setTarget(handler)
if (result != null) {
message.what = 1
val bundle = Bundle()
bundle.putString("address", result)
message.setData(bundle)
} else {
message.what = 1
val bundle = Bundle()
result = """Address: $locationAddress
Unable to get Latitude and Longitude for this address location."""
bundle.putString("address", result)
message.setData(bundle)
}
message.sendToTarget()
}
}
}
thread.start()
}
}
有人知道我做错了什么而一无所获吗?就像在配置文件片段中一样,我在日志中收到纬度和经度。
解决方案
将注册的观察者代码移到回调块之外。在回调内部,设置地图准备更新时的值。在观察者检查地图是否准备好,设置标记。希望有效!
private lateinit var googleMap: GoogleMap
private val callback = OnMapReadyCallback { map ->
googleMap = map
}
val model= activity?.let { ViewModelProviders.of(it).get(Communicator::class.java) }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView : View = inflater.inflate(R.layout.fragment_maps, container, false)
if (model != null) {
model.message.observe(this, { t ->
//txt.text = o!!.toString()
Log.e("Marker", t.toString())
var latlong = t.toString().split(",")
var lat = parseFloat(latlong[0])
var long = parseFloat(latlong[1])
googleMap?.let{
it.addMarker(
MarkerOptions()
.position(LatLng(lat.toDouble(), long.toDouble()))
.title("Der Neue")
)
})
}
}
return rootView
}
推荐阅读
- amazon-web-services - AWS Fargate - 应用程序负载均衡器 (ELB) 显示不健康的目标,错误“健康检查失败,这些代码:[502]”
- javascript - 样本生成器,对空值和未定义值停止函数
- python - Pygame 中的类型错误
- php - Laravel 中的 Psr-4 已弃用通知
- flutter - 仍然有未处理的异常:GSheetsException:调用者没有权限
- llvm - 如果根据定义它不带参数,为什么 llvm::FunctionType(Type*, bool) 具有 bool ?
- python - 如何将json文件中的句子连接成一个文本?
- python - 无法在python中使用for循环遍历列表
- pdf - 使用 Python 3.7 在 SharePoint 页面上读取 PDF 时出错
- python - Jupyter 笔记本环境