简体   繁体   English

长按触发点击,长按不注册

[英]long click triggers click, long click doesn't get registered

I have a listview in a constraintlayout . 我在constraintlayout有一个listview。 when I try to do a long click on one of the elements of the list, to inflate the context menu, there are 2 problems: 当我尝试长时间单击列表中的元素之一以使上下文菜单膨胀时,有两个问题:

1: It triggers the long click only sometimes, really random 1:仅偶尔触发长按,确实是随机的

2: After the long click was triggered the "normal" click is also triggered even though the onContextItemSelected returns true (to indicate the event was handled) 2:触发长按之后,即使onContextItemSelected返回true(指示事件已处理),也会触发“正常”点击

for some list elements, I want to have both the onClickListener and the long click for the contextmenu, on others only the contextmenu. 对于某些列表元素,我希望onClickListener具有onClickListener和长按,而另一些则只有上下文菜单。 (the listview is registered for contextmenu). (listview已注册为contextmenu)。 Heres the XML of the MainActivity 这是MainActivity的XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout  xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="it.netknights.piauthenticator.MainActivity"
tools:layout_editor_absoluteY="81dp"
tools:layout_editor_absoluteX="0dp">

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    app:backgroundTint="@color/PIBLUE"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:srcCompat="@drawable/ic_add_white_24dp" />

<TextView
    android:id="@+id/countdownfield"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:backgroundTint="@color/PIBLUE"
    android:text="TextView"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent" />

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="@color/PIBLUE"
    android:elevation="4dp"
    android:minHeight="?attr/actionBarSize"
    android:theme="?attr/actionBarTheme"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:popupTheme="@color/PIBLUE"
    tools:layout_editor_absoluteY="-57dp" />

<ListView
    android:id="@+id/listview"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    app:layout_constraintBottom_toTopOf="@+id/countdownfield"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/toolbar"
    app:layout_constraintVertical_bias="1.0" />

</android.support.constraint.ConstraintLayout>

and the XML of the listentry 以及侦听的XML

<android.support.constraint.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:longClickable="true"
tools:layout_editor_absoluteY="81dp"
tools:layout_editor_absoluteX="0dp">

<TextView
    android:id="@+id/textViewToken"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="124891"
    android:textSize="28sp"
    android:textStyle="bold"
    tools:layout_editor_absoluteY="0dp"
    android:layout_marginLeft="0dp"
    app:layout_constraintLeft_toLeftOf="parent" />

<!--    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"-->



<TextView
    android:id="@+id/textViewLabel"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="privacyidea something"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:layout_marginTop="0dp"
    app:layout_constraintTop_toBottomOf="@+id/textViewToken"
    android:layout_marginLeft="0dp"
    app:layout_constraintLeft_toLeftOf="parent" />

<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="0dp"
    android:layout_height="20dp"
    android:layout_marginLeft="0dp"
    app:layout_constraintLeft_toLeftOf="parent"
    android:layout_marginTop="0dp"
    app:layout_constraintTop_toBottomOf="@+id/textViewLabel"
    android:layout_marginRight="0dp"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintHorizontal_bias="0.517"
    />


</android.support.constraint.ConstraintLayout>

the part of the MainActivity.java MainActivity.java的一部分

final ListView listview = (ListView) findViewById(R.id.listview);

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Toast.makeText(view.getContext(), "SHORT itemclick", Toast.LENGTH_SHORT).show();
        }
    });
registerForContextMenu(listview);

and the getview method from my custom adapter: 和我的自定义适配器中的getview方法:

 @Override
public View getView(final int position, View v, ViewGroup parent) {
    if (v == null) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        v = inflater.inflate(R.layout.tokenentry, parent, false);
    }
    v.setLongClickable(true);
    v.setTag(position);

    final ProgressBar progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
    final Token token = getItem(position);
    final TextView tmp2 = (TextView) v.findViewById(R.id.textViewToken);
    final TextView tmp1 = (TextView) v.findViewById(R.id.textViewLabel);


    if (token.getType().equals(HOTP)) {
        progressBar.setVisibility(GONE);
    } else {
        progressBar.setVisibility(VISIBLE);
        //v.setClickable(false);
    }

    progressBar.setTag(position);
    progressBar.setMax(token.getPeriod());
    progressBar.getProgressDrawable().setColorFilter(
            Color.rgb(0x83, 0xc9, 0x27), android.graphics.PorterDuff.Mode.SRC_IN);

    token.setPb(progressBar);

    tmp1.setText(token.getLabel());
    tmp2.setText(token.getCurrentOTP());

EDIT: thank you for taking your time to post answers. 编辑:感谢您抽出宝贵时间发布答案。 Ive solved the/my problem: the rootelement of the listentries was a contraintlayout and that doesn't seem to work properly with the scenarios i want, so i changed it so a relativelayout and it now it works perfectly! 我已经解决了我的问题:listentries的rootelement是一个contraintlayout,似乎不适用于我想要的方案,所以我将它更改为一个relativelayout,现在它可以正常使用了!

hi Cxc the problem might be due to listView registered for both onClick and onLongClick . 嗨,Cxc,该问题可能是由于listView已为onClick和onLongClick注册的。 So instead of setting the onClickListener for the entire list view try setting the onClick listener to only the item view for which you need both onClickListener and long click. 因此,与其将onClickListener设置为整个列表视图,不如将onClick侦听器设置为仅需要onClickListener和长按的项目视图。 You can set onClickListener to particular views inside getView() method based on their position or view type. 您可以根据其位置或视图类型将getClick()方法内的特定视图设置为onClickListener。 for example, 例如,

      @Override
    public View getView(final int position, View v, ViewGroup parent) {
        if (v == null) {
            final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            v = inflater.inflate(R.layout.tokenentry, parent, false);
        }
        v.setLongClickable(true);
        v.setTag(position);
       if(position % 2 == 0)
       {
            v.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
            // TODO Auto-generated method stub
                Toast.makeText(v.getContext(), "SHORT itemclick", 
            Toast.LENGTH_SHORT).show();

         }

        });

hope this helps 希望这可以帮助

I think you can use both onClick and onLongClick and override the onLongClick method making it returns true to avoid conflict of triggering onClick event 我认为您可以同时使用onClick和onLongClick并重写onLongClick方法,使其返回true以避免触发onClick事件的冲突

ex: 例如:

GridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                <do somthing here>

        }
    });

    GridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, final View view, final int i, long l) {

            <do something here>
return true;
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM