i want to do some thing like instagram app when user double tab on photo it make like and while he just tab one time it open as full screen
6 Answers
If you don't need to prevent single click to be fired, you can do much more simple:
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
long currTime = System.currentTimeMillis();
if (currTime - mLastClickTime < ViewConfiguration.getDoubleTapTimeout()) {
onItemDoubleClick(adapterView, view, position, l);
}
mLastClickTime = currTime;
}
public void onItemDoubleClick(AdapterView<?> adapterView, View view, int position, long l) {
ToastHelper.showToast("Double click");
}

- 1,611
- 1
- 23
- 31
-
3A really good answer, however you do not check that the position is the same as Last position, so you could potentially "double click" via two different items. aka swapping between items fast. – IAmGroot Feb 12 '16 at 11:09
-
Very nice answer, however you have to initialize lastClickTime as below in onCreate method; lastClickTime = System.currentTimeMillis(); – amoljdv06 Feb 17 '20 at 06:45
If you don't want to use a GestureListener
for every list item or a GestureListener
for the ListView
which then needs to determine the item located under the double tap area you can use the following extension to the onItemClickListener
.
This implementation waits to confirm a single click so it introduces single click latency.
private Object mClickedItem;
@Override
public void onItemClick(final AdapterView<?> adapter, final View view, final int index, final long id) {
synchronized (DoubleClickAdapter.this) {
if(mClickedItem != null && mClickedItem.equals(getItem(index))) {
mClickedItem = null;
onDoubleClick(adapter, view, index, id);
return;
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
synchronized (DoubleClickAdapter.this) {
if(mClickedItem != null) {
mClickedItem = null;
DoubleClickAdapter.super.onItemClick(adapter, view, index, id);
}
}
}
}, ViewConfiguration.getDoubleTapTimeout());
mClickedItem = getItem(index);
}
}
This implementation doesn't wait to confirm a single click, it fires a single click event on the first click of a double click:
private Object mClickedItem;
@Override
public void onItemClick(final AdapterView<?> adapter, final View view, final int index, final long id) {
synchronized (DoubleClickAdapter.this) {
if(mClickedItem != null && mClickedItem.equals(getItem(index))) {
mClickedItem = null;
onDoubleClick(adapter, view, index, id);
return;
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
synchronized (DoubleClickAdapter.this) {
mClickedItem = null;
}
}
}, ViewConfiguration.getDoubleTapTimeout());
mClickedItem = getItem(index);
DoubleClickAdapter.super.onItemClick(adapter, view, index, id);
}
}

- 25,714
- 24
- 124
- 186
-
I think that the first implementation is mostly why most are looking for. It works very well. – Maxime Claude Dec 14 '17 at 20:42
I made this one based on Graeme's answer, it's works for me.
class VibinOnItemClickListener implements OnItemClickListener {
private boolean nonDoubleClick = true;
private long firstClickTime = 0L;
private final int DOUBLE_CLICK_TIMEOUT = 200;//ViewConfiguration.getDoubleTapTimeout();
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
// @TODO check and catch the double click event
synchronized(VibinOnItemClickListener.this) {
if(firstClickTime == 0) {
firstClickTime = SystemClock.elapsedRealtime();
nonDoubleClick = true;
} else {
long deltaTime = SystemClock.elapsedRealtime() - firstClickTime;
firstClickTime = 0;
if(deltaTime < DOUBLE_CLICK_TIMEOUT) {
nonDoubleClick = false;
this.onItemDoubleClick(parent, view, position, id);
return;
}
}
view.postDelayed(new Runnable() {
@Override
public void run() {
if(nonDoubleClick) {
// @TODO add your logic for single click event
}
}
}, DOUBLE_CLICK_TIMEOUT);
}
}
public void onItemDoubleClick(AdapterView<?> parent, View view, int position, long id) {
// @TODO override this method with your own logic
}
}

- 1
- 1

- 91
- 1
- 11
You can use the code below (lvData
is a ListView
variable):
int previousPosition=-1;
int count=0;
long previousMil=0;
private void addEvents() {
lvData.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(previousPosition==position)
{
count++;
if(count==2 && System.currentTimeMillis()-previousMil<=1000)
{
Toast.makeText(MainActivity.this,"Double tap at"+position,Toast.LENGTH_SHORT).show();
count=1;
}
}
else
{
previousPosition=position;
count=1;
previousMil=System.currentTimeMillis();
}
}
});
}

