Changing background of button depending on current background - java

I'm trying to change the background of a button when it's clicked but also be able to change it back when it's clicked again. What I'm trying to do is get the buttons current background and if it is (xxxxx) then change it to (yyyyy). I can't seem to find how to get the button's current background and compare it to one of my drawable resources.
Any help would be much appreciated.
Some pseudo code of what I'm trying to do:
if (button1.getBackground() == R.drawable.someDrawable) {
button1.setBackgroundResource(R.drawable.someOtherDrawable);
}

I think this is the right way: link

I simple solution will be to have two drawables for background. One for non_pressed_selector and pressed_selector and just keep track if the button is pressed or not.
private boolean isPressed = false;
public void onClick() {
if (isPressed) {
// set not_pressed_selector
} else {
// set pressed_selector
}
isPressed != isPressed;
}

It seems that you need a ToggleButton instead of simple Button. You could use isChecked() method to determine the state of your button in OnClickListener and set your background there. Or you can define selector in xml as pedr0 said.

What I did was:
Declare the button in it's initial state:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/StateA"/>
</selector>
Then I manage the events from the code controling the actual state of the button with a tag:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.drawables_buttons); //This is the layout where it's the button
threeStateButton = (Button)findViewById(R.id.three_States_Button); //This is the button
threeStateButton.setOnTouchListener(new CustomTouchListener());
threeStateButton.setTag("StateA"); //Set the control tag
}
private class CustomTouchListener implements View.OnTouchListener
{
#Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_UP: //When you lift your finger
if (threeStateButton.getTag().equals("StateA"))
{
threeStateButton.setBackgroundResource(R.drawable.StateB);
Toast.makeText(view.getContext(), "This gonna change my state from StateA to StateB",Toast.LENGTH_SHORT).show();
threeStateButton.setTag("StateB");
}
else //If when you lift your finger it was already on stateB
{
threeStateButton.setBackgroundResource(R.drawable.red_button);
Toast.makeText(view.getContext(), "This gonna change my state from StateB to StateA",Toast.LENGTH_SHORT).show();
threeStateButton.setTag("StateA");
}
break;
//In case you want that you button shows a different state when your finger is pressing it.
case MotionEvent.ACTION_DOWN:
threeStateButton.setBackgroundResource(R.drawable.StateButtonPressed);
break;
}
return false;
}
}
I don't know if this is the best way to do it but it works, and yes, I'd like to know wich is the optimal way.

Related

android - make textView invisible

When my app starts, the user needs to touch on the screen before the real action starts. I have a textView which gives the hint to touch the screen.
After the screen is touched, I want the text to get invisible. Right now the textView never disappears and always stays in the front.
public class MainActivity extends Activity implements OnGestureListener
{
public boolean touched = false;
TextView mMyView;
public void onTouch()
{
mMyView.setVisibility(View.GONE);
touched = true;
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
mMyView = (TextView)findViewById(R.id.textView6);
if(touched == true)
{
}
}
}
1.Always use if(something) if you want to see if it's true/false instead of writing if(something == true) [something is a boolian assigned with value true.]
2.If you point your views xml to a method using android:onClick like below,
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="onTouch" />
.
What's the point of implementing OnGestureListener?
If i do this onCreate i initialize my view
View myView = findViewById(R.id.my_view);
3.If i really want a touch i will do this
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// ... Respond to touch events --> tv.setVisibility(View.INVISIBLE);
return true; // if you return false with this then the listener will not be called for the subsequent ACTION_MOVE and ACTION_UP string of events.
}
});
Now you can see in the 3rd ones parameter there is a MotionEvent, you can identify the motion ACTION_DOWN , ACTION_MOVE and ACTION_UP
Now think have you ever used them. You got an idea in your head about a touch so tried to use touch events .. But you don't use them. So it does the same as what onClickListner does in your case. If you want motions use that 3rd one i gave.
But simply you can use
// view is the background layout
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here --> Hide your text tv.setVisibility(View.INVISIBLE);
}
});
Those view onClickListner or setOnTouchListener you can directly use them inside onCreate or keep them inside a method and you can call that method from onCreate. Why to keep a boolean? It's nothing major
Note i considered myView as the background layout not your textView , background is the one you click / touch
So now you changed the questions code several times and I hope it´s the final change. Only than my answer could help.
You have done this in your onCreate():
if(touched == true)
{
tv.setVisibility(View.INVISIBLE);
}
But this is executed directly and has nothing to do with you onTouch() method. Let´s assume your onTouch() works correctly. Make the TextView global:
TextView mMyView;
initialize it in onCreate():
mMyView = (TextView)findViewById(R.id.textView6);
and then hide it in onTouch():
onTouch(View view){
mMyView.setVisibility(View.GONE);
}
But you have to be sure that your method onTouch() works. You can make a Toast or a Log to check. You have to be sure that:
-The TextView is inside your layout xml that you set with setContentView(R.layout.activity_game);
-The onTouch() method is declared in your TextView's xml attribute
android:onClick="onTouch"
and set clickable of your TextView to true:
android:clickable="true";
EDIT
If you implement onGestureListener() I guess the touch event is consumed by the listener and your TextView did not recognize onTouch(). If you don´t do any gesture detection in your activity, then remove this implementation.
You are checking if screen was touched in onCreate() which is called only once at the start of the activity. Initialize TextView globally and set its visibility inside onTouch(View v, MotionEvent event)
Also your onTouch() isn;t correct. You should override public boolean onTouch(View v, MotionEvent event)
public class MainActivity extends Activity
{
public boolean touched = false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
TextView tv = (TextView) findViewById(R.id.textView6);
tv.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
touched = true;
tv.setVisibility(View.INVISIBLE);
return true;
}
});
}
}
Instead of implementing OnGestureListener add a setOnTouchListener in your root view of your activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlTestView"/>
For example rlTestView is your activity's root layout id, then use below code in your oncreate method
((RelativeLayout)findViewById(R.id.rlTestView)).setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
tv.setVisibility(View.GONE);
return true;
}
});`
Use the code below on the onCreate method and yes set the visibility as GONE instead of invisible. Also state the current visibilty of the TextView in the onTouch then set it to
tv.setVisibility(View.GONE);

Can a ToggleButton change the functionality of other buttons in the same Activity?

Summed up, can a ToggleButton change what other buttons in the activity do when toggled? If so, a more specific explanation of what I want to do is below:
Basically there are three buttons and a togglebutton. When the togglebutton is toggled, pressing any of the three buttons will take a picture and 'save it' for that button. When untoggled, pressing any of the three buttons simply displays their images. I think I can figure out the camera capture part, but I need some direction when it comes to the togglebutton.
Any help is appreciated and I can explain further if necessary.
What I would do is keep a couple flags for each state at the class level, like this:
public class MyClass {
private static final int STATE_SAVE = 0;
private static final int STATE_DISPLAY = 1;
private int currentState = STATE_DISPLAY;
// I made this default for the example,
// you should use what makes sense to your project.
}
Then, inside your toggle button, you can set the flag. Paraphrasing this code since I don't have an editor open:
toggleButton.setOnToggleListener(new OnToggleListener() {
#Override
public void onToggled(boolean toggled) {
if(toggled) {
currentState = STATE_SAVE;
} else {
currentState = STATE_DISPLAY;
}
});
Now, when the buttons are clicked, you can switch based on the state to do an action:
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(currentState == STATE_SAVE) {
// Save the image.
} else if (currentState == STATE_DISPLAY) {
// Display the image.
}
});
Create a boolean such as isToggleOn that is true or false depending on the ToggleButton. Then for each of your buttons, you can simply do:
Button button1 = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isToggleOn){
//do one thing
} else {
//do other thing
}
}
});
Yes, you definitely can. Very rarely is anything impossible with code!
All you have to do is to change the listener of the three buttons when the togglebutton is pressed. You keep alternating between the listeners each time you toggle.
For your purpose, I'd suggest defining two sets of listeners - two for each of the three buttons and then keep changing between them.

How do I get an image view to continually move across the screen when a button is held down?

I have searched high and low for an answer to this and can't find one anywhere that works.
For my university assignment i need to create an adventure game in android studio. I want it so when I click down and hold an arrow button (so in the case given its the up button), that the ImageView (player) will continually move across the screen until I release the button. Ive tried OnTouchListeners and mouse events using ACTION_UP and ACTION_DOWN and that works but not for what i need as it still only moves one step when clicked.
ImageView IV_player;
Button ButtonUp;
IV_player = (ImageView) findViewById(R.id.IV_player);
ButtonUp = (Button) findViewById(R.id.ButtonUp);
ButtonUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
IV_player.setY(IV_player.getY() - 32);
}
});
Treat your touch listener like a state machine. When an ACTION_DOWN event occurs, start doing whatever action you want to do. When an ACTION_UP/ACTION_CANCEL event occurs stop your action. So how do you go about implementing this?
Your state flag can be a simple boolean:
boolean shouldCharacterMove = false;
Define your touch listener for the view.
ButtonUp.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
setShouldCharacterMove(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
setShouldCharacterMove(false);
break;
}
return true;
}
});
Before we define setShouldCharacterMove we need to figure out a way to move items. We can do this through a Runnable that runs after X milliseconds.
private final Runnable characterMoveRunnable = new Runnable() {
#Override
public void run() {
float y = IV_player.getTranslationY();
IV_player.setTranslationY(y + 5); // Doesn't have to be 5.
if (shouldCharacterMove) {
IV_player.postDelayed(this, 16); // 60fps
}
}
};
Now we can define setShouldCharacterMove:
void setShouldCharacterMove(boolean shouldMove) {
shouldCharacterMove = shouldMove;
IV_player.removeCallbacks(characterMoveRunnable);
if (shouldMove) {
IV_player.post(characterMoveRunnable);
}
}

How to go about having a button and a custom paint view on the same screen? android

I am pretty new to android and am trying to build an app where the user can draw a letter, press a button that connects a service that reads it, and then the letter is displayed back to them.
This is my main layout:
!(http://i58.photobucket.com/albums/g271/billmoney3/layout_zps71eb45ca.jpg)
I want the user to be able to draw in the blue area. I made the blue area a custom view called InnerDrawingView. I need help on how to organize the views and the OnTouchListener.
Right now I have this java code:
public class DoodleActivity extends Activity {
Button confirmButton;
EditText drawingResult;
InnerDrawingView innerView;
// on create
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doodle); // main layout
// where the drawing happens
innerView = (InnerDrawingView) findViewById(R.id.innerDrawingView1);
innerView.setOnTouchListener(handleTouch);
...
...
// handle the touching of the inner view
private OnTouchListener handleTouch = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
drawingResult.setText("O RLY?!"); // just a test
return true;
}
}; // end of class
Is this the correct way to go about it? What kind of touch listener do I put in the InnerDrawingView class? Can I just call: innerView.onTouch() from inside my main activity's onTouch()? Or the onDraw() method? If someone could direct me to a good paint tutorial also that would help me a lot.
Thanks for the input.
You need to pull x and y from the "event" object. Then the code depends on your needs. You can connect a new point with the previous one (to make a segment) or just put it in the list. Pseudo-code:
public boolean onTouch(View v, MotionEvent event) {
innerView.submitNewPoint(event.getX()), event.getY());
return true;
}
If you want to handle multi-touch events you need to retrieve points count ( event.getPointerCount() ) and do something with coords from event.getX(i)/event.getY(i) (i - index of multi-touch event point).
Of cause you need to implement drawing of the points/segments/? list in the InnerDrawingView.
P.S. do not forget to make you fields private ;)

make RadioGroup to check button on ACTION_DOWN

i managed to do that by adding "actionDownChecker" on every RadioButton.
private View.OnTouchListener actionDownChecker = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN){
mTabbar.check(view.getId());
}
return true;
}
};
public void add(int radioButtonResourceId, Class<? extends Fragment> contentClass) {
mContent.put(radioButtonResourceId, new TabInfo(radioButtonResourceId, contentClass));
//hack to check radio button on ACTION_DOWN, not UP!
mTabbar.findViewById(radioButtonResourceId).setOnTouchListener(actionDownChecker);
}
Is there another more elegant way to do that?
The only other way I would know how to do it, is to physically change the code in the Listener. I'm not the smartest guy when it comes to developing for android, but the default constructor sets the boxes attached to RadioButtons to check on release.
Unless someone else knows something I don't, you either have to modify the listener class, or modify the entry after the listener has been evoked (by adding your actionDownCheker). Personally if it was me, i would just copy and paste your actionDownChecker, that way your listener class isn't messed up for your next project.
I'm sure there are some applications for it, but I'm not sure why you would want to do that. If someone presses down on the wrong button, they can just move off the button before it is released to cancel the press.

Categories

Resources