Created
August 8, 2013 13:19
-
-
Save tprochazka/6184505 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Activity; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.os.Bundle; | |
import android.os.Handler; | |
import android.os.Message; | |
import android.preference.Preference; | |
import android.preference.PreferenceGroup; | |
import android.preference.PreferenceManager; | |
import android.preference.PreferenceScreen; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.ViewParent; | |
import android.widget.ListView; | |
import com.actionbarsherlock.app.SherlockListFragment; | |
import java.lang.reflect.Constructor; | |
import java.lang.reflect.Method; | |
import eu.inmite.android.fw.DebugLog; | |
import eu.inmite.android.fw.R; | |
/** | |
* Based on code from Fr4gg0r from http://forum.xda-developers.com/showthread.php?t=1363906 | |
* | |
* <p>You must declare this method in host activity if you use some preference which open the dialog.</p> | |
* <code> | |
* @Override | |
* protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
* super.onActivityResult(requestCode, resultCode, data); | |
* mPrefFragment.onActivityResult(requestCode, resultCode, data); | |
* } | |
* </code> | |
*/ | |
public abstract class PreferenceListFragment extends SherlockListFragment { | |
private PreferenceManager mPreferenceManager; | |
/** | |
* The starting request code given out to preference framework. | |
*/ | |
private static final int FIRST_REQUEST_CODE = 100; | |
private static final int MSG_BIND_PREFERENCES = 0; | |
private Handler mHandler = new Handler() { | |
@Override | |
public void handleMessage(Message msg) { | |
switch (msg.what) { | |
case MSG_BIND_PREFERENCES: | |
bindPreferences(); | |
break; | |
} | |
} | |
}; | |
private ListView lv; | |
private int xmlId; | |
public PreferenceListFragment(int xmlId) { | |
this.xmlId = xmlId; | |
} | |
//must be provided | |
public PreferenceListFragment() { | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) { | |
postBindPreferences(); | |
return lv; | |
} | |
@Override | |
public void onDestroyView() { | |
super.onDestroyView(); | |
ViewParent p = lv.getParent(); | |
if (p != null) | |
((ViewGroup) p).removeView(lv); | |
} | |
@Override | |
public void onCreate(Bundle b) { | |
super.onCreate(b); | |
if (b != null) { | |
xmlId = b.getInt("xml"); | |
} | |
mPreferenceManager = onCreatePreferenceManager(); | |
lv = (ListView) LayoutInflater.from(getActivity()).inflate(R.layout.preference_list_content, null); | |
lv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); | |
if (xmlId > 0) { | |
addPreferencesFromResource(xmlId); | |
} | |
} | |
@Override | |
public void onViewCreated(View view, Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
postBindPreferences(); | |
onPreferenceAttached(getPreferenceScreen(), xmlId); | |
} | |
@Override | |
public void onStop() { | |
super.onStop(); | |
try { | |
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop"); | |
m.setAccessible(true); | |
m.invoke(mPreferenceManager); | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.onStop() - failed", e); | |
} | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
lv = null; | |
try { | |
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); | |
m.setAccessible(true); | |
m.invoke(mPreferenceManager); | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.onDestroy() - failed", e); | |
} | |
} | |
@Override | |
public void onSaveInstanceState(Bundle outState) { | |
outState.putInt("xml", xmlId); | |
super.onSaveInstanceState(outState); | |
} | |
@Override | |
public void onActivityResult(int requestCode, int resultCode, Intent data) { | |
super.onActivityResult(requestCode, resultCode, data); | |
try { | |
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class); | |
m.setAccessible(true); | |
m.invoke(mPreferenceManager, requestCode, resultCode, data); | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.onActivityResult() - failed", e); | |
} | |
} | |
/** | |
* Posts a message to bind the preferences to the list view. | |
* <p> | |
* Binding late is preferred as any custom preference types created in {@link #onCreate(Bundle)} are able to have | |
* their views recycled. | |
*/ | |
private void postBindPreferences() { | |
if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; | |
mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); | |
} | |
private void bindPreferences() { | |
final PreferenceScreen preferenceScreen = getPreferenceScreen(); | |
if (preferenceScreen != null) { | |
preferenceScreen.bind(lv); | |
} | |
} | |
/** | |
* Creates the {@link PreferenceManager}. | |
* | |
* @return The {@link PreferenceManager} used by this activity. | |
*/ | |
private PreferenceManager onCreatePreferenceManager() { | |
try { | |
Constructor<PreferenceManager> c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); | |
c.setAccessible(true); | |
PreferenceManager preferenceManager = c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); | |
return preferenceManager; | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.onCreatePreferenceManager() - failed", e); | |
return null; | |
} | |
} | |
/** | |
* Returns the {@link PreferenceManager} used by this activity. | |
* | |
* @return The {@link PreferenceManager}. | |
*/ | |
public PreferenceManager getPreferenceManager() { | |
return mPreferenceManager; | |
} | |
/** | |
* Sets the root of the preference hierarchy that this activity is showing. | |
* | |
* @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. | |
*/ | |
public void setPreferenceScreen(PreferenceScreen preferenceScreen) { | |
try { | |
Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class); | |
m.setAccessible(true); | |
boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen); | |
if (result && preferenceScreen != null) { | |
postBindPreferences(); | |
} | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.setPreferenceScreen() - failed", e); | |
} | |
} | |
/** | |
* Gets the root of the preference hierarchy that this activity is showing. | |
* | |
* @return The {@link PreferenceScreen} that is the root of the preference | |
* hierarchy. | |
*/ | |
public PreferenceScreen getPreferenceScreen() { | |
try { | |
Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen"); | |
m.setAccessible(true); | |
return (PreferenceScreen) m.invoke(mPreferenceManager); | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.getPreferenceScreen() - failed", e); | |
return null; | |
} | |
} | |
/** | |
* Adds preferences from activities that match the given {@link Intent}. | |
* | |
* @param intent The {@link Intent} to query activities. | |
*/ | |
public void addPreferencesFromIntent(Intent intent) { | |
throw new RuntimeException("Not implemented feature"); | |
} | |
/** | |
* Inflates the given XML resource and adds the preference hierarchy to the current | |
* preference hierarchy. | |
* | |
* @param preferencesResId The XML resource ID to inflate. | |
*/ | |
public void addPreferencesFromResource(int preferencesResId) { | |
try { | |
Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class); | |
m.setAccessible(true); | |
PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen()); | |
setPreferenceScreen(prefScreen); | |
} catch (Exception e) { | |
DebugLog.wtf("PreferenceListFragment.addPreferencesFromResource() - failed", e); | |
} | |
} | |
/** | |
* Finds a {@link Preference} based on its key. | |
* | |
* @param key The key of the preference to retrieve. | |
* @return The {@link Preference} with the key, or null. | |
* @see PreferenceGroup#findPreference(CharSequence) | |
*/ | |
public Preference findPreference(CharSequence key) { | |
if (mPreferenceManager == null) { | |
return null; | |
} | |
return mPreferenceManager.findPreference(key); | |
} | |
public abstract void onPreferenceAttached(PreferenceScreen root, int xmlId); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment