一、设计全局配置器
依照“单例模式”下的“懒汉式”,通过枚举类和静态内部类来实现,保证线程安全,也避免使用双重校验锁。
1. public class Configurator
该类用于配置文件的存储和获取,包括各种配置项(如,后端主机地址)、字体图标库的引用、用于线程通信的全局Handler。
import android.os.Handler;
import com.blankj.utilcode.util.Utils;
import com.joanzapata.iconify.IconFontDescriptor;
import com.joanzapata.iconify.Iconify;
import java.util.ArrayList;
import java.util.HashMap;
public class Configurator {
private static final HashMap<Object,Object> QILU_CONFIGS= new HashMap<>();
private static final Handler HANDLER = new Handler();
private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>();
// 不让其他类创建本类的对象
private Configurator(){
QILU_CONFIGS.put(ConfigKeys.CONFIG_READY, false);
QILU_CONFIGS.put(ConfigKeys.HANDLER, HANDLER);
}
//利用静态内部类进行初始化
private static class Holder {
private static final Configurator INSTANCE = new Configurator();
}
static Configurator getInstance() {
return Holder.INSTANCE;
}
final HashMap<Object, Object> getQiluConfigs() {
return QILU_CONFIGS;
}
public final void configure() {
initIcons();
QILU_CONFIGS.put(ConfigKeys.CONFIG_READY, true);
Utils.init(Qilu.getApplicationContext());
}
private void initIcons() {
if (ICONS.size() > 0) {
final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0));
for (int i = 1; i < ICONS.size(); i++) {
initializer.with(ICONS.get(i));
}
}
}
public final Configurator withIcon(IconFontDescriptor descriptor) {
ICONS.add(descriptor);
return this;
}
public final Configurator withApiHost(String host) {
QILU_CONFIGS.put(ConfigKeys.API_HOST, host);
return this;
}
public final Configurator withLoaderDelayed(long delayed) {
QILU_CONFIGS.put(ConfigKeys.LOADER_DELAYED, delayed);
return this;
}
private void checkConfiguration() {
final boolean isReady = (boolean) QILU_CONFIGS.get(ConfigKeys.CONFIG_READY);
if (!isReady) {
throw new RuntimeException("Configuration is not ready,call configure");
}
}
@SuppressWarnings("unchecked")
final <T> T getConfiguration(Object key) {
checkConfiguration();
final Object value = QILU_CONFIGS.get(key);
if (value == null) {
throw new NullPointerException(key.toString() + " IS NULL");
}
return (T) QILU_CONFIGS.get(key);
}
}
2. public final class Qilu
该类仅仅是对外提供操作的工具类,全部是静态方法。
import android.content.Context;
import android.os.Handler;
public final class Qilu {
//初始化
public static Configurator init(Context context) {
Configurator.getInstance()
.getQiluConfigs()
.put(ConfigKeys.APPLICATION_CONTEXT, context.getApplicationContext());
return Configurator.getInstance();
}
public static Configurator getConfigurator() {
return Configurator.getInstance();
}
public static <T> T getConfiguration(Object key) {
return getConfigurator().getConfiguration(key);
}
public static Context getApplicationContext() {
return getConfiguration(ConfigKeys.APPLICATION_CONTEXT);
}
public static Handler getHandler() {
return getConfiguration(ConfigKeys.HANDLER);
}
}
二、字体图标库的集成
App使用字体图标库来代替许多图片。
App使用很多图片有许多缺陷:App体积过大;屏幕分辨率变化时,图片很难保持高保真。
App使用字体图标库,可以显著减小App的体积,因为字体图标可以实时渲染,无需大量静态存储空间。App使用字体图标,即便屏幕分辨率大幅变化,字体图标也不会失真,因为字体图标基于SVG(可缩放的矢量图形)。
1. 添加依赖
GitHub链接:android-iconify
在core模块的build.gradle中添加以下内容:
api 'com.joanzapata.iconify:android-iconify-fontawesome:2.2.2'
api 'com.joanzapata.iconify:android-iconify-entypo:2.2.2'
api 'com.joanzapata.iconify:android-iconify-typicons:2.2.2'
api 'com.joanzapata.iconify:android-iconify-material:2.2.2'
api 'com.joanzapata.iconify:android-iconify-material-community:2.2.2'
api 'com.joanzapata.iconify:android-iconify-meteocons:2.2.2'
api 'com.joanzapata.iconify:android-iconify-weathericons:2.2.2'
api 'com.joanzapata.iconify:android-iconify-simplelineicons:2.2.2'
api 'com.joanzapata.iconify:android-iconify-ionicons:2.2.2'
同步项目
2. 在Configurator中添加初始化方法
private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>();
public final Configurator withIcon(IconFontDescriptor descriptor) {
ICONS.add(descriptor);
return this;
}
private void initIcons() {
if (ICONS.size() > 0) {
final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0));
for (int i = 1; i < ICONS.size(); i++) {
initializer.with(ICONS.get(i));
}
}
}
三、基础框架可用性验证
验证所搭建的基础框架是否生效
1. 主Application中执行初始化操作
import android.app.Application;
import com.joanzapata.iconify.fonts.EntypoModule;
import com.joanzapata.iconify.fonts.FontAwesomeModule;
import com.joanzapata.iconify.fonts.IoniconsModule;
import com.joanzapata.iconify.fonts.MaterialCommunityModule;
import com.joanzapata.iconify.fonts.MaterialModule;
import com.joanzapata.iconify.fonts.MeteoconsModule;
import com.joanzapata.iconify.fonts.SimpleLineIconsModule;
import com.joanzapata.iconify.fonts.TypiconsModule;
import com.joanzapata.iconify.fonts.WeathericonsModule;
import com.qilu.core.app.Qilu;
public class MainApp extends Application {
@Override
public void onCreate() {
super.onCreate();
Qilu.init(this)
.withIcon(new FontAwesomeModule())
.withIcon(new EntypoModule())
.withIcon(new TypiconsModule())
.withIcon(new MaterialModule())
.withIcon(new MaterialCommunityModule())
.withIcon(new MeteoconsModule())
.withIcon(new WeathericonsModule())
.withIcon(new SimpleLineIconsModule())
.withIcon(new IoniconsModule())
.withApiHost("http://106.13.96.60:8888/")
.withLoaderDelayed(3000)
.configure();
}
}
2. 在测试页面中查看效果
在测试页面的布局文件中使用了字体图标
<com.joanzapata.iconify.widget.IconTextView
android:text="I {fa-heart-o} to {fa-code} on {fa-android}"
android:shadowColor="#22000000"
android:shadowDx="3"
android:shadowDy="3"
android:shadowRadius="1"
android:textSize="40sp"
android:textColor="#FF..."
... />
运行结果