Not able to setup optionMenu using NavigationUI - android

I have Fragment and i want to add option menu. I have tried a lot but not found any solution.
Here is my code.
package com.code2hack.milkledger.fragment
import android.app.AlertDialog
import android.os.Bundle
import android.view.*
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.code2hack.milkledger.BaseActivity
import com.code2hack.milkledger.MainActivityViewModel
import com.code2hack.milkledger.R
import com.code2hack.milkledger.actionmode.ActionModeCallback
import com.code2hack.milkledger.adapter.CustomerAdapter
import com.code2hack.milkledger.dialog.AddUserDialog
import com.code2hack.milkledger.handler.ItemClickListener
import com.code2hack.milkledger.model.Customer
import com.code2hack.milkledger.util.Event
import com.google.android.material.card.MaterialCardView
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fragment_customer_list.*
class CustomerListFragment : BaseFragment() {
private val baseActivity: BaseActivity by lazy { activity as BaseActivity };
private var selectMode = false
val selectedCustomers = mutableSetOf<Customer>()
val selectedViews = mutableSetOf<View>()
private lateinit var actionMode: ActionMode
private val list = mutableListOf<Customer>()
private val model: MainActivityViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_customer_list, container, false)
}
private val customerAdapter: CustomerAdapter by lazy { CustomerAdapter(list,ClickHandler()) }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return NavigationUI.onNavDestinationSelected(item,
findNavController())
|| super.onOptionsItemSelected(item)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navController = findNavController()
val appBarConfiguration = AppBarConfiguration(navController.graph)
view.findViewById<Toolbar>(R.id.toolbar)
.setupWithNavController(navController, appBarConfiguration)
//baseActivity.setSupportActionBar(toolbar)
fab.setOnClickListener {
baseActivity.showDialog(AddUserDialog(null))
}
customer_view.apply {
layoutManager = LinearLayoutManager(activity)
adapter = customerAdapter
}
model.loadCustomers(userInfo().user_name,token())
observe();
}
private fun observe() {
with(model){
customers.observe(viewLifecycleOwner, Observer { items ->
if(items.isEmpty()){
baseActivity.showDialog(AddUserDialog(null))
}
list.clear();
list.addAll(items);
customerAdapter.notifyDataSetChanged();
})
customerSaved.observe(viewLifecycleOwner, Observer {
if(!it.handled){
Snackbar.make(requireView(),getString(R.string.message_customer_create),Snackbar.LENGTH_LONG).show()
list.add(it.getContentIfNotHandled()!!)
customerAdapter.notifyDataSetChanged()
}
})
customerDeleted.observe(viewLifecycleOwner, Observer {
if(!it.handled){
handleDeleteEvent(it, requireView(), customerAdapter)
}
})
}
}
private fun handleDeleteEvent(
it: Event<Boolean>,
view: View,
customerAdapter: CustomerAdapter
) {
it.getContentIfNotHandled()
Snackbar.make(view, getString(R.string.message_customer_delete), Snackbar.LENGTH_LONG).show()
model.loadCustomers(userInfo().user_name, token())
selectMode = false
selectedCustomers.clear()
selectedViews.clear()
actionMode.finish()
list.clear()
customerAdapter.notifyDataSetChanged()
}
private fun deleteCustomers(){
val dialog = AlertDialog.Builder(requireActivity())
.setMessage(R.string.delete_confirm_message)
.setPositiveButton(R.string.delete){ dialogInterface, _ ->
model.deleteCustomer(selectedCustomers, token(), userInfo().user_name)
clearSelectMode()
dialogInterface.cancel()
}.setNegativeButton(R.string.cancel){ dialogInterface, _ ->
clearSelectMode()
dialogInterface.cancel()
}
.create()
dialog.setOnShowListener {
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ContextCompat.getColor(requireContext(),R.color.colorAccent))
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(ContextCompat.getColor(requireContext(),R.color.cancel_text_red))
}
dialog.show();
}
val actionModeCallback = ActionModeCallback({
when(it) {
R.id.action_logout -> {
(baseActivity).logout();
true
}
R.id.delete -> {
deleteCustomers()
true
}
R.id.edit -> {
baseActivity.showDialog(AddUserDialog(selectedCustomers.first()))
true
}
else -> false
}
},{
selectMode = false
selectedCustomers.clear()
selectedViews.forEach{
(it as MaterialCardView).setCardBackgroundColor(ContextCompat.getColor(requireActivity(),android.R.color.white))
}
selectedViews.clear()
},{
it.findItem(R.id.delete).isVisible = selectedCustomers.size > 0
it.findItem(R.id.edit).isVisible = selectedCustomers.size == 1
})
inner class ClickHandler : ItemClickListener<Customer>() {
val TAG = "ClickHandler"
override fun onItemClick(item: Customer, view:View?) {
if(selectMode){
processSelection(item,view)
} else {
val action = CustomerListFragmentDirections.recordFragment(item.id)
action.setCowMilkRate(item.cowMilkRate)
action.setBuffaloMilkRate(item.buffaloMilkRate)
view!!.findNavController().navigate(action)
}
}
override fun onLongClick(item: Customer, view: View?){
selectMode = true
actionMode = baseActivity.startSupportActionMode(actionModeCallback)!!
processSelection(item,view)
}
private fun processSelection(customer: Customer, view: View?){
if(selectedCustomers.indexOf(customer) < 0) {
selectedCustomers.add(customer)
selectedViews.add(view!!)
(view as MaterialCardView).setCardBackgroundColor(ContextCompat.getColor(requireActivity(),R.color.background_light_green))
}
else {
selectedCustomers.remove(customer)
selectedViews.remove(view!!)
(view as MaterialCardView).setCardBackgroundColor(ContextCompat.getColor(requireActivity(),android.R.color.white))
}
if(selectedCustomers.size == 0){
clearSelectMode();
} else {
actionMode.invalidate()
}
}
}
private fun clearSelectMode() {
actionMode.finish()
selectMode = false
selectedCustomers.clear()
selectedViews.clear()
}
}
The method onCreateOptionsMenu is not getting executed.
What i am missing i have no idea. There is no actionbar in my activity. I have put action bar in the fragment_customer_list. Action bar is displayed properly. But not able to add menu to the toolbar

Since you are not calling the setSupportActionBar you should use the Toolbar APIs directly.
Something like:
toolbar.inflateMenu(R.menu.menu_main)
toolbar.setOnMenuItemClickListener {
it.onNavDestinationSelected(navController)
}
NavigationUI.setupWithNavController(
toolbar, navController, appBarConfiguration)

Related

How to call a method in adapter from a fragment in kotlin?

I have been trying to call a function from fragment to adapter, but I can't approach it right.
I want to invisible the button present in the fragment from adapter.
**My Adapter Code:**
package com.littleboo.brandlogo.Adapters
import android.R
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat.getSystemService
import androidx.recyclerview.widget.RecyclerView
import com.littleboo.brandlogo.Fragments.QuizFragment
import com.littleboo.brandlogo.MainActivity
import com.littleboo.brandlogo.Models.Question
import com.littleboo.brandlogo.databinding.ActivityMainBinding.inflate
import com.littleboo.brandlogo.databinding.FragmentQuizBinding
import kotlinx.coroutines.NonDisposableHandle.parent
class QuestionAdap(val context: Context, val question: Question) :
RecyclerView.Adapter<QuestionAdap.OptionViewHolder>() {
var index = 1
var score = 0
val animShake: Animation = AnimationUtils.loadAnimation(context, com.littleboo.brandlogo.R.anim.shake)
private var options: List<String> = listOf(question.option1, question.option2, question.option3, question.option4)
inner class OptionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var optionView = itemView.findViewById<TextView>(com.littleboo.brandlogo.R.id.quiz_option)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OptionViewHolder {
val view = LayoutInflater.from(context).inflate(com.littleboo.brandlogo.R.layout.quizoptions, parent, false)
return OptionViewHolder(view)
}
override fun onBindViewHolder(holder: OptionViewHolder, position: Int) {
holder.optionView.text = options[position]
holder.itemView.setOnClickListener {
question.userAnswer = options[position]
notifyDataSetChanged()
}
if(question.userAnswer == options[position] && question.userAnswer == question.answer){
holder.itemView.setBackgroundResource(com.littleboo.brandlogo.R.drawable.option_item_selected_bg)
score += 10
Toast.makeText(context,"Score is $score", Toast.LENGTH_SHORT).show()
}
else if(question.userAnswer == options[position] && question.userAnswer != question.answer){
holder.itemView.setBackgroundResource(com.littleboo.brandlogo.R.drawable.wrong_option_item_selected_bg)
holder.itemView.startAnimation(animShake)
}
else{
holder.itemView.setBackgroundResource(com.littleboo.brandlogo.R.drawable.non_option_item_selected_bg)
}
}
override fun getItemCount(): Int {
return options.size
}
}
My Quiz Fragment Code:
package com.littleboo.brandlogo.Fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import com.bumptech.glide.Glide
import com.google.firebase.firestore.FirebaseFirestore
import com.littleboo.brandlogo.Adapters.QuestionAdap
import com.littleboo.brandlogo.Models.Question
import com.littleboo.brandlogo.Models.quizmodel
import com.littleboo.brandlogo.R
import com.littleboo.brandlogo.databinding.FragmentQuizBinding
class QuizFragment : Fragment(){
lateinit var binding: FragmentQuizBinding
var quizzes: MutableList<quizmodel>? = null
private var questions = mutableMapOf<String, Question>()
private lateinit var mArraylist: ArrayList<Question>
var index = 1
private lateinit var mfirestore: FirebaseFirestore
private lateinit var mrecycler: RecyclerView
lateinit var myadapter: QuestionAdap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentQuizBinding.inflate(layoutInflater)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mrecycler = binding.optionList
mrecycler.layoutManager
myadapter = QuestionAdap(requireContext(),Question())
mArraylist = arrayListOf()
questions.map { it.key to it.value }.shuffled().toMap()
setUpFirestore()
setUpEventListener()
}
override fun onDestroy() {
super.onDestroy()
mfirestore.terminate()
// finish()
}
private fun setUpEventListener() {
binding.nextbtn.setOnClickListener {
index++
bindViews()
}
// binding.btnSubmit.setOnClickListener {
// Log.d("FINALQUIZ", questions.toString())
// val intent = Intent(this, ResultActivity::class.java)
// val json = Gson().toJson(quizzes!![0])
// intent.putExtra("QUIZ", json)
// startActivity(intent)
// finish()
// }
}
private fun setUpFirestore() {
mfirestore = FirebaseFirestore.getInstance()
val quizTitle = activity?.intent?.getStringExtra("title")
if (quizTitle != null) {
mfirestore.collection("Quizes").whereEqualTo("title", quizTitle)
.get()
.addOnSuccessListener {
if (it != null && !it.isEmpty) {
quizzes = it.toObjects(quizmodel::class.java)
questions = quizzes!![0].questions
shuffle()
bindViews()
}
}
}
}
private fun bindViews() {
// btnPrevious.visibility = View.GONE
// binding.btnSubmit.visibility = View.GONE
// binding.btnNext.visibility = View.GONE
// if (index == 1) { //first question
// binding.btnNext.visibility = View.VISIBLE
// } else if (index == questions!!.size) { // last question
// binding.btnSubmit.visibility = View.VISIBLE
//// btnPrevious.visibility = View.VISIBLE
// } else { // Middle
//// btnPrevious.visibility = View.VISIBLE
// binding.btnNext.visibility = View.VISIBLE
// }
val circularProgressDrawable = CircularProgressDrawable(requireContext())
circularProgressDrawable.strokeWidth = 8f
// circularProgressDrawable.colorFilter = ("#ac5fe1")
circularProgressDrawable.centerRadius = 30f
circularProgressDrawable.start()
val question = questions!!["question$index"]
question?.let {
Glide.with(this).load(it.imagequiz).placeholder(circularProgressDrawable).into(binding.imagequiz)
val optionAdapter = QuestionAdap(requireContext(), it)
mrecycler.layoutManager = LinearLayoutManager(requireContext())
mrecycler.adapter = optionAdapter
mrecycler.setHasFixedSize(true)
}
}
private fun shuffle() {
val keys = questions.keys.toMutableList().shuffled()
val values = questions.values.toMutableList().shuffled()
keys.forEachIndexed { index, key ->
questions[key] = values[index]
}
}
}
I tried calling fragment in adapter like:
QuizFragment().binding.btnxt.visibility = View.Visible
in BindViewHolder function.
Thank You
You can use kotlin lambda function to achieve it. Like this
class QuestionAdap(val context: Context, val question: Question, var onItemClicked: ((boolean) -> Unit))
call onItemClicked in your adapter where you want it
and in fragment
myadapter = QuestionAdap(requireContext(),Question()) { boolean ->
if (boolean) {
//hide/show
} else {
//hide/show
}
}
You can use the Callback functions of kotlin in your fragment, which will be passed into your adapter. So whenever you invoke that callback from your adapter, it will be triggered in your fragment.
Step 1: Create a method like the one below in your fragment.
private fun showHideButtonFromAdapter (
isButtonVisible: Boolean
) {
// set your button visibility according to isButtonVisible value.
}
Step 2: pass a method from your fragment to adapter as argument
val adapter = YourAdapter(::showHideButtonFromAdapter)
// set above adapter in your recycler view.
Step 3: In your adapter invoke that callback function like the one below.
class ColorPickerAdapter constructor(
private val onItemClicked: (Boolean) -> Unit
) : RecyclerView.Adapter<YourAdapter.ViewHolder>() {
// your other adapter methods here
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
onItemClicked.invoke(pass true or false as per your requirement)
// above invocation will trigger an event in the fragment.
}
}
In your adapter there need to be instance of your fragment, so change it like:
class QuestionAdap(val context: Context, val question: Question, fragment: Fragment) :
RecyclerView.Adapter<QuestionAdap.OptionViewHolder>() {
Then you can call your fragment by simply writing fragment in your adapter like:
override fun onBindViewHolder(holder: OptionViewHolder, position: Int) {
holder.optionView.text = options[position]
holder.itemView.setOnClickListener {
question.userAnswer = options[position]
notifyDataSetChanged()
}
//Example
fragment.shuffle()
And you need to send this fragment instance when you create it's adapter, so in your fragment use this:
myadapter = QuestionAdap(requireContext(),Question(), this)

One checkbox triggering another checkbox in a different layout

I'm currently writing an app that displays a list of movies. I have many fragments that display a cardview containing movies, and each cardview has a checkbox. The user can press on the cardview to go to the details page of the movie where another checkbox is present.
The goal of both checkboxes is to add the movie to the favorites tab.
My question is, how can I make the checkbox that is inside the details page checked when the user checks the one in the cardview?
Below is the relevant code.
Appreciate all the help I can get.
MoviesListFragment.kt
package com.example.moviesapp.ui.Fragments
import android.os.Bundle
import android.view.*
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.moviesapp.R
import com.example.moviesapp.databinding.FragmentMoviesListBinding
import com.example.moviesapp.network.MoviesFavorites
import com.example.moviesapp.network.MoviesResults
import com.example.moviesapp.ui.DaoViewModel
import com.example.moviesapp.ui.MovieApiStatus
import com.example.moviesapp.ui.MoviesListAdapter
import com.example.moviesapp.ui.MoviesListViewModel
import dagger.hilt.android.AndroidEntryPoint
#AndroidEntryPoint
class MoviesListFragment : Fragment(R.layout.fragment_movies_list), MoviesListAdapter.OnItemClickListener {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_movies_list, container, false)
}
private val daoViewModel by viewModels<DaoViewModel>()
private val viewModel by viewModels<MoviesListViewModel>()
private var _binding: FragmentMoviesListBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//View is inflated layout
_binding = FragmentMoviesListBinding.bind(view)
val adapter = MoviesListAdapter(this)
binding.apply {
recyclerView.layoutManager = LinearLayoutManager(requireContext())
//Disable animations
recyclerView.setHasFixedSize(true)
recyclerView.adapter = adapter
}
//Observe the movies livedata
//Use viewLifecycleOwner instead of this because the UI should stop being updated when the fragment view is destroyed
viewModel.getTrending()
viewModel.moviesTrending.observe(viewLifecycleOwner) {
adapter.submitList(it)
}
viewModel.networkState.observe(viewLifecycleOwner, {
binding.progressBar.isVisible = if (it==MovieApiStatus.LOADING) true else view.isGone
binding.buttonRetry.isVisible = if(it==MovieApiStatus.ERROR) true else view.isGone
binding.errorTextView.isVisible = if(it==MovieApiStatus.ERROR) true else view.isGone
binding.recyclerView.isVisible = if(it==MovieApiStatus.DONE) true else view.isGone
binding.noResultsText.isVisible = false
})
//Display trending movies
//loadstate is of type combined loadstates, which combines the loadstate of different scenarios(when we refresh dataset or when we append new data to it) into this one object
//We can use it to check for these scenarios and make our views visible or unvisible according to it
setHasOptionsMenu(true)
}
override fun onItemClick(movie: MoviesResults.Movies) {
val action = MoviesListFragmentDirections.actionMoviesListFragmentToMoviesDetailsFragment(movie)
findNavController().navigate(action)
}
override fun onFavoriteClick(favorites: MoviesFavorites) {
daoViewModel.addMovieToFavs(favorites)
}
override fun onDeleteClick(favorites: MoviesFavorites) {
daoViewModel.deleteMovieFromFavs(favorites)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
// Inflate the gallery menu
inflater.inflate(R.menu.menu_gallery, menu)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
MoviesListAdapter.kt
package com.example.moviesapp.ui
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.moviesapp.R
import com.example.moviesapp.databinding.MovieLayoutBinding
import com.example.moviesapp.network.MoviesFavorites
import com.example.moviesapp.network.MoviesResults
val IMAGE_BASE_URL = "https://image.tmdb.org/t/p/w500"
class MoviesListAdapter constructor(private val listener: OnItemClickListener) :
ListAdapter<MoviesResults.Movies, MoviesListAdapter.MoviesListViewHolder>(DiffCallback) {
private lateinit var fav: MoviesFavorites
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MoviesListViewHolder {
val binding = MovieLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MoviesListViewHolder(binding)
}
override fun onBindViewHolder(holder: MoviesListViewHolder, position: Int) {
val currentItem = getItem(position)
holder.binding.favoritesCheckbox.isChecked = currentItem.isFavorite
holder.binding.favoritesCheckbox.setOnCheckedChangeListener { _, isChecked ->
currentItem.isFavorite
}
if(holder.binding.favoritesCheckbox.isChecked ) {
currentItem.isFavorite = true
}
if (currentItem != null) {
holder.bind(currentItem)
}
}
inner class MoviesListViewHolder(val binding: MovieLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.root.setOnClickListener {
val position = absoluteAdapterPosition
if (position != RecyclerView.NO_POSITION) {
val item = getItem(position)
listener.onItemClick(item)
}
}
}
init {
binding.favoritesCheckbox.setOnClickListener{
if(binding.favoritesCheckbox.isChecked) {
val position = absoluteAdapterPosition
if (position != RecyclerView.NO_POSITION) {
val item = getItem(position)
item.isFavorite = true
fav = MoviesFavorites(item.title, item.id, item.release_date, item.overview, item.vote_average, item.poster_path, item.original_language, item.isFavorite)
listener.onFavoriteClick(fav)
listener.onCheckboxClick(binding.favoritesCheckbox.isChecked)
}
showToast("${fav.title} is added to your favorites")
}
else {
val position = absoluteAdapterPosition
if (position != RecyclerView.NO_POSITION) {
val item = getItem(position)
item.isFavorite = false
fav = MoviesFavorites(item.title, item.id, item.release_date, item.overview, item.vote_average, item.poster_path, item.original_language, item.isFavorite)
listener.onDeleteClick(fav)
listener.onCheckboxClick(binding.favoritesCheckbox.isChecked)
}
showToast("${fav.title} is removed from your favorites")
}
}
}
fun bind(movie: MoviesResults.Movies) {
binding.apply {
movieTitle.text = movie.title
movieRating.text = movie.vote_average
movieYear.text = movie.release_date
Glide.with(itemView)
.load(IMAGE_BASE_URL + movie.poster_path)
.centerCrop()
.error(R.drawable.ic_baseline_error_outline_24)
.into(movieImage)
val item = getItem(absoluteAdapterPosition)
favoritesCheckbox.isChecked = item.isFavorite
}
}
private fun showToast(string: String) {
Toast.makeText(itemView.context, string, Toast.LENGTH_SHORT).show()
}
}
interface OnItemClickListener {
fun onItemClick(movie: MoviesResults.Movies)
fun onFavoriteClick(favorites: MoviesFavorites)
fun onDeleteClick(favorites: MoviesFavorites)
fun onCheckboxClick(fav: Boolean)
}
companion object DiffCallback : DiffUtil.ItemCallback<MoviesResults.Movies>() {
override fun areItemsTheSame(
oldItem: MoviesResults.Movies,
newItem: MoviesResults.Movies
): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(
oldItem: MoviesResults.Movies,
newItem: MoviesResults.Movies
): Boolean {
return oldItem == newItem
}
}
}
MoviesDetailsFragment.kt
package com.example.moviesapp.ui.Fragments
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.navArgs
import com.bumptech.glide.Glide
import com.example.moviesapp.R
import com.example.moviesapp.databinding.FragmentMoviesDetailsBinding
import com.example.moviesapp.network.MoviesFavorites
import com.example.moviesapp.network.MoviesResults
import com.example.moviesapp.ui.DaoViewModel
import com.example.moviesapp.ui.IMAGE_BASE_URL
import com.example.moviesapp.ui.SharedViewModel
import dagger.hilt.android.AndroidEntryPoint
#AndroidEntryPoint
class MoviesDetailsFragment() : Fragment(R.layout.fragment_movies_details) {
//We can get the movies from the args property
private val args by navArgs<MoviesDetailsFragmentArgs>()
private val daoViewModel by viewModels<DaoViewModel>()
private val sharedViewModel by viewModels<SharedViewModel>()
private fun showToast(string: String) {
Toast.makeText(view?.context, string, Toast.LENGTH_SHORT).show()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentMoviesDetailsBinding.bind(view)
sharedViewModel.checkBox.observe(viewLifecycleOwner) {
binding.favCheckbox.isChecked = it
}
binding.apply {
val movie: MoviesResults.Movies = args.movie
val fav = MoviesFavorites(
movie.title,
movie.id,
movie.release_date,
movie.overview,
movie.vote_average,
movie.poster_path,
movie.original_language,
movie.isFavorite,
)
//When you are in fragment/activity, pass it to a glide.with because view is less efficient
Glide.with(this#MoviesDetailsFragment)
.load(IMAGE_BASE_URL + movie.poster_path)
//Have the textview visible only when image is visible
.error(R.drawable.ic_baseline_error_outline_24)
.fitCenter()
.into(coverPhoto)
title.text = movie.title
releaseDate.text = movie.release_date
language.text = movie.original_language
rating.text = movie.vote_average
plot.text = movie.overview
favCheckbox.setOnClickListener {
if (favCheckbox.isChecked) {
fav.isFavorite = true
daoViewModel.addMovieToFavs(fav)
showToast("${fav.title} is added to your favorites")
} else {
fav.isFavorite = false
daoViewModel.deleteMovieFromFavs(fav)
showToast("${fav.title} is removed from your favorites")
}
}
}
}
}
SharedViewModel.kt
package com.example.moviesapp.ui
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class SharedViewModel: ViewModel() {
val checkBox = MutableLiveData<Boolean>()
fun sendValue(favorite: Boolean) {
checkBox.value = favorite
}
class SharedViewModelFactor(
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SharedViewModel::class.java)) {
#Suppress("UNCHECKED_CAST")
return SharedViewModel() as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
}
You can user 2 methods to do so:
1 ) You can use LocalBroadcast to notify one fragment/activity of change in another.
Note: LocalBroadcast in now deprecated. Alternatively you can use eventbus to communication between fragments
Create a local Broadcast
private BroadcastReceiver onNotice= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// intent can contain anydata
Log.d(TAG,"onReceive called");
}
};
Register your receiver in onResume of fragment like:
public void onResume() {
super.onResume();
IntentFilter iff= new IntentFilter(MyIntentService.ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, iff);
}
unRegister receiver in onPause:
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
}
For more information can you can refer to:
https://blog.mindorks.com/using-localbroadcastmanager-in-android
2 ) You can use LiveData to observe data changes of one fragment in another
Create shared ViewModel
public class SharedViewModel extends ViewModel {
private MutableLiveData<String> name;
public void setNameData(String nameData) {
name.setValue(nameData);
}
public MutableLiveData<String> getNameData() {
if (name == null) {
name = new MutableLiveData<>();
}
return name;
}
}
Fragment One
private SharedViewModel sharedViewModel;
public FragmentOne() {
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sharedViewModel.setNameData(submitText.getText().toString());
}
});
}
Fragment Two
private SharedViewModel sharedViewModel;
public FragmentTwo() {
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
sharedViewModel.getNameData().observe(this, nameObserver);
}
Observer<String> nameObserver = new Observer<String>() {
#Override
public void onChanged(String name) {
receivedText.setText(name);
}
};
For more details on viewmodel you can refer to :
https://nabeelj.medium.com/android-how-to-share-data-between-fragments-using-viewmodel-and-livedata-android-mvvm-9fc463af5152
https://developer.android.com/guide/fragments/communicate#fragments

App closes after intent activity change - Kotlin

I have an image gallery on a Fragment and I want to create a program that, once the user clicks on a certain image, the program redirects the user to an Activity where more details are presented. However, after implementing the Intent, the program just crashes when the Activity opens.
I don't know what I might be doing wrong as I do not have much experience with fragments (I believe it is something I'm doing wrong in the fragment intent)
Here's the code:
Fragment
package cm.a12872_a18797.favlist.fragments
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.fragment.app.Fragment
import cm.a12872_a18797.favlist.ImageDetailActivity
import cm.a12872_a18797.favlist.Modal
import cm.a12872_a18797.favlist.R
class HomeFragment : Fragment() {
lateinit var rootView: View
public val modalList = ArrayList<Modal>()
lateinit var gridView: GridView
private var descriptions = arrayOf(
"Golden Bridge", "Tampa Bay Buccaneers", "Chevrolet Camaro",
"Vegetable Casserole", "Sweet and Sour Chicken", "Design Vector",
"Pork Loin", "Sidney's Opera House", "Pasta Dish",
"Dope Setup", "Singapore", "Tacos Dish",
"Toquio", "Warm Salad Dish"
)
private var images = intArrayOf(
R.drawable.bridge, R.drawable.buccaneers, R.drawable.camaro,
R.drawable.casserole, R.drawable.chicken, R.drawable.design,
R.drawable.lombo, R.drawable.operahouse, R.drawable.pasta,
R.drawable.setup, R.drawable.singapore, R.drawable.tacos,
R.drawable.toquio, R.drawable.warmsalad
)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
rootView = inflater.inflate(R.layout.fragment_home, container, false)
gridView = rootView.findViewById(R.id.home_grid)
for (i in descriptions.indices){
modalList.add(Modal(descriptions[i], images[i]))
}
var customAdapter = GridAdapter(modalList, this#HomeFragment.requireContext())
gridView.adapter = customAdapter
gridView.setOnItemClickListener() { adapterView, view, position, l ->
var intent = Intent(this#HomeFragment.requireContext(), ImageDetailActivity::class.java)
intent.putExtra("data", modalList[position])
startActivity(intent)
}
return rootView
}
class GridAdapter(var itemModel : ArrayList<Modal>, var context: Context): BaseAdapter(){
var layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var view = convertView
if (view == null){
view = layoutInflater.inflate(R.layout.home_grid_row, parent, false)
}
var imageViewName = view?.findViewById<ImageView>(R.id.grid_image)
imageViewName?.setImageResource(itemModel[position].image!!)
return view!!
}
override fun getItem(position: Int): Any {
return itemModel[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return itemModel.size
}
}
}
Activity:
package cm.a12872_a18797.favlist
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.Fragment
import cm.a12872_a18797.favlist.fragments.HomeFragment
import cm.a12872_a18797.favlist.fragments.ListsFragment
import cm.a12872_a18797.favlist.fragments.SearchFragment
import com.google.android.material.bottomnavigation.BottomNavigationView
class ImageDetailActivity : AppCompatActivity() {
val TAG = "ImageDetailActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_image_detail)
//region Bottom Navigation Menu =====================================
val bottomNavigation: BottomNavigationView = findViewById(R.id.bottom_navigation)
val homeFragment = HomeFragment()
val listsFragment = ListsFragment()
val searchFragment = SearchFragment()
bottomNavigation.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.nav_home -> {
setCurrentFragment(homeFragment)
Log.i(TAG, "Home Selected")
}
R.id.nav_lists -> {
setCurrentFragment(listsFragment)
Log.i(TAG, "My Lists Selected")
}
R.id.nav_search -> {
setCurrentFragment(searchFragment)
Log.i(TAG, "Search Selected")
}
}
true
}
//endregion ==
val detailText = findViewById<TextView>(R.id.detailText)
val detailImage = findViewById<ImageView>(R.id.detailImage)
var modalItems: Modal = intent.getSerializableExtra("data") as Modal
detailText.text = modalItems.name
detailImage.setImageResource(modalItems.image!!)
}
private fun setCurrentFragment(fragment : Fragment) =
supportFragmentManager.beginTransaction().apply {
replace(R.id.fl_wrapper, fragment)
commit()
}
}
Modal Class:
package cm.a12872_a18797.favlist
import java.io.Serializable
class Modal : Serializable {
var name:String? = null
var image:Int? = null
constructor(name:String, image:Int){
this.name = name
this.image = image
}
}

