I have to place an double click event on Image view..Whenever I double click on Image ,It sshould be Zoom.But I found that there is no such event like double click in Image Veiw.
Can Anyone Tell me How To DO it??
Thanks in Advance..
Try this approach:
add boolean doubleClick = false;
and Handler doubleHandler
in onClick check if doubleClick is true
if true, it is a double click
if not, set doubleClick to true and use the handlers postDelayed to set it back to false after i.e. 500ms
The easiest way is to use long variable instead handler
private var doubleClickLastTime = 0L
view.setOnClickListener {
if(System.currentTimeMillis() - doubleClickLastTime < 300){
doubleClickLastTime = 0
doAction()
}else{
doubleClickLastTime = System.currentTimeMillis()
}
}
whenever the onClick() is called the new instance of Handler is created, if the Handler object is instantiated inside onClick().
So, instantiate handler outside onClick().
boolean isDoubleClicked=false;
Handler handler=new Handler();
Runnable r=new Runnable(){
#Override
public void run(){
//Actions when Single Clicked
isDoubleClicked=false;
}
}
tv.setOnClickListener(new onClickListener){
#Override
public void onClick(View view){
if(isDoubleClicked){
//Actions when double Clicked
isDoubleClicked=false;
//remove callbacks for Handlers
handler.removeCallbacks(r);
}else{
isDoubleClicked=true;
handler.postDelayed(r,500);
}
}
}
Maaalte's answer helped me to write this code.
declare doubleClick variable globally
boolean doubleClick = false;
Logic to handle double click
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Runnable r = new Runnable() {
#Override
public void run() {
doubleClick = false;
}
};
if (doubleClick) {
//your logic for double click action
doubleClick = false;
}else {
doubleClick=true;
handler.postDelayed(r, 500);
}
}
});
You may use onDoubleTapListener.
This link may hep you.
Related
I am using following code for using a button. I works.(sendBtn is a button in a fragment)
sendText = view.findViewById(R.id.send_text);
View sendBtn = view.findViewById(R.id.send_btn);
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
Now i want to disable the button for 1 sec after a click
I found following solution but above code works "without onClick(View v)"method and without implementing View.OnClickListener in class. How to provide delay in such case..How code is working without onClick method.
#Override
public void onClick(View v) {
((Button) findViewById(R.id.click)).setEnabled(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
((Button) findViewById(R.id.click))
.setEnabled(true);
}
}, 1000);
}
});
Use this method when you want to interrupt user clicks:
private static long mLastClickTime = 0L;
public static boolean isOpenRecently() {
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) {
return true;
}
mLastClickTime = SystemClock.elapsedRealtime();
return false;
}
Usage:
if (v.getId() == R.id.sendBtn) {
if (isOpenRecently()) return;
// Your logic
}
Basically you are using lambda in your code, where v->{} represents the onCLick(View v) function.
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
You can do the following to disable the button for 1 second
void doOnSendButtonClick(View v){
//Send the message (your logic here)
send(sendText.getText().toString());
//Disable button
sendBtn.setEnabled(false);
//enable button after 1000 millisecond
new Handler(Looper.getMainLooper()).postDelayed(() -> {
sendBtn.setEnabled(true);
}, 1000);
}
And call this method when user clicks on the button
sendButton.setOnClickListener(view -> doOnSendButtonClick(view));
You could use a CountDownTimer.
CountDownTimewr timer = new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
// enable button
((Button) findViewById(R.id.click)).setEnabled(true);
}
}
#Override
public void onClick(View v) {
// disable btn and start timer of one second in millis
((Button) findViewById(R.id.click)).setEnabled(false);
timer.start();
}
});
Please try this way
Handler(Looper.getmainLooper()) and remove callback after you done your task inside runnable thread...also try to put this logic in any method outside in this class and call from setonclicklistener
Try the Timer.shedule with timertask
you can use runOnUIThread method inside where you can update UI.
you can also try to check the time difference of click and enable again in looping like while.
I'm building a simple counter, it has buttons to add or subtract from a total value, I want it to keep adding if I hold the button, incrementing +5 every second, but i'm having problems to make it work. I'm using onClickListener, but i can't find a way to make it work "together" with on touch listener.
pl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
lf++;
lt.setText(Integer.toString(lf));
}
}
You will have to use handler to schedule a runnable that increments +5 every 1 second (+1 per 200 milliseconds to keep it smooth)
Handler handler = new Handler();
Runnable incrementTask = new Runnable(){
#Override
public void run(){
lf++;
handler.postDelayed(incrementTask, 200); //Execute after 200 milliseconds
}
};
Then you implement onTouchListener and post this runnable when ACTION_DOWN is dispatched and cancel it when ACTION_UP is dispatched.
boolean buttonPressed = false;
pl.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
//This check is imporant since ACTION_DOWN might be called
// multiple times when finger is moving
if(!buttonPressed){
buttonPressed = true;
handler.post(incrementTask);
}
} else if(event.getAction() == MotionEvent.ACTION_UP){
if(buttonPressed)
{
buttonPressed = false;
handler.cancel(incrementTask);
}
}
return false;
}
});
Please note that this logic won't work well with your current click listener. For better user experience, I would recommend that you start this timer/runnable only when your button is long pressed. I had a similar situation in a project so I wrote a utility class to help me detect when a button is being held and released after a long click. Normal clicks work fine as well. You can find my ClickAndHoldManager class on Github.
To use it, you simply pass your view in the constructor and set a listener:
ClickAndHoldManager manager = new ClickAndHoldManager(myButton);
manager.setClickCallback(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Regular Click
}
});
manager.setHoldCallback(new ClickAndHoldManager.HoldListener() {
#Override
public void holdStarted() {
// do handler.post() here
}
#Override
public void holdEnded() {
//do handler.cancel() here
}
});
I have a button that when click shows a dialog. But when you click the button quickly in multiple times, it will show 2 or more dialog on the screen. Depends on how many times you click the button before dialog shows. So I have to close each dialog many times...
I already used dialog.isShowing but it seems that it will ignore it when you click the button quickly in multiple times.
...So I want to click button at a time when dialog is closed.
private var mFlag = false
fun myButton(view : View) {
var tempDialog = AlertDialog.Builder(this).create()
if (!mFlag) {
myDialog.show()
mFlag = true
}
if(dialog.isShowing){
mFlag = false
}
}
I have made public method for avoid double clicking issue on view.
Please check this method,
/***
* To prevent from double clicking the row item and so prevents overlapping fragment.
* **/
public static void avoidDoubleClicks(final View view) {
final long DELAY_IN_MS = 900;
if (!view.isClickable()) {
return;
}
view.setClickable(false);
view.postDelayed(new Runnable() {
#Override
public void run() {
view.setClickable(true);
}
}, DELAY_IN_MS);
}
You can use the method by following way,
buttonTest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(String clickedText) {
Utils.avoidDoubleClicks(alertViewHolder.tv_alert);
// Rest code here for onlick listener
});
Or another way is,
private long lastClickTime = 0;
View.OnClickListener buttonHandler = new View.OnClickListener() {
public void onClick(View v) {
// preventing double, using threshold of 1000 ms
if (SystemClock.elapsedRealtime() - lastClickTime < 1000){
return;
}
lastClickTime = SystemClock.elapsedRealtime();
}
}
I have a customView , i want to set onClick which will only be called on the very first click. In which i want to start a thread which will start a counter on other TextView , with simple onClickListener with each click a new threads starts which is a problem . How can i achieve such task ?
Another option is in your onClick() method do set a null listener, i.e.
#Override
public void onClick(View view) {
// disable any other clicks from now on
customView.setOnClickListener(null);
...
}
I think this is only logic problem, So I solve this problem by using a boolean variable for the first click:
boolean isFristClick = true;
#Override
public void onClick(View v) {
if (isFristClick) {
// Start your counter Thread here
isFristClick = false;
} else {
// Do nothing
}
}
What about making a workaround for that?!! like assigning a boolean value to tell if it's the first click:
private boolean first_click = true;
your_view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(first_click){
first_click = false;
// Do something on first click
}else{
// Do another thing on later clicks
}
}
});
I have an ImageButton in my application.
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="80dp"
android:layout_height="80dp"
android:clickable="true"
android:src="#drawable/button" />
I bind it to an onClickListener:
View.OnClickListener imgButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
// Here I update the image source to a different image.
}
};
Now what happens is: when I click the imagebutton, the imagebutton changes to a
different image. But I want it to change back automatically after 0.5 sec (during the
same time the user should not be able to click anything). How do I
implement that? I tried to sleep in the onClick function in the listener, but it's
not working...
New edit:
The proposed answer will solve my problem if I only have one imagebutton. I tried it out
and both work like charm!
Actually it is not working as expected. During that 500ms, the user still could click!
It is not solving the problem...
Posting a delayed runnable might do the job.
public void onClick(View v) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
(ImageButton)v.setBackgroundResource(R.drawable.someimage);
}
}, 500);
}
EDIT:
In fact, I've ran the following code on an actual device with two ImageButton and it works fine.
BTW, if you want the buttons to be un-clickable during the 500ms, just set it as imgBtn1.setClickable(false); and set it back to be clickable in the runnable as imgBtn1.setClickable(true);
public class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test_layout, container, false);
final ImageButton imgBtn1 = (ImageButton) view.findViewById(R.id.test_img_btn1);
final ImageButton imgBtn2 = (ImageButton) view.findViewById(R.id.test_img_btn2);
imgBtn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBtn1.setBackgroundResource(R.drawable.device_type_apple);
imgBtn1.setClickable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
imgBtn1.setBackgroundResource(R.drawable.device_type_windows);
imgBtn1.setClickable(true);
}
}, 500);
}
});
imgBtn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBtn2.setBackgroundResource(R.drawable.device_type_apple);
imgBtn2.setClickable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
imgBtn2.setBackgroundResource(R.drawable.device_type_android);
imgBtn2.setClickable(true);
}
}, 500);
}
});
return view;
}
}
You can use handle with runnable to auto update image
Handler mHandler = new Handler();
Runnable mUpdateTimer = new Runnable() {
#Override
public void run() {
// code update image here
// auto update after 0.5s
mHandler.postDelayed(mUpdateTimer, 500);
}
};
And when image button clicked:
View.OnClickListener imgButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
mHandler.postDelayed(mUpdateTimer, 500);
}
};
Handler.postDelayed
this method is not good way ,see http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable,long)
it say
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting. Note that a result of true does not mean the Runnable will be processed -- if the looper is quit before the delivery time of the message occurs then the message will be dropped.
so this methed may never invoke,it may be make you image button status never come back ,so you must be care the return value or use other widget ViewFliper,it can set animation when image switch and you can set delpoy .