2016-02-05 9 views
5

Ich habe ein DatePickerFragment, das ein sehr einfaches benutzerdefiniertes Layout verwendet. Das Layout nimmt den gesamten Alarmdialog auf kleineren Geräten (HTC One m7) auf, aber nicht auf dem Nexus 6. Weiß jemand, warum der DatePicker nicht die gesamte Breite des Nexus 6-Alarmdialogs einnimmt oder wo er mit der Fehlersuche beginnt? Vielen Dank!DatePicker Widget nimmt nicht den gesamten AlertDialog auf Nexus 6 auf 0

Nexus 6 (beachten Sie, dass Datum Header füllt nicht den gesamten Warndialog)

enter image description here

HTC One m7

enter image description here

dialog_date.xml

<?xml version="1.0" encoding="utf-8"?> 
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/dialog_date_date_picker" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:calendarViewShown="false"> 
</DatePicker> 

onCreateDialog() o f DatePickerFragment

public Dialog onCreateDialog(Bundle savedInstanceState) { 
     Date date = (Date) getArguments().getSerializable(ARG_DATE); 

     Calendar calendar = Calendar.getInstance(); 
     calendar.setTime(date); 
     int year = calendar.get(Calendar.YEAR); 
     int month = calendar.get(Calendar.MONTH); 
     int day = calendar.get(Calendar.DAY_OF_MONTH); 

     View v = LayoutInflater.from(getActivity()) 
       .inflate(R.layout.dialog_date, null); 

     mDatePicker = (DatePicker) 
    v.findViewById(R.id.dialog_date_date_picker); 
     mDatePicker.init(year, month, day, null); 

     return new AlertDialog.Builder(getActivity()) 
       .setView(v) 
//      .setTitle(R.string.date_picker_title) 
       .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         int year = mDatePicker.getYear(); 
         int month = mDatePicker.getMonth(); 
         int day = mDatePicker.getDayOfMonth(); 
         Date date = new GregorianCalendar(year, month, day).getTime(); 
         sendResult(Activity.RESULT_OK, date); 
        } 
       }) 
       .create(); 
     } 
+0

Es gab einige Vorschläge für die Verwendung von match_parent, aber der alertdialog wird immer gleich dargestellt, egal ob match_parent oder wrap_content verwendet wird. – dazza5000

+0

hast du das jemals gelöst? – Nico

+0

Ich habe kein Nexus 6, um das zu testen, aber ich habe die Datei dialog_date.xml geändert, um android: layout_width = "match_parent" zu haben – dazza5000

Antwort

0

ich nicht in der Lage war, dies mit dem Vorschlag von nitzanj zu arbeiten, aber ich eingeschaltet, wie ich die DatePickerDialog erstellt und es funktioniert jetzt wie erwartet. Die vollständige Quelle ist unten. Der Hauptunterschied liegt in onCreateDialog.

public class DatePickerFragment extends DialogFragment 
     implements DatePickerDialog.OnDateSetListener{ 

    public static final String EXTRA_DATE = 
      "com.amicly.acaringtext.date"; 

    private static final String ARG_DATE = "date"; 

    @NonNull 
    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     Date date = (Date) getArguments().getSerializable(ARG_DATE); 

     Calendar calendar = Calendar.getInstance(); 
     calendar.setTime(date); 
     int year = calendar.get(Calendar.YEAR); 
     int month = calendar.get(Calendar.MONTH); 
     int day = calendar.get(Calendar.DAY_OF_MONTH); 

     return new DatePickerDialog(getActivity(), this, year, month, day); 
    } 

    public static DatePickerFragment newInstance(Date date) { 
     Bundle args = new Bundle(); 
     args.putSerializable(ARG_DATE, date); 
     DatePickerFragment fragment = new DatePickerFragment(); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    private void sendResult(int resultCode, Date date) { 
     if (getTargetFragment() == null) { 
      return; 
     } 
     Intent intent = new Intent(); 
     intent.putExtra(EXTRA_DATE, date); 

     getTargetFragment(). 
       onActivityResult(getTargetRequestCode(), resultCode, intent); 
    } 

    @Override 
    public void onDateSet(DatePicker datePicker, int year, int month, int day) { 
     Date date = new GregorianCalendar(year, month, day).getTime(); 
     sendResult(Activity.RESULT_OK, date); 
    } 
} 
3

