jak zaimplementować odbiornik długich kliknięć w widoku listy

148

Chcę dodać OnLongClickListenerdo mojego widoku listy. Za każdym razem, gdy użytkownik długo naciska element na liście, należy wykonać jakąś akcję, ale mój kod nie przechwytuje tego nasłuchiwania. Proszę, daj mi znać, gdzie popełniam błąd. Podobny kod działa setOnItemClickListenerbardzo dobrze.

Oto kod:

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            public boolean onItemLongClick(AdapterView<?> arg0, View v,
                    int index, long arg3) {
                // TODO Auto-generated method stub
                 Log.d("in onLongClick");
                 String str=listView.getItemAtPosition(index).toString();

                 Log.d("long click : " +str);
                return true;
            }
}); 
techayu
źródło
Czy pamiętałeś o dodaniu „implementuje OnItemLongClickListener” do deklaracji klasy?
Barry
zobacz w xml, czy długie kliknięcie jest włączone?
Łączenie życia z Androidem
Może masz odbiornik gestów lub coś w tym rodzaju, co rejestruje długą prasę i ją zużywa.
Jon Zangitu

Odpowiedzi:

317

Musisz ustawić setOnItemLongClickListener () w ListView:

lv.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                    int pos, long id) {
                // TODO Auto-generated method stub

                Log.v("long clicked","pos: " + pos);

                return true;
            }
        }); 

XML dla każdego elementu na liście (jeśli używasz niestandardowego XML) również musi mieć android:longClickable="true"(lub możesz użyć wygodnej metody lv.setLongClickable(true);). W ten sposób możesz mieć listę z tylko niektórymi elementami reagującymi na długie kliknięcie.

Mam nadzieję, że to ci pomoże.

Dinesh Sharma
źródło
25
Koniecznie zadzwoń lv.setLongClickable(true);również.
Chris Lacy,
15
To nie zadziałało dla mnie. Ale to robi:lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {...
Luis A. Florit
w jakiś sposób adroid: longClickable = "true" jest domyślne. Używam API 19. Więc nie musiałem go w ogóle określać.
user1592714
2
Android ustawia longClickable = true podczas ustawiania nasłuchiwania.
Steven Spungin
jaka wartość jest przechowywana w long id? in public boolean onItemLongClick (AdapterView <?> arg0, View arg1, int pos, long id
Femn Dharamshi
26

Jeśli element wiersza ListView odwołuje się do oddzielnego pliku XML, pamiętaj, aby dodać android:longClickable="true"do tego pliku układu oprócz ustawienia setOnItemLongClickListener()do ListView.

Jonathan Lin
źródło
Dzięki! Waliłem się tym w głowę.
Shaihi
15

lub wypróbuj ten kod:

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            public boolean onItemLongClick(AdapterView<?> arg0, View v,
                    int index, long arg3) {

    Toast.makeText(list.this,myList.getItemAtPosition(index).toString(), Toast.LENGTH_LONG).show();
                return false;
            }
}); 
Ardi
źródło
6

Myślę, że powyższy kod będzie działał na LongClick w widoku listy, a nie na poszczególnych elementach.

dlaczego nie używać registerForContextMenu(listView). a następnie pobierz wywołanie zwrotne w OnCreateContextMenu.

W większości przypadków będzie to działać tak samo.

nandeesh
źródło
2

W xml dodaj

<ListView android:longClickable="true">

W pliku java

lv.setLongClickable(true) 

spróbuj tego setOnItemLongClickListener ()

lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int pos, long l) {
                //final String category = "Position at : "+pos;
                final String category = ((TextView) view.findViewById(R.id.textView)).getText().toString();
                Toast.makeText(getActivity(),""+category,Toast.LENGTH_LONG).show();
                args = new Bundle();
                args.putString("category", category);
                return false;
            }
        });
Vijay Sharma
źródło
1

to powinno działać

ListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                                           int pos, long id) {
                // TODO Auto-generated method stub

                Toast.makeText(getContext(), "long clicked, "+"pos: " + pos, Toast.LENGTH_LONG).show();

                return true;
            }
        });

nie zapomnij również o tym w swoim xml android:longClickable="true"lub jeśli masz widok niestandardowy, dodaj go do swojej klasy widoku niestandardowegoyouCustomView.setLongClickable(true);

tutaj jest wynik powyższego kodu wprowadź opis obrazu tutaj

Ayoub
źródło
1

Wypróbowałem większość tych odpowiedzi i wszystkie kończyły się niepowodzeniem w przypadku TextViews, które miały włączone automatyczne łącza, ale musiały też użyć długiego naciśnięcia w tym samym miejscu!

Stworzyłem niestandardową klasę, która działa.

public class TextViewLinkLongPressUrl extends TextView {

    private boolean isLongClick = false;

    public TextViewLinkLongPressUrl(Context context) {
        super(context);
    }

    public TextViewLinkLongPressUrl(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextViewLinkLongPressUrl(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text, type);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_UP && isLongClick) {
            isLongClick = false;
            return false;
        }

        if (event.getAction() == MotionEvent.ACTION_UP) {
            isLongClick = false;
        }

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            isLongClick = false;
        }

        return super.onTouchEvent(event);
    }

    @Override
    public boolean performLongClick() {
        isLongClick = true;
        return super.performLongClick();
    }
}
Oliver Dixon
źródło
0

To zadziałało dla mnie w przypadku cardView i będzie działać tak samo dla widoku listy w kcalach adaptera, w ramach onBindViewHolder()funkcji

holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return false;
            }
        });
niks
źródło
0

Jeśli chcesz to zrobić w adapterze, możesz po prostu zrobić to:

itemView.setOnLongClickListener(new View.OnLongClickListener()
        {
            @Override
            public boolean onLongClick(View v) {
                Toast.makeText(mContext, "Long pressed on item", Toast.LENGTH_SHORT).show();
            }
        });
user846316
źródło
0
    listView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
        return false;
    }
});

Zdecydowanie załatwia sprawę.

Kalaiyo5
źródło