How to open BottomNavigationView's fragment in activity?

I want to call method
showNewsPageTime()
from MainFragment.kt in AlertBoxActivity.kt to open
newsFragment,
but app has stopped.
MainFragment.kt
(BottomNavigationView located here. I want to open NewsFragment page from here, because if i'll open it directly bottom navigation disappears.)
package kz.app.fragment
import android.annotation.SuppressLint
import android.app.Activity
import android.os.Bundle
import android.support.design.widget.BottomNavigationView
import android.support.v4.app.Fragment
import android.support.v4.widget.DrawerLayout
import android.support.v7.content.res.AppCompatResources
import android.support.v7.view.SupportMenuInflater
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import kotlin.concurrent.schedule
import android.view.inputmethod.InputMethodManager
import kotlinx.android.synthetic.main.fragment_main.*
import kotlinx.android.synthetic.main.fragment_main.view.*
import kz.app.R
import kz.app.model.MainViewModel
import kz.app.model.Stat## Heading ##eViewModel
import kz.app.repository.PreferencesRepository
import kz.app.util.OnBackPressDelegate
import kz.app.util.bind
import kz.app.util.setBadge
class MainFragment : Fragment(), BottomNavigationView.OnNavigationItemSelectedListener, OnBackPressDelegate, DrawerLayout.DrawerListener {
private val model by lazy { StateViewModel.get<MainViewModel>(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val imm = context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
retainInstance = true
if (!PreferencesRepository.getInstance(context
?: return).isTutorialFinished.blockingFirst())
InstructionFragment().show(childFragmentManager)
}
#SuppressLint("SetTextI18n")
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_main, container, false)
view.bottomNavigation.initMenu()
view.bottomNavigation.setOnNavigationItemSelectedListener(this)
view.toolbar.setNavigationOnClickListener { view.drawer.openDrawer(Gravity.START) }
view.pickCity.setOnClickListener { _ -> CityPickerDialogFragment.show(childFragmentManager) { model.setCurrentCity(it.id) } }
view.pickCity.bind(model.currentCityIconResId) { setImageResource(it) }
view.flipper.displayedChild = savedInstanceState?.getInt(KEY_CURRENT_ITEM, 0) ?: 0
view.bottomNavigation.run {
selectedItemId = menu.getItem(view.flipper.displayedChild).itemId
}
view.drawer.addDrawerListener(this)
view.toolbar.setOnMenuItemClickListener {
val currentPage = view?.flipper?.displayedChild
?: return#setOnMenuItemClickListener false
val shoppingFragment = childFragmentManager.findFragmentById(R.id.shoppingFragment)
val newsFragment = childFragmentManager.findFragmentById(R.id.newsFragment)
val bonusFragment = childFragmentManager.findFragmentById(R.id.bonusFragment)
val notificationsFragment = childFragmentManager.findFragmentById(R.id.notificationsFragment)
val helpFragment = childFragmentManager.findFragmentById(R.id.helpFragment)
when (currentPage) {
0 -> shoppingFragment.onOptionsItemSelected(it)
1 -> newsFragment.onOptionsItemSelected(it)
2 -> bonusFragment.onOptionsItemSelected(it)
3 -> helpFragment.onOptionsItemSelected(it)
4 -> notificationsFragment.onOptionsItemSelected(it)
else -> false
}
}
return view
}
fun showBonusesPage() {
view?.flipper?.displayedChild = 2
view?.bottomNavigation?.selectedItemId = R.id.bonus
}
fun showNewsPage() {
view?.flipper?.displayedChild = 1
view?.bottomNavigation?.selectedItemId = R.id.news
System.out.println("HEloo")
}
//this method should be called in AlertBoxActivity
fun showNewsPageTime() {
var newsFragment = 1
childFragmentManager.findFragmentById(R.id.newsFragment)
InstructionFragment().show(childFragmentManager)
}
private fun BottomNavigationView.initMenu() {
menu.clear()
menu.add(0, R.id.main, 0, R.string.main).icon = AppCompatResources.getDrawable(context, R.drawable.ic_shopping)
menu.add(0, R.id.news, 0, R.string.news).icon = AppCompatResources.getDrawable(context, R.drawable.ic_news)
menu.add(0, R.id.bonus, 0, R.string.bonus).icon = AppCompatResources.getDrawable(context, R.drawable.ic_bonus)
menu.add(0, R.id.help, 0, R.string.help).icon = AppCompatResources.getDrawable(context, R.drawable.ic_help)
menu.add(0, R.id.notifications, 0, R.string.notifications).icon = AppCompatResources.getDrawable(context, R.drawable.ic_notification)
bind(model.unreadCount) { setBadge(R.id.notifications, if (it > 0) it.toString() else null) }
}
override fun onDrawerStateChanged(newState: Int) {
}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
}
override fun onDrawerClosed(drawerView: View) {
try {
childFragmentManager.findFragmentById(R.id.fragment_navigation_main)?.userVisibleHint = false
} catch (_: IllegalStateException) {
}
}
override fun onDrawerOpened(drawerView: View) {
try {
childFragmentManager.findFragmentById(R.id.fragment_navigation_main)?.userVisibleHint = true
} catch (_: java.lang.IllegalStateException) {
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
updateTitle()
}
private fun updateTitle() {
when (view?.flipper?.displayedChild) {
0 -> view?.toolbar?.setTitle(R.string.your_bright_shopping)
1 -> view?.toolbar?.setTitle(R.string.news)
2 -> view?.toolbar?.setTitle(R.string.bonus)
3 -> view?.toolbar?.setTitle(R.string.help)
4 -> view?.toolbar?.setTitle(R.string.notifications)
}
}
#SuppressLint("RestrictedApi")
private fun notifyFragments() {
val currentPage = view?.flipper?.displayedChild ?: return
val shoppingFragment = childFragmentManager.findFragmentById(R.id.shoppingFragment)
val newsFragment = childFragmentManager.findFragmentById(R.id.newsFragment)
val bonusFragment = childFragmentManager.findFragmentById(R.id.bonusFragment)
val notificationsFragment = childFragmentManager.findFragmentById(R.id.notificationsFragment)
val helpFragment = childFragmentManager.findFragmentById(R.id.helpFragment)
shoppingFragment?.userVisibleHint = currentPage == 0
newsFragment?.userVisibleHint = currentPage == 1
bonusFragment?.userVisibleHint = currentPage == 2
helpFragment?.userVisibleHint = currentPage == 3
notificationsFragment?.userVisibleHint = currentPage == 4
val menu = view?.toolbar?.menu ?: return
val inflater = SupportMenuInflater(view?.toolbar?.context)
menu.clear()
when (currentPage) {
0 -> shoppingFragment.onCreateOptionsMenu(menu, inflater)
1 -> newsFragment.onCreateOptionsMenu(menu, inflater)
2 -> bonusFragment.onCreateOptionsMenu(menu, inflater)
3 -> helpFragment.onCreateOptionsMenu(menu, inflater)
4 -> notificationsFragment.onCreateOptionsMenu(menu, inflater)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt(KEY_CURRENT_ITEM, view?.flipper?.displayedChild ?: 0)
}
override fun onBackPressed(): Boolean {
val drawer = view?.drawer ?: return false
return when {
drawer.isDrawerOpen(Gravity.START) -> {
drawer.closeDrawer(Gravity.START)
true
}
view?.bottomNavigation?.selectedItemId == R.id.main -> false
else -> {
view?.bottomNavigation?.selectedItemId = R.id.main
true
}
}
}
fun onBackPressedNews(): Boolean {
view?.bottomNavigation?.selectedItemId = R.id.news
return true
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val page = when (item.itemId) {
R.id.main -> 0
R.id.news -> 1
R.id.bonus -> 2
R.id.help -> 3
R.id.notifications -> 4
else -> return false
}
view?.flipper?.displayedChild = page
updateTitle()
notifyFragments()
return true
}
companion object {
private const val KEY_CURRENT_ITEM = "current_item"
}
}
AlertBoxActivity.kt
Activity where I call showNewsPageTime() method, but when running android has stopped.
package kz.app
import android.support.design.widget.BottomNavigationView
import android.annotation.SuppressLint
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v4.app.FragmentManager;
import kotlinx.android.synthetic.main.fragment_main.*
import kotlinx.android.synthetic.main.fragment_parking_payment.*
import kotlinx.android.synthetic.main.fragment_shopping.*
import kz.app.api.entity.PromoAction
import kz.app.model.PromoActionViewModel
import kz.app.fragment.NewsFragment
import kz.app.fragment.PromoDetailsFragment
import kz.app.fragment.MainFragment
import kz.app.fragment.ShoppingDetailsFragment
import kz.app.model.PromoDetailsViewModel
import android.widget.FrameLayout;
import android.R
class AlertBoxActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val fragmentManager = supportFragmentManager
super.onCreate(savedInstanceState)
val obj = MainFragment()
obj.showNewsPageTime()
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, obj)
.commit()

