I am designing an app that has 3 button in main activity, and several buttons in a fragment. I want to change the color of a button in the fragment, depending on which button of main activity is toggled.
color1.setOnClickListener {
brush_chosen = 1
color1.setBackgroundColor(R.color.black)
color2.setBackgroundColor(0x00000000)
color3.setBackgroundColor(0x00000000)
if (frag_num == 8 ){
frag_8p.set_frag_value(frag_num,brush_chosen)
}
}
The function set_frag_value is :
fun set_frag_value(frag_num:Int,brush:Int) : Int
{
brush_chosen=brush
return brush
}
This change the value of brush_chosen. Then I made a function :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ib0.setOnClickListener { view ->
Log.d("brush_color","Brush of 0 : "+brush_chosen)
if (brush_chosen==1)
{
Log.d("brush_color","Brush Confirm : "+brush_chosen)
DrawableCompat.setTint(ib0.drawable, ContextCompat.getColor(requireContext(),R.color.rndcolor1))
}
else if (brush_chosen==2)
{
Log.d("brush_color","Brush Confirm : "+brush_chosen)
DrawableCompat.setTint(ib0.drawable, ContextCompat.getColor(requireContext(),R.color.purple_500))
}
else if (brush_chosen==3)
{
Log.d("brush_color","Brush Confirm : "+brush_chosen)
DrawableCompat.setTint(ib0.drawable, ContextCompat.getColor(requireContext(),R.color.teal_200))
}
Log.d("brush_color","End of onclicklistener ")
}
}
I checked the log and theoretically this code should work correctly. However, I found that the button color did not change properly, even I checked my app prints all log correctly. For example, when I clicked button color1 in main activity, variable brush_chosen becomes 1 and the first button in fragment I clicked changes its color. But the second button I clicked does not change its color.
Is there any problem on my code using DrawableCompat ??
Android does some Drawable state caching under the hood. You might need to call mutate() on the Drawable you want to tint and then set the new Drawable in order for the tint to show up properly.
Related
i've a problem in my Android app.
I have a fragment that is generated as a list of editable textview. Every textview has a setOnFocusChangeListener that calls an API on server.
FocusChangedListener works correctly on last textview, and after that my textview remain focused as you can see in the figure below.
Problem
Now i have to change menu (fragment) by clicking on the right menu button.
When button is clicked and the new menu is about to be loaded, my textview loses focus and calls the API, but i don't want my app do that. If I click menu button is because i've to change it and i expect that my old fragment disappear or basically don't execute the FocusChangedListener.
Any ideas?
I made a little trick to solve the problem.
I just added this code inside OnCreate of my DrawerMenu and then i set a Global Variable "drawerOpened" to check every time if my Menu is open or not.
// Initialize the action bar drawer toggle instance
val drawerToggle:ActionBarDrawerToggle = object : ActionBarDrawerToggle(
this,
drawer_layout,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
){
override fun onDrawerClosed(view:View){
super.onDrawerClosed(view)
GlobalVar.drawerOpened = false
}
override fun onDrawerOpened(drawerView: View){
super.onDrawerOpened(drawerView)
GlobalVar.drawerOpened = true
currentFocus?.clearFocus() //clear focus - any view having focus
}
}
Then in my HomeFragment i did this:
// if GlobalVar.drawerOpened is false then setOnFocus
if (field.validatefield || field.nextpage != 0)
{
textView.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus && !GlobalVar.drawerOpened)
{
if ((field.mandatory && !textView.text.toString().isNullOrEmpty()) || (!field.mandatory)) {
if (field.validatefield) {
validateField(field.fieldcode, textView.text.toString(), field.nextpage)
} else {
_goToNextPageNo = field.nextpage
goToNextPageIfExist()
}
}
}
}
}
This is not a complete solution, but it works fine.
I assume that after a click, the application switches to touch mode and your EditText loses focus.
It happens at the system level.
A focus can have only one view at a time.
https://android-developers.googleblog.com/2008/12/touch-mode.html
I'm creating my Android application and faced this peculiar issue.
None of my teammates have experienced this before and I'm stuck with this for days now.
So what happens is that after going to Setting Fragment and coming back, ALL images (both ImageView and Facebook SimpleDraweeView) become white.
If you see pictures below, you may see how all images change to white.
This always occur if I tap the Setting tab (the last one on the right) and coming back to any tab.
This line of my Setting Fragment is what makes the problem.
childFragmentManager.beginTransaction().replace(R.id.settings_container, MainSettingsFragment()).commit()
If I comment this line out, then everything is fine. The problem is, the line below doesn't cause any problem. While the above line is for the fragment, the below line is for activity.
supportFragmentManager.beginTransaction().replace(R.id.msettings_container, MainSettingsFragment()).commit()
The below is the code block of fragment lifecycle.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
profile_profileimage.setOnClickListener {
val imageList = arrayListOf(MainActivity.myProfile)
val overlay = ImageOverlayView(requireContext())
ImageViewer.Builder(requireContext(), imageList)
.hideStatusBar(false)
.allowZooming(true)
.allowSwipeToDismiss(true)
.setOverlayView(overlay)
.setImageChangeListener { position ->
overlay.setImageUrl(MainActivity.myProfile)
}
.show()
}
}
override fun onResume() {
super.onResume()
refreshMemorials()
loadProfile()
}
private fun loadProfile() {
activity?.runOnUiThread {
...
profile_profileimage.setImageURI(MainActivity.myProfile)
...
}
}
This is the XML code for profile_profileimage
<com.facebook.drawee.view.SimpleDraweeView
android:layout_width="120dp"
android:layout_height="120dp"
android:id="#+id/profile_profileimage"
app:actualImageScaleType="fitXY"
app:roundAsCircle="true"
app:roundingBorderWidth="1dp"
app:roundingBorderColor="#android:color/white" />
But, I want to have Settings as one of fragment.
I can't see what is going wrong here. Is there any way to solve this?
In particular class, from many places call back is coming, i just want to whether it's coming text or button for example, so that I can set the data accordingly.
NOTE: I'm not talking about parent layout, I want to know exact name where the event click is happened!
If I'm doing this: Log.d("Hello", "Clicked finally: "+ view?.id)
This is coming:
D: Clicked finally: 2131296625
If you are using Kotlin, You can simply check if the View is Button or Image using is operator like:
when(view) {
is Button -> {
// a Button is clicked.
}
is AppCompatImageView -> {
// an Image is clicked.
}
else -> {
// any other view is clicked.
}
}
You can do something like this:
if (view.javaClass.simpleName == Button::class.java.simpleName) {
// it is a button
} else if (view.javaClass.simpleName == TextView::class.java.simpleName) {
// it is a text view
}
Please note that this won't work if you are using any subclass of Button or TextView. You will need to explicitly specify the class you want to check for.
I currently want to have a button that when I press it another button flashes as if it has been pressed at the same time and activates the function of the other button. My current code is as such:
fun onTwo(view: View) {
button1.callOnClick()
button1.isPressed = true
}
However the issue I am facing is that it freezes button1 as if it is pressed until it is pressed again. Anyone have a solution for this?
You could add listener in one of the button to check for clicks and then use that event to trigger click event in another button, like this:
val button1 = findViewById(R.id.btn1ID) as Button
button1.setOnClickListener {
val button2 = findViewById(R.id.btn2ID) as Button
button2.performClick()
}
Replace R.id.btn1ID and R.id.btn2ID with their respective id(a).
Reference: performClick()
You could also create a utility function to use it without making redundant variables like this:
#Suppress("UNCHECKED_CAST")
fun Activity.findButtonById(#IdRes res : Int) : Button =
findViewById(res) as Button
// and then in your create method of activity:
findButtonById(R.id.btn1ID).setOnClickListener {
findButtonById(R.id.btn2ID).performClick()
}
Try performClick() method like below:
fun onTwo(view: View)
{
button1.performClick()
}
I ended up fixing this issue using coroutines in the end as such:
fun onTwo(view: View){
GlobalScope.async{
delay(100)
button1.isPressed = false
GlobalScope.cancel()
}
button1.setPressed(true)
button1.performClick()
}
I have a listener that listens and makes focused items little bit bigger with animation.
private fun focus() {
itemView?.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
val anim : Animation = AnimationUtils.loadAnimation(itemView.context, R.anim.scale_in)
itemView.startAnimation(anim)
anim.fillAfter = true
} else {
val anim : Animation = AnimationUtils.loadAnimation(itemView.context, R.anim.scale_out)
itemView.startAnimation(anim)
anim.fillAfter = true
}
}
}
Besides this listener I also made custom function, that when focused item is clicked, it actually changes size back to normal
fun customFunction(): Unit = with(itemView) {
val anim : Animation = AnimationUtils.loadAnimation(itemView.context, R.anim.scale_out)
itemView.startAnimation(anim)
anim.fillAfter = true
}
PROBLEM: focus() and customFunction() functions work alright. Problem is, when I hit enter on focused element (customFunction() triggers) and element changes it size to normal - which is okay. But the moment I navigate to other element, the previous one scales out twice. How do I need to modify my onFocusListener to know that I shouldn't scale out twice if I've triggered customFunction() by clicking some item. Any idea is welcomed.
if i understand right your question you may have to try : itemView. setOnFocusChangeListener(null); in your customFunction()