implements IThemeObserver {
14 |
15 | private boolean underObservation = false;
16 |
17 | @Override
18 | public boolean add(View object) {
19 | boolean ret = super.add(object);
20 | checkObserver();
21 | return ret;
22 | }
23 |
24 | @Override
25 | public boolean addAll(Collection extends View> collection) {
26 | boolean ret = super.addAll(collection);
27 | checkObserver();
28 | return ret;
29 | }
30 |
31 | @Override
32 | public boolean remove(Object object) {
33 | boolean ret = super.remove(object);
34 | checkObserver();
35 | return ret;
36 | }
37 |
38 | @Override
39 | public boolean removeAll(Collection> collection) {
40 | boolean ret = super.removeAll(collection);
41 | checkObserver();
42 | return ret;
43 | }
44 |
45 | private void checkObserver() {
46 | if (this.size() > 0) {
47 | if (!underObservation) {
48 | MultiTheme.addObserver(this);
49 | underObservation = true;
50 | }
51 | } else {
52 | if (underObservation) {
53 | MultiTheme.removeObserver(this);
54 | underObservation = false;
55 | }
56 | }
57 | }
58 |
59 | @Override
60 | public void clear() {
61 | super.clear();
62 | checkObserver();
63 | }
64 |
65 | @Override
66 | public int getPriority() {
67 | return PRIORITY_VIEW;
68 | }
69 |
70 | @Override
71 | public void onThemeChanged(int whichTheme) {
72 | for (View view : this) {
73 | MultiTheme.applyTheme(view);
74 | }
75 | }
76 |
77 | @Override
78 | public int compareTo(IThemeObserver o) {
79 | return getPriority() > o.getPriority() ? 1 : -1;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/AndroidMultiTheme/android-multi-theme/src/main/java/io/github/leonhover/theme/annotation/MultiThemeAttrs.java:
--------------------------------------------------------------------------------
1 | package io.github.leonhover.theme.annotation;
2 |
3 | import androidx.annotation.AttrRes;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Inherited;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.RetentionPolicy;
9 | import java.lang.annotation.Target;
10 |
11 | /**
12 | * MultiThemeAttrs是一个Attribute的数组,用来注解MultiTheme支持的主题控件类。
13 | *
14 | * 这些Attribute是具体View的对应Styleable中的值
15 | * 这些值不但是作为MultiTheme中用来索引的Key,也是通过其从XML解析出的Attribute中取出主题元素的值的关键。
16 | *
17 | * 例:
18 | * android:background="?attr/theme_background"
19 | *
20 | * View中都有'android.R.attr.background'的标签,添加其作为View的MultiThemeAttrs,那么MultiTheme
21 | * 就会将'background'标签下的'theme_background'对应attrRes取出,作为主题元素的值来存储。当主题改变
22 | * 的时候,通过'android.R.attr.background'找到attrRes,然后分发到对应的
23 | * {@link io.github.leonhover.theme.widget.ViewWidget}的'applyElementTheme'。
24 | *
25 | * Created by wangzongliang on 2017/2/14.
26 | */
27 | @Retention(RetentionPolicy.RUNTIME)
28 | @Target(ElementType.TYPE)
29 | @Inherited
30 | public @interface MultiThemeAttrs {
31 | @AttrRes int[] value();
32 | }
33 |
--------------------------------------------------------------------------------
/AndroidMultiTheme/android-multi-theme/src/main/java/io/github/leonhover/theme/base/BaseThemeActivity.java:
--------------------------------------------------------------------------------
1 | package io.github.leonhover.theme.base;
2 |
3 | import android.content.res.Configuration;
4 | import android.os.Bundle;
5 | import androidx.appcompat.app.AppCompatActivity;
6 |
7 | import io.github.leonhover.theme.ActivityTheme;
8 | import io.github.leonhover.theme.DarkMode;
9 | import io.github.leonhover.theme.MultiTheme;
10 | import io.github.leonhover.theme.ThemeViewEntities;
11 |
12 | /**
13 | * Created by leonhover on 16-10-9.
14 | */
15 |
16 | public abstract class BaseThemeActivity extends AppCompatActivity {
17 |
18 | private final static String TAG = BaseThemeActivity.class.getSimpleName();
19 | private ActivityTheme activityTheme = new ActivityTheme(this);
20 | private ThemeViewEntities themeViewEntities = new ThemeViewEntities();
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | initTheme();
25 | super.onCreate(savedInstanceState);
26 | }
27 |
28 | private void initTheme() {
29 | configTheme(activityTheme);
30 | activityTheme.assembleThemeBeforeInflate();
31 | }
32 |
33 | /**
34 | * 配置Activity的主题
35 | *
36 | * @param activityTheme Activity主题
37 | */
38 | protected abstract void configTheme(ActivityTheme activityTheme);
39 |
40 | public final ThemeViewEntities getThemeViewEntities() {
41 | return this.themeViewEntities;
42 | }
43 |
44 | /**
45 | * 设置StatusBar的背景色
46 | *
47 | * @param color Color
48 | */
49 | public void setStatusBarColor(int color) {
50 | this.activityTheme.setStatusBarColor(color);
51 | }
52 |
53 | @Override
54 | public void onConfigurationChanged(Configuration newConfig) {
55 | super.onConfigurationChanged(newConfig);
56 | DarkMode mode = MultiTheme.getDarkMode();
57 | if (mode == DarkMode.followSystem) {
58 | int uiMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
59 | if (uiMode == Configuration.UI_MODE_NIGHT_YES) {
60 | MultiTheme.d("MultiTheme", "onConfigurationChanged mode:UI_MODE_NIGHT_YES");
61 | MultiTheme.setAppTheme(MultiTheme.DARK_THEME);
62 | } else {
63 | MultiTheme.d("MultiTheme", "onConfigurationChanged mode:UI_MODE_NIGHT_NO");
64 | MultiTheme.setAppTheme(MultiTheme.sDefaultThemeIndex);
65 | }
66 | }
67 | }
68 |
69 | @Override
70 | protected void onDestroy() {
71 | super.onDestroy();
72 | if (activityTheme != null) {
73 | activityTheme.destroy();
74 | activityTheme = null;
75 | }
76 |
77 | themeViewEntities.clear();
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/AndroidMultiTheme/android-multi-theme/src/main/java/io/github/leonhover/theme/base/BaseThemeFragment.java:
--------------------------------------------------------------------------------
1 | package io.github.leonhover.theme.base;
2 |
3 | import androidx.fragment.app.Fragment;
4 |
5 | import io.github.leonhover.theme.ThemeViewEntities;
6 |
7 | /**
8 | * Created by leonhover on 16-10-9.
9 | */
10 |
11 | public class BaseThemeFragment extends Fragment {
12 |
13 | private ThemeViewEntities themeViewEntities = new ThemeViewEntities();
14 |
15 | public ThemeViewEntities getThemeViewEntities() {
16 | return themeViewEntities;
17 | }
18 |
19 | @Override
20 | public void onDestroyView() {
21 | super.onDestroyView();
22 | themeViewEntities.clear();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/AndroidMultiTheme/android-multi-theme/src/main/java/io/github/leonhover/theme/base/widget/CoverImageView.java:
--------------------------------------------------------------------------------
1 | package io.github.leonhover.theme.base.widget;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Bitmap;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.PorterDuff;
10 | import androidx.appcompat.widget.AppCompatImageView;
11 | import android.util.AttributeSet;
12 |
13 | import java.lang.ref.SoftReference;
14 |
15 | import io.github.leonhover.theme.R;
16 |
17 | /**
18 | * Created by wangzongliang on 2016/11/8.
19 | */
20 |
21 | public class CoverImageView extends AppCompatImageView {
22 |
23 | public static final String TAG = "CoverImageView";
24 |
25 | private Paint mPaint;
26 | private SoftReference tmpBitmapReference = null;
27 | private SoftReference