我試圖動態地在ListView
中添加項目。當我第一次這樣做(所以列表爲空)時,getView()
工作得很好,convertView爲null
,因此我可以使用ViewHolder
來存儲對項目視圖的引用,並通過setTag將其綁定到視圖)。但是當我用數據添加第二個項目到列表並且調用notifyOnDataSetChanged()
真的奇怪的行爲已經被注意到了。當我添加新項目到列表視圖時,getVIew的convertView == null爲已存在的項目
基本上,notifyOnDataSetChanged()
使所有可見項目被重新繪製,並從第一個可見項目開始。問題是,當第一個項目(之前已經繪製過)正在重繪時,convertView == null,因此我需要爲它添加新的視圖並使用findViewById()
來查找我之前已經找到並存儲在內部的所有引用ViewHolder。對於第二個項目,我收到第一個參考的convertView,因此我需要爲第二個項目找到它。我想要的是獲取之前創建的視圖(並且其ViewHolder中包含所有引用),併爲第二個項目創建新視圖,即在繪製剛剛添加的項目時使convertView == null。有沒有辦法做到這一點?
編輯1:添加新項目:
alarmClocksList.add(new AlarmClock(time, songTitle, weekDaysPanelVisible, weekDaysOn)); alarmsArrayAdapter.notifyDataSetChanged();
ArrayAdapter:
package com.example;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class AlarmsArrayAdapter extends ArrayAdapter {
ArrayList<AlarmClock> alarmClockArrayList;
private Context context;
static class ViewHolder {
TextView time;
TextView songTitle;
TextView nextRingTime;
CheckBox repeatCheckBox;
RelativeLayout repeatPanel;
WeekDayCheckBox monday;
WeekDayCheckBox tuesday;
WeekDayCheckBox wednesday;
WeekDayCheckBox thursday;
WeekDayCheckBox friday;
WeekDayCheckBox saturday;
WeekDayCheckBox sunday;
}
public AlarmsArrayAdapter(Context context, ArrayList<AlarmClock> alarmClocks) {
super(context, -1, alarmClocks);
alarmClockArrayList = alarmClocks;
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.alarm_clock_item, parent, false);
holder = new ViewHolder();
holder.time = (TextView) convertView.findViewById(R.id.alarmClockTime);
holder.songTitle = (TextView) convertView.findViewById(R.id.alarmClockSong);
holder.nextRingTime = (TextView) convertView.findViewById(R.id.nextRindDay);
holder.repeatCheckBox = (CheckBox) convertView.findViewById(R.id.repeatCheckBox);
holder.repeatPanel = (RelativeLayout) convertView.findViewById(R.id.repeatPanel);
holder.monday = (WeekDayCheckBox) convertView.findViewById(R.id.MO);
holder.tuesday = (WeekDayCheckBox) convertView.findViewById(R.id.TU);
holder.wednesday = (WeekDayCheckBox) convertView.findViewById(R.id.WE);
holder.thursday = (WeekDayCheckBox) convertView.findViewById(R.id.TH);
holder.friday = (WeekDayCheckBox) convertView.findViewById(R.id.FR);
holder.saturday = (WeekDayCheckBox) convertView.findViewById(R.id.SA);
holder.sunday = (WeekDayCheckBox) convertView.findViewById(R.id.SU);
holder.songTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
holder.time.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, TimePickerActivity.class);
((FragmentActivity) context).startActivityForResult(intent, MainActivity.TIME_PICK_REQUEST);
}
});
holder.repeatCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!isChecked) {
holder.repeatPanel.setVisibility(View.GONE);
} else {
holder.repeatPanel.setVisibility(View.VISIBLE);
}
}
});
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
AlarmClock alarmClock = alarmClockArrayList.get(position);
holder.time.setText(alarmClock.time);
holder.songTitle.setText(alarmClock.songTitle);
holder.nextRingTime.setText("No data");
return convertView;
}
}
發佈一些代碼.... –
「有什麼辦法可以做到嗎?」 - 不。你無法控制哪個'View',如果有的話,將會交給你的'getView()'方法。而且,它根本就不重要。如果需要的話,膨脹一個'View'。否則,只需更新給定的那個。 –
@MikeM。所以每次我畫新的項目(即使我只是上下滾動列表),我不得不調用'findViewByID'? –