私は30日間の月/カレンダー(Outlookカレンダーと考える)のように見える日付選択ツールを作成しています。日付ピッカーには、個々の日のTableViewであるMonthViewビューのListView(スクロール用)が含まれています。 MonthViewの個々の日はボタンです。 MonthViewがインスタンス化されるとき、私は日のそれぞれを歩く(ボタン)、クリックリスナーを添付:Android:ListView内のボタンはonClickイベントを受け取りません
final Button b = getButtonAt(i);
b.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
setSelectedDate(buttonDayClosure, b);
}
});
setSelectedDateは、物事の様々なを行いますが、それはまた、日付が選択されている意味する黄色のボタンの背景をオンにします。
私のエミュレータでは、すべてが期待通りに機能します。アクティビティが始まり、あなたは1日を押すと、その日は黄色に変わります。問題はありません。
しかし、私の仲間のエミュレータや物理的なデバイスのいくつかでは、何も起こりません... ListViewをスクロールするまで、そして突然選択した日が黄色に変わります。たとえば、「the 3rd」をタッチすると何も起こりません。数秒待ってからListViewをスクロールしてください(3番目ではないカレンダーの領域に触れる)、ListViewがスクロールするとすぐに3番目が魔法のように黄色に変わります。
この動作を示す私のピアエミュレータでは、onClickの第1行にブレークポイントを設定することができ、BPが実際にはListViewがスクロールされるまで、ヒットしないことがわかります。
この動作は私には意味がありません。私はonClickの振る舞いが、カプセル化されたViewのスクロールの努力と無関係であると期待します。
なぜこれが当てはまるのか、ボタンを押したときにonClicksがすぐに起きるように状況を修正する方法について考えてみましょうか?
ありがとうございました。
ポストScriptus:ArrayAdapterとListViewのコードは、要求された:
public class MonthArrayAdapter extends ArrayAdapter<Date> {
private MonthView[] _views;
private Vector<Procedure<Date>> _dateSelectionChangedListeners = new Vector<Procedure<Date>>();
public MonthArrayAdapter(Context context, int textViewResourceId, Date minSelectableDay, Date maxSelectableDay) {
super(context, textViewResourceId);
int zeroBasedMonth = minSelectableDay.getMonth();
int year = 1900 + minSelectableDay.getYear();
if(minSelectableDay.after(maxSelectableDay))
{
throw new IllegalArgumentException("Min day cannot be after max day.");
}
Date prevDay = minSelectableDay;
int numMonths = 1;
for(Date i = minSelectableDay; !sameDay(i, maxSelectableDay); i = i.addDays(1))
{
if(i.getMonth() != prevDay.getMonth())
{
numMonths++;
}
prevDay = i;
}
_views = new MonthView[numMonths];
for(int i = 0; i<numMonths; i++)
{
Date monthDate = new Date(new GregorianCalendar(year, zeroBasedMonth, 1, 0, 0).getTimeInMillis());
Date startSunday = findStartSunday(monthDate);
this.add(monthDate);
_views[i] = new MonthView(this.getContext(), startSunday, minSelectableDay, maxSelectableDay);
zeroBasedMonth++;
if(zeroBasedMonth == 12)
{
year++;
zeroBasedMonth = 0;
}
}
for(final MonthView a : _views)
{
a.addSelectedDateChangedListener(new Procedure<MonthView>()
{
@Override
public void execute(MonthView input) {
for(final MonthView b: _views)
{
if(a != b)
{
b.clearCurrentSelection();
}
}
for(Procedure<Date> listener : _dateSelectionChangedListeners)
{
listener.execute(a.getSelectedDate());
}
}
});
}
}
void addSelectedDateChangedListener(Procedure<Date> listener)
{
_dateSelectionChangedListeners.add(listener);
}
private boolean sameDay(Date a, Date b)
{
return a.getYear() == b.getYear() && a.getMonth() == b.getMonth() &&
a.getDate() == b.getDate();
}
@Override
public View getView (int position, View convertView, ViewGroup parent)
{
return _views[position];
}
private Date findStartSunday(Date d)
{
return d.subtractDays(d.getDay());
}
public void setSelectedDate(Date date)
{
for(MonthView mv : _views)
{
mv.setSelectedDate(date);
}
}
}
と
public class DatePicker extends ActivityBase {
public static final String CHOSEN_DATE_RESULT_KEY = "resultKey";
public static final String MIN_SELECTABLE_DAY = DatePicker.class.getName() + "MIN";
public static final String MAX_SELECTABLE_DAY = DatePicker.class.getName() + "MAX";
private static final String SELECTED_DATE = UUID.randomUUID().toString();
private long _selectedDate = -1;
private MonthArrayAdapter _monthArrayAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Date now = new Date();
Bundle inputs = this.getIntent().getExtras();
long min = inputs.getLong(MIN_SELECTABLE_DAY, 0);
Date minSelectableDate;
if(min == 0)
{
minSelectableDate = new Date(now);
}
else
{
minSelectableDate = new Date(min);
}
Log.i(DatePicker.class.getName(), "min date = " + minSelectableDate.toString());
long max = inputs.getLong(MAX_SELECTABLE_DAY, 0);
Date maxSelectableDate;
if(max == 0)
{
maxSelectableDate = new Date(now.addDays(35).getTime());
}
else
{
maxSelectableDate = new Date(max);
}
setContentView(R.layout.date_picker);
Button doneButton = (Button) findViewById(R.id.DatePickerDoneButton);
if(doneButton == null)
{
Log.e(this.getClass().getName(), "Could not find doneButton from view id.");
finish();
return;
}
doneButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
Intent result = new Intent();
result.putExtra(CHOSEN_DATE_RESULT_KEY, _selectedDate);
setResult(RESULT_OK, result);
finish();
}
});
Button cancelButton = (Button) findViewById(R.id.DatePickerCancelButton);
if(cancelButton == null)
{
Log.e(this.getClass().getName(), "Could not find cancelButton from view id.");
finish();
return;
}
cancelButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
setResult(RESULT_CANCELED, null);
finish();
}
});
ListView lv = (ListView)findViewById(R.id.DatePickerMonthListView);
lv.setDividerHeight(0);
_monthArrayAdapter =
new MonthArrayAdapter(this, android.R.layout.simple_list_item_1, minSelectableDate, maxSelectableDate);
_monthArrayAdapter.addSelectedDateChangedListener(new Procedure<Date>()
{
@Override
public void execute(Date input) {
_selectedDate = input.getTime();
}
});
lv.setAdapter(_monthArrayAdapter);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
if(savedInstanceState.containsKey(SELECTED_DATE))
{
_selectedDate = savedInstanceState.getLong(SELECTED_DATE);
_monthArrayAdapter.setSelectedDate(new Date(_selectedDate));
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
savedInstanceState.putLong(SELECTED_DATE, _selectedDate);
}
}
は、あなたがしてください、あなたのアダプタのとあなたのListActivityの完全なコードを投稿することができますか? – nbarraille
ここにアダプターがあります。 ListViewのために待機します。 – Dejas
Ok、nbarraille、助けてくれることを願っています。 – Dejas