0

我有一个 ListActivity。我的 onListItemClick() 方法应该使用点击位置的值更新点击项目内的 TextView(例如,如果我点击第三个项目,考虑到索引为 0 的项目列表,它会显示为“点击位置 = 2”)。但是,它似乎更新了多个项目(尽管调试器仅通过该方法一次)。有时会发生其他故障,例如单击的项目“单击的位置”文本消失或其内容在我滚动列表时发生变化。这是一种奇怪的行为,可以通过如下简单的项目设置来重现。也许我的 BaseAdapter 有问题?

事件列表.java:

package com.example.listactivitytest;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;

public class EventList extends ListActivity {

    private List<String> mEventList = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEventList = new ArrayList<String>();
        for (int i = 0; i < 200; i++) {
            mEventList.add("Position = " + i);
        }
        setListAdapter(new EventListAdapter(mEventList));
    }

    protected void onListItemClick(ListView l, View v, int position, long id) {

        TextView textView = (TextView)(v.findViewById(R.id.textClickedPosition));
        String clickedPosition = "Clicked position = " + position;
        textView.setText(clickedPosition);
    }
}

EventListAdapter.java:

package com.example.listactivitytest;

import java.util.ArrayList;
import java.util.List;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class EventListAdapter extends BaseAdapter {

    private List<String> eventList = new ArrayList<String>();

    public EventListAdapter() {
    }

    public EventListAdapter(List<String> eventList) {
        this.eventList = eventList;
    }

    @Override
    public int getCount() {
        return eventList.size();
    }

    @Override
    public Object getItem(int index) {
        return eventList.get(index);
    }

    @Override
    public long getItemId(int index) {
        return index;
    }

    @Override
    public View getView(int index, View view, ViewGroup parent) {
        if (view == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            view = inflater.inflate(R.layout.line_event_list, parent, false);
        }

        String event = eventList.get(index);

        TextView textView = (TextView) view.findViewById(R.id.textPosition);
        textView.setText(event);

        return view;
    }

    public List<String> getEventList() {
        return eventList;
    }
}

活动主.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" >
    </ListView>

    <TextView android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Empty list"
        android:layout_weight="1" />

</LinearLayout>

line_event_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="3dp"
    android:orientation="vertical"
    android:background="#ffffff" >

    <TextView android:id="@+id/textPosition"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView android:id="@+id/textClickedPosition"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.listactivitytest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.listactivitytest.EventList"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
4

1 回答 1

1

ListViews 重用它们的行布局,因为它比为每一行拥有一个独特的布局更有效。(10 个布局比 10,000 个要快。)因此,您需要更改为 Adapter 供电的数据集,而不是 TextView 本身。首先保存new EventListAdapter()为字段变量,调用它mAdapter,然后尝试:

protected void onListItemClick(ListView l, View v, int position, long id) {
    String clickedPosition = "Clicked position = " + position;
    mAdapter.getEventList().set(position, clickedPosition);
    mAdapter.notifyDataSetChanged();
}

你应该观看 Google I/O 演示Turbo Charge 你的 UI以了解 ListViews 为何这样做以及如何利用此功能。(例如 ViewHolder 会有所帮助。)

于 2013-04-15T18:25:44.323 回答