SORU
12 Temmuz 2012, PERŞEMBE


Jelly Bean DatePickerDialog --- iptal etmek için bir yol var mı?

---Moderatörler için not:Bugün (15 Temmuz), biri zaten 35 ** bu sorunla karşı karşıya olduğunu fark ettik. Ama eğer uygun bir konu çok daha iyi bir açıklamam sağlanan bence beri yinelenen bu kadar yakın, Bu olup olmadığından emin değilim. Eğer başka soru düzenlemek ve bu içeriği oraya yapıştır konusunda emin değilim, ama başkasının soru çok fazla değişen pek rahat değilim.---

Bir şey vargaripburada.

Sorun karşı geliştiren bağlıdır sanmıyorum. Cihaz OS sürümü önemli olan da budur.

Sorun #1: varsayılan olarak tutarsızlık

DatePickerDialog değişti (?) Fasulye ve şimdi sadece Jelly sağlarBittidüğme. Önceki sürümleri dahilİptaldüğme, ve bu kullanıcı deneyimi (tutarsızlık, önceki Android sürümlerinde Kas hafızası) etkileyebilir.

Çoğaltılması:Basic projesi oluşturun. onCreate koy:

DatePickerDialog picker = new DatePickerDialog(
        this,
        new OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker v, int y, int m, int d) {
                Log.d("Picker", "Set!");
            }
        },
        2012, 6, 15);
picker.show();

Beklenen:Birİptaldüğme iletişim kutusunda görünür.

Geçerli:Birİptaldüğme görünmüyor.

Ekran görüntüleri:4.0.3 (TAMAM) ve 4.1.1 (kötü?).

Davranış kapatmak yanlış . Problem #2:

Gerçekten de, ve sonra aramak gerekir hangisi iletişim çağırırher zamanaramalar OnDateSetListener dinleyici. İptal hala set yöntemini çağırır ve bu ayar yöntemini çağırır iki kez.

Çoğaltılması:#1 kodu kullanır, ama altına Ekle (ama bu sadece görsel/UI #1, çözer görürsünüz) kod:

picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d("Picker", "Cancel!");
            }
        });

Beklenen:

  • GERİ tuşu veya iletişim dışında tıklamak gerekirhiçbir şey yapma.
  • "İptal" Yazdır . basarak ^strong>Seçici İptal!.
  • Basarak "" YazdırSeçici Ayarlayın!.

Geçerli:

  • GERİ tuşu veya iletişim yazdırır dışında tıklatarakSeçici Ayarlayın!.
  • Basarak "İptal" yazdırırSeçici İptal!ve sonraSeçici Ayarlayın!.
  • "Set" yazdırır . tuşuna basarak ^strong>Seçici Ayarlayın!ve sonraSeçici Ayarlayın!.

Günlük satırları davranış göstererek:

07-15 12:00:13.415: D/Picker(21000): Set!

07-15 12:00:24.860: D/Picker(21000): Cancel!
07-15 12:00:24.876: D/Picker(21000): Set!

07-15 12:00:33.696: D/Picker(21000): Set!
07-15 12:00:33.719: D/Picker(21000): Set!

Diğer notlar ve yorumlar

  • DatePickerFragment etrafında sarma bir önemi yok. Sorun basit, ama bunu test ettik.

CEVAP
15 Temmuz 2012, Pazar


Not:Fixed as of Lollipop, source here. Otomatik class for use in clients () tüm Android sürümleri ile uyumlu olarak güncellenmiş.

TL;DR: 1-2-3 küresel bir çözüm: ölü kolay adımda

  1. this sınıf indir.
  2. Aktivite OnDateSetListener (veya sınıfı ihtiyaçlarınıza göre değiştirin) uygulamak.
  3. Bu kod ile iletişim (bu örnekte, Fragment içinde kullanıyorum) tetik:

    Bundle b = new Bundle();
    b.putInt(DatePickerDialogFragment.YEAR, 2012);
    b.putInt(DatePickerDialogFragment.MONTH, 6);
    b.putInt(DatePickerDialogFragment.DATE, 17);
    DialogFragment picker = new DatePickerDialogFragment();
    picker.setArguments(b);
    picker.show(getActivity().getSupportFragmentManager(), "frag_date_picker");
    

Ve hepsi bu kadar!Neden hala tutmak benim cevap olarak "kabul" çünkü ben hala tercih çözümüm bu yana bir çok küçük ayak izi istemci kodu, hitap ettiği temel sorun, (dinleyici olmak denir çerçevesinde sınıf), gayet iyi çalışıyor genelinde yapılandırma değişiklikleri ve güzergah kod mantığı için varsayılan uygulama bir önceki Android sürümleri değil rahatsız bu hata (bkz: sınıf kaynak).

(Tarihi ve didaktik nedenden dolayı orijinal) cevap:

