Commit a844a53a authored by Matthias Urhahn's avatar Matthias Urhahn

Cleaned up SettingsActivity

* Introduced `Themeable` interface .
* Created custom views for settings (that also implement the interface).
* Refactored SettingsActivity to use the new stuff.
* Tweaked layouts according to material.io guidelines
parent 79e001b7
......@@ -48,7 +48,7 @@ android {
}
}
project.ext.supportLib = "25.0.1"
project.ext.supportLib = "25.2.0"
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
......@@ -78,4 +78,8 @@ dependencies {
compile 'com.github.Commit451:bypasses:1.0.4'
compile 'com.github.jetradarmobile:desertplaceholder:1.1.1'
//Butter Knife
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}
......@@ -4,6 +4,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.Toolbar;
......@@ -207,8 +208,10 @@ public class AboutActivity extends ThemedActivity {
((TextView) findViewById(R.id.about_version_item_sub)).setText(BuildConfig.VERSION_NAME);
}
@CallSuper
@Override
public void updateUiElements() {
super.updateUiElements();
toolbar.setBackgroundColor(getPrimaryColor());
toolbar.setNavigationIcon(getToolbarIcon(GoogleMaterial.Icon.gmd_arrow_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
......
......@@ -3,6 +3,7 @@ package org.horaapps.leafpic.activities;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v7.widget.CardView;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
......@@ -163,8 +164,10 @@ public class BlackWhiteListActivity extends SharedMediaActivity {
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
@CallSuper
@Override
public void updateUiElements(){
super.updateUiElements();
toolbar.setBackgroundColor(getPrimaryColor());
mRecyclerView.setBackgroundColor(getBackgroundColor());
setStatusBarColor();
......
......@@ -14,6 +14,7 @@ import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.CallSuper;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
......@@ -420,9 +421,10 @@ public class MainActivity extends SharedMediaActivity {
}).start();
}
@CallSuper
@Override
public void updateUiElements() {
super.updateUiElements();
//TODO: MUST BE FIXED
toolbar.setPopupTheme(getPopupToolbarStyle());
toolbar.setBackgroundColor(getPrimaryColor());
......
......@@ -25,6 +25,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.CallSuper;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
......@@ -483,8 +484,10 @@ public class PlayerActivity extends ThemedActivity implements ExoPlayer.EventLi
/**** THEMING STUFF ****/
@CallSuper
@Override
public void updateUiElements() {
super.updateUiElements();
toolbar.setBackgroundColor(getPrimaryColor());
setStatusBarColor();
setNavBarColor();
......
......@@ -3,6 +3,7 @@ package org.horaapps.leafpic.activities;
import android.content.DialogInterface;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.SwitchCompat;
......@@ -167,8 +168,10 @@ public class SecurityActivity extends ThemedActivity {
}
@CallSuper
@Override
public void updateUiElements() {
super.updateUiElements();
setRecentApp(getString(R.string.security));
toolbar.setBackgroundColor(getPrimaryColor());
......
......@@ -11,6 +11,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
......@@ -178,7 +179,9 @@ public class SingleMediaActivity extends SharedMediaActivity {
}
}
@CallSuper
public void updateUiElements() {
super.updateUiElements();
/**** Theme ****/
toolbar = (Toolbar) findViewById(R.id.toolbar);
activityBackground = (RelativeLayout) findViewById(R.id.PhotoPager_Layout);
......
......@@ -11,6 +11,7 @@ import android.graphics.PorterDuff;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.util.Log;
......@@ -149,8 +150,10 @@ public class SplashScreen extends SharedMediaActivity {
}
}
@CallSuper
@Override
public void updateUiElements() {
super.updateUiElements();
((ProgressBar) findViewById(R.id.progress_splash)).getIndeterminateDrawable().setColorFilter(getPrimaryColor(), PorterDuff.Mode.SRC_ATOP);
findViewById(org.horaapps.leafpic.R.id.Splah_Bg).setBackgroundColor(getBackgroundColor());
}
......
......@@ -7,9 +7,11 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
......@@ -27,6 +29,8 @@ import org.horaapps.leafpic.util.ColorPalette;
import org.horaapps.leafpic.util.PreferenceUtil;
import org.horaapps.leafpic.util.Theme;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
import org.horaapps.leafpic.util.ViewUtil;
import java.util.ArrayList;
......@@ -66,6 +70,14 @@ public abstract class ThemedActivity extends AppCompatActivity implements UiElem
applyThemeSingleImgAct = SP.getBoolean(getString(R.string.preference_apply_theme_pager), true);
}
@CallSuper
@Override
public void updateUiElements() {
for (View view : ViewUtil.getAllChildren(findViewById(android.R.id.content))) {
if (view instanceof Themeable) ((Themeable) view).refreshTheme(getThemeHelper());
}
}
@Override
protected void attachBaseContext(Context newBase) {
// NOTE: icons stuff
......
......@@ -68,7 +68,9 @@ public class ColorsSetting extends ThemedSetting {
public interface ColorChooser {
void onColorSelected(int color);
void onDialogDismiss();
void onColorChanged(int color);
}
......@@ -123,7 +125,10 @@ public class ColorsSetting extends ThemedSetting {
dialogBuilder.setPositiveButton(getActivity().getString(R.string.ok_action).toUpperCase(), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
AlertDialog alertDialog = (AlertDialog) dialog;
alertDialog.setOnDismissListener(null);
chooser.onColorSelected(colorPicker2.getColor());
}
});
......
package org.horaapps.leafpic.util;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
* Views that can react to theme changes should implement this.
*/
public interface Themeable {
void refreshTheme(ThemeHelper themeHelper);
}
package org.horaapps.leafpic.util;
import android.app.Activity;
import android.content.res.Resources;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ViewUtil {
// http://stackoverflow.com/questions/18668897/android-get-all-children-elements-of-a-viewgroup
public static List<View> getAllChildren(View target) {
if (!(target instanceof ViewGroup)) return Collections.singletonList(target);
ArrayList<View> allChildren = new ArrayList<>();
ViewGroup viewGroup = (ViewGroup) target;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
ArrayList<View> targetsChildren = new ArrayList<>();
targetsChildren.add(target);
targetsChildren.addAll(getAllChildren(child));
allChildren.addAll(targetsChildren);
}
return allChildren;
}
public static boolean hasNavBar(Activity activity) {
Resources resources = activity.getResources();
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
return resources.getBoolean(id);
} else { // Check for keys
boolean hasMenuKey = ViewConfiguration.get(activity).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
return !hasMenuKey && !hasBackKey;
}
}
}
package org.horaapps.leafpic.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.mikepenz.iconics.view.IconicsImageView;
import org.horaapps.leafpic.R;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class SettingBasic extends FrameLayout implements Themeable {
private final String iconString;
@StringRes private final int titleRes;
@StringRes private final int captionRes;
@BindView(R.id.icon) IconicsImageView icon;
@BindView(R.id.title) TextView title;
@BindView(R.id.caption) TextView caption;
public SettingBasic(Context context) {
this(context, null);
}
public SettingBasic(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SettingBasic(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setBackgroundResource(R.drawable.ripple);
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.view_setting_basic, this);
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.SettingBasic);
iconString = a.getString(R.styleable.SettingBasic_settingIcon);
titleRes = a.getResourceId(R.styleable.SettingBasic_settingTitle, 0);
captionRes = a.getResourceId(R.styleable.SettingBasic_settingCaption, 0);
int minimumApi = a.getInteger(R.styleable.SettingBasic_settingMinApi, 0);
a.recycle();
if (Build.VERSION.SDK_INT < minimumApi) setVisibility(GONE);
}
@Override
protected void onFinishInflate() {
ButterKnife.bind(this);
icon.setIcon(iconString);
title.setText(titleRes);
caption.setText(captionRes);
setPadding(
(int) getResources().getDimension(R.dimen.medium_spacing),
0,
(int) getResources().getDimension(R.dimen.medium_spacing),
0
);
setMinimumHeight((int) getResources().getDimension(R.dimen.listitem_height_twoline));
super.onFinishInflate();
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
}
}
package org.horaapps.leafpic.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.mikepenz.iconics.view.IconicsImageView;
import org.horaapps.leafpic.R;
import org.horaapps.leafpic.activities.base.ThemedActivity;
import org.horaapps.leafpic.util.PreferenceUtil;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class SettingWithSwitchView extends FrameLayout implements View.OnClickListener, Themeable {
private final String iconString;
private final String preferenceKey;
@StringRes private final int titleRes;
@StringRes private final int captionRes;
private final boolean defaultValue;
@BindView(R.id.icon) IconicsImageView icon;
@BindView(R.id.title) TextView title;
@BindView(R.id.caption) TextView caption;
@BindView(R.id.toggle) SwitchCompat toggle;
private PreferenceUtil preferences;
@Nullable private OnClickListener clickListener;
public SettingWithSwitchView(Context context) {
this(context, null);
}
public SettingWithSwitchView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SettingWithSwitchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setBackgroundResource(R.drawable.ripple);
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.view_setting_switch, this);
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.SettingWithSwitchView);
iconString = a.getString(R.styleable.SettingBasic_settingIcon);
final int prefKeyRes = a.getResourceId(R.styleable.SettingWithSwitchView_settingPreferenceKey, 0);
if (prefKeyRes == 0) throw new IllegalArgumentException("Invalid preference reference");
preferenceKey = getResources().getString(prefKeyRes);
titleRes = a.getResourceId(R.styleable.SettingBasic_settingTitle, 0);
captionRes = a.getResourceId(R.styleable.SettingBasic_settingCaption, 0);
defaultValue = a.getBoolean(R.styleable.SettingWithSwitchView_settingDefaultValue, false);
int minimumApi = a.getInteger(R.styleable.SettingBasic_settingMinApi, 0);
a.recycle();
preferences = PreferenceUtil.getInstance(getContext());
if (Build.VERSION.SDK_INT < minimumApi) setVisibility(GONE);
}
@Override
protected void onFinishInflate() {
ButterKnife.bind(this);
icon.setIcon(iconString);
title.setText(titleRes);
caption.setText(captionRes);
toggle.setChecked(isChecked());
super.setOnClickListener(this);
setPadding(
(int) getResources().getDimension(R.dimen.medium_spacing),
0,
(int) getResources().getDimension(R.dimen.medium_spacing),
0
);
setMinimumHeight((int) getResources().getDimension(R.dimen.listitem_height_twoline));
super.onFinishInflate();
}
@Override
public void setOnClickListener(@Nullable OnClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!isInEditMode()) refreshTheme(((ThemedActivity) getContext()).getThemeHelper());
}
@Override
public void onClick(View view) {
toggle();
refreshTheme(((ThemedActivity) getContext()).getThemeHelper());
if (clickListener != null) clickListener.onClick(this);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
themeHelper.setSwitchCompactColor(toggle, themeHelper.getAccentColor());
}
public boolean isChecked() {
return preferences.getBoolean(preferenceKey, defaultValue);
}
public boolean toggle() {
preferences.getEditor().putBoolean(preferenceKey, !isChecked()).apply();
boolean checked = isChecked();
toggle.setChecked(checked);
return checked;
}
}
package org.horaapps.leafpic.views.themeable;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ThemeableCardView extends CardView implements Themeable {
public ThemeableCardView(Context context) {
this(context, null);
}
public ThemeableCardView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemeableCardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
setCardBackgroundColor(themeHelper.getCardBackgroundColor());
}
}
package org.horaapps.leafpic.views.themeable;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ScrollView;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ThemeableScrollView extends ScrollView implements Themeable {
public ThemeableScrollView(Context context) {
this(context, null);
}
public ThemeableScrollView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemeableScrollView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
themeHelper.setScrollViewColor(this);
}
}
package org.horaapps.leafpic.views.themeable;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ThemeableSettingsCaption extends android.support.v7.widget.AppCompatTextView implements Themeable {
public ThemeableSettingsCaption(Context context) {
this(context, null);
}
public ThemeableSettingsCaption(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemeableSettingsCaption(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
setTextColor(themeHelper.getSubTextColor());
}
}
package org.horaapps.leafpic.views.themeable;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ThemeableSettingsCategory extends android.support.v7.widget.AppCompatTextView implements Themeable {
public ThemeableSettingsCategory(Context context) {
this(context, null);
}
public ThemeableSettingsCategory(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemeableSettingsCategory(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
themeHelper.setTextViewColor(this, themeHelper.getAccentColor());
}
}
package org.horaapps.leafpic.views.themeable;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import com.mikepenz.iconics.view.IconicsImageView;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ThemeableSettingsIcon extends IconicsImageView implements Themeable {
public ThemeableSettingsIcon(Context context) {
this(context, null);
}
public ThemeableSettingsIcon(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemeableSettingsIcon(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
setColor(themeHelper.getIconColor());
}
}
package org.horaapps.leafpic.views.themeable;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import org.horaapps.leafpic.util.ThemeHelper;
import org.horaapps.leafpic.util.Themeable;
/**
* Created by darken (darken@darken.eu) on 04.03.2017.
*/
public class ThemeableSettingsTitle extends android.support.v7.widget.AppCompatTextView implements Themeable {
public ThemeableSettingsTitle(Context context) {
this(context, null);
}
public ThemeableSettingsTitle(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemeableSettingsTitle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void refreshTheme(ThemeHelper themeHelper) {
setTextColor(themeHelper.getTextColor());
}
}