mobile/android/base/background/preferences/PreferenceFragment.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2  * Copyright (C) 2013 The Android Open Source Project
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *      http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    17 package org.mozilla.gecko.background.preferences;
    19 import org.mozilla.gecko.R;
    21 import android.content.Intent;
    22 import android.os.Bundle;
    23 import android.os.Handler;
    24 import android.os.Message;
    25 import android.preference.Preference;
    26 import android.preference.PreferenceGroup;
    27 import android.preference.PreferenceManager;
    28 import android.preference.PreferenceScreen;
    29 import android.support.v4.app.Fragment;
    30 import android.view.KeyEvent;
    31 import android.view.LayoutInflater;
    32 import android.view.View;
    33 import android.view.View.OnKeyListener;
    34 import android.view.ViewGroup;
    35 import android.widget.ListView;
    37 public abstract class PreferenceFragment extends Fragment implements PreferenceManagerCompat.OnPreferenceTreeClickListener {
    38   private static final String PREFERENCES_TAG = "android:preferences";
    40   private PreferenceManager mPreferenceManager;
    41   private ListView mList;
    42   private boolean mHavePrefs;
    43   private boolean mInitDone;
    45   /**
    46    * The starting request code given out to preference framework.
    47    */
    48   private static final int FIRST_REQUEST_CODE = 100;
    50   private static final int MSG_BIND_PREFERENCES = 1;
    52   // This triggers "This Handler class should be static or leaks might occur".
    53   // The issue is that the Handler references the Fragment; messages targeting
    54   // the Handler reference it; and if such messages are long lived, the Fragment
    55   // cannot be GCed. This is not an issue for us; our messages are short-lived.
    56   private Handler mHandler = new Handler() {
    57     @Override
    58     public void handleMessage(Message msg) {
    59       switch (msg.what) {
    61       case MSG_BIND_PREFERENCES:
    62         bindPreferences();
    63         break;
    64       }
    65     }
    66   };
    68   final private Runnable mRequestFocus = new Runnable() {
    69     @Override
    70     public void run() {
    71       mList.focusableViewAvailable(mList);
    72     }
    73   };
    75   /**
    76    * Interface that PreferenceFragment's containing activity should
    77    * implement to be able to process preference items that wish to
    78    * switch to a new fragment.
    79    */
    80   public interface OnPreferenceStartFragmentCallback {
    81     /**
    82      * Called when the user has clicked on a Preference that has
    83      * a fragment class name associated with it.  The implementation
    84      * to should instantiate and switch to an instance of the given
    85      * fragment.
    86      */
    87     boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref);
    88   }
    90   @Override
    91   public void onCreate(Bundle paramBundle) {
    92     super.onCreate(paramBundle);
    93     mPreferenceManager = PreferenceManagerCompat.newInstance(getActivity(), FIRST_REQUEST_CODE);
    94     PreferenceManagerCompat.setFragment(mPreferenceManager, this);
    95   }
    97   @Override
    98   public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) {
    99     return paramLayoutInflater.inflate(R.layout.fxaccount_preference_list_fragment, paramViewGroup,
   100         false);
   101   }
   103   @Override
   104   public void onActivityCreated(Bundle savedInstanceState) {
   105     super.onActivityCreated(savedInstanceState);
   107     if (mHavePrefs) {
   108       bindPreferences();
   109     }
   111     mInitDone = true;
   113     if (savedInstanceState != null) {
   114       Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
   115       if (container != null) {
   116         final PreferenceScreen preferenceScreen = getPreferenceScreen();
   117         if (preferenceScreen != null) {
   118           preferenceScreen.restoreHierarchyState(container);
   119         }
   120       }
   121     }
   122   }
   124   @Override
   125   public void onStart() {
   126     super.onStart();
   127     PreferenceManagerCompat.setOnPreferenceTreeClickListener(mPreferenceManager, this);
   128   }
   130   @Override
   131   public void onStop() {
   132     super.onStop();
   133     PreferenceManagerCompat.dispatchActivityStop(mPreferenceManager);
   134     PreferenceManagerCompat.setOnPreferenceTreeClickListener(mPreferenceManager, null);
   135   }
   137   @Override
   138   public void onDestroyView() {
   139     mList = null;
   140     mHandler.removeCallbacks(mRequestFocus);
   141     mHandler.removeMessages(MSG_BIND_PREFERENCES);
   142     super.onDestroyView();
   143   }
   145   @Override
   146   public void onDestroy() {
   147     super.onDestroy();
   148     PreferenceManagerCompat.dispatchActivityDestroy(mPreferenceManager);
   149   }
   151   @Override
   152   public void onSaveInstanceState(Bundle outState) {
   153     super.onSaveInstanceState(outState);
   155     final PreferenceScreen preferenceScreen = getPreferenceScreen();
   156     if (preferenceScreen != null) {
   157       Bundle container = new Bundle();
   158       preferenceScreen.saveHierarchyState(container);
   159       outState.putBundle(PREFERENCES_TAG, container);
   160     }
   161   }
   163   @Override
   164   public void onActivityResult(int requestCode, int resultCode, Intent data) {
   165     super.onActivityResult(requestCode, resultCode, data);
   167     PreferenceManagerCompat.dispatchActivityResult(mPreferenceManager, requestCode, resultCode, data);
   168   }
   170   /**
   171    * Returns the {@link PreferenceManager} used by this fragment.
   172    * @return The {@link PreferenceManager}.
   173    */
   174   public PreferenceManager getPreferenceManager() {
   175     return mPreferenceManager;
   176   }
   178   /**
   179    * Sets the root of the preference hierarchy that this fragment is showing.
   180    *
   181    * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
   182    */
   183   public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
   184     if (PreferenceManagerCompat.setPreferences(mPreferenceManager, preferenceScreen) && preferenceScreen != null) {
   185       mHavePrefs = true;
   186       if (mInitDone) {
   187         postBindPreferences();
   188       }
   189     }
   190   }
   192   /**
   193    * Gets the root of the preference hierarchy that this fragment is showing.
   194    *
   195    * @return The {@link PreferenceScreen} that is the root of the preference
   196    *         hierarchy.
   197    */
   198   public PreferenceScreen getPreferenceScreen() {
   199     return PreferenceManagerCompat.getPreferenceScreen(mPreferenceManager);
   200   }
   202   /**
   203    * Adds preferences from activities that match the given {@link Intent}.
   204    *
   205    * @param intent The {@link Intent} to query activities.
   206    */
   207   public void addPreferencesFromIntent(Intent intent) {
   208     requirePreferenceManager();
   210     setPreferenceScreen(PreferenceManagerCompat.inflateFromIntent(mPreferenceManager, intent, getPreferenceScreen()));
   211   }
   213   /**
   214    * Inflates the given XML resource and adds the preference hierarchy to the current
   215    * preference hierarchy.
   216    *
   217    * @param preferencesResId The XML resource ID to inflate.
   218    */
   219   public void addPreferencesFromResource(int preferencesResId) {
   220     requirePreferenceManager();
   222     setPreferenceScreen(PreferenceManagerCompat.inflateFromResource(mPreferenceManager, getActivity(),
   223         preferencesResId, getPreferenceScreen()));
   224   }
   226   /**
   227    * {@inheritDoc}
   228    */
   229   @Override
   230   public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
   231       Preference preference) {
   232     //if (preference.getFragment() != null &&
   233     if (
   234         getActivity() instanceof OnPreferenceStartFragmentCallback) {
   235       return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment(
   236           this, preference);
   237     }
   238     return false;
   239   }
   241   /**
   242    * Finds a {@link Preference} based on its key.
   243    *
   244    * @param key The key of the preference to retrieve.
   245    * @return The {@link Preference} with the key, or null.
   246    * @see PreferenceGroup#findPreference(CharSequence)
   247    */
   248   public Preference findPreference(CharSequence key) {
   249     if (mPreferenceManager == null) {
   250       return null;
   251     }
   252     return mPreferenceManager.findPreference(key);
   253   }
   255   private void requirePreferenceManager() {
   256     if (mPreferenceManager == null) {
   257       throw new RuntimeException("This should be called after super.onCreate.");
   258     }
   259   }
   261   private void postBindPreferences() {
   262     if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
   263     mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
   264   }
   266   private void bindPreferences() {
   267     final PreferenceScreen preferenceScreen = getPreferenceScreen();
   268     if (preferenceScreen != null) {
   269       preferenceScreen.bind(getListView());
   270     }
   271   }
   273   public ListView getListView() {
   274     ensureList();
   275     return mList;
   276   }
   278   private void ensureList() {
   279     if (mList != null) {
   280       return;
   281     }
   282     View root = getView();
   283     if (root == null) {
   284       throw new IllegalStateException("Content view not yet created");
   285     }
   286     View rawListView = root.findViewById(android.R.id.list);
   287     if (!(rawListView instanceof ListView)) {
   288       throw new RuntimeException(
   289           "Content has view with id attribute 'android.R.id.list' "
   290               + "that is not a ListView class");
   291     }
   292     mList = (ListView)rawListView;
   293     if (mList == null) {
   294       throw new RuntimeException(
   295           "Your content must have a ListView whose id attribute is " +
   296           "'android.R.id.list'");
   297     }
   298     mList.setOnKeyListener(mListOnKeyListener);
   299     mHandler.post(mRequestFocus);
   300   }
   302   private OnKeyListener mListOnKeyListener = new OnKeyListener() {
   304     @Override
   305     public boolean onKey(View v, int keyCode, KeyEvent event) {
   306       Object selectedItem = mList.getSelectedItem();
   307       if (selectedItem instanceof Preference) {
   308         @SuppressWarnings("unused")
   309         View selectedView = mList.getSelectedView();
   310         //return ((Preference)selectedItem).onKey(
   311         //        selectedView, keyCode, event);
   312         return false;
   313       }
   314       return false;
   315     }
   317   };
   318 }

mercurial