How to use ImageButton state_focused? - android

my xml file
<LinearLayout
android:id="#+id/fragmentSelectorArea"
android:layout_width="fill_parent"
android:layout_height="#dimen/main_seletor_height"
android:layout_marginBottom="#dimen/main_seletor_margin_bottom"
android:background="#color/mainBtnBg" >
<ImageButton
android:id="#+id/myBtn"
android:layout_width="0dp"
android:layout_height="#dimen/main_btn_height"
android:layout_weight="1"
android:background="#drawable/btn_selector" />
</LinearyLayout>
btn_selector.xml
<item android:state_pressed="true"
android:drawable="#drawable/pressed_btn" />
<item android:state_focused="true"
android:drawable="#drawable/focused_btn" />
<item android:drawable="#drawable/nonselected_btn"/>
activity.java
ImageButton btn1 = (ImageButton) findViewById(R.id.myBtn);
OnClickListener btnListener = new OnClickListener() {
#Override
public void onClick(View btn) {
switch (btn.getId()) {
case R.id.myBtn:
mPager.setCurrentItem(0);
break;
...
default:
break;
}
}
};
btn1.setOnClickListener(btnListener);
I want to use effect when I clicked buttons.
normal(no focused), focused, pressed<-
But the state_focused is not working.
So I can't see focused effect.
Please help me..
add image.

I solved it.
button selector just two case. (pressed, non-pressed)
I overriding onPageChangeListener() in ViewPagerIndicator.

state_focused applied whenever the button is focused on using a dpad or the trackball. Views don't generally show a focused state when using touch.

You can use setonTouchListener to create an effect on the touch of your ImageButton like ...
myBtn.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
myBtn.setImageResource(R.drawable.quit_yes_selected);
else if(event.getAction() == MotionEvent.ACTION_UP)
myBtn.setImageResource(R.drawable.quit_yes);
return false;
}
});
Or you ca simply create an btn_selector.xml file in your drawable and set that to your ImageBackgroundResource like
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected, you should use bg with grey -->
<item android:drawable="#drawable/pressed_btn"
android:state_selected="true" />
<!-- When not selected, you should use bg with white -->
<item android:drawable="#drawable/nonselected_btn" />
</selector>
And in the java you have to assign your ImageButton background resource as that file
myBtn.setBackgroundResource(R.drawable.btn_selector);

Related

Relative layout onpress

What I want is, When the RelativeLayout press state is active, I want the layout alpha to be 50% and when its not I need 100% alpha.
The following code doesn't seem to be working.
if (relativelayout.hasFocus()){
relativelayout.setAlpha(0.5f);
}
I tried setting the background of the relative layout to this
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/drawer_list_pressed" />
<item android:state_focused="false"
android:drawable="#drawable/drawer_list_normal" />
<item android:state_selected="true"
android:drawable="#drawable/drawer_list_pressed" />
</selector>
It is working on changing the background but not alpha of the contents.
after some thinking i found a solution
public void pressed(final View view){
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
view.setAlpha(0.5f);
}
else {
view.setAlpha(1.0f);
}
return true;
}
});
}

Custom Button Doesn't work with OnTouchListener

