私はListView
に項目を動的に追加しようとしています。私が初めてそれを行うと(リストが空であるため)、getView()
はかなりうまく動作します。convertViewはnull
であるため、ViewHolder
を使用してアイテムのビューへの参照を格納し、setTagを通してビューにバインドします)。しかし、2番目のアイテムをリストに追加すると、notifyOnDataSetChanged()
と呼ぶと本当に奇妙な動作が気づいています。getVIewは、listViewに新しい項目を追加すると、既に存在していた項目のconvertView == nullを持っています
基本的にnotifyOnDataSetChanged()
は、すべての表示項目を再描画し、最初の表示項目から開始します。問題は、既に描画されていた最初のアイテムが再描画されているときにconvertView == nullが発生するため、新しいビューを展開してfindViewById()
を使用して、 ViewHolder。 2番目のアイテムについては、最初のものへの参照を持つconvertViewを受け取るので、2番目のアイテムのためにそれを見つける必要があります。私が欲しいのは、最初に作成したビュー(ViewHolder内のすべての参照)を最初のアイテム用に取得し、2番目のアイテム用の新しいビューを作成することです。それを行う方法はありますか?
EDIT 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'を呼び出さなければなりません? –