I would like to start a timer that begins when a button is first pressed and ends when it is released (basically I want to measure how long a button is held down). I'll be using the System.nanoTime() method at both of those times, then subtract the initial number from the final one to get a measurement for the time elapsed while the button was held down.
(If you have any suggestions for using something other than nanoTime() or some other way of measuring how long a button is held down, I'm open to those as well.)
Thanks!
Andy
Use OnTouchListener instead of OnClickListener:
// this goes somewhere in your class:
long lastDown;
long lastDuration;
...
// this goes wherever you setup your button listener:
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
lastDown = System.currentTimeMillis();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
lastDuration = System.currentTimeMillis() - lastDown;
}
return true;
}
});
This will definitely work:
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
increaseSize();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
resetSize();
}
return true;
}
});
In onTouchListener start the timer.
In onClickListener stop the times.
calculate the differece.
Related
I have an editText which is disabled and I want to enable it when I touch it.
Here is what I've done but it doesn't work :
if(textmail.isEnabled() == false){
textmail.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
textmail.setEnabled(true);
return true;
}
});
}
i read your use-case carefully you want to disable your TextView and want to disable it onTouch() (Correct me if i am wrong)
Here's a solution instead of using setEnabled() as if you set it onTouch() is not called so better to do it manually by declaring a global variable(boolean) in your (View/activity/fragment/class) where you are writing the logic.
//this as global variable
private boolean isTextViewDisabled=false;
//place this code on onCreate()
textmail.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN ){
if(isTextViewDisabled){
return false;
}
}
return true;
}
});
Set your isTextViewDisabled to true and false when needed as per your use-case.
But confusion here is condition for enabling and disabling should be something else not the touch event as according to your use case code should be like below:
//place this code on onCreate()
textmail.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN ){
if(isTextViewDisabled){
isTextViewDisabled=false;
}
}
return true;
}
});
The above code doesn't make a lot of sense until you explain why you want to disable the textView
If you disable the Edittext, it will not trigger the events i.e. onTouch/onClick. In order to tackle this issue, you need to avoid using disable and use clickable instead. textmail.setClickable(false); within your onCreate method.
To make the component look like it has been disabled, you can also work with the Alpha value where you are to reduce the opacity of the component to make it look faded away.
textmail.setAlpha(0.5f);
Now it should response to your listener...
textmail.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
textmail.setClickable(true);
textmail.setAlpha(1f);
return false;
}
});
try this i hope this help
textmail.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(textmail.isEnabled() == false){
textmail.setEnabled(true);
}
return true;
}
});
my problem is :
As in the Instagram's Video recording activity, I whant to perform an action(record audio) for the time that a button is pressed..
than when the button is released i whant to perform another action (the saving of the audio file and the release of the resoruces)
thaks you in advantage
You can use OnTouchListener :
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if(arg1.getAction() == MotionEvent.ACTION_DOWN) {
//start recording
}
else if(arg1.getAction() == MotionEvent.ACTION_UP) {
//stop recording
}
return true;
}
});
What I am looking for is to have a button where:
If you just push it, does nothing.
If you push and hold it for, let's say, 3 seconds, perform an action().
Any idea of what to do?
Thank you in advance.
If you want to be able to specify the time, here is an implementation of OnTouchListener that does that for you, without using a Timer:
class TimedTouchListener implements OnTouchListener{
private final long millisRequired = 3000;
private long downTime;
#Override
public boolean onTouch(View v, MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
downTime = System.currentTimeMillis();
return true;
break;
case MotionEvent.ACTION_UP:
long upTime = System.currentTimeMillis();
if( upTime - downTime > millisRequired ){
doAction(); //doAction can be a method call, or any code you want to be executed.
return true;
}else{
return true;
}
}
return false;
}
}
If you don't need to specify the time, just go with an OnLongClickListener as suggested by others.
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
// remeber here that ACTION_DOWN has occured
// set the timer for 3 seconds
// if ACTION_UP occured and timer has elapsed, then call action().
}});
or as ntc noticed, you can use OnLongClickListener instead.
Thats what the LongClickListener is for: http://developer.android.com/reference/android/view/View.OnLongClickListener.html
on finger down start a 3 second timer.
on finger up if timer is still active cancel it.
on timer expire run action.
brown = (Button) findViewById(R.id.brownButton);
brown.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
count++;
Log.d("count", "" + count);
return true;
} else if (event.getAction() == (MotionEvent.ACTION_UP)) {
count--;
Log.d("count", "" + count);
return true;
}
return false;
}
});
When my finger presses and holds the button my count will only increment ONCE. When I let go it will decrement accordingly. Please can someone show me how I can get my code to increment as long as my finger is holding the button down. Thanks.
A touch listener works like this:
It receives a ACTION_DOWN event (the user touches)
It then receives all the following events (if true is returned) and treats all the following events as ACTION_MOVE events
The touch lisetener keeps receiving ACTION_MOVE events until it receives an ACTION_UP or ACTION_CANCEL event.
So ACTION_DOWN is only triggered once, then any number of ACTION_MOVE events, then either a single ACTION_UP or ACTION_CANCEL.
If you want your counter to increment you need to check for ACTION_MOVE events.
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
//do something on DOWN
break;
case MotionEvent.ACTION_MOVE:
//do something on MOVE
break;
case MotionEvent.ACTION_UP:
//do something on UP
break;
}
return true;
}
I also needed to do this, but this question was never adequately answered, even though it is fairly old. However, a good solution can be found here: android repeat action on pressing and holding a button
I am adapting that solution to this problem. I tested it and it works for me.
Button brown = (Button) findViewById(R.id.brownButton);
brown.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
private int count = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mHandler != null)
return true;
mHandler = new Handler();
mHandler.postDelayed(mAction, 500);
break;
case MotionEvent.ACTION_UP:
if (mHandler == null)
return true;
mHandler.removeCallbacks(mAction);
mHandler = null;
break;
}
return true; // before I had written false
}
Runnable mAction = new Runnable() {
#Override
public void run() {
Log.d("count: ", "" + count);
count++;
mHandler.postDelayed(this, 500);
}
};
});
In the future I will apply this solution to a custom soft keyboard to allow the space and delete keys to continue working when being held down.
Update: Today I finally got around to making the continuous delete key. I thought I had tested my above code before, but today when I was doing it I had to return true from the onTouch method in order to get it to work.
I want to capture two events from a relativeLayout. When the user clicks it and when the user releases his click (like mousedown/mouseup)
rl.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//
}
});
I tried setting up something like:
if(event == MotionEvent.ACTION_DOWN) {
}
But eclipse just throws an error about an incompatible operand type. Anyone who knows how to do this?
Try...
if (event.getAction() == MotionEvent.ACTION_DOWN) {
...
}