Alert-Dialog hat einige strenge (komisch?) Regeln seiner Größe regeln. Ich bin mir nicht sicher, wie ich es lösen soll, aber es gibt eine Problemumgehung - Sobald der Dialog angezeigt wird, können Sie erzwingen, dass seine Breite der Breite des Datumsauswahlgeräts entspricht. Dies löste es für mich, hoffentlich wird es auch für Sie arbeiten:

public Dialog onCreateDialog(Bundle savedInstanceState) { 
    ... 
    final AlertDialog alertDialog = new AlertDialog.Builder(getActivity()) 
      ... 
      .create(); 

    alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { 
     @Override public void onShow(DialogInterface dialog) { 
      WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 
      final Window window = getDialog().getWindow(); 
      lp.copyFrom(window.getAttributes()); 
      final View picker = window.findViewById(R.id.dialog_date_date_picker); 
      lp.width = picker.getWidth(); 
      lp.height = picker.getHeight(); 
      window.setAttributes(lp); 
     } 
    }); 

    return alertDialog; 
} 
+0

Perfekt, danke! Ich wünschte, ich wüsste, warum es nicht normal passt, aber diese Lösung funktioniert völlig, danke nochmal :) – Nico

+0

Das hat es nicht für mich behoben. experimentiere immer noch, um zu sehen, ob ich eine Lösung finden kann. Prost! – dazza5000

+0

@ dazza5000 Es ist wichtig, den 'android.app.AlertDialog', ** nicht ** den' android.support.v7.app.AlertDialog' zu verwenden. –

1

Wenn jemand ihren Kopf gegen die Wand bashing darüber (ich war auf jeden Fall nach sechs Stunden mit ihm zu tun), dann wird dies wahrscheinlich für Sie arbeiten.

Anstatt einen AlertDialog mit einem DatePicker darin zu verwenden, verwenden Sie einen DatePickerDialog. Es ist nicht nur viel einfacher einzurichten, sondern es wird tatsächlich wie erwartet angezeigt.

Beispiel Nutzung:

DateTime dateTime = new DateTime(); 

new DatePickerDialog(
        getActivity(), 
        R.style.DatePickerDialogCustom, 
        new DatePickerDialog.OnDateSetListener() { 
         @Override 
         public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { 
          dateTime = new DateTime(
            year, 
            month + 1, 
            dayOfMonth, 
            dateTime.getHourOfDay(), 
            dateTime.getMinuteOfHour() 
          ); 
          etDate.setText(dateFormatter.print(dateTime)); 
         } 
        }, 
        dateTime.getYear(), 
        dateTime.getMonthOfYear() - 1, 
        dateTime.getDayOfMonth() 
      ).show(); 

Die Monate um 1 versetzt, da die Datepicker Monat Rückgabewerte zwischen 0 und 11.

Für den Stil, nicht über eine Alert-Dialog-Stil verwenden. Dies ist tatsächlich, was das ursprüngliche Problem verursacht. Wenn Sie keinen benutzerdefinierten Stil benötigen, entfernen Sie ihn einfach aus dem Konstruktor (verwenden Sie nicht null). Wenn Sie einen benutzerdefinierten Stil verwenden, dann einfach einen neuen Stil in Ihrem styles.xml machen:

<style name="DatePickerDialogCustom" parent="@style/Theme.AppCompat.Dialog"> 
    <item name="android:colorBackground">@color/background</item> 
    <item name="colorAccent">@color/colorAccent</item> 
    <item name="android:datePickerStyle">@style/DatePickerCustom</item> 
</style> 

<style name="DatePickerCustom" parent="@android:style/Widget.Material.DatePicker"> 
    <item name="android:headerBackground">@color/colorAccent</item> 
</style> 

Ich weiß nicht, ob das gleiche Problem TimePickers plagt, aber wenn es tut stelle ich mir eine ähnliche Lösung arbeiten.

5

Der Grund ist, dass AlertDialog mehr Platz benötigt als der untergeordnete DatePicker.

Stellen Sie sicher, dass das Dialogfelddesign (z. B. Theme.AppCompat.Light.Dialog) ohne .Alert Suffix verwendet wird.

+0

Vielen Dank für diese kurze und prägnante Information. Wirklich Segen. :) –

+0

@YunhaoLIU es ist Arbeit –