I have a problem with OnTouchListener. I created a custom button. This button properly works with onClick event. But it doesn't work with onTouch Event
This is my custom button. I want only two options just button and button_pressed.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button2_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/button2_pressed"
android:state_focused="true" />
<item android:drawable="#drawable/button2" />
This is my Ontouch button code. When I keep the button pressed, audio is playing and looping. When I release the button audio is stopped. This code correctly works but it doesn't work with my custom button. So when i have my finger on this button, then when I release the button or when I hold the button shortly, in every case this button show me only button2.png (above the custom button code)
pl6.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
n6=MediaPlayer.create(MainActivity.this, R.raw.audio4);
n6.start();
n6.setLooping(true);
return true;
case MotionEvent.ACTION_UP:
n6.stop();
n6.release();
break;
}
return false;
}
});
This is my other button. it is correctly work. This button is a normal button just click and play.
When i pressed the button button2_pressed is appear and when I unpressed button2 is appear.
play2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
stopPlaying2();
m2=MediaPlayer.create(MainActivity.this, R.raw.sound2);
m2.start();
}
});
I solved my problem again on my own. Lets explain;
Firstly I clonned all button for example btnPlay1 and btnPlay1c
but the buttons xml different to each other. the difference is only id and custom button xml file. I used 2 custom button xml I show below.
First Custom button mybutton1.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button"
android:state_pressed="true" />
<item android:drawable="#drawable/button"
android:state_focused="true" />
<item android:drawable="#drawable/button" />
</selector>
Second custom button mybutton1c.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/button_pressed"
android:state_focused="true" />
<item android:drawable="#drawable/button_pressed" />
</selector>
And example from my buttons. clone button is invisible. (btnPlay2c)
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<Button
android:id="#+id/btnPlay2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/mybutton1" />
<Button
android:id="#+id/btnPlay2c"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/mybutton1c"
android:visibility="gone" />
</FrameLayout>
Lastly, this is my java file. When I pressed the button, button clone is showing and when I unpressed normal button is showing. That's all.
pl10.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
n10=MediaPlayer.create(MainActivity.this, R.raw.audio7);
n10.start();
n10.setLooping(true);
///focus here\\
pl10c.setVisibility(View.VISIBLE);
return true;
case MotionEvent.ACTION_UP:
n10.stop();
n10.release();
//and here\\\
pl10c.setVisibility(View.INVISIBLE);
break;
}
return false;
}
});
This solution might be tiring but its solve the problem.

android button setPressed after onClick

yesterday I noticed the possibility to integrate Fragments in older API Levels through the Compatibility package, but thats not really essential for the question. :)
I have a Button with an OnClickListener
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
doSomething();
button.setPressed(true);
}
});
Because of the actual clicking, it is shown as pressed and after releasing the click, the button state is not pressed and stays that way.
Is there a simple way that keeps the button state pressed after releasing?
First thing I can think of would be some sort of timer, but that seems unreasonable.
Just to note this is because Android is changing the setPressed both before and after your onClickEvent, so changing it yourself has no effect. Another way to get around this is to use the onTouchEvent.
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// show interest in events resulting from ACTION_DOWN
if (event.getAction() == MotionEvent.ACTION_DOWN) return true;
// don't handle event unless its ACTION_UP so "doSomething()" only runs once.
if (event.getAction() != MotionEvent.ACTION_UP) return false;
doSomething();
button.setPressed(true);
return true;
}
});
Use ToggleButton instead of Button.
<ToggleButton
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/topping_selector"
android:checked="false"
android:textOff="Topping2"
android:textOn="Topping2" />
topping_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/btn_topping_on" />
<item android:state_checked="false"
android:drawable="#drawable/btn_topping_off" />
</selector>
You can keep the button states in xml file under drawable folder, then used as background for button.
For example:
android:background="#drawable/buttonstate"
buttonstate.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/back_focused" />
<item android:drawable="#drawable/back" /> <!-- default -->
</selector>
Better solution:
In xml file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_activated="true">
<bitmap android:src="#drawable/image_selected"/>
</item>
<item>
<bitmap android:src="#drawable/image_not_selected"/>
</item>
</selector>
And in java:
#Override
public void onClick(View v) {
v.setActivated(!v.isActivated());
}
You can use android.os.Handler class. Ugly, but works also:
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
doSomething();
new Handler().post(new Runnable() {
#Override
public void run() {
button.setPressed(true);
}
});
}
});
Another solution is to extend Button and override setPressed(boolean pressed) method so you can handle platform calls from the onClickEvent using a flag, for example changing the boolean pressed parameter depending on your needs.
public class MyButton extends Button {
boolean isSelected = false; //this is your flag
#Override
public void setPressed(boolean pressed) {
if(isSelected) {
//here you change the parameter so it stays pressed
super.setPressed(true);
return;
}
super.setPressed(pressed);
}
public void setIsSelected(boolean selected) {
this.isSelected = selected;
}
public MyButton(Context context) {
super(context);
}
}
This is the solution I used, It also works on android 7.0 at the moment.
YourActivity.java
public void onStandbyStart(String message) {
startStandbyBtn.setActivated(true);
}
public void onBackOnline(String message) {
startStandbyBtn.setActivated(false);
}
YourActivityLayout
<Button
...
style="#style/generic_btn_style"
... />
values/styles.xml
<style name="generic_btn_style" parent="#android:style/Widget.Button">
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:background">#drawable/generic_btn</item>
<item name="android:textColor">#color/selector_white_black</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
</style>
drawable/generic_btn.xml
This selector chooses the button background. I use the pressed as the activated.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/generic_btn_disabled" android:state_enabled="false" />
<item android:drawable="#drawable/generic_btn_pressed" android:state_enabled="true" android:state_pressed="true" />
<item android:drawable="#drawable/generic_btn_pressed" android:state_activated="true" />
<item android:drawable="#drawable/generic_btn_focused" android:state_enabled="true" android:state_focused="true" />
<item android:drawable="#drawable/generic_btn_enabled" android:state_enabled="true" />
</selector>
color/selector_black_white
Here I set the text color. In my case, I need to pick the textcolor black when pressed.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#fff" android:state_pressed="true" /> <!-- pressed -->
<item android:color="#fff" android:state_activated="true" /> <!-- pressed -->
<item android:color="#000" /> <!-- default -->
</selector>

