2013-04-15 2 views
0

У меня есть ListActivity. Ожидается, что мой метод onListItemClick() обновит TextView внутри щелкнутого элемента со значением щелкнутой позиции (например, если я нажму на третий элемент, появится «Clicked position = 2», учитывая список позиций с индексом 0). Однако, похоже, он обновляет несколько элементов (хотя отладчик выполняет этот метод только один раз). Иногда происходят другие сбои, например, текст щелкнутого элемента «По нажатию позиции» исчезает или его содержимое изменяется при прокрутке списка. Это странное поведение, которое можно воспроизвести с помощью простой настройки проекта, как показано ниже. Может быть, проблема с моим BaseAdapter?Android onListItemClick() действует для более чем одного элемента списка

EventList.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; 
    } 
} 

activity_main.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> 

ответ

1

ListViews повторно использовать их раскладки строк, поскольку она более эффективна, чем иметь уникальное расположение для каждой строки. (10 макетов быстрее, чем 10 000.) Таким образом, вам нужно изменить набор данных, питающий адаптер, а не сам 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 your UI, чтобы узнать, почему ListViews сделать это, и как воспользоваться этой функцией. (Например, ViewHolder поможет.)

+0

Вы избили меня :-) Также вы можете удалить строку «TextView textView ...», поскольку она больше не используется. – Ridcully

+0

Упс, спасибо! – Sam

+0

Это сработало! Большое спасибо! Вы, конечно же, очень быстрые :) – Piovezan

Смежные вопросы