Initializing "intent.extras" with a null variable declared as "Bundle" object

There is a type mismatch when initializing b as intent.extra. Though b is of type Bundle? and intent.extra doesn't take null values and also Bundle can't be null.
Please suggest a solution for this issue. The app keeps on crashing when installed on an android phone and ready to run.
The following code snippet present in the code body is showing only warning but ends up in application crash on start only.
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.provider.MediaStore
import android.support.design.widget.Snackbar
import android.support.design.widget.NavigationView
import android.support.v4.view.GravityCompat
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Toast
import com.example.debo.kickv01.R.id.lvTweets
import kotlinx.android.synthetic.main.activity_navig.*
import kotlinx.android.synthetic.main.app_bar_navig.*
import com.example.debo.kickv01.saved
import com.example.debo.kickv01.login as lg
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.activity_saved.view.*
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.*
class navig : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private var mAuth: FirebaseAuth?=null
private var database= FirebaseDatabase.getInstance()
private var myRef = database.reference
var list_T=ArrayList<ticket>()
var adaptor:MyPrjAdaptor?=null
var UserUID:String?=null
var myEmail:String?=null
// var b:Bundle= intent.extras
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navig)
val toolbar= null
var b:Bundle = intent.extras
myEmail = b.getString("email")
UserUID = b.getString("uid")
list_T.add(ticket("0","him","url","add"))
list_T.add(ticket("0","him","url","debo"))
list_T.add(ticket("0","him","url","debo_2"))
adaptor=MyPrjAdaptor(this,list_T)
lvTweets.adapter=adaptor
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
nav_view.setNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
when (item.itemId) {
R.id.nav_home -> {
// Handle the camera action
var intent = Intent(this, navig::class.java)
startActivity(intent)
}
R.id.nav_explore -> {
var intent = Intent(this, explore::class.java)
startActivity(intent)
}
R.id.nav_Saved -> {
var intent = Intent(this, saved::class.java)
startActivity(intent)
}
R.id.nav_actions -> {
var intent = Intent(this, actions::class.java)
startActivity(intent)
}
R.id.nav_login -> {
var intent = Intent(this, com.example.debo.kickv01.login::class.java)
startActivity(intent)
}
}
drawer_layout.closeDrawer(GravityCompat.START)
return true
}
inner class MyPrjAdaptor: BaseAdapter{
var listNotesAdaptor= ArrayList<ticket>()
var context:Context?=null
constructor(context: Context,listNotesAdaptor: ArrayList<ticket>):super(){
this.listNotesAdaptor=listNotesAdaptor
this.context=context
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var myTweet=listNotesAdaptor[position]
if (myTweet.tweetPersonUID.equals("add")) {
var myView = layoutInflater.inflate(R.layout.activity_saved, null)
myView.etAttach.setOnClickListener {
loadImage()
}
myView.etPost.setOnClickListener {
myRef.child("posts").push().setValue(PostInfo(UserUID!!,
myView.etProject.text.toString(),
myView.etDescription.text.toString(),
DownloadURL!!))
}
return myView
}else{
var myView = layoutInflater.inflate(R.layout.activity_explore, null)
return myView
}
}
override fun getItem(position: Int): Any {
return listNotesAdaptor[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return listNotesAdaptor.size
}
}
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.navig, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_settings -> return true
else -> return super.onOptionsItemSelected(item)
}
}
var PICK_IMAGE_CODE=123
fun loadImage(){
var intent=Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent, PICK_IMAGE_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
{
super.onActivityResult(requestCode, resultCode, data)
if(requestCode==PICK_IMAGE_CODE && resultCode== Activity.RESULT_OK && data!=null){
val selectedImage=data.data
val filePathColum = arrayOf(MediaStore.Images.Media.DATA)
val cursor= contentResolver.query(selectedImage,filePathColum,null,null,null)
cursor.moveToFirst()
val columIndex= cursor.getColumnIndex(filePathColum[0])
val picturepath= cursor.getString(columIndex)
cursor.close()
UploadImage(BitmapFactory.decodeFile(picturepath))
}
}
var DownloadURL:String?=null
fun UploadImage(bitmap: Bitmap){
var currentUser= mAuth!!.currentUser
val storage = FirebaseStorage.getInstance()
val storageRef= storage.getReferenceFromUrl("gs://kick-13840.appspot.com")
val df= SimpleDateFormat("ddMMyyHHmmss")
val dataobj= Date()
val imagePath= SplitString(myEmail!!) + "."+ df.format(dataobj)+ ".jpg"
val ImageRef= storageRef.child("imagePost/"+imagePath)
val baos= ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG,100,baos)
val data=baos.toByteArray()
val uploadTask=ImageRef.putBytes(data)
uploadTask.addOnFailureListener{
Toast.makeText(applicationContext,"fail to upload", Toast.LENGTH_LONG).show()
}.addOnSuccessListener { taskSnapshot ->
DownloadURL = taskSnapshot.storage.downloadUrl.toString()
}
}
fun SplitString(email: String):String{
val split= email.split("#")
return split[0]
}
}
b is of type Bundle whereas intent.extras returns Bundle? (Intent.getExtras() is annotated with #Nullable if you look at the code for it) as indicated by the IDE. You need to either use the not-null assertion operator, !!, or change b to type Bundle?.

Categories

Resources