How do I change the tint of an ImageButton on focus/press

I have an ImageButton in my app and I need to change the tint of the image when the button is pressed/focused. I have the ImageButton set to get its src from an XML file which as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item
android:state_pressed="true"
android:tint="#color/black"
android:drawable="#drawable/search"
/>
<!-- focused -->
<item
android:state_focused="true"
android:tint="#color/black"
android:drawable="#drawable/search"
/>
<!-- default -->
<item
android:tint="#null"
android:drawable="#drawable/search"
/>
</selector>
However the tint isn't applied when the ImageButton is pressed or focused - the image just displays as normal. The color black is defined as #000000 as always. Any ideas?
You can change the tint, quite easily in code via:
ImageButton button = (ImageButton) this.findViewById(R.id.button_i_want_to_modify);
button.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
Here is how to do it using just xml.
In your drawable folder create a selector. Eg: touch_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item android:state_pressed="true" android:color="#color/semi_slate" />
<!-- When the view is "activated". In SINGLE_CHOICE_MODE, it flags the active row
of a ListView -->
<item android:state_activated="true" android:color="#color/semi_slate" />
<!-- Default, "just hangin' out" state. -->
<item android:color="#android:color/transparent" />
</selector>
In my Image view in xml I set the android:tint attribute to the drawable created above.
android:tint = "#drawable/touch_selector"
The whole code looked like this:
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/poster"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:tint="#drawable/touch_selector" />
This is an all xml solution, to put tint on an ImageView on press or on active.
Similar can be done for ImageButton
Note that this only works for API level >= 21.
Finally I have found a solution for API < 21:
Button more = (Button) findViewById(R.id.more);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
more.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
} else {
Drawable wrapDrawable = DrawableCompat.wrap(more.getBackground());
DrawableCompat.setTint(wrapDrawable, color));
more.setBackgroundDrawable(DrawableCompat.unwrap(wrapDrawable));
}
May this help someone not to lose 2 hours !
I found a way to do this in xml (in api 21 and up at least).
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<bitmap
android:src="#drawable/search"
android:tint="#color/black"
/>
</item>
<item android:drawable="#drawable/search"/>
</selector>
By setting the tint on the bitmap it's possible to reuse the same drawable in xml without having to intercept touches or subclass ImageView or ImageButton.
Once the selector has been created, just apply that as the src of the ImageView or ImageButton.
bt.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
bt.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
return true; // if you want to handle the touch event
case MotionEvent.ACTION_UP:
bt.clearColorFilter(); // White Tint
return true; // if you want to handle the touch event
}
return false;
}
});
What I'm doing is add a custom button that has the function setColorFilter.
Like this I can use the new button in the xml.
public class CustomButton extends Button {
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attributes) {
super(context, attributes);
};
#Override
public boolean onTouchEvent(MotionEvent event) {
int maskedAction = event.getActionMasked();
if (maskedAction == MotionEvent.ACTION_DOWN)
getBackground().setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
else if (maskedAction == MotionEvent.ACTION_UP)
getBackground().setColorFilter(null);
return super.onTouchEvent(event);
}}
and for the ImageButton
public class CustomImageButton extends ImageButton {
public CustomImageButton(Context context) {
super(context);
}
public CustomImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int maskedAction = event.getActionMasked();
if (maskedAction == MotionEvent.ACTION_DOWN)
setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
else if (maskedAction == MotionEvent.ACTION_UP)
setColorFilter(null);
return super.onTouchEvent(event);
}}
I noticed there are some requests here for people wanting to know how to do this in XML. It is actually quite simple. This can be accomplished using a layer-list
Your button's drawable (drawable/some_button.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/some_button_highlighted" />
<item android:drawable="#drawable/some_button_image" />
</selector>
And this is the highlighted drawable (drawable/some_button_highlighted.xml)
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/some_button_image"/>
<item>
<shape>
<solid android:color="#color/highlighted_button_color" />
</shape>
</item>
</layer-list>
Now you can use this in any other xml:
...
android:drawable="#drawable/some_button"
...
I hope this helps someone in the future.
You can set color (tint) from xml.
Set transparent (android:background="#null") for background then use tint :
<ImageButton
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:tint="#color/Amber_200"
android:background="#null"
android:src="#drawable/back_selector" />
I have the same issue and I found this solution :
logoImage.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
if (logoImage.isSelected) {
logoImage.setColorFilter(context.getColor(R.color.blue_unselect), PorterDuff.Mode.SRC_IN)
} else {
logoImage.setColorFilter(null)
}
} else if (event.action == MotionEvent.ACTION_UP) {
if (!logoImage.isSelected) {
logoImage.setColorFilter(null)
} else {
logoImage.setColorFilter(context.getColor(R.color.blue_unselect), PorterDuff.Mode.SRC_IN)
}
} else if (event.action == MotionEvent.ACTION_CANCEL) {
if (root.isSelected) {
logoImage.setColorFilter(null)
} else {
logoImage.setColorFilter(context.getColor(R.color.blue_unselect), PorterDuff.Mode.SRC_IN)
}
}
false
}
it's working for me.
As you defined the selector to be the src of the ImageButton Android will AFAIK just take the drawable because that's what matches the type of src. So tint won't be used.
Nevertheless, I had a similar problem: I also tried to use a selector like yours but for the android:tint value of the ImageButton instead of android:src. Of course I omitted the tint values you have in your selector. This would solve your problem, too, because you want to use the same drawable for all states. Curiously I get a NumberFormatException everytime stating that the system was unable to parse 'res/color/tint_selector.xml' (which is indeed my selector) as integer. To be specific my code looks like this:
This is my selector, saved in /res/color/tint_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#D3D3D3"/> <!-- pressed -->
<item android:color="#ff000000"/> <!-- default -->
</selector>
And this is the corresponding ImageButton:
<ImageButton android:id="#+id/program_help"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/symbol"
android:tint="#color/tint_selector">
</ImageButton>
Maybe this helps you a bit although it currently doesn't work.

