diff --git a/.gitignore b/.gitignore index 578cc9238..36c1ea6f6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build.properties bin/* gen/* proguard.cfg +build.xml *~ .idea *.iml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c7fa5e9b1..971ba3f90 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -31,6 +31,7 @@ android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:allowBackup="true" + android:theme="@style/AppThemeDark" android:supportsRtl="false" > <activity android:name=".FDroid" diff --git a/CHANGELOG.md b/CHANGELOG.md index 335bcda7c..8bb4cb19a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### Future release +* Add theming with Light and Dark themes * New launcher and notification icons * New default/loading app icon * List anti-features on the App Details screen diff --git a/proguard-project.txt b/proguard-project.txt index 30ccaf578..e9caf6359 100644 --- a/proguard-project.txt +++ b/proguard-project.txt @@ -1,2 +1 @@ -dontobfuscate - diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml new file mode 100644 index 000000000..2c6cc4705 --- /dev/null +++ b/res/values-v11/styles.xml @@ -0,0 +1,11 @@ +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + + <style name="AppBaseThemeDark" parent="android:Theme.Holo"> + <!-- API 11 theme customizations go here --> + </style> + + <style name="AppBaseThemeLight" parent="android:Theme.Holo.Light"> + <!-- API 11 theme customizations go here --> + </style> + +</resources> diff --git a/res/values/array.xml b/res/values/array.xml index aa3def54d..f72e1ac1f 100644 --- a/res/values/array.xml +++ b/res/values/array.xml @@ -15,6 +15,15 @@ <item>24</item> </string-array> + <string-array name="themeNames"> + <item>Dark</item> + <item>Light</item> + </string-array> + <string-array name="themeValues"> + <item>dark</item> + <item>light</item> + </string-array> + <string-array name="dbSyncModeNames"> <item>Off (unsafe)</item> <item>Normal</item> diff --git a/res/values/strings.xml b/res/values/strings.xml index 1d3efa3fd..72e796099 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -146,5 +146,7 @@ <string name="no_handler_app">You don\'t have any available app that can handle %s</string> <string name="compactlayout">Compact Layout</string> <string name="compactlayout_long">Only show app names and summaries in list</string> + <string name="theme">Theme</string> + <string name="theme_long">Choose a theme to use</string> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 000000000..9a13e761c --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,27 @@ +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + + <style name="AppBaseThemeDark" parent="android:Theme.Black"> + <!-- backward-compatibility theme options go here --> + </style> + + <style name="AppBaseThemeLight" parent="android:Theme.Light"> + <!-- backward-compatibility theme options go here --> + </style> + + <color name="black">#FF000000</color> + <color name="white">#FFFFFFFF</color> + + <style name="AboutDialogLight" parent="@android:style/Theme.Dialog"> + <item name="@android:windowBackground">@color/black</item> + <item name="@android:textColor">@color/white</item> + </style> + + <style name="AppThemeDark" parent="AppBaseThemeDark"> + <!-- customizations that are not API-level specific go here. --> + </style> + + <style name="AppThemeLight" parent="AppBaseThemeLight"> + <!-- customizations that are not API-level specific go here. --> + </style> + +</resources> diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 6dadfa468..3c75c506c 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -26,6 +26,11 @@ <CheckBoxPreference android:title="@string/compactlayout" android:defaultValue="false" android:summary="@string/compactlayout_long" android:key="compactlayout"/> + <ListPreference android:title="@string/theme" + android:summary="@string/theme_long" android:key="theme" + android:defaultValue="dark" + android:entries="@array/themeNames" + android:entryValues="@array/themeValues" /> </PreferenceCategory> <PreferenceCategory android:title="@string/appcompatibility"> <CheckBoxPreference android:title="@string/show_incompat_versions" diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java index 053ab21c4..dd515e4c9 100644 --- a/src/org/fdroid/fdroid/AppDetails.java +++ b/src/org/fdroid/fdroid/AppDetails.java @@ -202,6 +202,8 @@ public class AppDetails extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { + ((FDroidApp) getApplication()).applyTheme(this); + super.onCreate(savedInstanceState); ActionBarCompat abCompat = ActionBarCompat.create(this); abCompat.setDisplayHomeAsUpEnabled(true); diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java index 19459d6c7..5068adada 100644 --- a/src/org/fdroid/fdroid/FDroid.java +++ b/src/org/fdroid/fdroid/FDroid.java @@ -30,12 +30,14 @@ import android.app.ProgressDialog; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.support.v4.app.FragmentActivity; import android.support.v4.view.ViewPager; import android.util.Log; +import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -61,6 +63,7 @@ public class FDroid extends FragmentActivity { private ProgressDialog pd; private ViewPager viewPager; + private AppListFragmentPageAdapter viewPageAdapter; private AppListManager manager = null; @@ -73,6 +76,8 @@ public class FDroid extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { + ((FDroidApp) getApplication()).applyTheme(this); + super.onCreate(savedInstanceState); manager = new AppListManager(this); setContentView(R.layout.fdroid); @@ -165,20 +170,35 @@ public class FDroid extends FragmentActivity { return true; case ABOUT: - LayoutInflater li = LayoutInflater.from(this); - View view = li.inflate(R.layout.about, null); + View view = null; + if (Build.VERSION.SDK_INT >= 11) { + LayoutInflater li = LayoutInflater.from(this); + view = li.inflate(R.layout.about, null); + } else { + view = View.inflate( + new ContextThemeWrapper(this, R.style.AboutDialogLight), + R.layout.about, null); + } // Fill in the version... - TextView tv = (TextView) view.findViewById(R.id.version); - PackageManager pm = getPackageManager(); try { - PackageInfo pi = pm.getPackageInfo(getApplicationContext() - .getPackageName(), 0); - tv.setText(pi.versionName); + PackageInfo pi = getPackageManager() + .getPackageInfo(getApplicationContext() + .getPackageName(), 0); + ((TextView) view.findViewById(R.id.version)) + .setText(pi.versionName); } catch (Exception e) { } - Builder p = new AlertDialog.Builder(this).setView(view); + Builder p = null; + if (Build.VERSION.SDK_INT >= 11) { + p = new AlertDialog.Builder(this).setView(view); + } else { + p = new AlertDialog.Builder( + new ContextThemeWrapper( + this, R.style.AboutDialogLight) + ).setView(view); + } final AlertDialog alrt = p.create(); alrt.setIcon(R.drawable.ic_launcher); alrt.setTitle(getString(R.string.about_title)); @@ -244,6 +264,16 @@ public class FDroid extends FragmentActivity { } else if ((resultCode & PreferencesActivity.RESULT_REFILTER) != 0) { ((FDroidApp) getApplication()).filterApps(); } + + if ((resultCode & PreferencesActivity.RESULT_RESTART) != 0) { + ((FDroidApp) getApplication()).reloadTheme(); + final Intent intent = getIntent(); + overridePendingTransition(0, 0); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + finish(); + overridePendingTransition(0, 0); + startActivity(intent); + } break; } @@ -251,7 +281,7 @@ public class FDroid extends FragmentActivity { private void createViews() { viewPager = (ViewPager)findViewById(R.id.main_pager); - AppListFragmentPageAdapter viewPageAdapter = new AppListFragmentPageAdapter(this); + viewPageAdapter = new AppListFragmentPageAdapter(this); viewPager.setAdapter(viewPageAdapter); viewPager.setOnPageChangeListener( new ViewPager.SimpleOnPageChangeListener() { public void onPageSelected(int position) { diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java index 061a0d280..9d401f92c 100644 --- a/src/org/fdroid/fdroid/FDroidApp.java +++ b/src/org/fdroid/fdroid/FDroidApp.java @@ -26,6 +26,7 @@ import java.util.concurrent.Semaphore; import android.os.Build; import android.app.Application; +import android.app.Activity; import android.preference.PreferenceManager; import android.util.Log; import android.content.Context; @@ -43,6 +44,27 @@ import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; public class FDroidApp extends Application { + private static enum Theme { + dark, light + } + private static Theme curTheme = Theme.dark; + + public void reloadTheme() { + curTheme = Theme.valueOf(PreferenceManager + .getDefaultSharedPreferences(getBaseContext()) + .getString("theme", "dark")); + } + public void applyTheme(Activity activity) { + switch (curTheme) { + case dark: + //activity.setTheme(R.style.AppThemeDark); + return; + case light: + activity.setTheme(R.style.AppThemeLight); + return; + } + } + @Override public void onCreate() { super.onCreate(); @@ -58,6 +80,7 @@ public class FDroidApp extends Application { // because the install intent says it's finished when it hasn't. SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(getBaseContext()); + curTheme = Theme.valueOf(prefs.getString("theme", "dark")); if (!prefs.getBoolean("cacheDownloaded", false)) { File local_path = DB.getDataPath(this); diff --git a/src/org/fdroid/fdroid/ManageRepo.java b/src/org/fdroid/fdroid/ManageRepo.java index d2275d10b..12a9076c7 100644 --- a/src/org/fdroid/fdroid/ManageRepo.java +++ b/src/org/fdroid/fdroid/ManageRepo.java @@ -81,6 +81,8 @@ public class ManageRepo extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { + ((FDroidApp) getApplication()).applyTheme(this); + super.onCreate(savedInstanceState); ActionBarCompat abCompat = ActionBarCompat.create(this); abCompat.setDisplayHomeAsUpEnabled(true); diff --git a/src/org/fdroid/fdroid/PreferencesActivity.java b/src/org/fdroid/fdroid/PreferencesActivity.java index 59bb1bf1a..d0690d808 100644 --- a/src/org/fdroid/fdroid/PreferencesActivity.java +++ b/src/org/fdroid/fdroid/PreferencesActivity.java @@ -35,15 +35,20 @@ public class PreferencesActivity extends PreferenceActivity implements public static final int RESULT_RELOAD = 1; public static final int RESULT_REFILTER = 2; + public static final int RESULT_RESTART = 4; private int result = 0; @Override protected void onCreate(Bundle savedInstanceState) { + + ((FDroidApp) getApplication()).applyTheme(this); + super.onCreate(savedInstanceState); ActionBarCompat.create(this).setDisplayHomeAsUpEnabled(true); addPreferencesFromResource(R.xml.preferences); for (String prefkey : new String[] { - "updateInterval", "rooted", "incompatibleVersions" }) { + "updateInterval", "rooted", "incompatibleVersions", + "theme" }) { findPreference(prefkey).setOnPreferenceChangeListener(this); } CheckBoxPreference onlyOnWifi = (CheckBoxPreference) @@ -83,6 +88,11 @@ public class PreferencesActivity extends PreferenceActivity implements setResult(result); return true; } + if (key.equals("theme")) { + result |= RESULT_RESTART; + setResult(result); + return true; + } return false; } diff --git a/src/org/fdroid/fdroid/SearchResults.java b/src/org/fdroid/fdroid/SearchResults.java index 14975b43d..e1b2ece03 100644 --- a/src/org/fdroid/fdroid/SearchResults.java +++ b/src/org/fdroid/fdroid/SearchResults.java @@ -70,6 +70,8 @@ public class SearchResults extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { + ((FDroidApp) getApplication()).applyTheme(this); + super.onCreate(savedInstanceState); ActionBarCompat.create(this).setDisplayHomeAsUpEnabled(true); applist = new AvailableAppListAdapter(this);