如何在Android的ListView中处理点击事件?

50
以下是我的测试代码来创建列表视图,列表视图已经成功显示,但是点击事件有错误。我想创建一个意图来发送硬编码消息到一个新的活动。然而,在该行中出现错误。
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);
            }
        });
    }
6个回答

113

我无法看到你在哪里声明了context。为了创建Intent,您可以使用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);

2
这是一个抽象类,其实现由Android系统提供。它允许访问特定于应用程序的资源和类,以及应用程序级操作的上调,例如启动活动、广播和接收意图。它包含Android启动SendMessage活动所需的信息。 - Blackbelt
谢谢,另外为什么找不到显式活动类{com.example.listviewtest/com.example.listviewtest.ItemDetails}?你在AndroidManifest.xml中声明了这个活动吗? - user782104
我已经创建了公共类ItemDetails扩展活动(Activity) - user782104
你必须在 AndroidManifest.xml 中声明 ItemDetails。所有的活动都必须在 AndroidManifest.xml 中声明。 - Blackbelt
已解决。最后一个问题...如果条目对象(ListEntry)有3个项目?两个字符串和一个整数(存储的照片),如何公开它并传递到新活动中(是否必要)? - user782104
显示剩余9条评论

13

ListView有一个“Item click listener”回调函数。您应该在ListView中设置onItemClickListener,回调包含AdapterViewposition作为参数,这些参数可以给您提供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);
            }
        });

1
谢谢。如果entry对象有3个项目?两个字符串和一个整数(存储了一张照片),如何公开它并传递到新的活动中(是否必要)? - user782104
你可以在ListEntry中实现Parceble或Serializable,并将整个对象传递到你的新活动中。 - Kapil Vats

6
首先,这个类必须实现点击监听器:
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();
}

6

根据您的说法,代码中出现了错误

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

这是因为您将OnItemClickListener匿名类的上下文提供给Intent构造函数,但根据Intent的构造函数。
android.content.Intent.Intent(Context packageContext, Class<?> cls)

您需要提供使用Intent的活动上下文,这是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>();

全局性,即在onCreate之前,将您的监听器更改为以下内容:

 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() 是一个 getter 方法,在你的 ListEntry 类中指定,用于获取之前设置的消息。


方法getMessage()对于类型ListEntry未定义。 - user782104

2
    //get main activity
    final Activity main_activity=getActivity();

    //list view click listener
    final ListView listView = (ListView) inflatedView.findViewById(R.id.listView_id);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String stringText;

            //in normal case
            stringText= ((TextView)view).getText().toString();                

            //in case if listview has separate item layout
            TextView textview=(TextView)view.findViewById(R.id.textview_id_of_listview_Item);
            stringText=textview.getText().toString();                

            //show selected
            Toast.makeText(main_activity, stringText, Toast.LENGTH_LONG).show();
        }
    });

    //populate listview

2

根据我的测试,

  1. 实现OnItemClickListener -> 可行。

  2. setOnItemClickListener -> 可行。

  3. ListView默认可点击(API 19)

重要的是,“点击”只适用于TextView(如果您选择simple_list_item_1.xml作为项目)。这意味着如果您为ListView提供文本数据,则单击文本区域时“点击”有效。单击空白区域不会触发“单击事件”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接