I have this interactive game with 2 buttons and 1 image where images are stored in a map of drawables. The current image is var currentImageDrawable, so when you click a button, the image changes together with the currentImageVariable. But since I added a TextView, just to change the text when a specific image is displayed, unfortunately it doesn't change. It just remains at the first text which is "Start the game?".
import com.example.thegame.R.drawable.*
var tv = findViewById<TextView>(R.id.textView)
var currentImageDrawable = menu
data class Choice(val choice1: Int, val choice2: Int)
val choicesMap = mapOf(
menu to Choice(door1, menu),
door1 to Choice(door_inside, door_back),
door_inside to Choice(door_inside2, door_inside2_1),
door_back to Choice(door_back2, door_back2_1)
)
buttonYes.setOnClickListener {
currentImageDrawable = choicesMap[currentImageDrawable]!!.choice1
imageView.setImageResource(currentImageDrawable)
}
buttonNo.setOnClickListener {
currentImageDrawable = choicesMap[currentImageDrawable]!!.choice2
imageView.setImageResource(currentImageDrawable)
if (currentImageDrawable== menu) {
finishAffinity()
}
}
if (currentImageDrawable== menu) {
tv.setText("Start the game?") }
else if (currentImageDrawable== door1) {
tv.setText("Open the door?") }
else {
tv.setText("")
}
/*
when (currentImageDrawable) {
menu -> tv.setText("start the game?")
door1 -> tv.setText("open the door?")
else -> tv.text = ("")
}
*/
I think your code comes from your OnCreate method, can it be?
OnCreate is executed once when you create your activity. To change the text content when clicking the button you have to write the part in the OnClickListener.
buttonYes.setOnClickListener {
currentImageDrawable = choicesMap[currentImageDrawable]!!.choice1
imageView.setImageResource(currentImageDrawable)
if (currentImageDrawable== menu) {
tv.setText("Start the game?") }
else if (currentImageDrawable== door1) {
tv.setText("Open the door?") }
else {
tv.setText("")
}
}
buttonNo.setOnClickListener {
currentImageDrawable = choicesMap[currentImageDrawable]!!.choice2
imageView.setImageResource(currentImageDrawable)
if (currentImageDrawable== menu) {
tv.setText("Start the game?")
finishAffinity()
} else if (currentImageDrawable== door1) {
tv.setText("Open the door?")
} else {
tv.setText("")
}
}
The OnClick method is not executed immediately, but each time the button is clicked.
Related
I have an awkward situation for which I have been trying to find the reason and fix it for two days and I failed.
Let me explain it first.
On launching the app recyclerView in the 'HomeFragment' is filled with data that fetched from Firestore. I have a search bar on the toolbar at the top and when I type in something, it narrows down the list of items in the recyclerView.
I have a FloatingActionButton which will bring up a BottomSheetDialogFragment that contains item categories. When I select a category from it, the recyclerView in the 'HomeFragment' is populated based on the category selected. There is no issues until here.
If I do a search after selecting the category, it narrows down the list of items without any issues. When I select the 'HomeFragment' from the bottomNavigation, after selecting a category from the BottomSheetDialogFragment, the search result is not showing. However, if I select the 'HomeFragment' from the bottomNavigation after selecting any other bottom menu item, but not go to the BottomSheetDialogFragment and select a category, then there is no issue with the search. It happens only when I select the category and then go back to the 'HomeFragment' by hitting the bottom menu. Can somebody help me find and fix the issue?
Following is what I have in the 'HomeFragment' for search.
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
menu.clear() // THIS LINE OF CODE IS ADDED SO THAT WHEN WE SELECT A CATEGORY FROM THE BOTTOMSHEET THE MENU ITEMS WON'T DUPLICATE
inflater.inflate(R.menu.home_menu, menu)
super.onCreateOptionsMenu(menu, inflater)
val item = menu.findItem(R.id.my_search_bar)
val searchView = item?.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
srchTempProductsList.clear()
if (query != null) {
if (query.isNotEmpty()) {
srchProductsList.forEach {
if (it.label.toLowerCase(Locale.getDefault()).contains(query)) {
srchTempProductsList.add(it)
}
binding.rvHomeItems.adapter?.notifyDataSetChanged()
}
if (srchTempProductsList.size == 0) {
showCustomAlertDialog()
}
} else {
srchTempProductsList.clear()
srchTempProductsList.addAll(srchProductsList)
binding.rvHomeItems.adapter?.notifyDataSetChanged()
}
}
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
srchTempProductsList.clear()
val searchText = newText!!.toLowerCase(Locale.getDefault())
if (searchText.isNotEmpty()) {
srchProductsList.forEach {
if (it.label.toLowerCase(Locale.getDefault()).contains(searchText)) {
srchTempProductsList.add(it)
}
binding.rvHomeItems.adapter?.notifyDataSetChanged()
}
if (srchTempProductsList.size == 0) {
showCustomAlertDialog()
}
} else {
srchTempProductsList.clear()
srchTempProductsList.addAll(srchProductsList)
binding.rvHomeItems.adapter?.notifyDataSetChanged()
}
return false
}
})
}
I have the following in the 'BottomSheetDialogFragment' to pass the category to the 'HomeFragment'
categoryAdapter.setOnClickListener(object :HomeCategoryListAdapter.OnClickListener{
override fun onClick(position: Int, category: Categories) {
val myFragment = HomeFragment()
val bundle = Bundle()
bundle.putString("category", category.category)
myFragment.arguments = bundle
fragmentManager?.beginTransaction()?.replace(R.id.nav_host_fragment,myFragment)?.commit()
dismiss()
}
})
and the following in the onCreateView of 'HomeFragment'
val bundle = this.arguments
if (bundle!=null) {
if (bundle.getString("category")!="All Products"){
filterCategory = bundle.getString("category")
}else{
filterCategory =null
}
}
and this is how I get the product list in 'HomeFragment'
fun getProductList() {
srchProductsList.clear()
srchTempProductsList.clear()
if (filterCategory!=null){
mFireStore.collection("prods")
.whereEqualTo("category",filterCategory)
.get()
.addOnCompleteListener {
if (it.isSuccessful) {
for (document in it.result) {
val product = document.toObject(Product::class.java)
product.product_id = document.id
srchProductsList.add(product)
}
} else {
}
srchTempProductsList.addAll(srchProductsList)
listProductBasedOnView()
}
.addOnFailureListener {
Log.d("Known Error", "This ....")
}
}else{
mFireStore.collection("prods")
.get()
.addOnCompleteListener {
if (it.isSuccessful) {
for (document in it.result) {
val product = document.toObject(Product::class.java)
product.product_id = document.id
srchProductsList.add(product)
}
} else {
}
srchTempProductsList.addAll(srchProductsList)
listProductBasedOnView()
}
.addOnFailureListener {
Log.d("Known Error", "This ...")
}
}
}
i am working on QuizApp and I get a problem when I choose an answer and click submit it show me the correct and wrong answer and then I should click submit again to go to the next question, i want to disable that , I want when someone click submit he cant change the answer or choose another answer
here is my code
override fun onClick(v: View?) {
when (v?.id) {
R.id.tv_option_one -> {
selectedOptionView(tv_option_one, 1)
}
R.id.tv_option_two -> {
selectedOptionView(tv_option_two, 2)
}
R.id.tv_option_three -> {
selectedOptionView(tv_option_three, 3)
}
R.id.tv_option_four -> {
selectedOptionView(tv_option_four, 4)
}
R.id.btn_submit -> {
if (mSelectedOptionPosition == 0) {
mCurrentPosition++
when {
mCurrentPosition <= mQuestionsList!!.size -> {
setQuestion()
}
else -> {
// TODO (STEP 5: Now remove the toast message and launch the result screen which we have created and also pass the user name and score details to it.)
// START
val intent =
Intent(this, ResultActivity::class.java)
intent.putExtra(Constants.USER_NAME, mUserName)
intent.putExtra(Constants.CORRECT_ANSWERS, mCorrectAnswers)
intent.putExtra(Constants.TOTAL_QUESTIONS, mQuestionsList!!.size)
startActivity(intent)
finish()
// END
}
}
} else {
val question = mQuestionsList?.get(mCurrentPosition - 1)
// This is to check if the answer is wrong
if (question!!.correctAnswer != mSelectedOptionPosition) {
answerView(mSelectedOptionPosition, R.drawable.wrong_option_border_bg)
//
}
else {
mCorrectAnswers++
}
// This is for correct answer
answerView(question.correctAnswer, R.drawable.correct_option_border_bg)
if (mCurrentPosition == mQuestionsList!!.size) {
btn_submit.text = "FINISH"
} else {
btn_submit.text = "GO TO NEXT QUESTION"
}
mSelectedOptionPosition = 0
}
}
}
}
private fun setQuestion() {
val question = mQuestionsList!!.get(mCurrentPosition - 1) // Getting the question from the list with the help of current position.
defaultOptionsView()
if (mCurrentPosition == mQuestionsList!!.size) {
btn_submit.text = "FINISH"
} else {
btn_submit.text = "SUBMIT"
}
progressBar.progress = mCurrentPosition
tv_progress.text = "$mCurrentPosition" + "/" + progressBar.getMax()
tv_question.text = question.question
iv_image.setImageResource(question.image)
tv_option_one.text = question.optionOne
tv_option_two.text = question.optionTwo
tv_option_three.text = question.optionThree
tv_option_four.text = question.optionFour
}
/**
* A function to set the view of selected option view.
*/
private fun selectedOptionView(tv: TextView, selectedOptionNum: Int) {
defaultOptionsView()
mSelectedOptionPosition = selectedOptionNum
tv.setTextColor(
Color.parseColor("#363A43")
)
tv.setTypeface(tv.typeface, Typeface.BOLD)
tv.background = ContextCompat.getDrawable(
this,
R.drawable.selected_option_border_bg
)
}
/**
* A function to set default options view when the new question is loaded or when the answer is reselected.
*/
private fun defaultOptionsView() {
val options = ArrayList<TextView>()
options.add(0, tv_option_one)
options.add(1, tv_option_two)
options.add(2, tv_option_three)
options.add(3, tv_option_four)
for (option in options) {
option.setTextColor(Color.parseColor("#7A8089"))
option.typeface = Typeface.DEFAULT
option.background = ContextCompat.getDrawable(
this,
R.drawable.default_option_border_bg
)
}
}
/**
* A function for answer view which is used to highlight the answer is wrong or right.
*/
private fun answerView(answer: Int, drawableView: Int) {
when (answer) {
1 -> {
tv_option_one.background = ContextCompat.getDrawable(
this,
drawableView
)
}
2 -> {
tv_option_two.background = ContextCompat.getDrawable(
this,
drawableView
)
}
3 -> {
tv_option_three.background = ContextCompat.getDrawable(
this,
drawableView
)
}
4 -> {
tv_option_four.background = ContextCompat.getDrawable(
this,
drawableView
)
}
}
}
}
in your onclick, change the other views
view.isClickable = false
This is the code in onNavigationItemSelected
R.id.nav_subscribed -> {
if (prefs.getLong("userid", 0L) == 0L) {
when (currentGal) {
"top" -> {
// navView.setCheckedItem(R.id.nav_top)
// navView.menu.getItem(R.id.nav_top).isChecked = true
}
}
val i = Intent(this, Login::class.java)
this.startActivity(i)
} else {
if(currentGal != "subscriptions"){
getMemes("subscriptions", 0)
}
}
}
I try to prevent nav_subscribed to be checked when the user isn't logged in and check/keep checked nav_top
navView.setCheckedItem(R.id.nav_top)
isn't working and
navView.menu.getItem(R.id.nav_top).isChecked = true
crashed the app. So how to do this? Btw android is awful broken garbage software
navigationView?.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.nav_subscribed -> {
// if you don't want an item to be selected return false
return#setOnNavigationItemSelectedListener false
}
R.id.nav_top -> {
}
}
//return true to select the other items
true
}
The function showActionMenu() shows a popup menu, it works well.
I hope to change the title of a menu item when the menu is popup.
I try to add onPrepareOptionsMenu(menu: Menu) in the code, but it doesn't work, how can I fix it?
Code A
private fun showActionMenu() {
val view = mActivity.findViewById<View>(R.id.menuMoreAction) ?: return
PopupMenu(mContext, view).run {
menuInflater.inflate(R.menu.menu_option_action, menu)
/*
onPrepareOptionsMenu(menu: Menu) {
for (item in menu){
if (item.itemId == R.id.menuMoreActionSelectAll){
item.title = "My new title"
}
}
}
*/
setOnMenuItemClickListener {
when (it.itemId) {
R.id.menuMoreActionSelectAll -> {
mHomeViewModel.setSelectStatus(ESelect.SelectAll)
}
...
}
true
}
show()
}
}
You call show() immediately, so the menu is being shown immediately. Therefore you don't need any onPrepareOptionsMenu() call - just run that code immediately after your call to inflate():
PopupMenu(mContext, view).run {
menuInflater.inflate(R.menu.menu_option_action, menu)
for (item in menu){
if (item.itemId == R.id.menuMoreActionSelectAll){
item.title = "My new title"
}
}
setOnMenuItemClickListener {
when (it.itemId) {
R.id.menuMoreActionSelectAll -> {
mHomeViewModel.setSelectStatus(ESelect.SelectAll)
}
...
}
true
}
show()
}
Of course, if you're always setting the title of R.id.menuMoreActionSelectAll, you should just set that title in your R.menu.menu_option_action and skip your 'prepare' work entirely.
I have a bottom sheet dialog fragment that i use as a menu for my bottom app bar.
If i click on the menu icon really quick two times, the dialog shows up two times and i have to close it two times which is annoying.
My code is as follows:
ActivityHome.kt
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
if(mBottomNavDrawerFragment != null && mBottomNavDrawerFragment!!.dialog!!.isShowing){
mBottomNavDrawerFragment?.dismiss()
return false
}
mBottomNavDrawerFragment = RoundedBottomSheetDialogFragment()
mBottomNavDrawerFragment?.show(supportFragmentManager, mBottomNavDrawerFragment?.tag)
true
}
R.id.BottomAppBar_fromHomeActivity_MenuMain_Search -> {
Toast.makeText(this, "Not Implemented yet!", Toast.LENGTH_SHORT).show()
false
}
else -> true
}
}
Can anyone help? Thanks
Show the dialogFragment using a tag. Check if the tag exists in the stack before showing it again
if(getChildFragmentManager().findFragmentByTag(FragmentDialog.TAG) == null) {
fragmentDialog.show(getChildFragmentManager(), FragmentDialog.TAG);
}
You can do a little bit hack here. Here is the code.
private var saveClickCounter = 0
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return when (item?.itemId) {
R.id.home -> {
if (saveClickCounter++ == 0) {
//Your Dialog Showing Code
Handler().postDelayed({
saveClickCounter=0
},1000)
}
true
}
R.id.BottomAppBar_fromHomeActivity_MenuMain_Search -> {
Toast.makeText(this, "Not Implemented yet!", Toast.LENGTH_SHORT).show()
false
}
else -> true
}
}
Make a variable saveClickCounter to store your counts.
On clicks increase the value of saveClickCounter and change it to zero after N seconds of delayed. I used 1 second in below code.