1

Je souhaite modifier DatePickerDialogs et TimePickerDialogs en utilisant leur style spinner. Pour ce cas, j'ai ajouté android: datePickerStyle et android: timePickerStyle à mon AppTheme. Lorsque je testais les changements de style, tout va bien sur un périphérique Nexus virtuel émulé. Mais quand je l'ai testé sur un appareil Samsung, là où noch changé de styles chargés. Les deux appareils fonctionnent avec Nougat.Les modifications de style Android ne fonctionnent pas avec les périphériques Samsung

Voici un extrait de mon style.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 
    <item name="colorPrimary">@color/colorPrimary</item> 
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item> 
    <item name="colorAccent">@color/colorAccent</item> 
    <item name="android:datePickerStyle">@style/AppTheme.DatePicker</item> 
    <item name="android:timePickerStyle">@style/AppTheme.TimePicker</item> 
</style> 

<style name="AppTheme.DatePicker" parent="android:Widget.DatePicker"> 
    <item name="android:spinnersShown">true</item> 
    <item name="android:calendarViewShown">false</item> 
</style> 

<style name="AppTheme.TimePicker" parent="android:Widget.Material.TimePicker"> 
    <item name="android:timePickerMode">spinner</item> 
</style> 

Et c'est la façon dont je l'appelle DatePickerDialog. (Les TimePickerDialogs sont appelés de la même manière)

DatePickerDialog datePickerDialog = new DatePickerDialog(
        getView().getContext(), SettingsFragment.this, 2000 , 10, 1); 
datePickerDialog.show(); 

Settings.Fragment est le fragment qui appelle les boîtes de dialogue.

Cela lui comment il devrait ressembler Nexus device

Ce qu'il ne devrait pas comment regarder Samsung device

Edit: L'appareil Nexus est un émulé Nexus 5X virtuel avec Android 7.1.1 et l'appareil Samsung est un Samsung S7 Edge avec Android 7.0.

Répondre

0

J'ai trouvé une solution de contournement pour le problème moi-même. La solution de contournement consiste à ne pas utiliser les styles globaux. Au lieu de cela j'ai dû écrire mon propre DatePickerDialog.

Dans la disposition de boîte de dialogue personnalisée, je pouvais utiliser les préférences DatePicker que je voulais. Cela ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:gravity="center" 
     android:orientation="vertical"> 

     <DatePicker 
      android:id="@+id/spinnerDatePicker" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:calendarViewShown="false" 
      android:datePickerMode="spinner" 
      android:focusable="true" 
      android:spinnersShown="true" /> 
    </LinearLayout> 

La boîte de dialogue personnalisée se présente comme suit:

public class SpinnerDatePickerDialog extends DialogFragment { 

    private ISpinnerDatePickerDialogListener listener; 
    private DatePicker datePicker; 

    // this is no clean android fragment constructor, but we want to use it here 
    @SuppressLint("ValidFragment") 
    public SpinnerDatePickerDialog(ISpinnerDatePickerDialogListener listener) { 
     super(); 
     this.listener = listener; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     // Build the dialog and set up the button click handlers 
     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_date, null); 
     datePicker = (DatePicker) view.findViewById(R.id.spinnerDatePicker); 
     datePicker.updateDate(defaultYear, defaultMonth, defaultDay); 
     builder.setView(view); 
     builder 
      .setPositiveButton(R.string.submit, new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        // Send the positive button event back to the host activity 
        listener.onSpinnerDateDialogPositiveClick(SpinnerDatePickerDialog.this); 
       } 
      }) 
      .setNegativeButton(R.string.abort, new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        // Send the negative button event back to the host activity 
        listener.onSpinnerDateDialogNegativeClick(SpinnerDatePickerDialog.this); 
       } 
      }); 
     return builder.create(); 
    } 

} 

Pour envoyer des valeurs au fragment d'origine, j'ai créé une interface. Le fragment original implémente cette interface et le dialogue personnalisé obtient le fragment en tant que paramètre dans son constructeur. De cette façon, je peux déclencher l'auditeur dans le fragment original. L'interface:

public interface ISpinnerDatePickerDialogListener { 
    void onSpinnerDateDialogPositiveClick(SpinnerDatePickerDialog dialog); 
    void onSpinnerDateDialogNegativeClick(SpinnerDatePickerDialog dialog); 
} 

La classe fragment qui appelle la boîte de dialogue:

public class SettingsFragment extends Fragment implements ISpinnerDatePickerDialogListener, ISpinnerTimePickerDialogListener { 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     // initialize listeners for text inputs, to open picker dialogs 
     periodBegin = (EditText) getView().findViewById(R.id.editPeriodBegin); 
     periodBegin.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       showDialog(PERIOD_BEGIN_DIALOG_ID); 
      } 
     }); 

    } 

    /** 
    * opens dialog for id 
    * 
    * @param id 
    */ 
    private void showDialog(int id) { 
     switch(id) { 
      case PERIOD_BEGIN_DIALOG_ID: 
       SpinnerDatePickerDialog datePickerDialog; 
       datePickerDialog = new SpinnerDatePickerDialog(this); 
       datePickerDialog.show(getFragmentManager(), datePickerDialog.getTAG()); 
       break; 

    } 

    @Override 
    public void onSpinnerDateDialogPositiveClick(SpinnerDatePickerDialog dialog) { 
     // TODO send DatePicker values with listener 
     // load DatePicker from dialog and set them to EditText text 
     DatePicker datePicker = dialog.getDatePicker(); 
     int day = datePicker.getDayOfMonth(); 
     int month = datePicker.getMonth(); 
     int year = datePicker.getYear(); 

     // TODO 
     String formattedDate = FORMAT.format(new Date(year - 1900, month, day)); 
     periodBegin.setText(formattedDate); 
    } 

    @Override 
    public void onSpinnerDateDialogNegativeClick(SpinnerDatePickerDialog dialog) { 
     // Nothing to do here 
    } 

} 
+0

Vous devez utiliser le contexte constructeur AlertDialog pour gonfler les vues personnalisées. LayoutInflater.from (builder.getContext()) gonfler (R.layout.dialog_date, null); Si vous utilisez AppCompat, le thème AlertDialog est un thème de superposition appliqué sur le thème Activité. – BladeCoder

+0

Merci beaucoup. Avoir eu tellement de mal avec Samsung remplaçant les thèmes par défaut depuis si longtemps ... Cela fonctionne! – Otziii

+0

Les fragments doivent toujours avoir un constructeur sans-arg. Il existe une autre solution qui vous permettra d'utiliser un écouteur de rappel à l'intérieur du fragment. Utilisez la méthode getActivity ou getParentFragment(). –