- 1,328
- 4
- 16
- 20

- 16
- 1
-
It's did not work. When i tap an item in every 1.5 sec then the count just increasing and increasing... and never will appear the Toast. – Abigail La'Fay May 02 '19 at 11:42
if ()//add this block
else if(count>=3){previousMil2=System.currentTimeMillis();
you can not change click another row thne click selected row.This code prevent click another view then you want to click row.
then change if control
if(count>=2 && (System.currentTimeMillis()-previousMil<=1000 ||System.currentTimeMillis()-previousMil2<=1000) )

- 965
- 12
- 27

- 1
- 1
Using @Graeme's answer I came up with this: DoubleTapListViewItem.class:
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AdapterView;
import android.widget.ListView;
import com.badoo.mobile.util.WeakHandler; //or any other handler
public class DoubleTapListViewItem {
private Object mClickedItem;
private WeakHandler handler;
private ListView listView;
private DoubleTapListViewItemInterface doubleTapInterface;
public DoubleTapListViewItem(final AdapterView<?> parent, final View view, final int position, final long id, final WeakHandler handler, final ListView listView, final DoubleTapListViewItemInterface doubleTap){
if(handler == null)
throw new NullPointerException("handler must not be null");
this.handler = handler;
if(listView == null)
throw new NullPointerException("listView must not be null.");
this.listView = listView;
if(doubleTap == null)
throw new NullPointerException("doubleTap must not be null. The calling class should implement DoubleTapListViewItemInterface.java");
doubleTapInterface = doubleTap;
onItemTouch(parent,view,position,id);
}
public void onItemTouch(final AdapterView<?> parent, final View view, final int position, final long id){
synchronized (listView){
if(mClickedItem != null && mClickedItem.equals(parent.getItemAtPosition(position))) {
mClickedItem = null;
doubleTapInterface.onItemDoubleClick(parent, view, position, id); //double tap action
return;
}
handler.postDelayed(new Runnable() {
@Override
public void run() {
synchronized (listView) {
if(mClickedItem != null) {
mClickedItem = null;
doubleTapInterface.onItemClick(parent, view, position, id); //single tap
}
}
}
}, ViewConfiguration.getDoubleTapTimeout());
mClickedItem = parent.getItemAtPosition(position);
}
}
}
The DoubleTapListViewItemInterface:
import android.view.View;
import android.widget.AdapterView;
public interface DoubleTapListViewItemInterface {
void onItemClick(AdapterView<?> parent, View view, int position, long id);
void onItemDoubleClick(AdapterView<?> parent, View view, int position, long id);
}
And to add the feature to and activity (or a fragment):
public class ExampleActivity extends AppCompatActivity implements DoubleTapListViewItemInterface {
@BindView(R.id.listViewLayout) ListView listView; //ButterKnife
private DoubleTapListViewItem doubleTapListViewItem;
private Adapter listViewAdapter;
private WeakHandler mainHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
ButterKnife.bind(this);
mainHandler = new WeakHandler();
//get data, pass to the adapter and call listView.setAdapter(listViewAdapter);
}
@Override
protected void onDestroy(){
mainHandler.removeCallbacksAndMessages(null);
super.onDestroy();
}
@OnItemClick(R.id.listViewLayout) //ButterKnife
public void onItemClickListInstance(final AdapterView<?> parent, final View view, final int position, final long id){
if(doubleTapListViewItem == null)
doubleTapListViewItem = new DoubleTapListViewItem(parent, view, position, id, mainHandler, listView,this);
else
doubleTapListViewItem.onItemTouch(parent, view, position, id);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Toast.makeText(getActivityFromWeakReference(),"single tap detected",Toast.LENGTH_SHORT).show();
}
@Override
public void onItemDoubleClick(AdapterView<?> parent, View view, int position, long id){
Toast.makeText(getActivityFromWeakReference(),"double tap detected",Toast.LENGTH_SHORT).show();
}
}

- 965
- 12
- 27