Как обработать событие клика в Listview на Android?

Ниже приведен мой тестовый код для создания представления списка, представление списка отображается успешно, однако в событии щелчка возникает ошибка. Я хотел бы создать намерение отправить жесткое сообщение в новое действие. Однако он показывает ошибку для строки

Intent intent = new Intent(context, SendMessage.class);

Итак, проблема в том, что я должен предоставить для этого класса?

Кроме того, вместо жесткого кода выходного сообщения, как захватить данные в строке представления списка и перейти к новому действию? например BBB,AAA,R.drawable.tab1_hdpi для первой строки.

Спасибо.

public class MainActivity extends Activity {
    public final static String EXTRA_MESSAGE = "com.example.ListViewTest.MESSAGE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayList<ListEntry> members = new ArrayList<ListEntry>(); 
        members.add(new ListEntry("BBB","AAA",R.drawable.tab1_hdpi));
        members.add(new ListEntry("ccc","ddd",R.drawable.tab2_hdpi));
        members.add(new ListEntry("assa","cxv",R.drawable.tab3_hdpi));
        members.add(new ListEntry("BcxsadvBB","AcxdxvAA"));
        members.add(new ListEntry("BcxvadsBB","AcxzvAA"));
        members.add(new ListEntry("BcxvBB","AcxvAA"));
        members.add(new ListEntry("BvBB","AcxsvAA"));
        members.add(new ListEntry("BcxvBB","AcxsvzAA"));
        members.add(new ListEntry("Bcxadv","AcsxvAA"));
        members.add(new ListEntry("BcxcxB","AcxsvAA"));
        ListView lv = (ListView)findViewById(R.id.listView1);
        Log.i("testTag","before start adapter");
        StringArrayAdapter ad = new StringArrayAdapter (members,this);
        Log.i("testTag","after start adapter");
        Log.i("testTag","set adapter");
        lv.setAdapter(ad);
        lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                Intent intent = new Intent(context, SendMessage.class);
                String message = "abc";
                intent.putExtra(EXTRA_MESSAGE, message);
                startActivity(intent);
            }
        });
    }

person user782104    schedule 25.07.2013    source источник


Ответы (5)


Я не вижу, где вы объявляете context. Для создания намерения вы можете использовать MainActivity.this

 lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                Intent intent = new Intent(MainActivity.this, SendMessage.class);
                String message = "abc";
                intent.putExtra(EXTRA_MESSAGE, message);
                startActivity(intent);
            }
        });

Чтобы получить объект после того, как вы щелкнули, вы можете использовать AdapterView:

ListEntry entry = (ListEntry) parent.getItemAtPosition(position);
person Blackbelt    schedule 25.07.2013
comment
Спасибо, а что вообще означает контекст? - person user782104; 25.07.2013
comment
Это означает, что на самом деле представляет первый параметр в классе Intent? Что означает MainActivity.this? Спасибо - person user782104; 25.07.2013
comment
из документации This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents. У него есть информация, необходимая андроиду для запуска вашей активности SendMessage. - person Blackbelt; 25.07.2013
comment
Спасибо, а также почему Не удалось найти явный класс активности {com.example.listviewtest/com.example.listviewtest.ItemDetails}; Вы объявили эту активность в своем AndroidManifest.xml? - person user782104; 25.07.2013
comment
Я уже создал публичный класс ItemDetails, расширяющий активность. - person user782104; 25.07.2013
comment
вам нужно объявить ItemDetails внутри AndroidManifest.xml. Все действия должны быть объявлены внутри AndroidManifest.xml. - person Blackbelt; 25.07.2013
comment
Фиксированный. Последний вопрос... Если объект записи (ListEntry) имеет 3 элемента? две строки и одно целое число (фото сохранено), как его выставить и перейти к новой активности (нужно ли)? - person user782104; 25.07.2013
comment
если ListEntry сериализуем, вы можете передать весь объект, иначе вам придется передать все нужные вам поля через itent (вы уже использовали EXTRA_MESSAGE). Имейте в виду, что это работает как HashMap. Для каждого поля вы должны предоставить другой ключ - person Blackbelt; 25.07.2013
comment
Не лучше ли было бы передать Object at Position целевому действию? - person peterb; 17.04.2016
comment
@peterb это возможно. это зависит от варианта использования. ListEntry, в этом случае, должен быть разделяемым/сериализуемым для передачи в новое действие - person Blackbelt; 17.04.2016
comment
@Blackbelt, можешь дать мне класс ListEntry? - person TapanHP; 13.12.2016
comment
@TapanHP ListEntry не является частью фреймворка, это был класс модели OP. - person Blackbelt; 13.12.2016
comment
Хорошо, понял @Blackbelt - person TapanHP; 13.12.2016
comment
Большое спасибо! это очень полезно - person Serg Shapoval; 10.04.2017

ListView имеет обратный вызов прослушивателя щелчка элемента. Вы должны установить onItemClickListener в ListView. Обратный вызов содержит AdapterView и position в качестве параметра. Что может дать вам ListEntry.

lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                ListEntry entry= (ListEntry) parent.getAdapter().getItem(position);
                Intent intent = new Intent(MainActivity.this, SendMessage.class);
                String message = entry.getMessage();
                intent.putExtra(EXTRA_MESSAGE, message);
                startActivity(intent);
            }
        });
person Kapil Vats    schedule 25.07.2013
comment
Спасибо. Если объект ввода имеет 3 элемента? две строки и одно целое число (фото сохранено), как его выставить и перейти к новой активности (нужно ли)? - person user782104; 25.07.2013
comment
Вы можете реализовать Parceble или Serializable в ListEntry и можете передать весь объект своей новой активности. - person Kapil Vats; 24.10.2015

Ошибка возникает в вашем коде из этого утверждения, как вы сказали

Intent intent = new Intent(context, SendMessage.class);

Это связано с тем, что вы предоставляете контекст анонимного класса OnItemClickListener в конструктор Intent, но в соответствии с конструктором Intent

android.content.Intent.Intent(Context packageContext, Class<?> cls)

Вы должны предоставить контекст своей деятельности, в которой вы используете намерение, которое является контекстом класса MainActivity. поэтому ваше утверждение, которое дает ошибку, будет преобразовано в

Intent intent = new Intent(MainActivity.this, SendMessage.class);

Также для отправки вашего сообщения из этого класса MainActivity в класс SendMessage см. приведенный ниже код.

lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                ListEntry entry= (ListEntry) parent.getAdapter().getItem(position);
                Intent intent = new Intent(MainActivity.this, SendMessage.class);
                intent.putExtra(EXTRA_MESSAGE, entry.getMessage());
                startActivity(intent);
            }
        });

Пожалуйста, дайте мне знать, если это поможет вам

РЕДАКТИРОВАТЬ: - Если вы обнаружите какую-то проблему, чтобы получить значение списка, сделайте одну вещь, объявите свой список массивов

ArrayList<ListEntry> members = new ArrayList<ListEntry>();

глобально, т.е. перед созданием и изменением слушателя, как показано ниже.

 lv.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position,
                        long id) {
                    Intent intent = new Intent(MainActivity.this, SendMessage.class);
                    intent.putExtra(EXTRA_MESSAGE, members.get(position));
                    startActivity(intent);
                }
            });

Таким образом, весь ваш код будет выглядеть как

public class MainActivity extends Activity {
    public final static String EXTRA_MESSAGE = "com.example.ListViewTest.MESSAGE";
ArrayList<ListEntry> members = new ArrayList<ListEntry>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        members.add(new ListEntry("BBB","AAA",R.drawable.tab1_hdpi));
        members.add(new ListEntry("ccc","ddd",R.drawable.tab2_hdpi));
        members.add(new ListEntry("assa","cxv",R.drawable.tab3_hdpi));
        members.add(new ListEntry("BcxsadvBB","AcxdxvAA"));
        members.add(new ListEntry("BcxvadsBB","AcxzvAA"));
        members.add(new ListEntry("BcxvBB","AcxvAA"));
        members.add(new ListEntry("BvBB","AcxsvAA"));
        members.add(new ListEntry("BcxvBB","AcxsvzAA"));
        members.add(new ListEntry("Bcxadv","AcsxvAA"));
        members.add(new ListEntry("BcxcxB","AcxsvAA"));
        ListView lv = (ListView)findViewById(R.id.listView1);
        Log.i("testTag","before start adapter");
        StringArrayAdapter ad = new StringArrayAdapter (members,this);
        Log.i("testTag","after start adapter");
        Log.i("testTag","set adapter");
        lv.setAdapter(ad);
        lv.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
                        Intent intent = new Intent(MainActivity.this, SendMessage.class);
                        intent.putExtra(EXTRA_MESSAGE, members.get(position).getMessage());
                        startActivity(intent);
                    }
                });
    }

Где getMessage() будет методом получения, указанным в вашем классе ListEntry, который вы используете для получения ранее установленного сообщения.

person Abhinav Singh Maurya    schedule 25.07.2013
comment
Метод getMessage() не определен для типа ListEntry? - person user782104; 25.07.2013

Во-первых, класс должен реализовать прослушиватель кликов:

implements OnItemClickListener

Затем установите прослушиватель в ListView

yourList.setOnItemclickListener(this);

И, наконец, создайте метод clic:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(MainActivity.this, "You Clicked at ",   
 Toast.LENGTH_SHORT).show();
}
person Avinash Garg    schedule 03.12.2014

Согласно моему тесту,

  1. реализует OnItemClickListener -> работает.

  2. setOnItemClickListener -> работает.

  3. ListView по умолчанию активен (API 19)

Важно то, что «щелчок» работает только с TextView (если вы выберете simple_list_item_1.xml в качестве элемента). Это означает, что если вы предоставляете текстовые данные для ListView, «щелчок» работает, когда вы нажимаете на текстовую область. Щелчок по пустой области не вызывает «событие щелчка».

person Chaohsiung Huang    schedule 29.08.2016