I am using android eclipse for programming.
I will use this basic calculation to fit to what I want to happen.
Here:
I got two buttons add and minus. if i press add it will obviously call the method add.
But my problem is. if I will keep pressing add button. It will keep adding multiple times and
if I will click 2 buttons at the same time it will also do add and minus. What I want is that
if i click both button at the same time there's priority that add button will execute first
and the minus button will not send data.
Add(){
a = b + c;
}
Minus(){
a = b - c;
}
public void add(View view){
Add();
}
public void subtract(View view){
Minus();
}
Just set button_minus.setClickable(false); in Add method and
button_add.setClickable(false); in Minus method. Then enable them back.
try:
private boolean isAddButtonPressed;
private void setListener(){
buttonAdd.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
isAddButtonPressed = true;
else
isAddButtonPressed = false;
return false;
}
});
}
public void add(View view){
doMath(true);
}
public void subtract(View view){
if(!isAddButtonPressed)
doMath(false);
}
// "synchronized" means that this method can ran only one time at a time
private synchronized void doMath(boolean isAdd) {
if(isAdd) {
Add();
} else {
Minus();
}
}
Related
I have three text input layouts in my activity, I apply a listener on them and it changes background color when I click on it .but need to click again if I want to click the other two .my question is that how I implement such type of logic that when it 1st clicked and I click on one of the other two, the first one clickable color disappear and 2nd one or third one clicked and its background color change and same for others
View.OnClickListener listener = new View.OnClickListener() {
#SuppressLint("NonConstantResourceId")
#Override
public void onClick(View v) {
if (v.getId() == R.id.textViewLoseWeightSubtitle) {
if (mStateChanged) {
v.setBackgroundResource(R.drawable.textview_after_click);
// mLoseWgt.setTextColor(Color.WHITE);
mStateChanged = false;
mFittedToned.setClickable(false);
mBuildMuscle.setClickable(false);
} else {
v.setBackgroundResource(R.drawable.textview_outline_style);
//mLoseWgt.setTextColor(Color.parseColor("#363C60"));
mStateChanged = true;
mFittedToned.setClickable(true);
mBuildMuscle.setClickable(true);
}
}
if (v.getId() == R.id.textViewBuildMusclesSubtitle) {
if (mStateChanged) {
v.setBackgroundResource(R.drawable.textview_after_click);
// mLoseWgt.setTextColor(Color.WHITE);
mStateChanged = false;
mLoseWgt.setClickable(false);
mFittedToned.setClickable(false);
} else {
v.setBackgroundResource(R.drawable.textview_outline_style);
//mLoseWgt.setTextColor(Color.parseColor("#363C60"));
mStateChanged = true;
mLoseWgt.setClickable(true);
mFittedToned.setClickable(true);
}
}
if (v.getId() == R.id.textViewFittedAndTonedSubtitle) {
if (mStateChanged) {
v.setBackgroundResource(R.drawable.textview_after_click);
// mLoseWgt.setTextColor(Color.WHITE);
mStateChanged = false;
mLoseWgt.setClickable(false);
mBuildMuscle.setClickable(false);
} else {
v.setBackgroundResource(R.drawable.textview_outline_style);
//mLoseWgt.setTextColor(Color.parseColor("#363C60"));
mStateChanged = true;
mLoseWgt.setClickable(true);
mBuildMuscle.setClickable(true);
}
}
}
};
mLoseWgt.setOnClickListener(listener);
mBuildMuscle.setOnClickListener(listener);
mFittedToned.setOnClickListener(listener);
}
What you need is a onFocusChangedListener(). It gives a callback with a boolean which can be used to identify whether the current view is selected or not.
Declare it as:
View.OnFocusChangeListener listener = new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
v.setBackgroundResource(R.drawable.textview_after_click);
// mLoseWgt.setTextColor(Color.WHITE);
} else {
v.setBackgroundResource(R.drawable.textview_outline_style);
//mLoseWgt.setTextColor(Color.parseColor("#363C60"));
}
}
});
Set it as:
mLoseWgt.setOnFocusChangeListener(listener);
mBuildMuscle.setOnFocusChangeListener(listener);
mFittedToned.setOnFocusChangeListener(listener);
That's it. Your other code seems redundant. For EditText specific functions, you can typecast the view provided by onFocusChange().
I am trying to implement some button events without any reference to the XML-File and with databinding instead of FindByID. Is this possible? I am having the problem that, within the OnKeyListener, the bound InputBox from which I try to get the typed text seems inaccessible (this.binding shows in red color where I put it bold). Is this a wrong approach or am I making a mistake? I'd like to avoid all that FindByID-Lines.
this.binding =
DataBindingUtil.setContentView(this, R.layout.content_main);
this.binding.EditNumber.setText("553");
this.binding.EditNumber.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
Cat supertest = Manager.CreateMainCat(this.**binding**.EditNumber.toString());
this.**binding**.DisplayCurrentBudget.setText(supertest.getsName());
return true;
default:
break;
}
}
return false;
}
});
Thank you very much
Strangely, it works when I simply put the binding in another method:
(...)
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xxx();
}
});
}
public void xxx()
{
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
But this doesn't:
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
The propblem is solved easily, but I'd be very interested to know what's going if someone has the answer :)
I've tried a hundred different methods to implement a delay between automated button clicks, including thread.sleep, Handler.postDelayed, and so on… It could be I have used it incorrectly somehow. My most recent attempt was with a simple boolean toggle. It seems that no matter how I try, all the buttons that are to be automatically clicked happen at the same time after the delay, INSTEAD of being delayed between clicks.
my code as it stands now:
setting up button onClickListener:
for (int i = 0; i < mDifficulty; i++) {
ButtonsOCLArray[i].setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
animating = true;
while (animating) {
animateButtons(v);
}
}
});
}
animation of buttons:
public static void animateButtons(View v) {
AlphaAnimation fadeInAnimation = new AlphaAnimation(0F, 1F);
fadeInAnimation.setDuration(1500);
fadeInAnimation.setFillAfter(true);
v.startAnimation(fadeInAnimation);
animating = false;
}
and finally, from a separate class, the automatic button setup:
public void pushAiButton(final View [] v){
mWhichButton = (mGameAi.getRandomNumber(MainActivity.mDifficulty)); // get random number for random button to press
mListOfAiButtonsToPress.add(mWhichButton); // add random number to mLOABTP
mListOfAiButtonsTemp.addAll(mListOfAiButtonsToPress); // add all elements of mLOABTP to mLOABT
boolean empty = false;
while (!empty) {
if (empty) {
break;
}
tempArrayIndex = mListOfAiButtonsTemp.get(0); // tempArray given value in first slot of mLOABT
mListOfAiButtonsTemp.remove(mListOfAiButtonsTemp.get(0)); // first slot of MLOABT removed
if (mListOfAiButtonsTemp.isEmpty()) {
// looped through whole list, empty now
empty = true;
} // end if
v[tempArrayIndex].performClick(); // click button at index *button*[*index*]
} // end !empty while
} // end pushAiButton()
any ideas HIGHLY appreciated! thanks!
UPDATE
This got it working:
mButtonStart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
Log.d(TAG, "START BUTTON CLICKED!");
if (firstRun) {
mGameAi.setupAiButtons();
firstRun = false;
}
v.setVisibility(View.INVISIBLE);
animateButtons(ButtonsOCLArray[mGameAi.getFirstButtonInList()]);
mGameAi.deleteFirstButtonInList();
v.postDelayed(new Runnable() {
public void run() {
if (!mGameAi.buttonsListIsEmpty()) {
v.performClick();
}
else {
v.setVisibility(View.VISIBLE);
firstRun = true;
}
}
}, 500);
System.out.println("end of mButtonStart's onclicklistener");
}
});
You have coded it so that they all click nearly simultaneously. The automatic button setup does a "while" loop that iterates through all the buttons - removing them one at a time nearly simultaneously.
In other words, your while loop iterating through the buttons needs to pause (or not queue another click) until the animation is complete.
Here is the problem said another way; when each "onClick" occurs, the boolean "animateButtons" is true and they all enter into the animateButtons method.
You need to have a thread with a wait call on in pushAiButton and wait for each button to finish its animation.
I'm a student of Yonsei graduate school, Korea.
I want to make a simple application that measures an time interval - between
touching the screen and display-updating.
I found that following method catch the touching event.
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if(event.getAction() == MotionEvent.ACTION_DOWN ){
...
Now I'm searching the Android APIs, but I coudn't find the method which catches
display-updating event. If you have any information about this problem,
please show mercy to me. Thank you.
Try adding a ViewTreeObserver.onDrawListener to a view in your Activity's content view. You can make a class that implements the that interface. When you get the touch event, call a method on your draw listener to record the time of the next draw event.
private MyDrawListener myDrawListener = new MyDrawListener();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
findViewById(...).getViewTreeObserver().addOnDrawListener(myDrawListener);
}
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
myDrawListener.recordNextDrawTime();
}
}
public static class MyDrawListener implements ViewTreeObserver.OnDrawListener {
private boolean recordNextDrawTime;
public void recordNextDrawTime() {
recordNextDrawTime = true;
}
#Override
public void onDraw() {
if (recordNextDrawTime) {
Log.d("MyDrawListener", "Draw time = " + System.currentTimeMillis());
recordNextDrawTime = false;
}
}
}
Well I have made a custom Android UI, and I need my UI view to handle this control.
a) While my mouse button is pressed (onDown / Key pressed) , the view should keep doing a thing (For example : Key is down)
b) As soon as i release my mouse key , the view should say (example: Key is up).
The Sample Flow should be something like when I press the view.
Output:
(I press mouse button on the view and hold it)
Key is down
Key is down
Key is down
Key is down
Key is down
Key is down
(I now release mouse button)
Key is up.
To more explain my problem . I am posting a code snippet where the logic should go
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, event.getAction());
}
When I press my mouse button , it prints "0" (meaning mouse is down), while if i leave it , it prints on the log "1", meaning mouse is up. That should help with the logic.
Thanks for helping.
Well I have tried something like
private static int checkValue = 0;
#Override
public boolean onTouchEvent(MotionEvent event) {
checkValue = event.getAction();
while (checkValue == 0 ){
Log.d(TAG, "Pressed");
checkValue = checkMethod(event.getAction);
}
private int checkMethod(int test){
if (checkValue == 0){
checkValue = 0;
}
else checkValue = 1;
}
Just define an OnTouchEventListener...
private OnTouchListener onTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.button) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//start loop or background task
} else if (event.getAction() == MotionEvent.ACTION_UP) {
//do something different
}
}
return true;
}
}
...and assign it to your button.
button.setOnTouchListener(onTouchListener);
When the user touches the button the ACTION_DOWN event is fired. When the user releases the button, the ACTION_UP event is fired. If you want you can start a loop in a thread which can check against a boolean variable. I didn't check if it is correct but it should look like this:
private OnTouchListener onTouchListener = new OnTouchListener() {
private boolean flag = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.button) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
flag = true;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while(flag) {
//do something
}
}
});
thread.start();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
flag = false;
}
}
return true;
}
}
Maybe you could create and start a thread when the touch occurs that has a volatile boolean stop = false field and that checks for this value in every loop after sleeping for a while. When the touch ends, you can set the boolean variable to false.
Edit: added an example
private MyHandler h;
public void handleDown() {
System.out.println("touch began");
h = new MyHandler();
h.start();
}
public void handleUp() {
h.pleaseStop = true;
System.out.println("touch ended");
}
class MyHandler extends Thread {
volatile boolean pleaseStop = false;
public void run() {
while (!pleaseStop) {
System.out.println("touch is active...");
Thread.sleep(500);
}
}
}
checkValue = event.getAction();
while (checkValue == 0 ){
You should never ever be using magical integers. Use the constants as defined by the API:
http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_DOWN
In fact your code isn't even accounting for move events; it seems to assume that if it isn't a down event it is an up... which is completely wrong.
Look at the documentation to see what action values you can expect, and do the right thing for the specific actions you are interested in. For example up:
http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_UP
Create a thread which is initiated by the touch and have boolean flag to keep it alive. When the touch is released, set the flag to false so the thread joins (terminates).
Because the thread is independent from the main logic, the process is faster.