如何识别 ListView 中重复使用的小部件

发布于 2025-01-05 05:31:56 字数 1834 浏览 1 评论 0原文

我有一个我认为很奇怪的困境,尽管 YMMV。

我正在使用一个布局文件来描述 ListView 中的每一行/行(没有什么太奇特的)。我为每一个分配了一个 id,例如:

android:id="@+id/checkBox1" android:id="@+id/checkBox2" android:id="@+id/checkBox3"
android:id="@+id/contactLabel" // a TextView

现在这似乎没有意义,因为这些 id 应该是唯一的,那么第二个 id 是多少 排?也就是说,如果“row 1”遵循 checkbox1、checkbox2、checkbox3 和 contactLabel 的指定 id,那么“row 2”id 是什么?

我很好奇,但我也需要知道,因为我想将复选框的值保存到 SharedPreferences 对象。

谁知道如何解决这个问题?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 更新

我需要解决的第一件事是如何响应 ListView 上的点击。这是我当前与所有这些相关的难题:

ListView 不知道它已被单击,或者不会告诉我

我已将此事件处理程序添加到我的 ListActivity:

  @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        String item = (String) getListAdapter().getItem(position);
        Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show();
    }

...但它不是被打电话。我单击显示的联系人,但没有执行。

我也尝试过这种方式:

lv.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) {
        Toast.makeText(getApplicationContext(),
            "Click ListItem Number " + position, Toast.LENGTH_LONG)
            .show();
    }
});

...仍然没有乐趣...我在两条“Toast”行上都放置了断点,但它们从未到达。

我在这里读到:

http://www.vogella.de/articles/AndroidListView/article .html#listsactivity_layout

...即,“如果您在 Activity 中需要更多的 ListView,您可以使用自己的布局 ListActivity。”

...我这样做,因为除了 listview 之外,我还添加了页眉和页脚。

它接着说,“在这种情况下,您的布局必须具有带有 android:id 的 ListView 元素 属性设置为@android:id/list。”

所以我将其添加到我的布局中:

...但无论哪种方式都没有区别。

I have what I consider to be a strange dilemma, although YMMV.

I'm using a layout file that describes each line/row in a ListView (nothing too exotic about that). I have an id assigned to each one, such as:

android:id="@+id/checkBox1"
android:id="@+id/checkBox2"
android:id="@+id/checkBox3"
android:id="@+id/contactLabel" // a TextView

Now this doesn't seem to make sense, as these ids should be unique, so what is the id of the second
row? That is, if "row 1" honors the specified ids of checkbox1, checkbox2, checkbox3, and contactLabel, what would the "row 2" ids be?

I'm curious, but also I need to know because I want to save the values of the checkboxes to a SharedPreferences object.

Who has a clue about how to get around this?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Update

The first thing I need to solve is how to respond to a click on the ListView. This is my current conundrum related to all of this:

ListView doesn't know it's been clicked, or won't tell me

I've added this event handler to my ListActivity:

  @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        String item = (String) getListAdapter().getItem(position);
        Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show();
    }

...but it's not getting called. I click on the Contacts that display, but no go.

I also tried it this way:

lv.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) {
        Toast.makeText(getApplicationContext(),
            "Click ListItem Number " + position, Toast.LENGTH_LONG)
            .show();
    }
});

...still no joy...I put breakpoints on both "Toast" lines, and they never get reached.

I read here:

http://www.vogella.de/articles/AndroidListView/article.html#listsactivity_layout

...that, "In case you need more the just a ListView in your Activity, you can use you own layout for
ListActivity."

...which I do, because I add a header and a footer in addition to the listview.

It goes on to say, "In this case your layout must have an ListView element with the android:id
attribute set to @android:id/list."

So I added this to my layout:

...but it makes no difference one way or the other.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

[旋木] 2025-01-12 05:31:56

当您在 getView() 方法中对其进行扩充时,ListView 小部件中的项目的 ID 将通过其父视图进行引用。

详细来说,您的 ListView 适配器将具有类似这样的内容。

public View getView(int position, View convertView, ViewGroup viewGroup) {
        if (convertView == null) {
            convertView = LayoutInflater.from(ctx).inflate(R.layout.list_view_item, null);
            }

现在,一个新的视图实例作为convertView 存在。您可以使用 covertView.findViewById(R.id.checkBox1)convertView.findViewById(R.id.checkBox2) 等访问您的小部件。

每个视图都是一个ListView 的子级。您可以使用 ListView 中的 getChildCount()getChildAt() 方法引用 ListView 中的每个单独视图目的。
但是,由于建议使用 convertView 视图来回收视图,在这种情况下,您一次只能引用屏幕上的视图。

另外,对于 SharedPreferencesListView 中的所有视图都由 Adapter 子类填充,该子类是放置CheckboxTextView 小部件中的值。此适配器有一个您提供的数据集。为什么不直接引用数据集中的值,而不是尝试从无论如何都从数据集填充的列表项中查找它们?当有人单击 CheckBox 时,您可以从 ListView 写入数据集,这样您就可以轻松有序地引用 ListView 中的所有项目。


更新:添加了虚拟源代码

好的。让我们从一个假设的列表开始。我们想要显示列表中的五个项目。为简单起见,我假设每个都有一个 TextView 和一个 Checkbox。所以我的容器类是:

class Item {
    String textView;
    boolean checked;
}

现在在我想要显示此列表的 Activity 中,我将一个 ArrayList 项目(您可以使用几乎任何数据结构)作为一个类多变的。然后我获取 ListView 引用并为其分配一个适配器。

class MyActivity extends Activity {
    ArrayList<Item> listItems;
    .....
    onCreate(Bundle icicle) {
        .....
        ListView listView = (ListView) findViewById(R.id.listView1); // this will be you list view
        MyAdapter listAdapter = new MyAdapter();
        listView.setAdapter(listAdapter);
        ....
        // Rest of your Activity
        ....
        MyAdapter extends BaseAdapter {

            int getItemCount() {
                return listItems.size();
            }

            Item getItem(int position) {
                return listItems.get(position);
            }

            View getView(int position, View convertView, ViewGroup parent) {
                // Here's the important part
                Item currentItem = listItems.getItem(position); // Since the array is a class variable, you can do either get or getItem

                ..... // do the standard individual item inflating ....

                checkbox = convertView.findViewById(R.id.checkbox);
                checkbox.OnItemSelectedListener( new OnItemSelectedListener() { // or whatever listener there should be... I didn't check
                    ... // do whatever...
                    currentItem.setChecked(true);
            }

当您想要检索单击的项目时,只需迭代 Item 类并查找哪些项目是 true,或者您在 Listener 中执行您想要的任何操作,因为您有一个标识 ListView 各个成员的引用数据集(此处为 listItems ArrayList)。

对于任何错误,我们深表歉意。没有做任何检查。

The ID's for the items within the ListView widget are referenced through their parent view when you inflate it in your getView() method.

To elaborate, you would have something like this is you ListView adapter.

public View getView(int position, View convertView, ViewGroup viewGroup) {
        if (convertView == null) {
            convertView = LayoutInflater.from(ctx).inflate(R.layout.list_view_item, null);
            }

Nown, a new view instance exists as the convertView. You can access your widgets using covertView.findViewById(R.id.checkBox1), convertView.findViewById(R.id.checkBox2), etc.

Each of these views is a child of your ListView. You can reference each individual view from your ListView using the getChildCount() and getChildAt() methods from the ListView object.
However, since it is recommended to use the convertView view to recycle views, in that case you will only have reference to the views on screen at a time.

Also, with regards to the SharedPreferences, all the views in your ListView are populated by an Adapter subclass which would be the actual object that puts the values in the Checkbox and TextView widgets. This Adapter has a dataset that you provide it. Why not reference the values from the dataset directly, instead of trying to find them from the list items which are populated from the dataset in any case ? You can write to the dataset from the ListView when someone clicks a CheckBox so you have an easy ordered reference to all the items in the ListView.


UPDATE: Added dummy source code

OK. Let's start with a hypothical list. We want to display say five items on the list. For simplicity, I'll assume each has a TextView and a Checkbox. So my container class is:

class Item {
    String textView;
    boolean checked;
}

Now in my Activity where I want to display this list, I put an ArrayList of items (you can use just about any datastructure) as a class variable. Then I get the ListView reference and assign it an adapter.

class MyActivity extends Activity {
    ArrayList<Item> listItems;
    .....
    onCreate(Bundle icicle) {
        .....
        ListView listView = (ListView) findViewById(R.id.listView1); // this will be you list view
        MyAdapter listAdapter = new MyAdapter();
        listView.setAdapter(listAdapter);
        ....
        // Rest of your Activity
        ....
        MyAdapter extends BaseAdapter {

            int getItemCount() {
                return listItems.size();
            }

            Item getItem(int position) {
                return listItems.get(position);
            }

            View getView(int position, View convertView, ViewGroup parent) {
                // Here's the important part
                Item currentItem = listItems.getItem(position); // Since the array is a class variable, you can do either get or getItem

                ..... // do the standard individual item inflating ....

                checkbox = convertView.findViewById(R.id.checkbox);
                checkbox.OnItemSelectedListener( new OnItemSelectedListener() { // or whatever listener there should be... I didn't check
                    ... // do whatever...
                    currentItem.setChecked(true);
            }

When you want to retrieve what items were clicked, just iterate through the Item class and find which ones are true or you perform whatever action you want within the Listener since you have a reference identifying individual members of the ListView dataset (here listItems ArrayList).

Apologies for any errors. Didn't do any checking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文