Android how to make button text bold when pressed or focussed

I want to change the text inside a button to be bold when the button is highlighted or pressed. I currently use a xml file to define the button and use the XML to change how it looks when pressed but I would like to do this without using an image.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:state_pressed="false"
android:drawable="#drawable/reset_hover" />
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="#drawable/reset_hover" />
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/reset_hover" />
<item android:drawable="#drawable/reset" />
</selector>
I tried using something like the following, but it doesn't seem to ever get called.
final Button btn_reset = (Button) findViewById(R.id.btn_reset);
btn_reset.setOnClickListener(this);
btn_reset.setOn(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus){btn_reset.setTypeface(null, Typeface.BOLD);}
else{btn_reset.setTypeface(null, Typeface.NORMAL);}
}
});
You could try putting the bold code inside the click event for the button:
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Set bold on click
button.setTypeface(null, Typeface.BOLD);
}
});
Attention! See update below
You could create your own style.xml in which you define the text style. In your selector you can reference to the style.
style.xml
<style name="myStyle">
<item name="android:textSize">9px</item>
<item name="android:gravity">center_horizontal</item>
<item name="android:textColor">#fff</item>
<item name="android:textStyle">bold</item>
</style>
And in your selector
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:state_pressed="false"
style="#style/myStyle" /> </selector>
Update 2020: My answer is more than 10 years old. It doesn´t work anymore!
Styles are not allowed in selectors. Reference
And to make the text bold, use this code:
btn_reset.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
// When the user clicks the Button
case MotionEvent.ACTION_DOWN:
btn_reset.setTypeface(Typeface.DEFAULT_BOLD);
break;
// When the user releases the Button
case MotionEvent.ACTION_UP:
btn_reset.setTypeface(Typeface.DEFAULT);
break;
}
return false;
}
});

Categories

Resources