代理自定义view换肤功能

This commit is contained in:
wangcongtao
2020-09-03 14:27:56 +08:00
parent c94b883182
commit ac007ba4d8
8 changed files with 389 additions and 7 deletions

View File

@@ -14,7 +14,7 @@ public
*
* 代理 skin.support.widget.SkinCompatBackgroundHelper 类
*/
class MogoSkinCompatBackgroundHelperDelegate extends MogoSkinCompatHelperDelegate implements IMogoSkinCompatSupportable {
class MogoSkinCompatBackgroundHelperDelegate extends MogoSkinCompatHelperDelegate {
private static Method sMethodOnSetBackgroundResource;
@@ -24,8 +24,12 @@ class MogoSkinCompatBackgroundHelperDelegate extends MogoSkinCompatHelperDelegat
}
public MogoSkinCompatBackgroundHelperDelegate( View view ) {
loadClazz();
initDelegateInstance( view );
super( view );
}
@Override
protected Class< ? extends View >[] getConstructParameterClazz() {
return new Class[]{View.class};
}
public void onSetBackgroundResource( int resId ) {

View File

@@ -21,6 +21,7 @@ abstract class MogoSkinCompatHelperDelegate implements IMogoSkinCompatSupportabl
protected Object mDelegate;
protected volatile static Method sMethodApplySkin;
protected volatile static Method sMethodLoadFromAttributes;
private static Constructor sConstructor;
public MogoSkinCompatHelperDelegate( View view ) {
loadClazz();
@@ -41,10 +42,14 @@ abstract class MogoSkinCompatHelperDelegate implements IMogoSkinCompatSupportabl
protected void initDelegateInstance( View view ) {
try {
if ( mTargetClazz != null ) {
Constructor constructor = mTargetClazz.getConstructor( getConstructParameterClazz() );
constructor.setAccessible( true );
mDelegate = constructor.newInstance( view );
if ( sConstructor == null ) {
if ( mTargetClazz != null ) {
sConstructor = mTargetClazz.getConstructor( getConstructParameterClazz() );
sConstructor.setAccessible( true );
}
}
if ( sConstructor != null ) {
mDelegate = sConstructor.newInstance( view );
}
} catch ( Exception e ) {
e.printStackTrace();

View File

@@ -0,0 +1,53 @@
package com.mogo.skin.support.helper;
import android.view.View;
import android.widget.ImageView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public
/**
* @author congtaowang
* @since 2020/9/3
*
* 描述
*/
class MogoSkinCompatImageHelperDelegate extends MogoSkinCompatHelperDelegate {
private static Method sSetImageResourceMethod;
public MogoSkinCompatImageHelperDelegate( ImageView view ) {
super( view );
}
@Override
protected Class< ? extends View >[] getConstructParameterClazz() {
return new Class[]{ImageView.class};
}
public void setImageResource( int resId ) {
if ( sSetImageResourceMethod == null ) {
try {
sSetImageResourceMethod = mTargetClazz.getDeclaredMethod( "setImageResource", int.class );
sSetImageResourceMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sSetImageResourceMethod != null ) {
try {
sSetImageResourceMethod.invoke( mDelegate, resId );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
@Override
protected String getDelegateClazzName() {
return "skin.support.widget.SkinCompatImageHelper";
}
}

View File

@@ -0,0 +1,28 @@
package com.mogo.skin.support.helper;
import android.view.View;
import android.widget.ProgressBar;
public
/**
* @author congtaowang
* @since 2020/9/3
*
* 描述
*/
class MogoSkinCompatProgressBarHelperDelegate extends MogoSkinCompatHelperDelegate {
public MogoSkinCompatProgressBarHelperDelegate( ProgressBar view ) {
super( view );
}
@Override
protected Class< ? extends View >[] getConstructParameterClazz() {
return new Class[]{ProgressBar.class};
}
@Override
protected String getDelegateClazzName() {
return "skin.support.widget.SkinCompatProgressBarHelper";
}
}

View File

@@ -0,0 +1,28 @@
package com.mogo.skin.support.helper;
import android.view.View;
import android.widget.SeekBar;
public
/**
* @author congtaowang
* @since 2020/9/3
*
* 描述
*/
class MogoSkinCompatSeekBarHelperDelegate extends MogoSkinCompatHelperDelegate {
public MogoSkinCompatSeekBarHelperDelegate( SeekBar view ) {
super( view );
}
@Override
protected Class< ? extends View >[] getConstructParameterClazz() {
return new Class[]{SeekBar.class};
}
@Override
protected String getDelegateClazzName() {
return "skin.support.widget.SkinCompatSeekBarHelper";
}
}

View File

@@ -0,0 +1,122 @@
package com.mogo.skin.support.helper;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public
/**
* @author congtaowang
* @since 2020/9/3
*
* 描述
*/
class MogoSkinCompatTextHelperDelegate extends MogoSkinCompatHelperDelegate {
private static Method sOnSetTextAppearanceMethod;
private static Method sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod;
private static Method sOnSetCompoundDrawablesWithIntrinsicBoundsMethod;
private static Method sGetTextColorResIdMethod;
public MogoSkinCompatTextHelperDelegate( TextView view ) {
super( view );
}
@Override
protected Class< ? extends View >[] getConstructParameterClazz() {
return new Class[]{TextView.class};
}
public void onSetTextAppearance( Context context, int resId ) {
if ( sOnSetTextAppearanceMethod == null ) {
try {
sOnSetTextAppearanceMethod = mTargetClazz.getDeclaredMethod( "onSetTextAppearance", Context.class, int.class );
sOnSetTextAppearanceMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sOnSetTextAppearanceMethod != null ) {
try {
sOnSetTextAppearanceMethod.invoke( mDelegate, context, resId );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
public void onSetCompoundDrawablesRelativeWithIntrinsicBounds(
@DrawableRes int start, @DrawableRes int top, @DrawableRes int end, @DrawableRes int bottom ) {
if ( sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod == null ) {
try {
sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod = mTargetClazz.getDeclaredMethod( "onSetCompoundDrawablesRelativeWithIntrinsicBounds", int.class, int.class, int.class, int.class );
sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod != null ) {
try {
sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod.invoke( mDelegate, start, top, end, bottom );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
public void onSetCompoundDrawablesWithIntrinsicBounds(
@DrawableRes int left, @DrawableRes int top, @DrawableRes int right, @DrawableRes int bottom ) {
if ( sOnSetCompoundDrawablesWithIntrinsicBoundsMethod == null ) {
try {
sOnSetCompoundDrawablesWithIntrinsicBoundsMethod = mTargetClazz.getDeclaredMethod( "onSetCompoundDrawablesWithIntrinsicBounds", int.class, int.class, int.class, int.class );
sOnSetCompoundDrawablesWithIntrinsicBoundsMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sOnSetCompoundDrawablesWithIntrinsicBoundsMethod != null ) {
try {
sOnSetCompoundDrawablesWithIntrinsicBoundsMethod.invoke( mDelegate, left, top, right, bottom );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
public int getTextColorResId() {
if ( sGetTextColorResIdMethod == null ) {
try {
sGetTextColorResIdMethod = mTargetClazz.getDeclaredMethod( "getTextColorResId" );
sGetTextColorResIdMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sGetTextColorResIdMethod != null ) {
try {
Object result = sGetTextColorResIdMethod.invoke( mDelegate );
return ( ( Integer ) result ).intValue();
} catch ( Exception e ) {
e.printStackTrace();
}
}
return 0;
}
@Override
protected String getDelegateClazzName() {
return "skin.support.widget.SkinCompatTextHelper";
}
}

View File

@@ -0,0 +1,126 @@
package com.mogo.skin.support.helper;
import android.annotation.TargetApi;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.RequiresApi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public
/**
* @author congtaowang
* @since 2020/9/3
*
* 描述
*/
@RequiresApi( 17 )
@TargetApi( 17 )
class MogoSkinCompatTextHelperV17Delegate extends MogoSkinCompatHelperDelegate {
private static Method sOnSetTextAppearanceMethod;
private static Method sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod;
private static Method sOnSetCompoundDrawablesWithIntrinsicBoundsMethod;
private static Method sGetTextColorResIdMethod;
public MogoSkinCompatTextHelperV17Delegate( TextView view ) {
super( view );
}
@Override
protected Class< ? extends View >[] getConstructParameterClazz() {
return new Class[]{TextView.class};
}
public void onSetTextAppearance( Context context, int resId ) {
if ( sOnSetTextAppearanceMethod == null ) {
try {
sOnSetTextAppearanceMethod = mTargetClazz.getDeclaredMethod( "onSetTextAppearance", Context.class, int.class );
sOnSetTextAppearanceMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sOnSetTextAppearanceMethod != null ) {
try {
sOnSetTextAppearanceMethod.invoke( mDelegate, context, resId );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
public void onSetCompoundDrawablesRelativeWithIntrinsicBounds(
@DrawableRes int start, @DrawableRes int top, @DrawableRes int end, @DrawableRes int bottom ) {
if ( sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod == null ) {
try {
sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod = mTargetClazz.getDeclaredMethod( "onSetCompoundDrawablesRelativeWithIntrinsicBounds", int.class, int.class, int.class, int.class );
sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod != null ) {
try {
sOnSetCompoundDrawablesRelativeWithIntrinsicBoundsMethod.invoke( mDelegate, start, top, end, bottom );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
public void onSetCompoundDrawablesWithIntrinsicBounds(
@DrawableRes int left, @DrawableRes int top, @DrawableRes int right, @DrawableRes int bottom ) {
if ( sOnSetCompoundDrawablesWithIntrinsicBoundsMethod == null ) {
try {
sOnSetCompoundDrawablesWithIntrinsicBoundsMethod = mTargetClazz.getDeclaredMethod( "onSetCompoundDrawablesWithIntrinsicBounds", int.class, int.class, int.class, int.class );
sOnSetCompoundDrawablesWithIntrinsicBoundsMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sOnSetCompoundDrawablesWithIntrinsicBoundsMethod != null ) {
try {
sOnSetCompoundDrawablesWithIntrinsicBoundsMethod.invoke( mDelegate, left, top, right, bottom );
} catch ( IllegalAccessException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
}
}
}
public int getTextColorResId() {
if ( sGetTextColorResIdMethod == null ) {
try {
sGetTextColorResIdMethod = mTargetClazz.getDeclaredMethod( "getTextColorResId" );
sGetTextColorResIdMethod.setAccessible( true );
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
}
}
if ( sGetTextColorResIdMethod != null ) {
try {
Object result = sGetTextColorResIdMethod.invoke( mDelegate );
return ( ( Integer ) result ).intValue();
} catch ( Exception e ) {
e.printStackTrace();
}
}
return 0;
}
@Override
protected String getDelegateClazzName() {
return "skin.support.widget.SkinCompatTextHelperV17";
}
}

View File

@@ -5,6 +5,8 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import com.mogo.skin.support.IMogoSkinCompatSupportable;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -21,6 +23,7 @@ public class SkinCompatDelegate implements LayoutInflater.Factory2 {
private final Context mContext;
private SkinCompatViewInflater mSkinCompatViewInflater;
private List<WeakReference<SkinCompatSupportable>> mSkinHelpers = new CopyOnWriteArrayList<>();
private List<WeakReference< IMogoSkinCompatSupportable >> mMogoSkinHelpers = new CopyOnWriteArrayList<>();
private SkinCompatDelegate(Context context) {
mContext = context;
@@ -36,6 +39,9 @@ public class SkinCompatDelegate implements LayoutInflater.Factory2 {
if (view instanceof SkinCompatSupportable) {
mSkinHelpers.add(new WeakReference<>((SkinCompatSupportable) view));
}
if (view instanceof IMogoSkinCompatSupportable) {
mMogoSkinHelpers.add(new WeakReference<>((IMogoSkinCompatSupportable) view));
}
return view;
}
@@ -50,6 +56,9 @@ public class SkinCompatDelegate implements LayoutInflater.Factory2 {
if (view instanceof SkinCompatSupportable) {
mSkinHelpers.add(new WeakReference<>((SkinCompatSupportable) view));
}
if (view instanceof IMogoSkinCompatSupportable) {
mMogoSkinHelpers.add(new WeakReference<>((IMogoSkinCompatSupportable) view));
}
return view;
}
@@ -82,5 +91,12 @@ public class SkinCompatDelegate implements LayoutInflater.Factory2 {
}
}
}
if (mMogoSkinHelpers != null && !mMogoSkinHelpers.isEmpty()) {
for (WeakReference ref : mMogoSkinHelpers) {
if (ref != null && ref.get() != null) {
((IMogoSkinCompatSupportable) ref.get()).applySkin();
}
}
}
}
}