如何检测Android中ListView项目的双击?

时间:2013-12-15 13:21:35

标签: android double gesture

我想做一些像Instagram应用程序的东西,当用户在照片上制作双标签时,它只是标签一次打开为全屏

7 个答案:

答案 0 :(得分:3)

如果您不需要阻止单击被触发,您可以做得更简单:

@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 :(得分:2)

我认为这也回答了你的问题。检查此链接:

how to implement double click in android

答案 2 :(得分:2)

如果您不想为每个列表项使用GestureListener,或为GestureListener使用ListView,那么您需要确定位于双击区域下的项目使用以下扩展名onItemClickListener

此实现等待确认单击,因此会引入单击延迟。

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);
    }
}

此实现不等待确认单击,它会在第一次单击双击时触发单击事件:

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);
    }
}

答案 3 :(得分:0)

我根据Graeme's回答做了这个,这对我有用。

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
    }
}

答案 4 :(得分:0)

您可以使用以下代码(lvDataListView变量):

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();
            }
        }
    });
}

答案 5 :(得分:0)

if()//添加此块

else if(count>=3){previousMil2=System.currentTimeMillis(); 

您无法更改单击另一行单击所选行。此代码阻止单击另一个视图,然后您要单击行。

然后改变控件

if(count>=2 && (System.currentTimeMillis()-previousMil<=1000 ||System.currentTimeMillis()-previousMil2<=1000) )

答案 6 :(得分:0)

使用@ Graeme的回答我想出了这个: 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);
        }
    }
}

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);
}

将功能添加到活动(或片段):

 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();
    }
}