5

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

user3102156
  • 183
  • 2
  • 2
  • 11

6 Answers6

5

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");
}
Oleksandr Albul
  • 1,611
  • 1
  • 23
  • 31
  • 3
    A 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
2

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);
    }
}
Graeme
  • 25,714
  • 24
  • 124
  • 186
0

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
    }
}
Community
  • 1
  • 1
tomisyourname
  • 91
  • 1
  • 11
0

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();
            }
        }
    });
}
mnille
  • 1,328
  • 4
  • 16
  • 20
duythanhit
  • 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
0

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) )
Maxime Claude
  • 965
  • 12
  • 27
0

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();
    }
}
Maxime Claude
  • 965
  • 12
  • 27