Bear with me - new to Kotlin so probably missing something obvious. As commented in the fragment code 'myPolyLine?.points = it' doesn't work but 'myPolyLine?.points = pLines.value' does (problem being that if I navigate away from the fragment I lose the existing polyline). Snip from Fragment:
class MapFragment : Fragment() {
private lateinit var mapViewModel: MapViewModel
private var myPositionMarker: Marker? = null
private lateinit var googleMap: GoogleMap
private var myPolyLine: Polyline? = null
private var isPolyAdded: Boolean = false
private lateinit var mo:MarkerOptions
private var pLines:MutableLiveData<ArrayList<LatLng>> = MutableLiveData<ArrayList<LatLng>>()
private val callback = OnMapReadyCallback { googleMap ->
this.googleMap = googleMap
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12.0F))
mo = MarkerOptions()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
pLines.value = ArrayList<LatLng>()
mapViewModel = ViewModelProvider(this).get(MapViewModel::class.java)
mapViewModel.theLocation.observe(viewLifecycleOwner, Observer {
val position = LatLng(it.latitude, it.longitude)
googleMap.moveCamera(CameraUpdateFactory.newLatLng(position))
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12.0F))
if (myPositionMarker == null) {
myPositionMarker = googleMap.addMarker(
mo.position(position).title("Me")
)
} else {
myPositionMarker!!.position = position
}
pLines.value?.add(position)
})
mapViewModel.points.observe(viewLifecycleOwner, Observer {
if (this::googleMap.isInitialized) {
if (!isPolyAdded) {
var lineOptions = PolylineOptions()
.color(Color.RED)
.width(8F)
myPolyLine = googleMap.addPolyline(lineOptions)
isPolyAdded = true
} else {
//Why doesn't this work (doesn't show polyline):
myPolyLine?.points = it
//But this does:
myPolyLine?.points = pLines.value
//Shows expected size in both cases
Log.d("Fragment", "myPolyLine has ${myPolyLine?.points?.size} points")
}
}
})
return inflater.inflate(R.layout.fragment_map, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(callback)
}
}
ViewModel:
class MapViewModel(application: Application) : AndroidViewModel(application){
private val repo = LocationRepository(application)
lateinit var theLocation: LiveData<Location>
lateinit var points: LiveData<ArrayList<LatLng>>
init {
theLocation = repo.theLocation
points = repo.points
}
override fun onCleared() {
Log.d("View Model", " Cleared")
super.onCleared()
repo.unregister()
}
}
Repository:
class LocationRepository(context: Context) {
var theLocation: MutableLiveData<Location> = MutableLiveData()
private var internalPoints: ArrayList<LatLng> = ArrayList()
var points: MutableLiveData<ArrayList<LatLng>> = MutableLiveData()
val context: Context = context
private val lr0: BroadcastReceiver
init {
points.value = ArrayList<LatLng>()
// points = MutableLiveData<ArrayList<LatLng>>()
lr0 = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val currentlocation = intent?.getParcelableExtra<Location>("Location")
theLocation.setValue(currentlocation)
if (currentlocation != null) {
internalPoints.add(LatLng(currentlocation.longitude, currentlocation.latitude))
points.value = internalPoints
}
}
}
Log.d("Repo"," Registering receiver")
val intentFilter = IntentFilter("locationChange")
context.registerReceiver(lr0, intentFilter)
}
fun unregister() {
Log.d("Repo"," Unregistering receiver")
context.unregisterReceiver(lr0)
}
}
Related
class ProfileFragment : Fragment() {
private lateinit var firestore: FirebaseFirestore
private lateinit var auth: FirebaseAuth
private lateinit var storage: FirebaseStorage
private lateinit var activityResultLauncher : ActivityResultLauncher<Intent>
private lateinit var permissionLauncher : ActivityResultLauncher<String>
var selectedPicture : Uri? = null
private var _binding: FragmentProfileBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
auth = Firebase.auth
firestore = Firebase.firestore
storage = Firebase.storage
registerLauncher()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navController = Navigation.findNavController(requireActivity(), R.id.fragment)
binding.bottomNavigationView.setupWithNavController(navController)
imageUpload.setOnClickListener {
if (ContextCompat.checkSelfPermission(requireContext(),android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
if (ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(),android.Manifest.permission.READ_EXTERNAL_STORAGE)){
Snackbar.make(view,"Galeriye erişmek için izin vermeniz gerekmektedir.",Snackbar.LENGTH_INDEFINITE).setAction("İzin Ver"){
permissionLauncher.launch(android.Manifest.permission.READ_EXTERNAL_STORAGE)
}.show()
}else{
permissionLauncher.launch(android.Manifest.permission.READ_EXTERNAL_STORAGE)
}
}else{
val intentToGallery = Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
activityResultLauncher.launch(intentToGallery)
}
val uuid = UUID.randomUUID()
val imageName = "$uuid.jpg"
val reference = storage.reference
val imageReference = reference.child("images").child(imageName)
if (selectedPicture!=null){
imageReference.putFile(selectedPicture!!).addOnSuccessListener {
val uploadPictureReference = storage.reference.child("images").child(imageName)
uploadPictureReference.downloadUrl.addOnSuccessListener {
val downloadUrl = it.toString()
val profileMap = hashMapOf<String, Any>()
profileMap.put("downloadUrl",downloadUrl)
firestore.collection("Profile").add(profileMap).addOnSuccessListener {
}.addOnFailureListener {
Toast.makeText(requireContext(),it.localizedMessage,Toast.LENGTH_SHORT).show()
}
}
}.addOnFailureListener {
Toast.makeText(requireContext(),it.localizedMessage,Toast.LENGTH_SHORT).show()
}
}
}
}
private fun registerLauncher(){
activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){result ->
if (result.resultCode == RESULT_OK){
val intentFromResult = result.data
if (intentFromResult !=null){
selectedPicture = intentFromResult.data
selectedPicture?.let {
binding.selectImage.setImageURI(it)
}
}
}
}
permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()){result->
if (result){
val intentToGallery = Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
activityResultLauncher.launch(intentToGallery)
}else{
Toast.makeText(requireContext(),"Galeriye Erişim İçin İzin Gereklidir.", Toast.LENGTH_SHORT).show()
}
}
}
The codes written here belong to the fragment I created the profile page for.
I am trying to upload an image to Firebase Storage by clicking the button with imageUpload id. However, it is not saved to the Storage and the photo I uploaded disappears when I click on a different page.
Do I need to add the codes somewhere other than OnViewCreated?
Also, when I assign an onClick method to a button, image or something else, I cannot call it with the fun method. For example, let uploadImage be the onClick function, not the button's id. I can't define it as 'fun uploadImage' anywhere in the fragment, why?
I am using exoplayer for playing videos .And for this we are used Fragment instance with pagerstateadapter and viewpager2.
But when scroll fast previous played video sound listen in background as well as in screen video means mix the sound in same video player.
Please help me how to solve this.
1.State adapter
class StoriesPagerAdapter(
fragment: Fragment,
val onClick1: VideoItemAdapter.OnItemClicked?,
val onlikeClick: VideoItemAdapter.OnLikeCLicked?,
val onFollowClick: VideoItemAdapter.OnFollowCLicked?,
val ontrendingClick: VideoItemAdapter.OnTrendCLicked?,
val oniconCLick: VideoItemAdapter.OnIconClick?) : FragmentStateAdapter(fragment) {
val dataList:MutableList<Gettrendingvideos.Data.Postlist>=mutableListOf()
override fun getItemCount(): Int {
return dataList.size
}
fun addAll(movies: MutableList<Gettrendingvideos.Data.Postlist>) {
for (movie in movies) {
add(movie)
}
}
fun add(moive: Gettrendingvideos.Data.Postlist) {
dataList.add(moive)
notifyItemInserted(dataList.size - 1)
}
override fun createFragment(position: Int): Fragment {
return StoryViewFragment.newInstance(
onClick1,
onlikeClick,
onFollowClick,
ontrendingClick,
oniconCLick,
dataList[position]
)
}}
2 Fragment
class StoryViewFragment : Fragment(), CommentFragment.onCommentCountIncrease {
private var storyUrl: String? = null
private var storiesDataModel: Gettrendingvideos.Data.Postlist? = null
lateinit var mView: View
private var simplePlayer: SimpleExoPlayer? = null
private var cacheDataSourceFactory: CacheDataSourceFactory? = null
private val simpleCache = MainApplication.simpleCache
private var toPlayVideoPosition: Int = -1
lateinit var viewModel: MainViewModel
lateinit var preferences: SecurePreferences
private var bool: Boolean? = false
var onItemClick: VideoItemAdapter.OnItemClicked? = null
var onlikeCLicked: VideoItemAdapter.OnLikeCLicked? = null
var onFollowCLicked: VideoItemAdapter.OnFollowCLicked? = null
var onTrendCLicked: VideoItemAdapter.OnTrendCLicked? = null
var onIconClick: VideoItemAdapter.OnIconClick? = null
lateinit var huserId: String
lateinit var token: String
companion object {
fun newInstance(
itemClicked: VideoItemAdapter.OnItemClicked?,
likeCLicked: VideoItemAdapter.OnLikeCLicked?,
onFollowCLicked: VideoItemAdapter.OnFollowCLicked?,
onTrendCLicked: VideoItemAdapter.OnTrendCLicked?,
onIconClick: VideoItemAdapter.OnIconClick?,
storiesDataModel: Gettrendingvideos.Data.Postlist
) = StoryViewFragment()
.apply {
arguments = Bundle().apply {
putParcelable(Constants.KEY_STORY_DATA, storiesDataModel)
}
this.onItemClick = itemClicked
this.onlikeCLicked = likeCLicked
this.onFollowCLicked = onFollowCLicked
this.onTrendCLicked = onTrendCLicked
this.onIconClick = onIconClick
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
mView = inflater.inflate(
R.layout.layout_main,
container,
false
)
return mView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(this, ViewModelFactory(RetrofitBuilder.apiService))
.get(MainViewModel::class.java)
preferences =
SecurePreferences(
requireActivity(),
AppConstants.preferenceName,
AppConstants.USER_DETAILS,
true
)
storiesDataModel = arguments?.getParcelable(Constants.KEY_STORY_DATA)
setData()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (!preferences.getString(AppConstants.USER_ID).equals(null)) {
huserId = preferences.getString(AppConstants.USER_ID)!!
Log.d("TAG", "onActivityCreated: $huserId")
}
}
#SuppressLint("SetTextI18n")
private fun setData() {
Log.d("TAG", "setData: $storiesDataModel")
mView.textview2.text = storiesDataModel?.user_name
mView.like_count.text = storiesDataModel?.total_likes.toString()
comment_count.text = storiesDataModel?.total_comments.toString()
mView.textview.text = storiesDataModel?.type
Glide.with(this).load(storiesDataModel?.user_profile_pic).placeholder(R.drawable.profile).into(mView.image)
if (storiesDataModel?.is_like == 0) {
mView.imageView4.setImageResource(R.drawable.ic_like)
} else {
mView.imageView4.setImageResource(R.drawable.ic_like_red)
}
if (storiesDataModel?.is_following!! == 0) {
mView.textview3.text = "Follow"
} else {
mView.textview3.text = "Following"
}
if (storiesDataModel?.user_id.toString()==preferences.getString(AppConstants.USER_ID)) {
mView.textview3.visibility = View.GONE
}
image.setOnClickListener {
if (preferences.getString(AppConstants.token).equals(null)) {
MainActivity().show(childFragmentManager, "")
} else {
preferences.put(
AppConstants.OtherProfile_UserId,
storiesDataModel?.user_id.toString()
)
}
}
val simplePlayer = getPlayer()
player_view_story.player = simplePlayer player_view_story.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL)
simplePlayer?.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING)
storyUrl = storiesDataModel?.video_url
prepareMedia(storiesDataModel)
}
override fun onPause() {
pauseVideo()
super.onPause()
}
override fun onResume() {
restartVideo()
super.onResume()
}
override fun onDestroy() {
releasePlayer()
super.onDestroy()
}
private fun pausePlayer() {
simplePlayer?.setPlayWhenReady(false)
simplePlayer?.getPlaybackState()
}
private fun startPlayer() {
simplePlayer?.setPlayWhenReady(true)
simplePlayer?.getPlaybackState()
}
private val playerCallback: Player.EventListener? = object : Player.EventListener {
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
}
override fun onPlayerError(error: com.google.android.exoplayer2.ExoPlaybackException?) {
super.onPlayerError(error)
}
}
private fun prepareVideoPlayer() {
simplePlayer = ExoPlayerFactory.newSimpleInstance(context)
cacheDataSourceFactory = CacheDataSourceFactory(
simpleCache,
DefaultHttpDataSourceFactory(
Util.getUserAgent(
context,
"exo"
)
)
)
}
private fun getPlayer(): SimpleExoPlayer? {
if (simplePlayer == null) {
prepareVideoPlayer()
}
return simplePlayer
}
private fun prepareMedia(datamodel: Gettrendingvideos.Data.Postlist?{
val uri = Uri.parse(datamodel?.video_url)
simplePlayer.repeatMode = Player.REPEAT_MODE_ONE
simplePlayer.playWhenReady = true
if (storiesDataModel!!.type == "following") {
following_page.typeface = Typeface.DEFAULT_BOLD
trending_page.setTypeface(null, Typeface.NORMAL)
} else {
following_page.setTypeface(null, Typeface.BOLD)
}
if (storiesDataModel.type == "treading") {
trending_page.typeface = Typeface.DEFAULT_BOLD
following_page.setTypeface(null, Typeface.NORMAL)
} else {
trending_page.setTypeface(null, Typeface.BOLD)
}
if (simplePlayer.playWhenReady == true) {
}
simplePlayer.addListener(playerCallback)
toPlayVideoPosition = -1
}
private fun setArtwork(drawable: Drawable, playerView: PlayerView) {
playerView.useArtwork = true
playerView.defaultArtwork = drawable
}
private fun playVideo() {
simplePlayer.playWhenReady = true
}
private fun restartVideo() {
if (simplePlayer == null) {
prepareMedia(storiesDataModel)
} else {
simplePlayer.seekToDefaultPosition()
simplePlayer.playWhenReady = true
}
}
private fun pauseVideo() {
simplePlayer.playWhenReady = false
}
private fun releasePlayer() {
simplePlayer.stop(true)
simplePlayer.release()
}}
override fun setMenuVisibility(menuVisible: Boolean) {
if (!menuVisible){
simplePlayer?.playWhenReady = false
simplePlayer?.pause()
}
super.setMenuVisibility(menuVisible)
}
JUST ADD THIS IN YOUR StoryViewFragment.
I am developing an app, where users can add their address in their profile and now I want to add a viewModel observer on the coordinates I am receiving from the profile fragment, like my fragment A and give this information to a map fragment, so I can create a new marker on that location. Apparently I am not getting any information of the observer in my fragment B.
So that is my code:
This is the first fragment of the profile:
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)
}
}
}
}
And this is the map fragment where the message should appear:
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
}
and this is the communicator class I am using:
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class Communicator : ViewModel(){
val message =MutableLiveData<Any>()
fun setMsgCommunicator(msg:String){
message.setValue(msg)
}
}
and maybe it is important to also show the GeoLocator from where I am getting the coordinates:
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()
}
}
Does anybody know what I am doing wrong to get absolutely nothing? Like in the profile fragment I am receiving a latitude and longitude in the Log.
Move the registering observer code, outside the callback block. Inside the callback, set the value when map is ready to update. In the observer check if map is ready, set the marker. Hope that works!
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
}
1.The "address" variable here gives me a city name with coordinates.I would like to write this address instead of Istanbul in the retrofit so that it can automatically show the weather of the selected location on the map.(Googlemap)
private const val TAG = "MapViewFragment"
class MapViewFragment: Fragment(), OnMapReadyCallback {
companion object{
private lateinit var nMap: GoogleMap
var address:String = ""
var test:String = ""
var test2:String = ""
var cacik:String = "adana"
private var markers:MutableList<Marker> = mutableListOf<Marker>()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
map_view.onCreate(savedInstanceState)
map_view.onResume()
map_view.getMapAsync(this)
setToolbar()
}
override fun onMapReady(map: GoogleMap?) {
if (map != null) {
nMap = map
}
map?.let {
nMap = it
nMap.setOnInfoWindowClickListener { markerToDelete ->
Log.i(TAG, "onWindowsClickListener - Delete Thismarker")
markers.remove(markerToDelete)
markerToDelete.remove()
}
nMap.setOnMapLongClickListener { latlng ->
Log.i(TAG, "onMapLongClickListener" + latlng)
Toast.makeText(
requireContext(),
"this is toast message" + latlng,
Toast.LENGTH_SHORT
).show()
showAlertDialog(latlng)
address= getAddress(latlng.latitude, latlng.longitude)
test = getAddress(37.000000,35.321335)
test2 = "istanbul"
Log.d(TAG,"test5 $address ${latlng.latitude} ${latlng.longitude}")
Toast.makeText(requireContext(),"test"+address,Toast.LENGTH_LONG).show()
}
}
}
private fun getAddress(lat: Double, lng: Double): String {
val geocoder = Geocoder(requireContext())
val list = geocoder.getFromLocation(lat, lng, 1)
return list[0].getAddressLine(0)
//val stateName: String = addresses[0].getAddressLine(1)
}
private fun showAlertDialog(latlng: LatLng) {
val dialog =
AlertDialog.Builder(requireContext())
.setTitle("Create a marker").setMessage("add marker...")
.setNegativeButton("Cancel", null)
.setPositiveButton("Ok", null)
.show()
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
val marker = nMap.addMarker(
MarkerOptions().position(latlng).title("my new marker").snippet(
"a cool snippet"
)
)
markers.add(marker)
dialog.dismiss()
}
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener {
dialog.dismiss()
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.mapviewfragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
private fun setToolbar(){
val actionBar : ActionBar? =(requireActivity() as MainActivity).supportActionBar
actionBar?.apply {
title = getString(R.string.Kartenansicht)
setDisplayShowTitleEnabled(true)
setHomeButtonEnabled(true)
}
}
}
3.i just want to call "address" in my retrofit response .I want to call the address on the other class and write the location of Istanbul.The getter and setter methods don't work because I haven't written them inside the class.How can I use the address in another class.
private const val TAG = "Retrofit Connection"
fun main(){
retrofitResponse()
}
object RetrofitSetup {
//var test = MapViewFragment.address
var urlAll = "api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}"
var url = "https://api.openweathermap.org/data/2.5/"
val apiKey = "d459f98ffa705ad3f6c5e02f86d9fab9"
}
fun retrofitResponse(){
val retrofit = Retrofit.Builder()
.baseUrl(RetrofitSetup.url)
.addConverterFactory(GsonConverterFactory.create())
.build()
val weatherApi = retrofit.create(CallWeatherApi::class.java)
val weatherResponseCall = weatherApi.getWeather(MapViewFragment.test,RetrofitSetup.apiKey)
weatherResponseCall!!.enqueue(object : Callback<CurrentWeatherResponse?> {
override fun onResponse(call: Call<CurrentWeatherResponse?>, response: Response<CurrentWeatherResponse?>
) {
if (response.code() == 404) {
Log.d(TAG,"Successfuly")
} else if (!response.isSuccessful) {
Log.d(TAG,"Error")
}
val mydata = response.body()
val main = mydata!!.main
val temp = main!!.temp
val pres =main!!.pressure
val temperature = (temp!! - 273.15).toInt()
Log.d("TAG","City pressure :" + pres)
Log.d("TAG","City Temp : " + temperature)
}
override fun onFailure(call: Call<CurrentWeatherResponse?>, t: Throwable) {}
})
}
if i write default istanbul.its working
if i create another varible in other class dosent work
exception
put "retrofitResponse" inside "RetrofitSetup" and add a parameter for the addresss
object RetrofitSetup {
private const val urlAll = "api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}"
private const val url = "https://api.openweathermap.org/data/2.5/"
private const val apiKey = "keep this private"
fun retrofitResponse(address: String) {
...
val weatherResponseCall = weatherApi.getWeather(address, apiKey)
...
}
}
then pass the address as argument
nMap.setOnMapLongClickListener { latlng ->
val address = getAddress(latlng.latitude, latlng.longitude)
RetrofitSetup.retrofitResponse(address)
}
I have added firebase database and the data also gets saved into the firebase realtime database, but it doesnot gets shown into the spinner, my spinner is showing no value.If theres some other way?
This is the code of my fragment:
class IncomeFragment: Fragment(){
//FAB
lateinit var addBankFab: FloatingActionButton
lateinit var addBankText: TextView
//Spinner
lateinit var spinner: Spinner
lateinit var dropDown: TextView
//Firebase Database
lateinit var mAuth: FirebaseAuth
lateinit var mIncomeDatabase: DatabaseReference
lateinit var mBankDatabase: DatabaseReference
lateinit var helper: FirebaseHelper
//Recycler View
lateinit var recyclerView: RecyclerView
//TextView
lateinit var incomeTotal : TextView
//Update Edit Text
lateinit var editAmount: EditText
lateinit var editType: EditText
lateinit var editNote: EditText
lateinit var editBankName:EditText
//Button for update and delete
lateinit var btnUpdate: Button
lateinit var btnDelete: Button
lateinit var btnSave : Button
lateinit var btnCancel:Button
//Data item Value
lateinit var type: String
lateinit var note: String
var amount: Int = 0
lateinit var post_key:String
lateinit var name:String
lateinit var ac:String
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val myview= inflater.inflate(R.layout.fragment_income, container, false)
mAuth= FirebaseAuth.getInstance()
val mUser = mAuth.currentUser
val uid = mUser?.uid
addBankFab=myview.findViewById(R.id.add_bank_fab)
addBankText=myview.findViewById(R.id.add_bank_text)
spinner=myview.findViewById(R.id.incomeSpinner)
mIncomeDatabase =
FirebaseDatabase.getInstance().reference.child("IncomeData").child(uid.toString())
incomeTotal=myview.findViewById(R.id.income_txt_result)
mBankDatabase= FirebaseDatabase.getInstance().reference.child("BankData").child(uid.toString())
helper = FirebaseHelper(mBankDatabase)
spinner.setAdapter(
activity?.let {
ArrayAdapter<String>(
it,
android.R.layout.simple_list_item_1,
helper.retrieve()
)
}
)
recyclerView=myview.findViewById(R.id.incomeRecyclerView)
val layoutManager = LinearLayoutManager(activity)
layoutManager.reverseLayout = true
layoutManager.stackFromEnd = true
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = layoutManager
mIncomeDatabase.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
var totalvalue :Int = 0
for (ds in dataSnapshot.children) {
val data: Data = ds.getValue<Data>(Data::class.java)!!
totalvalue+=data.amount
val stTotalValue:String = valueOf(totalvalue)
incomeTotal.text = stTotalValue+".00"
}
}
override fun onCancelled(databaseError: DatabaseError) {}
})
return myview
}
private fun insertBank() {
val bankdialog = AlertDialog.Builder(activity)
val inflater = LayoutInflater.from(activity)
val view: View = inflater.inflate(R.layout.add_bank_layout, null)
bankdialog.setView(view)
val dialog = bankdialog.create()
dialog.setCancelable(false)
val BankName = view.findViewById<EditText>(R.id.account_bank)
val BankAc = view.findViewById<EditText>(R.id.account_number)
val btnSaveBank = view.findViewById<Button>(R.id.btn_save_bank)
val btnCancelBank = view.findViewById<Button>(R.id.btn_cancel_bank)
btnSaveBank.setOnClickListener {
val name = BankName.text.toString().trim()
val ac = BankAc.text.toString().trim()
if (TextUtils.isEmpty(name)) {
BankName.error = "Required Field..."
return#setOnClickListener
}
if (TextUtils.isEmpty(ac)) {
BankAc.error = "Required Field..."
return#setOnClickListener
}
val bankacno = ac.toInt()
val id: String? = mBankDatabase.push().key
val mDate: String = DateFormat.getDateInstance().format(Date())
val bankdata = EmiData(bankacno, name, id, mDate)
mBankDatabase.child(id.toString()).setValue(bankdata)
Toast.makeText(activity, "DATA ADDED", Toast.LENGTH_SHORT).show()
dialog.dismiss()
}
btnCancelBank.setOnClickListener {
dialog.dismiss()
}
dialog.show()
}
override
fun onStart() {
super.onStart()
val options = FirebaseRecyclerOptions.Builder<Data>()
.setQuery(mIncomeDatabase, Data::class.java)
.setLifecycleOwner(this)
.build()
val firebaseRecyclerAdapter: FirebaseRecyclerAdapter<Data, MyViewHolder> =
object : FirebaseRecyclerAdapter<Data, MyViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.income_recycler_data, parent, false)
)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int, model: Data) {
holder.setType(model.type)
holder.setAmount(model.amount)
holder.setDate(model.date)
holder.setNote(model.note)
holder.mView.setOnClickListener {
post_key= getRef(position).key.toString()
type=model.type
note=model.note
amount=model.amount
updateDataItem()
}
}
}
recyclerView.adapter = firebaseRecyclerAdapter
}
class MyViewHolder(itemView: View) : ViewHolder(itemView) {
val mView = itemView
fun setType(type: String) {
val mType = mView.findViewById<TextView>(R.id.type_txt_income)
mType.text = type
}
fun setNote(note: String) {
val mNote = mView.findViewById<TextView>(R.id.note_txt_income)
mNote.text = note
}
fun setDate(date: String) {
val mDate = mView.findViewById<TextView>(R.id.date_txt_income)
mDate.text = date
}
fun setAmount(amount: Int) {
val mAmount = mView.findViewById<TextView>(R.id.amount_txt_income)
val stAmount = valueOf(amount)
mAmount.text = stAmount
}
}
private fun updateDataItem() {
val mydialog = AlertDialog.Builder(activity)
val inflater = LayoutInflater.from(activity)
val myView: View = inflater.inflate(R.layout.update_data_item, null)
mydialog.setView(myView)
val dialog = mydialog.create()
val editAmount = myView.findViewById<EditText>(R.id.amount_edit)
val editType = myView.findViewById<EditText>(R.id.type_edit)
val editNote = myView.findViewById<EditText>(R.id.note_edit)
//Set data to edit text..
editType.setText(type)
editType.setSelection(type.length)
editNote.setText(note)
editNote.setSelection(note.length)
editAmount.setText(valueOf(amount))
editAmount.setSelection(valueOf(amount).length)
val btnUpdate = myView.findViewById<Button>(R.id.btn_update)
val btnDelete = myView.findViewById<Button>(R.id.btn_delete)
btnUpdate.setOnClickListener {
type = editType.text.toString().trim()
note = editNote.text.toString().trim()
var mdAmount = amount.toString()
mdAmount = editAmount.text.toString().trim { it <= ' ' }
val myAmount = mdAmount.toInt()
val mDate: String = DateFormat.getDateInstance().format(Date())
val data = Data(myAmount, type, note, post_key, mDate)
mIncomeDatabase.child(post_key).setValue(data)
dialog.dismiss()
}
btnDelete.setOnClickListener {
mIncomeDatabase.child(post_key).removeValue()
dialog.dismiss()
}
dialog.show()
}
}
This is my firebase helper:
class FirebaseHelper(val db: DatabaseReference) {
private var saved: Boolean? = null
//SAVE
fun save(bankData: BankData?): Boolean? {
saved = if (bankData == null) {
false
} else {
try {
db.child("name").push().setValue(bankData)
true
} catch (e: DatabaseException) {
e.printStackTrace()
false
}
}
return saved
}
//READ
fun retrieve(): ArrayList<String> {
val bankNames = ArrayList<String>()
db.addChildEventListener(object : ChildEventListener {
override fun onChildAdded(
dataSnapshot: DataSnapshot,
s: String?
) {
fetchData(dataSnapshot, bankNames)
}
override fun onChildChanged(
dataSnapshot: DataSnapshot,
s: String?
) {
fetchData(dataSnapshot, bankNames)
}
override fun onChildRemoved(dataSnapshot: DataSnapshot) {}
override fun onChildMoved(
dataSnapshot: DataSnapshot,
s: String?
) {
}
override fun onCancelled(databaseError: DatabaseError) {}
})
return bankNames
}
private fun fetchData(
snapshot: DataSnapshot,
bankData: ArrayList<String>
) {
bankData.clear()
val name: BankData? = snapshot.getValue(BankData::class.java)
bankData.add(bankData.toString())
}
}
Your spinner shows no value because the data is not retrieved yet from the DB.
So what you should do is create a callback from FirebaseHelper to IncomeFragment
First, create a callback
interface FirebaseHelperCallback {
fun dataRetrievedFromDB(data: List<String>)
}
Second, create a variable, setter function and call dataRetrievedFromDB function in FirebaseHelper class
class FirebaseHelper(val db: DatabaseReference) {
private lateinit var firebaseHelperCallback: FirebaseHelperCallback
fun setFirebaseHelperCallback(firebaseHelperCallback: FirebaseHelperCallback) {
this.firebaseHelperCallback = firebaseHelperCallback
}
...
private fun fetchData(snapshot: DataSnapshot, bankData: ArrayList<String>) {
bankData.clear()
val name: BankData? = snapshot.getValue(BankData::class.java)
bankData.add(bankData.toString())
firebaseHelperCallback.dataRetrievedFromDB(bankData)
}
}
Lastly, implement the callback in IncomeFragment
class IncomeFragment: Fragment(), FirebaseHelperCallback {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
...
helper.setFirebaseHelperCallback(this)
}
...
override fun dataRetrievedFromDB(data: List<String>) {
spinner.setAdapter(
activity?.let {
ArrayAdapter<String>(
it,
android.R.layout.simple_list_item_1,
data
)
}
)
}
}