title: Appcompatactivity with custom native (not compatibility) dialogpreference containing a TimePicker
body: <p>I am building a preferences / settings screen inside an Android <code>AppCompatActivity</code>. One requirement is a custom <code>[DialogPreference][1]</code> with a <code>TimePicker</code>.</p>
  
  <p>The DialogPreference must be 'native', meaning not the compatibility version like described <a href="https://stackoverflow.com/questions/5533078/timepicker-in-preferencescreen/34398747#34398747">here</a> and <a href="https://medium.com/@JakobUlbrich/building-a-settings-screen-for-android-part-3-ae9793fd31ec" rel="nofollow noreferrer">here</a>.</p>
  
  <p>The code for the AppCompatActivity:</p>
  
  <pre><code>...
  
  public class SettingsActivity extends AppCompatActivity
  {
      @Override
      protected void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_preferences);
  
          Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_settings);
          setSupportActionBar(toolbar);
          getSupportActionBar().setDisplayHomeAsUpEnabled(true);
      }
  }
  </code></pre>
  
  <p>The layout of activity_preferences.xml:</p>
  
  <pre><code>...
  
      &lt;android.support.v4.widget.NestedScrollView
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:scrollbars="vertical"
          app:layout_behavior="@string/appbar_scrolling_view_behavior"&gt;
  
          &lt;fragment
              android:name="nl.waywayway.broodkruimels.SettingsFragment"
              android:id="@+id/settings_fragment"
              android:layout_width="match_parent"
              android:layout_height="match_parent" /&gt;
  
      &lt;/android.support.v4.widget.NestedScrollView&gt;
  </code></pre>
  
  <p>The SettingsFragment class:</p>
  
  <pre><code>...
  
  public class SettingsFragment extends PreferenceFragment
  {
      Context mContext;
  
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
          addPreferencesFromResource(R.xml.preferences);
      }
  }
  </code></pre>
  
  <p>The preferences.xml file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;PreferenceScreen
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"&gt;
  
      &lt;SwitchPreference
          android:key="pref_notify"
          android:title="@string/pref_notify"
          android:summary="@string/pref_notify_summ"
          android:defaultValue="false" /&gt;
  
      &lt;nl.waywayway.broodkruimels.TimePreference
          android:dependency="pref_notify"
          android:key="pref_notify_time"
          android:title="@string/pref_notify_time"
          android:summary="@string/pref_notify_time_summ"
          android:defaultValue="390" /&gt;
  
  &lt;/PreferenceScreen&gt;
  </code></pre>
  
  <p>And the custom TimePreference class:</p>
  
  <pre><code>public class TimePreference extends DialogPreference
  {
      private TimePicker mTimePicker = null;
      private int mTime;
      private int mDialogLayoutResId = R.layout.preferences_timepicker_dialog;
  
      // 4 constructors for the API levels,
      // calling each other
  
      public TimePreference(Context context)
      {
          this(context, null);
      }
  
      public TimePreference(Context context, AttributeSet attrs)
      {
          this(context, attrs, R.attr.preferenceStyle);
      }
  
      public  TimePreference(Context context, AttributeSet attrs, int defStyleAttr)
      {
          this(context, attrs, defStyleAttr, defStyleAttr);
      }
  
      public  TimePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
      {
          super(context, attrs, defStyleAttr, defStyleRes);
      }
  
      public int getTime()
      {
          return  mTime;
      }
  
      public void setTime(int time)
      {
          mTime = time;
  
          // Save to Shared Preferences
          persistInt(time);
      }
  
      @Override
      public int getDialogLayoutResource()
      {
          return mDialogLayoutResId;
      }
  
      @Override
      protected Object onGetDefaultValue(TypedArray a, int index)
      {
          //  Default  value  from  attribute.  Fallback  value  is  set  to  0.
          return a.getInt(index,  0);
      }
  
      @Override
      protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue)
      {
          // Read the value. Use the default value if it is not possible.
          setTime(restorePersistedValue ?
                  getPersistedInt(mTime) : (int) defaultValue);
      }
  
      @Override
      protected void onBindDialogView(View view)
      {
          super.onBindDialogView(view);
  
          mTimePicker = (TimePicker) view.findViewById(R.id.preferences_timepicker);
  
          if (mTimePicker == null)
          {
              throw new IllegalStateException("Dialog view must contain a TimePicker with id 'preferences_timepicker'");
          }
  
          // Get the time from the related Preference
          Integer minutesAfterMidnight = null;
          TimePreference preference = (TimePreference) findPreferenceInHierarchy("pref_notify_time");
          minutesAfterMidnight = preference.getTime();
  
          // Set the time to the TimePicker
          if (minutesAfterMidnight != null)
          {
              int hours = minutesAfterMidnight / 60;
              int minutes = minutesAfterMidnight % 60;
              boolean is24hour = DateFormat.is24HourFormat(getContext());
  
              mTimePicker.setIs24HourView(is24hour);
  
              if (Build.VERSION.SDK_INT &gt;= 23)
              {
                  mTimePicker.setHour(hours);
                  mTimePicker.setMinute(minutes);
              }
              else
              {
                  mTimePicker.setCurrentHour(hours);
                  mTimePicker.setCurrentMinute(minutes);
              }
          }
      }
  
      @Override
      protected void onDialogClosed(boolean positiveResult)
      {
          if (positiveResult)
          {
              // Get the current values from the TimePicker
              int hours;
              int minutes;
              if (Build.VERSION.SDK_INT &gt;= 23)
              {
                  hours = mTimePicker.getHour();
                  minutes = mTimePicker.getMinute();
              }
              else
              {
                  hours = mTimePicker.getCurrentHour();
                  minutes = mTimePicker.getCurrentMinute();
              }
  
              // Generate value to save
              int minutesAfterMidnight = (hours * 60) + minutes;
  
              // Save the value
              TimePreference timePreference = (TimePreference) findPreferenceInHierarchy("pref_notify_time");
  
              // This allows the client to ignore the user value.
              if (timePreference.callChangeListener(minutesAfterMidnight))
              {
                  // Save the value
                  timePreference.setTime(minutesAfterMidnight);
              }
          }
      }
  }
  </code></pre>
  
  <p>The preferences_timepicker_dialog.xml file is as follows:</p>
  
  <pre><code>...
  &lt;TimePicker 
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/preferences_timepicker"
      android:layout_width="match_parent"
      android:layout_height="match_parent" /&gt;
  </code></pre>
  
  <p>The result is like the screenshot below. On a Moto G5 plus phone with Android 7.</p>
  
  <p><a href="https://i.stack.imgur.com/kNHyZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/kNHyZ.png" alt="Screenshot"></a></p>
  
  <p><strong>Question:</strong>
  There should be two preferences. However, the custom DialogPreference is not showing in the settings list. 
  What is going wrong here?
  Does the AppCompatActivity actually work with the 'native' DialogPreference?</p>
  
  <p>The TimePreference class is actually instantiated from the preferences xml, that could be logged from the constructor. Also no compile time errors, no runtime errors.</p>