I've one menu button and a motion class for a longer state_pressed state (0,5 sec.). So long all works fine, but one problem occurs :
I've to press first time on my button, state_pressed doesn't work at this first time then on the second attempt my code works correctly and state_pressed works with 0,5 seconds duration.
How can I make it that it works on the first press? I think tehre is a problem with the hover.xml file and in combination with the setBackgroundDrawable?
Thanks all in advance for ur help!
This is my hover.XML drawable
<?xml version="1.0" encoding="utf-8"?>
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/buttonstyle_pressed" />
<item android:drawable="#drawable/buttonstyle" />
And this is my java code
Button menubutton_start;
menubutton_start = (Button) FindViewById(R.id.menustart);
menubutton_start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
menubutton_start.setBackgroundDrawable(getResources().getDrawable(R.drawable.hover));
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Intent myIntent = new Intent(GameActivity.this, NextActivity.class);
GameActivity.this.startActivity(myIntent);
}
}, 500); // end of Handler new Runnable()
} // end of OnClick()
}); // end of setOnClickListener
The pressed state will happen automatically if you apply that style to the button.
You shouldn't have to manually set the pressed state in your code at all.
Related
I'm making an app that has buttons and when a button is clicked, it will play a sound. My problem is that I couldn't find a way to change mSoundButton's background when pressed and released. I'm using 'background' instead of 'src' so I can shrink the button without cutting from edges. I haven't added sounds yet because I want to solve this issue before starting to add sounds.
Here is my codes for the button in MainActivity.java (It works okay, but not in the way I wanted. It changes background when pressed but not released.)
final ImageButton mSoundBtn;
final boolean[] soundBtnClicked = {false};
mSoundBtn = findViewById(R.id.soundButton);
mSoundBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(soundBtnClicked[0])
mSoundBtn.setBackgroundResource(R.drawable.button_clicked);
else
mSoundBtn.setBackgroundResource(R.drawable.button_not_clicked);
soundBtnClicked[0] = !soundBtnClicked[0];
}
});
and here is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="#+id/soundButton"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#drawable/button_not_clicked"
android:contentDescription="TODO" />
</LinearLayout>
UPDATE (PROBLEM SOLVED):
I wanted the mSoundBtn to change image when pressed, then change image again when it is released. I used the Handler class and the postDelayed() method to create a delay between two image changes. It doesn't actually wait for user to release the button but still solved my issue. Following is the solution I found:
public ImageButton mSoundBtn;
Handler h = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSoundBtn = findViewById(R.id.soundButton);
mSoundBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mSoundBtn.setBackgroundResource(R.drawable.button_clicked);
h.postDelayed(new Runnable() {
public void run() {
mSoundBtn.setBackgroundResource(R.drawable.button_not_clicked);
}
}, 1000); // 1 Second
}
});
What happens is when the mSoundBtn is clicked, It changes image and waits for 1000 milliseconds (1 second), then changes back to previous image which creates some kind of animation when it is pressed so the user can understand when the button is pressed.
Thanks for anyone who have tried to help, thanks for reading. :)
You shouldn't define it as 'final'
Sample:
public class SampleActivity extends AppCompatActivity {
//Variables
public ImageButton mSoundBtn;
public boolean isSoundBtnSelected = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
mSoundBtn = findViewById(R.id.soundButton);
mSoundBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(!isSoundBtnSelected)
mSoundBtn.setBackgroundResource(R.drawable.button_clicked);
else
mSoundBtn.setBackgroundResource(R.drawable.button_not_clicked);
isSoundBtnSelected = !isSoundBtnSelected;
}
});
}
}
If I understand you correctly, you want an action to be done after the user removed the finger from the button (meaning the press is done).
Try using OnTouchListener instead of OnClickListener:
imageButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_UP)
{
// change background and other stuff...
return true;
}
return false;
}
});
If you only wanted to change the button's background when it pressed, you can use a selector drawable for that, like so:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#color/black" /> <!-- pressed -->
<item android:state_activated="true"
android:drawable="#color/colorAccent" /> <!-- focused -->
<item android:drawable="#color/colorPrimary" /> <!-- default -->
and just place it as the button's background.
Another option is to use a toggle button and OnChecked listener and change the background when the user checks (press) the button. If you want the background to be permanently changed after the first toggle you can implement this by changing the background only after the first toggle.
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);
...
}
I have a project which a activity have more than 1000 buttons. i am updating the background color of these buttons after taking the color information from the database. This whole process is a very big process and took 8 seconds to load my activity.
i have implement Asynctask for that but the problem is with this exception because "Only the original thread that created a view hierarchy can touch its views". because my long operation is on that part where i am updating my UI elements
After that i have implemented a thread that runs on UIthread for updating ui elements, this works fine according to its function, this thread update my ui but it stucks my application for 5-6 seconds. and then i thought of implementing a progress dialog for that 5-6 seconds. but if i implement progress dialog on runOnUiThread(new Runnable(){} it doesn't work. because updating ui and progress dialog runs on the same time. so progress dialog flashes for few milliseconds. and the activity still remains the same as it was before.
I don't know that to use for updating ui if they took long time to update.
This is my code where i update by ui elements from database.
for (int i = 0; i < list.size(); i++) {
Button btn = list.get(i);
Platform p = db.setplatformncolor(btn.getTag().toString());
String color = p.getColor();
if (color.equals("red")) {
btn.setBackgroundColor(Color.RED);
}
if (color.equals("green")) {
btn.setBackgroundColor(Color.rgb(0, 176, 80));
}
Any help is appreciated.
Thanks.!!
the for loop take two long time, try to just put the loop in thread and setBackgroundColor in ui thread.
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < list.size(); i++) {
final Button btn = list.get(i);
Platform p = db.setplatformncolor(btn.getTag().toString());
String color = p.getColor();
if (color.equals("red")) {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.RED);
}
});
}
if (color.equals("green")) {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.rgb(0, 176, 80));
}
});
}
}
}
}).start();
You can declare a green button theme and a red button theme like this
<style name="RedButton" parent="#android:style/Widget.Button">
<item name="android:background">#android:color/holo_red_light</item>
</style>
<style name="GreenButton" parent="#android:style/Widget.Button">
<item name="android:background">#android:color/holo_green_light</item>
</style>
Then just apply the theme. The system will automatically apply your background color for all buttons. See here if want more details about themes switching.
AsyncTask can fix your problem. the most time consuming operation in this code is
db.setplatformncolor(btn.getTag().toString());
so you have to move this line into doInBackground() method and after adding to DB call publishProgress() also you should implement onProgressUpdate() and change your button backgrounds in this method
this might be a bit tricky and complex solution for starters , but is efficient and applicable to your requirement.
Android has launched DataBinding Library, which will update your XML dynamically , try it
https://developer.android.com/topic/libraries/data-binding/index.html
If your app api level >=11 and if you only need two colors, then you can create a drawable xml for your buttons' background like:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/red" android:state_activated="false" />
<item android:drawable="#color/green" android:state_activated="true"/>
and then just change btn.setActivated(true/false);
I am generating my buttons programmatically.I want to change the background of the clicked button to menuitemsactivity_button_backgrnd.
The default background of the buttons is popup. I have done the following coding but the problem is that when I click the first button it changes its background, then when I click the second button the second button changes its background but the first button has the same menuitemsactivity_button_backgrnd background.
What I want to do is change the background of only the clicked button i.e at a time only one button has menuitemsactivity_button_backgrnd background.
I am posting my codes please guide me step by step:
final Button tv1 = new Button(this);
tv1.setId(i);
tv1.setText(value);
tv1.setTextSize(35);
tv1.setTextColor(Color.parseColor("#1569C7"));
tv1.setGravity(Gravity.CENTER);
tv1.setBackgroundDrawable(getResources().getDrawable(R.drawable.popup));
tv1.setLayoutParams(new LinearLayout.LayoutParams(300,90));
tv1.setOnClickListener(getOnClickDoSomething(tv1));
l1.addView(tv2);
private OnClickListener getOnClickDoSomething(final Button tv1) {
// TODO Auto-generated method stub
return new View.OnClickListener() {
public void onClick(View v) {
String text = tv1.getText().toString();
Log.e("text message", "" + text);
tv1.setBackgroundDrawable(getResources().getDrawable(R.drawable.menuitemsactivity_button_backgrnd));
Toast.makeText(MenuItemsActivity.this, "clicked"+v.getId()+","+tv1.getId(), 1000)
.show();
}
};
}
menuitemsactivity_button_backgrnd
<?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/blue_tab"
/>
</selector>
try doing something like this :
"<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/blue_tab"
/>
<item android:state_pressed="false"
android:drawable="#drawable/whatever_the_unselected_drawable_is"
/>
</selector>"
I created a button in the layout . In the Drawable folder I created a XML file named btn01_state. The btn01_state.xml is assigned to the button i created through "android:background=#drawable/btn01_state"
Now, the button has a default image img1.when i click on the button, the image1 changes to img2, and once i release the clicked mouse button, the image2 again changed to img1 again.
what i want to do is,to change the image of the button with evey click.
for an example, initially
btn01 has img01
if btn01 is pressed==> set img of btn01 to img02 and keep img02 till the btn01 is pressed again. Now, btn01 has img02 on it.
When btn01 is pressed, set img01 to btn01.
I hope this clarified more what i want to do.
btn_selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/android_blue"
android:state_pressed="true" />
<item android:drawable="#drawable/ic_launcher"
android:state_focused="true" />
<item android:drawable="#drawable/ic_launcher" />
main.xml
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/btn01"
android:background="#drawable/btn01_state"/>
You can do it easily within the code.
boolean isPressed = false;
button.setOnClickListener(buttonListener);
OnClickListener buttonListener = new OnClickListener() {
#Override
public void onClick(View v) {
if(isPressed)
button.setBackgroundResource(R.drawable.icon1);
else
button.setBackgroundResource(R.drawable.icon2);
isPressed = !isPressed;
}
};
Simple way
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
btn.setBackgroundDrawable(getResources().getDrawable(R.drawable.locationbutton_on));
}
});
Make it in code perhaps. Put a listener on the button and when the button is clicked the background is changed.