Hata kaynağı

TAMAM, gerçekten bir hata olduğunu ve başkası zaten dolu gibi görünüyor. Issue 34833.

Sorun muhtemelen DatePickerDialog.java olduğunu buldum. Okur:

private void tryNotifyDateSet() {
    if (mCallBack != null) {
        mDatePicker.clearFocus();
        mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
                mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
    }
}

@Override
protected void onStop() {
    tryNotifyDateSet();
    super.onStop();
}

Olabilirdi sanırım:

@Override
protected void onStop() {
    // instead of the full tryNotifyDateSet() call:
    if (mCallBack != null) mDatePicker.clearFocus();
    super.onStop();
}

Şimdi eğer birisi yama/hata raporu Android için teklif nasıl yapabileceğimi anlatırsan çok memnun olurum. Bu arada Sorunun DatePickerDialog.java eklenmiş bir versiyonu olarak olası bir düzeltme (basit) önerdim.

Konsept hata önlemek için

Kurucu null dinleyici kümesi ve BUTTON_POSITIVE kendi düğmesi daha sonra oluşturmak. Bu, detaylar aşağıda.

Sorunun kaynağı olarak gördüğünüz gibi DatePickerDialog.java, yapıcı geçildi dinleyici saklayan global bir değişken (mCallBack) aramaları için olur:

    /**
 * @param context The context the dialog is to run in.
 * @param callBack How the parent is notified that the date is set.
 * @param year The initial year of the dialog.
 * @param monthOfYear The initial month of the dialog.
 * @param dayOfMonth The initial day of the dialog.
 */
public DatePickerDialog(Context context,
        OnDateSetListener callBack,
        int year,
        int monthOfYear,
        int dayOfMonth) {
    this(context, 0, callBack, year, monthOfYear, dayOfMonth);
}

    /**
 * @param context The context the dialog is to run in.
 * @param theme the theme to apply to this dialog
 * @param callBack How the parent is notified that the date is set.
 * @param year The initial year of the dialog.
 * @param monthOfYear The initial month of the dialog.
 * @param dayOfMonth The initial day of the dialog.
 */
public DatePickerDialog(Context context,
        int theme,
        OnDateSetListener callBack,
        int year,
        int monthOfYear,
        int dayOfMonth) {
    super(context, theme);

    mCallBack = callBack;
    // ... rest of the constructor.
}

Yani, mesele sağlamak null dinleyici olmak saklı olarak dinleyici ve sonra rulo kendi ayarlama düğmesi (aşağıda orijinal kodu #1, güncellenir)

    DatePickerDialog picker = new DatePickerDialog(
        this,
        null, // instead of a listener
        2012, 6, 15);
    picker.setCancelable(true);
    picker.setCanceledOnTouchOutside(true);
    picker.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d("Picker", "Correct behavior!");
            }
        });
    picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d("Picker", "Cancel!");
            }
        });
picker.show();

Şimdi ben yukarıda yayınlanmıştır Olası düzeltme nedeniyle çalışacak.

Ve okur, her DatePickerDialog.java null mCallback kontrol beri(since the days of API 3/1.5 it seems --- tabii ki Petek kontrol edemez), bu durum tetikleyici olmaz.Lolipop konu sabit, ona bakmak için gitmiyorum düşünürsek: sadece varsayılan uygulama (sana verilen sınıf kaplı).

İlk clearFocus() ama burada test ettik aramadığım korktum ve Günlük hat temiz. Bu hat teklif ettiğim zaman sonra bile gerekli olmayabilir, ama bilmiyorum.

Önceki API düzeyleri ile uyumluluk(düzenlenmiş)

Bu yorum, aşağıda belirttiğim gibi, bir kavram olduğunu, 44**. Ben eskisi gibi, varsayılan sistem uygulaması sürümleri hata etkilenmez.

Birkaç varsayımlar (düğme adları vb.) aldım bu en az müşteri sınıflarda demirbaş kodu azaltmak için istedim çünkü benim ihtiyaçları için uygundur. Tam kullanım örneği:

class YourActivity extends SherlockFragmentActivity implements OnDateSetListener

// ...

Bundle b = new Bundle();
b.putInt(DatePickerDialogFragment.YEAR, 2012);
b.putInt(DatePickerDialogFragment.MONTH, 6);
b.putInt(DatePickerDialogFragment.DATE, 17);
DialogFragment picker = new DatePickerDialogFragment();
picker.setArguments(b);
picker.show(getActivity().getSupportFragmentManager(), "fragment_date_picker");

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Matthew Pearce

    Matthew Pear

    9 AĞUSTOS 2009
  • Tahir Jahi

    Tahir Jahi

    6 Mart 2006
  • Triune Films

    Triune Films

    9 ŞUBAT 2006