Some XML attributes of buttons (such as background, textColor, etc) can be defined with color or drawable state List like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#ffff0000"/>
<item android:state_focused="true"
android:color="#ff0000ff"/>
<item android:state_enabled="true"
android:color="#ff00ffff"/>
<item android:color="#ff000000"/>
</selector>
When view state changes (pressed/unpressed, for example), corresponding color is changed automatically.
How can I prograqmmatically handle some kind of stateChangedEvent to perform more complicated layout change, than just changing a color (for example, change font size or set another text)?
For focus changes and touch events you can register listeners by setOnFocusChangeListener and setOnTouchListener. And changes about disabled/enabled states you can perform directly after changing your button state.
// use the selector method to pass your button and image
// you can use color also
b1=(Button)findViewById(R.id.button1);
// b2=(Button)findViewById(R.id.button2);
selector(b1, R.drawable.image_1_2, R.drawable.image_1);
// selector(b2, R.drawable.image_2_2, R.drawable.image_2);
}
public void selector(Button b,int pressed_image,int normal_image )
{
StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
getResources().getDrawable(pressed_image));
states.addState(new int[] { },
getResources().getDrawable(normal_image));
b.setBackgroundDrawable(states);
}
Just override View.setPressed:
#Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
...
}
Handler onTouch(View v, MotionEvent event) for specific views and perform actions in MotionEvent.DOWN / Up according to your requirement.
You have to take a reference to the View Object (button) via findViewById(<object_id>) and than use the appropriate methods from the API.
For example:
private Button aButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
aButton = (Button) findViewById(R.id.your_button_id);
//example 1
aButton.setVisibility(SomeExpressionEvaluation ? View.GONE : View.VISIBLE);
//example 2
if (SomeExpressionEvaluation) {
aButton.setText("Some Text");
}
and so on, just take a look at the API, especially inherited methods from the View class.
I must say you can use a (touch listner) this how u use a touch listner
image=(ImageView)findViewById(R.id.image);
find ur image first
Add a touch Listner to ur image
image.setOnTouchListener(image_onTouch);
//Add a touch method which is by name image_onTouch
OnTouchListener image_onTouch=new OnTouchListener(){
#Override
public boolean onTouch(View arg0,MotionEvent arg1){
int iAction=arg1.getAction();
if(iAction==0){
image.setImageResource(R.drawable.image1);
}
else{
image.setImageResource(R.drawable.image2);
}
return false;
}
};
// image 1 is ur image which u want 2 click and image 2 is the image when you touch that image you have to make an another image in which background color do u wanna show and use it in the code
I had also this kind of problem in past. I solved by putting this XML file in separate drawable folder in Res instaed of drawable-mdpi or else. And make sure that you have to give this Xml as your button's background.
Related
I saw some posts with a similar question but they still differ from my problem here. I am making painting app in Android Studio and I want to indicate the option which user selected (whether it is move tool, pencil etc.) Here is the picture:
So, I want to change the background color of the button when it is selected and revert it back to default color when another button is selected.
I tried doing it with XML selector but later I saw that there is now "selected" attribute for a regular button. These are regular buttons. What is the easiest way to solve this?
Try this code (button_selector.xml, put it in your drawable folder)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/holo_blue_dark" android:state_selected="true"></item>
<item android:drawable="#android:color/holo_blue_dark" android:state_pressed="true"></item>
<item android:drawable="#android:color/darker_gray"></item>
</selector>
XML
<Button
android:background="#drawable/button_selector" />
You could use a class variable for keeping track of the currently selected button, and detect when a new button is selected. You would then perform the action of "selecting" the new button, and "deselecting" the previous one. Example:
private Button mSelectedButton;
private void setOnClickListeners() {
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
Button clickedButton = (Button) view;
//in case no button is selected, this will only "select" the clickedButton
if (mSelectedButton == null) mSelectedButton = clickedButton;
//previous selected button (should return to original state)
mSelectedButton.setBackgroundColor(R.color.original_state);
//your new selected button
clickedButton.setBackgroundColor(R.color.selected_state);
mSelectedButton = clickedButton; //save currently selected button
}
};
yourButton1.setOnClickListener(listener);
yourButton2.setOnClickListener(listener);
yourButton3.setOnClickListener(listener);
...
}
On Android, a Button changes its background color when pressed.
How can we tell a button that it is pressed (without firing the onClick-action), so that it changes color, without the user pressing it? (for example triggered by a swipe action)
It should change color briefly, and then change back.
There a quite a few questions concerning keeping the pressed state. This question asks, how to set the button_pressed state briefly, as if clicked, but without a real click.
Button.setPressed(true) has not given a color change, neither has Button.performClick().
First, create the effect when button is hovered, clicked etc in XML. Put this style in your drawable.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed button -->
<item android:drawable="#color/dark_green"
android:state_focused="true"
android:state_pressed="false"
/>
<item android:drawable="#color/dark_green"
android:state_focused="true"
android:state_pressed="true"
/>
<item android:drawable="#color/dark_green"
android:state_focused="false"
android:state_pressed="true"/>
<!-- Normal button -->
<item android:drawable="#color/green"
android:state_focused="false"
android:state_pressed="false"/>
</selector>
Then in your XML, initiates the style by using:
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/the_style_in_drawable"
android:text="click"/>
By putting the style in your XML, you don't have to initiate the style when button on click. Android will detect the button state and do the work for you. Just remember to put the state in selector.
To change a button state without anything else is done via
btn1.getBackground().setState(new int[]{android.R.attr.state_pressed});
To reset to ordinary, you use
btn1.getBackground().setState(new int[]{android.R.attr.state_enabled});
A Button's states can be found out via
btn1.getBackground().getState();
which resturns an int[]. You can compare its values to android.R.attr to find out which states are set.
Example Code
private void simulateClick(final ImageButton button,
final long clickDuration) {
button.getBackground().setState(new int[]{android.R.attr.state_pressed});
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(clickDuration);
} catch ( InterruptedException e ) {
// not bad if interrupted: sleeps a bit faster (can happen?)
}
Count.this.runOnUiThread(new Runnable() {
public void run() {
button.getBackground().setState(new int[]{android.R.attr.state_enabled});
}
});
}}).start();
}
Explanation
Each View has a Drawable as background image. A Drawable can be of different subtypes, here it is a StateListDrawable, as defined per XML. (See #Lynx's answer as an example of a XML defined drawable).
This Drawable can be told which state it is to assume (via setState) and does the layout itself.
AsyncTask for button color change illusion:
private class ChangeButtonColorMomentarily extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
btn1.setBackgroundDrawable(new ColorDrawable(Color.rgb(50, 50, 50)));//pressed state
}
#Override
protected String doInBackground(String... params) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
return "";
}
#Override
protected void onPostExecute(String result) {
btn1.setBackgroundDrawable(new ColorDrawable(Color.rgb(200, 200, 200)));//normal state
}
}
Also take note that if your API 16 above use setBackground() instead.
For changing the color of button at that time, you can use setOnTouchListener as:
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
//Button Pressed
}
if(event.getAction() == MotionEvent.ACTION_UP){
//finger was lifted
}
return false;
}
});
I have imageview and i whant when user click this imageview the background of this changed this is my code
btnImage =(ImageView) findViewById(R.id.image_button);
btnImage.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
Intent i=new Intent(fierst.this,second.class);
startActivity(i);
}
});
but i dont know how in onclick change this background image
Why you do not use Selctor for ImageView when clicked.
res/drawable/selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/your_iamge_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/your_iamge_pressed"
android:state_focused="true"
android:state_enabled="true"
android:state_window_focused="true" />
<item android:drawable="#drawable/your_iamge_normal" />
here in you ImageView set the selector as background : android:background="#drawable/selector.xml"
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/selector.xml" />
OR USE TouchListener To implement such idea
when you touch(Action Down) set one image as background and when you release (Action Up) set another Image as background.
here is the code
buttonONE.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN) {
buttonONE.setBackground(R.drawable.round_button_focus);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
buttonONE.setBackground(R.drawable.round_button_unfocused);
// *******start Intent here********
}
}
};
I'm agree with #sajidkhan answer but #zahra you are doing mistake to set the selector as background wrong.
here i will explain #sajidkhan's answer as i know he might be expected here an image.png etc not a selector.xml
buttonONE.setBackground(R.drawable.round_button_focus);
round_button_focus means round_button_focus.png etc,
in MotionEvent.ACTION_DOWN set one background and when you release the button set another background eg. MotionEvent.ACTION_UP
follow #sajidkhan suggestion his answer might deserve as accepted if you think this helped you.
Here is the code
btnImage =(ImageView) findViewById(R.id.image_button);
btnImage.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
btnImage.setBackgroundResource(R.drawable.ic_launcher);
//put your image in drawable folder and change ic_luncher by your image.
Intent i=new Intent(fierst.this,second.class);
startActivity(i);
}
});
Intent i=new Intent(fierst.this,second.class);
startActivity(i);
by executing these two line it will move to second activity so you can't able to see the result for image changed or not. To see the proper output for image change make these lines as comment
Hope this will helpful .thanks
How can I respond to an event based on clicking a disabled Button.
I have a requirement that I have to present Dialog, when a disabled Button is clicked but the listener I have assigned does not fire even when I setClickable(false)
Am an android noob, sorry.
You can for example use #setActivated() method instead. Disabling a view will ignore all events.
https://developer.android.com/reference/android/view/View.html#setActivated(boolean).
Then you can customize text and background styles with android:state_activate attribute if you need:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="false"
android:color="#color/a_color" />
<item android:state_activated="true"
android:color="#color/another_color" />
</selector>
A disabled button cannot listen to any event, but you can customize your own button by extending Button class to make your own definition of disabling
You can override onTouchEvent and create a listener like this :
class MyButton #JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.materialButtonStyle) : MaterialButton(context, attrs, defStyleAttr) {
private var onDisableClickListener: OnClickListener? = null
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (!isEnabled && event?.action == MotionEvent.ACTION_DOWN) {
onDisableClickListener?.onClick(this)
}
return super.onTouchEvent(event)
}
fun setOnDisableClickListener(l: OnClickListener?) {
onDisableClickListener = l
}
}
In your activity :
button.setOnDisableClickListener {
Toast.makeText(this), "The button is disabled", Toast.LENGTH_SHORT).show()
}
button.setOnClickListener {
Toast.makeText(this), "The button is enabled", Toast.LENGTH_SHORT).show()
}
Instead of disabling it, keep it enabled but use a flag to control your "inner state"
I solved this issue by using a flag to keep my button's state.
private boolean isMyButtonEnabled = false;
public void onMyButtonClick(View v) {
if(isMyButtonEnabled){
..
}
}
you can add android:allowClickWhenDisabled attribute to your button in xml like this:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:allowClickWhenDisabled="true"/>
I looked for it but got nothing to listen the EditText block. So I find another way to activate it. If there is a near button or area that you already listen, you can enable SetOnLongClickListener to activate the block. It will be a secret but you can tell the users.
button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
editText.setEnabled(true)
return true;
}
});
I'm about to tackle this by using the selected state, which is generally available for use in widgets, and can be used in state list drawables. A simple search for usage of isSelected turns up results in ListView, GridView, TextView and TabLayout. And the documentation states
Views are typically
* selected in the context of an AdapterView like ListView or GridView;
* the selected view is the view that is highlighted.
You should use activated state to enable or disable button . It is clickable or as someone point use selected or checked state. Each of these state has a different meaning so use it carefully
create in res/color/color_state.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#767C7F" android:state_activated="true" />
<item android:color="#CBCBCB" android:state_activated="false" />
<item android:color="#CBCBCB" />
</selector>
set textColor by:
android:textColor="#color/color_state"
set event click to change state color:
binding.format1.setOnClickListener {
binding.format1.isActivated = true
binding.format2.isActivated = false
binding.format3.isActivated = false
}
I have an ImageButton which on click i show a dialog box where users can either take a photo from the camera or choose from the gallery. On selecting image from either sources i setBitmap for that ImageButton to the image selected like this
SelectedPhoto = BitmapFactory.decodeFile(selectedImagePath);
DisplayPhoto.setImageBitmap(SelectedPhoto);
Now when some one has already selected an image and click the image again i want to show a different dialog which contains a third option "Remove Photo".
What property of the image button should i check and against what ?
ImageButton in XML
<ImageButton
android:id="#+id/DisplayPhoto"
android:layout_width="95dip"
android:layout_height="95dip"
android:layout_marginRight="8dip"
android:background="#drawable/signup_photo_selector" android:scaleType="centerCrop" />
ImageButton Background XML
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/signup_form_photo_selected" android:state_pressed="true"/>
<item android:drawable="#drawable/signup_form_photo"/>
</selector>
Would imgButton.getDrawable() work, since it returns null if no drawable has been assigned to the imagebutton?
If not, or if you don't want to get the entire drawable just to see if it's there, you can use a tag. imgButton.setTag(object) lets you store any object within the imagebutton... every time you set its background, you can tag a value that identifies whether its background was set. You could even use different values to differentiate whether you set its background using a camera or from the gallery, if that's useful. When you want to see if the imagebutton has a background or not, use imgButton.getTag() to retrieve the object.
Edit. Here is how you would use setTag and getTag. I will use an Integer object as the ImageButton's tag, where a value of 0 indicates no background has been set and a value of 1 indicates a background has been set. You can use an enum or final variables if you want to make the code a bit clearer, but using an Integer will work as an example.
public class MainActivity extends Activity, implements OnClickListener {
private ImageButton imgButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imgButton = (ImageButton)findViewById(R.id.imgID);
imgButton.setTag(new Integer(0)); // no background
...
}
public void onClick(View view) {
ImageButton ib = (ImageButton)view;
int hasBackground = ib.getTag().intValue();
if(hasBackground==0) {
// imagebutton does not have a background. do not include remove option
...
} else {
// imagebutton has a background. include remove option
}
}
}