Просмотр исходного кода

智慧产城首页显示优化

raomeng 8 лет назад
Родитель
Сommit
355dcdfde9
28 измененных файлов с 1979 добавлено и 431 удалено
  1. 0 1
      WeiChat/src/main/AndroidManifest.xml
  2. 47 24
      WeiChat/src/main/java/com/xzjmyk/pm/activity/CaptureResultActivity.java
  3. 0 45
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/account/RegisterSelectActivity.java
  4. 9 4
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/fragment/WorkPlatFragment.java
  5. 0 24
      WeiChat/src/main/res/drawable/bg_bule_btn.xml
  6. 0 23
      WeiChat/src/main/res/drawable/bg_bule_btn1.xml
  7. 0 24
      WeiChat/src/main/res/drawable/bg_green_btn.xml
  8. 0 7
      WeiChat/src/main/res/drawable/bg_green_button.xml
  9. 0 44
      WeiChat/src/main/res/layout/activity_register_select.xml
  10. 3 3
      WeiChat/version.properties
  11. 4 0
      app_core/common/src/main/java/com/core/api/wxapi/ApiPlatform.java
  12. 1 1
      app_core/common/src/main/java/com/core/app/Constants.java
  13. 9 0
      app_core/common/src/main/java/com/core/base/activity/BaseMVPActivity.java
  14. 4 4
      app_core/common/src/main/java/com/core/net/http/ViewUtil.java
  15. 2 2
      app_core/common/src/main/java/com/core/utils/CommonUtil.java
  16. 1607 0
      app_core/common/src/main/java/com/core/utils/SpanUtils.java
  17. 18 1
      app_core/common/src/main/java/com/core/utils/ToastUtil.java
  18. 3 3
      app_core/common/src/main/res/drawable/bg_green_btn.xml
  19. 1 2
      app_core/common/src/main/res/layout/activity_register_select.xml
  20. 12 27
      app_core/network/src/main/java/com/me/network/app/http/rx/ResultSubscriber.java
  21. 4 4
      app_modular/appworks/src/main/java/com/uas/appworks/activity/CityIndustryFuncSetActivity.java
  22. 101 33
      app_modular/appworks/src/main/java/com/uas/appworks/activity/CityIndustryServiceMainActivity.java
  23. 3 5
      app_modular/appworks/src/main/java/com/uas/appworks/activity/CommonDataFormActivity.java
  24. 6 6
      app_modular/appworks/src/main/java/com/uas/appworks/model/WorkPlatModel.java
  25. 2 2
      app_modular/appworks/src/main/res/anim/announce_enter_bottom.xml
  26. 2 2
      app_modular/appworks/src/main/res/anim/announce_leave_top.xml
  27. 140 139
      app_modular/appworks/src/main/res/layout/activity_main_city_industry_service.xml
  28. 1 1
      version.gradle

+ 0 - 1
WeiChat/src/main/AndroidManifest.xml

@@ -1037,7 +1037,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".ui.account.RegisterSelectActivity" />
         <activity android:name=".ui.me.TemperatureActivity" />
 
         <!--数据统计,报表查询-->

+ 47 - 24
WeiChat/src/main/java/com/xzjmyk/pm/activity/CaptureResultActivity.java

@@ -27,8 +27,8 @@ import com.xzjmyk.pm.activity.view.crouton.LifecycleCallback;
 
 /**
  * @author RaoMeng
- * update fanglh 2017-6-7 新增扫描名片二维码需求
- * update fanglh 2017-9-14 新增扫描UAS二维码登录功能
+ *         update fanglh 2017-6-7 新增扫描名片二维码需求
+ *         update fanglh 2017-9-14 新增扫描UAS二维码登录功能
  */
 public class CaptureResultActivity extends Activity {
     private WebView mWebView;
@@ -71,11 +71,11 @@ public class CaptureResultActivity extends Activity {
                 Log.d("fileurl", url);
                 String fileName = url.substring(url.lastIndexOf("/") + 1);
 
-                new AlertDialog.Builder(CaptureResultActivity.this).setTitle("提示").setMessage("确定下载文件<"+fileName+">吗?").setNegativeButton(R.string.cancel, null)
+                new AlertDialog.Builder(CaptureResultActivity.this).setTitle("提示").setMessage("确定下载文件<" + fileName + ">吗?").setNegativeButton(R.string.cancel, null)
                         .setPositiveButton(R.string.sure, new DialogInterface.OnClickListener() {
                             @Override
                             public void onClick(DialogInterface dialog, int which) {
-                                DownloadUtil.DownloadFile(CaptureResultActivity.this,url,"/sdcard/uu");
+                                DownloadUtil.DownloadFile(CaptureResultActivity.this, url, "/sdcard/uu");
 
                             }
                         }).create().show();
@@ -85,15 +85,15 @@ public class CaptureResultActivity extends Activity {
 
 
     private void initData() {
-
         Intent intent = getIntent();
         if (null != intent) {
             Bundle bundle = intent.getExtras();
-            if (bundle == null){
+            if (bundle == null) {
                 return;
             }
-            if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS){
+            if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                 String result = bundle.getString(CodeUtils.RESULT_STRING);
+                Log.d("scanurl", result);
                 //TODO update fanglh 2017-6-7 新增扫描名片二维码需求
                 if (StringUtil.isEmpty(result)) {
                     Crouton crouton = Crouton.makeText(CaptureResultActivity.this, "您扫描的二维码信息为空", 0xffff4444, 1500);
@@ -109,40 +109,63 @@ public class CaptureResultActivity extends Activity {
                             finish();
                         }
                     });
-                }else {
-                    if (CommonUtil.isWebsite(result)){
+                } else {
+                    if (CommonUtil.isWebsite(result)) {
                         mWebView.loadUrl(result);
-                    }else {
+                    } else {
                         doJudgeInfoCard(result);//进行是否为名片二维码判断
                     }
                 }
-                Log.d("scanurl",result);
             }
         }
     }
 
     private void doJudgeInfoCard(String result) {
         Boolean isJSONData = JSONUtil.validate(result);//是否是JSON格式字符
-        if (isJSONData && result.contains("uu_name") && result.contains("uu_phone")){
+        if (isJSONData && result.contains("uu_name") && result.contains("uu_phone")) {
             startActivity(new Intent(this, ScanInfoResultsActivity.class)
-                    .putExtra("ScanResults",result)
-                    .putExtra("isQRData",true));// true :扫描到的是名片信息标志
-        }else if (isJSONData && result.contains("clientId")){
+                    .putExtra("ScanResults", result)
+                    .putExtra("isQRData", true));// true :扫描到的是名片信息标志
+        } else if (isJSONData && result.contains("clientId")) {
             doUasLoginRequest(result);
-        }else {
+        } else if (isJSONData && result.contains("token")) {
+            doB2BLoginRequest(result);
+        } else {
             startActivity(new Intent(this, ScanInfoResultsActivity.class)
-                    .putExtra("ScanResults",result)
-                    .putExtra("isQRData",false));
+                    .putExtra("ScanResults", result)
+                    .putExtra("isQRData", false));
+        }
+        finish();
+    }
+
+    private void doB2BLoginRequest(String result) {
+        String token = JSON.parseObject(result).getString("token");
+        if (StringUtil.isEmail(token)) {
+            return;
         }
+        String url = null;
+//        url = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "erp_baseurl") + "common/checkQrcodeScan.action";
+        url = "http://192.168.253.66:8080/" + "sso/qrcode/check";
+        String photo = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "user_phone");
+        String password = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "user_password");
+        String enuu = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "erp_uu");
+        Intent intent_web = new Intent("com.modular.main.WebViewCommActivity");
+        url = url + "?uid=" + photo + "&token=" + token + "&password=" + password + "&enuu=" + enuu;
+        intent_web.putExtra("url", url);
+        LogUtil.i("loginUrl", url);
+        intent_web.putExtra("mTitle", "扫码登录");
+        intent_web.putExtra("cookie", true);
+        startActivity(intent_web);
         finish();
     }
 
     /**
      * 新增扫描UAS二维码登录功能
+     *
      * @param result
      */
     private void doUasLoginRequest(String result) {
-        String clientId  = JSON.parseObject(result).getString("clientId");
+        String clientId = JSON.parseObject(result).getString("clientId");
         if (StringUtil.isEmail(clientId)) return;
 
         /*HttpClient httpClient = new HttpClient.Builder("http://192.168.253.63:8080/ERP/").build();
@@ -160,15 +183,15 @@ public class CaptureResultActivity extends Activity {
             }
         }));*/
         String url = null;
-        url = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "erp_baseurl")+"common/checkQrcodeScan.action";
+        url = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "erp_baseurl") + "common/checkQrcodeScan.action";
 //        url = "http://192.168.253.6/ERP/"+"common/checkQrcodeScan.action";
         String em_code = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "erp_username");
         String sob = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "erp_master");
         String password = CommonUtil.getSharedPreferences(MyApplication.getInstance(), "user_password");
         Intent intent_web = new Intent("com.modular.main.WebViewCommActivity");
         url = url + "?em_code=" + em_code + "&sob=" + sob + "&clientId=" + clientId + "&password=" + password;
-        intent_web.putExtra("url",url);
-        LogUtil.i("flh",url);
+        intent_web.putExtra("url", url);
+        LogUtil.i("flh", url);
         intent_web.putExtra("mTitle", "扫码登录");
         intent_web.putExtra("cookie", true);
         startActivity(intent_web);
@@ -177,8 +200,8 @@ public class CaptureResultActivity extends Activity {
 
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK){
-            if (mWebView.canGoBack()){
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            if (mWebView.canGoBack()) {
                 mWebView.goBack();
                 return true;
             }

+ 0 - 45
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/account/RegisterSelectActivity.java

@@ -1,45 +0,0 @@
-package com.xzjmyk.pm.activity.ui.account;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
-
-import com.core.base.BaseActivity;
-import com.core.utils.IntentUtils;
-import com.lidroid.xutils.ViewUtils;
-import com.lidroid.xutils.view.annotation.ViewInject;
-import com.xzjmyk.pm.activity.R;
-import com.xzjmyk.pm.activity.ui.erp.activity.message.PersonalRegActivity;
-
-public class RegisterSelectActivity extends BaseActivity {
-    @ViewInject(R.id.person_btn)
-    Button person_btn;
-    @ViewInject(R.id.company_btn)
-    Button company_btn;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.activity_register_select);
-        ViewUtils.inject(this);
-        getSupportActionBar().setTitle("新用户注册");
-        person_btn.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                startActivity(new Intent(mContext, PersonalRegActivity.class));
-                finish();
-            }
-        });
-
-        company_btn.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                IntentUtils.webLinks(mContext,
-                        "https://account.ubtob.com/sso/register",
-                        "企业注册");
-            }
-        });
-    }
-}

+ 9 - 4
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/fragment/WorkPlatFragment.java

@@ -112,14 +112,15 @@ public class WorkPlatFragment extends BaseMVPFragment<WorkPlatPresenter> impleme
             mPresenter.uasRequest(mContext, new Request.Bulider().setWhat(Constants.LOAD_WORK_MENU_CACHE).bulid());
             loadOrdersCaller();
         }
+
         obtainCityIndustryService();
     }
 
     private void obtainCityIndustryService() {
         Map<String, Object> params = new HashMap<>();
         params.put("kind", "app");
-        params.put("client_type", "cc");
-        params.put("access_token", "123456");
+//        params.put("client_type", "cc");
+//        params.put("access_token", "123456");
         params.put("Cookie", "JSESSIONID=" + com.core.utils.CommonUtil.getSharedPreferences(mContext, "sessionId"));
 
         LinkedHashMap<String, Object> header = new LinkedHashMap<>();
@@ -198,7 +199,9 @@ public class WorkPlatFragment extends BaseMVPFragment<WorkPlatPresenter> impleme
         } else if (what == OBTAIN_APP_CITY_INDUSTRY_SERVICE) {
             String result = object.toString();
             Log.e("cityindustryservice", result);
-            analyzeCityIndustry(result);
+            if (JSONUtil.validate(result)) {
+                analyzeCityIndustry(result);
+            }
         }
     }
 
@@ -359,6 +362,8 @@ public class WorkPlatFragment extends BaseMVPFragment<WorkPlatPresenter> impleme
 
     @Override
     public void requestError(int what, String errorMsg) {
-        toast(errorMsg);
+        if (errorMsg != null && errorMsg.length() <= 40) {
+            toast(errorMsg);
+        }
     }
 }

+ 0 - 24
WeiChat/src/main/res/drawable/bg_bule_btn.xml

@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true">
-        <shape>
-            <solid android:color="@color/btn_orange_press" />
-            <corners android:radius="3dp" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-    <item android:state_enabled="false">
-        <shape>
-            <solid android:color="@color/btn_orange_press" />
-            <corners android:radius="3dp" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-    <item>
-        <shape>
-            <solid android:color="@color/titleBlue" />
-            <corners android:radius="3dp" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-</selector>

+ 0 - 23
WeiChat/src/main/res/drawable/bg_bule_btn1.xml

@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true">
-        <shape>
-            <solid android:color="@color/btn_orange_press" />
-
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-    <item android:state_enabled="false">
-        <shape>
-            <solid android:color="@color/btn_orange_press" />
-       
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-    <item>
-        <shape>
-            <solid android:color="@color/titleBlue" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-</selector>

+ 0 - 24
WeiChat/src/main/res/drawable/bg_green_btn.xml

@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true">
-        <shape>
-            <solid android:color="@color/btn_orange_press" />
-            <corners android:radius="8dp" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-    <item android:state_enabled="false">
-        <shape>
-            <solid android:color="@color/btn_orange_press" />
-            <corners android:radius="8dp" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-    <item>
-        <shape>
-            <solid android:color="@color/light_green" />
-            <corners android:radius="8dp" />
-            <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
-        </shape>
-    </item>
-</selector>

+ 0 - 7
WeiChat/src/main/res/drawable/bg_green_button.xml

@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/bg_button_green_focus" android:state_pressed="true"/>
-    <item android:drawable="@drawable/bg_button_green_focus" android:state_enabled="true"/>
-    <item android:drawable="@drawable/bg_button_invalid" android:state_enabled="false"/>
-    <item android:drawable="@drawable/bg_button_normal"/>
-</selector>

+ 0 - 44
WeiChat/src/main/res/layout/activity_register_select.xml

@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="center"
-    android:orientation="vertical"
-    tools:context="com.xzjmyk.pm.activity.ui.account.RegisterSelectActivity">
-    <de.hdodenhof.circleimageview.CircleImageView
-        android:id="@+id/iv_head"
-        android:layout_width="90dp"
-        android:layout_height="90dp"
-        android:layout_centerHorizontal="true"
-        android:layout_marginTop="100dp"
-        android:src="@drawable/login_header" />
-    
-    <Button
-        android:id="@+id/company_btn"
-        android:layout_width="match_parent"
-        android:layout_height="40dp"
-        android:layout_gravity="center"
-        android:layout_marginLeft="20dp"
-        android:layout_centerInParent="true"
-        android:layout_marginRight="20dp"
-        android:layout_marginTop="10dp"
-        android:background="@drawable/bg_green_btn"
-        android:text="企业注册"
-        android:textColor="@color/white"
-        android:textSize="@dimen/text_main" />
-
-    <Button
-        android:id="@+id/person_btn"
-        android:layout_width="match_parent"
-        android:layout_height="40dp"
-        android:layout_below="@+id/company_btn"
-        android:layout_gravity="center"
-        android:layout_marginLeft="20dp"
-        android:layout_marginRight="20dp"
-        android:layout_marginTop="20dp"
-        android:background="@drawable/bg_bule_btn"
-        android:text="个人注册"
-        android:textColor="@color/white"
-        android:textSize="@dimen/text_main" />
-</RelativeLayout>

+ 3 - 3
WeiChat/version.properties

@@ -1,5 +1,5 @@
-#Mon Nov 27 11:51:42 CST 2017
+#Wed Nov 29 15:33:40 CST 2017
 debugName=1
-versionName=619
+versionName=651
 debugCode=90
-versionCode=119
+versionCode=151

+ 4 - 0
app_core/common/src/main/java/com/core/api/wxapi/ApiPlatform.java

@@ -11,6 +11,10 @@ import com.common.config.BaseConfig;
 public class ApiPlatform extends ApiBase implements ApiModel {
     private String mBaseUrl = "";
 
+    public String getBaseUrl() {
+        return mBaseUrl;
+    }
+
     public ApiPlatform() {
         if (BaseConfig.isDebug()) {
             mBaseUrl = "http://uas.ubtob.com/";

+ 1 - 1
app_core/common/src/main/java/com/core/app/Constants.java

@@ -16,7 +16,7 @@ public class Constants {
 	public static String IM_BASE_URL() {
 		String url = "";
 		if (BaseConfig.isDebug()) {
-			url = IM_BASE_URL;
+			url = IM_BASE_URL_TEST;
 		} else {
 			url = IM_BASE_URL;
 		}

+ 9 - 0
app_core/common/src/main/java/com/core/base/activity/BaseMVPActivity.java

@@ -4,6 +4,7 @@ import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
 import android.view.View;
+import android.view.ViewGroup;
 
 import com.core.base.BaseActivity;
 import com.core.base.presenter.BasePresenter;
@@ -69,6 +70,14 @@ public abstract class BaseMVPActivity<T extends BasePresenter> extends BaseActiv
         ToastUtil.showToast(this, resId);
     }
 
+    protected void toast(String text, ViewGroup viewGroup) {
+        ToastUtil.showToast(this, text, viewGroup);
+    }
+
+    protected void toast(int resId, ViewGroup viewGroup) {
+        ToastUtil.showToast(this, resId, viewGroup);
+    }
+
     /**
      * [页面跳转]
      *

+ 4 - 4
app_core/common/src/main/java/com/core/net/http/ViewUtil.java

@@ -1036,15 +1036,15 @@ public class ViewUtil {
     public static void LoginERPTask(String url, String master, String username,
                                     String password) {
         mdProcessDialog.setContent(MyApplication.getInstance().getString(R.string.login_progress_erp));
-//        url = url + "mobile/login.action";
+        url = url + "mobile/login.action";
 //        url = "http://192.168.253.29:8080/ERP/mobile/login.action";
 //        url = "http://192.168.253.6/uas_dev/mobile/login.action";
-        url = "https://admin-city.ubtob.com/mobile/login.action";
+//        url = "https://admin-city.ubtob.com/mobile/login.action";
         Map<String, String> params = new HashMap<String, String>();
         params.put("username", username);
         params.put("password", password);
-//        params.put("master", master);
-        params.put("master", "CITIES_CONTROL");
+        params.put("master", master);
+//        params.put("master", "CITIES_CONTROL");
         LogUtil.i("login", "url=" + url);
         LogUtil.i("login", "params=" + JSONUtil.map2JSON(params));
         startNetThread(url, params, handler, Constants.SUCCESS_ERP, null, null, "post");

+ 2 - 2
app_core/common/src/main/java/com/core/utils/CommonUtil.java

@@ -98,10 +98,10 @@ public class CommonUtil {
             return "";
         }
         String baseUrl = getSharedPreferences(ct, "erp_baseurl");
-        //return baseUrl;
+        return baseUrl;
         //return "http://192.168.253.6/uas_dev/";
 //        return "http://192.168.253.29:8080/ERP/";
-        return "https://admin-city.ubtob.com/";
+//        return "https://admin-city.ubtob.com/";
     }
 
     /**

+ 1607 - 0
app_core/common/src/main/java/com/core/utils/SpanUtils.java

@@ -0,0 +1,1607 @@
+package com.core.utils;
+
+import android.annotation.SuppressLint;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BlurMaskFilter;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.Typeface;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.support.annotation.ColorInt;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.FloatRange;
+import android.support.annotation.IntDef;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+import android.text.Layout;
+import android.text.Layout.Alignment;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.style.AbsoluteSizeSpan;
+import android.text.style.AlignmentSpan;
+import android.text.style.BackgroundColorSpan;
+import android.text.style.CharacterStyle;
+import android.text.style.ClickableSpan;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.LeadingMarginSpan;
+import android.text.style.MaskFilterSpan;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.ReplacementSpan;
+import android.text.style.ScaleXSpan;
+import android.text.style.StrikethroughSpan;
+import android.text.style.StyleSpan;
+import android.text.style.SubscriptSpan;
+import android.text.style.SuperscriptSpan;
+import android.text.style.TypefaceSpan;
+import android.text.style.URLSpan;
+import android.text.style.UnderlineSpan;
+import android.text.style.UpdateAppearance;
+import android.util.Log;
+
+import com.core.app.MyApplication;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+
+import static android.graphics.BlurMaskFilter.Blur;
+
+/**
+ * <pre>
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 16/12/13
+ *     desc  : SpannableString相关工具类
+ * </pre>
+ */
+public final class SpanUtils {
+
+    private static final int COLOR_DEFAULT = 0xFEFFFFFF;
+
+    public static final int ALIGN_BOTTOM = 0;
+    public static final int ALIGN_BASELINE = 1;
+    public static final int ALIGN_CENTER = 2;
+    public static final int ALIGN_TOP = 3;
+
+    @IntDef({ALIGN_BOTTOM, ALIGN_BASELINE, ALIGN_CENTER, ALIGN_TOP})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Align {
+    }
+
+    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+    private CharSequence mText;
+    private int flag;
+    private int foregroundColor;
+    private int backgroundColor;
+    private int lineHeight;
+    private int alignLine;
+    private int quoteColor;
+    private int stripeWidth;
+    private int quoteGapWidth;
+    private int first;
+    private int rest;
+    private int bulletColor;
+    private int bulletRadius;
+    private int bulletGapWidth;
+    private Bitmap iconMarginBitmap;
+    private Drawable iconMarginDrawable;
+    private Uri iconMarginUri;
+    private int iconMarginResourceId;
+    private int iconMarginGapWidth;
+    private int alignIconMargin;
+    private int fontSize;
+    private boolean fontSizeIsDp;
+    private float proportion;
+    private float xProportion;
+    private boolean isStrikethrough;
+    private boolean isUnderline;
+    private boolean isSuperscript;
+    private boolean isSubscript;
+    private boolean isBold;
+    private boolean isItalic;
+    private boolean isBoldItalic;
+    private String fontFamily;
+    private Typeface typeface;
+    private Alignment alignment;
+    private ClickableSpan clickSpan;
+    private String url;
+    private float blurRadius;
+    private Blur style;
+    private Shader shader;
+    private float shadowRadius;
+    private float shadowDx;
+    private float shadowDy;
+    private int shadowColor;
+    private Object[] spans;
+
+    private Bitmap imageBitmap;
+    private Drawable imageDrawable;
+    private Uri imageUri;
+    private int imageResourceId;
+    private int alignImage;
+
+    private int spaceSize;
+    private int spaceColor;
+
+    private SpannableStringBuilder mBuilder;
+
+    private int mType;
+    private final int mTypeCharSequence = 0;
+    private final int mTypeImage = 1;
+    private final int mTypeSpace = 2;
+
+
+    public SpanUtils() {
+        mBuilder = new SpannableStringBuilder();
+        mText = "";
+        setDefault();
+    }
+
+    private void setDefault() {
+        flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
+        foregroundColor = COLOR_DEFAULT;
+        backgroundColor = COLOR_DEFAULT;
+        lineHeight = -1;
+        quoteColor = COLOR_DEFAULT;
+        first = -1;
+        bulletColor = COLOR_DEFAULT;
+        iconMarginBitmap = null;
+        iconMarginDrawable = null;
+        iconMarginUri = null;
+        iconMarginResourceId = -1;
+        iconMarginGapWidth = -1;
+        fontSize = -1;
+        proportion = -1;
+        xProportion = -1;
+        isStrikethrough = false;
+        isUnderline = false;
+        isSuperscript = false;
+        isSubscript = false;
+        isBold = false;
+        isItalic = false;
+        isBoldItalic = false;
+        fontFamily = null;
+        typeface = null;
+        alignment = null;
+        clickSpan = null;
+        url = null;
+        blurRadius = -1;
+        shader = null;
+        shadowRadius = -1;
+        spans = null;
+
+        imageBitmap = null;
+        imageDrawable = null;
+        imageUri = null;
+        imageResourceId = -1;
+
+        spaceSize = -1;
+    }
+
+    /**
+     * 设置标识
+     *
+     * @param flag <ul>
+     *             <li>{@link Spanned#SPAN_INCLUSIVE_EXCLUSIVE}</li>
+     *             <li>{@link Spanned#SPAN_INCLUSIVE_INCLUSIVE}</li>
+     *             <li>{@link Spanned#SPAN_EXCLUSIVE_EXCLUSIVE}</li>
+     *             <li>{@link Spanned#SPAN_EXCLUSIVE_INCLUSIVE}</li>
+     *             </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setFlag(final int flag) {
+        this.flag = flag;
+        return this;
+    }
+
+    /**
+     * 设置前景色
+     *
+     * @param color 前景色
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setForegroundColor(@ColorInt final int color) {
+        this.foregroundColor = color;
+        return this;
+    }
+
+    /**
+     * 设置背景色
+     *
+     * @param color 背景色
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setBackgroundColor(@ColorInt final int color) {
+        this.backgroundColor = color;
+        return this;
+    }
+
+    /**
+     * 设置行高
+     * <p>当行高大于字体高度时,字体在行中的位置默认居中</p>
+     *
+     * @param lineHeight 行高
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setLineHeight(@IntRange(from = 0) final int lineHeight) {
+        return setLineHeight(lineHeight, ALIGN_CENTER);
+    }
+
+    /**
+     * 设置行高
+     * <p>当行高大于字体高度时,字体在行中的位置由{@code align}决定</p>
+     *
+     * @param lineHeight 行高
+     * @param align      对齐
+     *                   <ul>
+     *                   <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *                   <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *                   <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *                   </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setLineHeight(@IntRange(from = 0) final int lineHeight, @Align final int align) {
+        this.lineHeight = lineHeight;
+        this.alignLine = align;
+        return this;
+    }
+
+    /**
+     * 设置引用线的颜色
+     *
+     * @param color 引用线的颜色
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setQuoteColor(@ColorInt final int color) {
+        return setQuoteColor(color, 2, 2);
+    }
+
+    /**
+     * 设置引用线的颜色
+     *
+     * @param color       引用线的颜色
+     * @param stripeWidth 引用线线宽
+     * @param gapWidth    引用线和文字间距
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setQuoteColor(@ColorInt final int color, @IntRange(from = 1) final int stripeWidth, @IntRange(from = 0) final int gapWidth) {
+        this.quoteColor = color;
+        this.stripeWidth = stripeWidth;
+        this.quoteGapWidth = gapWidth;
+        return this;
+    }
+
+    /**
+     * 设置缩进
+     *
+     * @param first 首行缩进
+     * @param rest  剩余行缩进
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setLeadingMargin(@IntRange(from = 0) final int first, @IntRange(from = 0) final int rest) {
+        this.first = first;
+        this.rest = rest;
+        return this;
+    }
+
+    /**
+     * 设置列表标记
+     *
+     * @param gapWidth 列表标记和文字间距离
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setBullet(@IntRange(from = 0) final int gapWidth) {
+        return setBullet(0, 3, gapWidth);
+    }
+
+    /**
+     * 设置列表标记
+     *
+     * @param color    列表标记的颜色
+     * @param radius   列表标记颜色
+     * @param gapWidth 列表标记和文字间距离
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setBullet(@ColorInt final int color, @IntRange(from = 0) final int radius, @IntRange(from = 0) final int gapWidth) {
+        this.bulletColor = color;
+        this.bulletRadius = radius;
+        this.bulletGapWidth = gapWidth;
+        return this;
+    }
+
+    /**
+     * 设置图标
+     * <p>默认0边距,居中对齐</p>
+     *
+     * @param bitmap 图标bitmap
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(final Bitmap bitmap) {
+        return setIconMargin(bitmap, 0, ALIGN_CENTER);
+    }
+
+    /**
+     * 设置图标
+     *
+     * @param bitmap   图标bitmap
+     * @param gapWidth 图标和文字间距离
+     * @param align    对齐
+     *                 <ul>
+     *                 <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *                 <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *                 <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *                 </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(final Bitmap bitmap, final int gapWidth, @Align final int align) {
+        this.iconMarginBitmap = bitmap;
+        this.iconMarginGapWidth = gapWidth;
+        this.alignIconMargin = align;
+        return this;
+    }
+
+    /**
+     * 设置图标
+     * <p>默认0边距,居中对齐</p>
+     *
+     * @param drawable 图标drawable
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(final Drawable drawable) {
+        return setIconMargin(drawable, 0, ALIGN_CENTER);
+    }
+
+    /**
+     * 设置图标
+     *
+     * @param drawable 图标drawable
+     * @param gapWidth 图标和文字间距离
+     * @param align    对齐
+     *                 <ul>
+     *                 <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *                 <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *                 <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *                 </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(final Drawable drawable, final int gapWidth, @Align final int align) {
+        this.iconMarginDrawable = drawable;
+        this.iconMarginGapWidth = gapWidth;
+        this.alignIconMargin = align;
+        return this;
+    }
+
+    /**
+     * 设置图标
+     * <p>默认0边距,居中对齐</p>
+     *
+     * @param uri 图标uri
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(final Uri uri) {
+        return setIconMargin(uri, 0, ALIGN_CENTER);
+    }
+
+    /**
+     * 设置图标
+     *
+     * @param uri      图标uri
+     * @param gapWidth 图标和文字间距离
+     * @param align    对齐
+     *                 <ul>
+     *                 <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *                 <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *                 <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *                 </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(final Uri uri, final int gapWidth, @Align final int align) {
+        this.iconMarginUri = uri;
+        this.iconMarginGapWidth = gapWidth;
+        this.alignIconMargin = align;
+        return this;
+    }
+
+    /**
+     * 设置图标
+     * <p>默认0边距,居中对齐</p>
+     *
+     * @param resourceId 图标resourceId
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(@DrawableRes final int resourceId) {
+        return setIconMargin(resourceId, 0, ALIGN_CENTER);
+    }
+
+    /**
+     * 设置图标
+     *
+     * @param resourceId 图标resourceId
+     * @param gapWidth   图标和文字间距离
+     * @param align      对齐
+     *                   <ul>
+     *                   <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *                   <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *                   <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *                   </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setIconMargin(@DrawableRes final int resourceId, final int gapWidth, @Align final int align) {
+        this.iconMarginResourceId = resourceId;
+        this.iconMarginGapWidth = gapWidth;
+        this.alignIconMargin = align;
+        return this;
+    }
+
+    /**
+     * 设置字体尺寸
+     *
+     * @param size 尺寸
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setFontSize(@IntRange(from = 0) final int size) {
+        return setFontSize(size, false);
+    }
+
+    /**
+     * 设置字体尺寸
+     *
+     * @param size 尺寸
+     * @param isDp 是否使用dip
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setFontSize(@IntRange(from = 0) final int size, final boolean isDp) {
+        this.fontSize = size;
+        this.fontSizeIsDp = isDp;
+        return this;
+    }
+
+    /**
+     * 设置字体比例
+     *
+     * @param proportion 比例
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setFontProportion(@FloatRange(from = 0, fromInclusive = false) final float proportion) {
+        this.proportion = proportion;
+        return this;
+    }
+
+    /**
+     * 设置字体横向比例
+     *
+     * @param proportion 比例
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setFontXProportion(@FloatRange(from = 0, fromInclusive = false) final float proportion) {
+        this.xProportion = proportion;
+        return this;
+    }
+
+    /**
+     * 设置删除线
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setStrikethrough() {
+        this.isStrikethrough = true;
+        return this;
+    }
+
+    /**
+     * 设置下划线
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setUnderline() {
+        this.isUnderline = true;
+        return this;
+    }
+
+    /**
+     * 设置上标
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setSuperscript() {
+        this.isSuperscript = true;
+        return this;
+    }
+
+    /**
+     * 设置下标
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setSubscript() {
+        this.isSubscript = true;
+        return this;
+    }
+
+    /**
+     * 设置粗体
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setBold() {
+        isBold = true;
+        return this;
+    }
+
+    /**
+     * 设置斜体
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setItalic() {
+        isItalic = true;
+        return this;
+    }
+
+    /**
+     * 设置粗斜体
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setBoldItalic() {
+        isBoldItalic = true;
+        return this;
+    }
+
+    /**
+     * 设置字体系列
+     *
+     * @param fontFamily 字体系列
+     *                   <ul>
+     *                   <li>monospace</li>
+     *                   <li>serif</li>
+     *                   <li>sans-serif</li>
+     *                   </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setFontFamily(@NonNull final String fontFamily) {
+        this.fontFamily = fontFamily;
+        return this;
+    }
+
+    /**
+     * 设置字体
+     *
+     * @param typeface 字体
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setTypeface(@NonNull final Typeface typeface) {
+        this.typeface = typeface;
+        return this;
+    }
+
+    /**
+     * 设置对齐
+     *
+     * @param alignment 对其方式
+     *                  <ul>
+     *                  <li>{@link Alignment#ALIGN_NORMAL}正常</li>
+     *                  <li>{@link Alignment#ALIGN_OPPOSITE}相反</li>
+     *                  <li>{@link Alignment#ALIGN_CENTER}居中</li>
+     *                  </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setAlign(@NonNull final Alignment alignment) {
+        this.alignment = alignment;
+        return this;
+    }
+
+    /**
+     * 设置点击事件
+     * <p>需添加view.setMovementMethod(LinkMovementMethod.getInstance())</p>
+     *
+     * @param clickSpan 点击事件
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setClickSpan(@NonNull final ClickableSpan clickSpan) {
+        this.clickSpan = clickSpan;
+        return this;
+    }
+
+    /**
+     * 设置超链接
+     * <p>需添加view.setMovementMethod(LinkMovementMethod.getInstance())</p>
+     *
+     * @param url 超链接
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setUrl(@NonNull final String url) {
+        this.url = url;
+        return this;
+    }
+
+    /**
+     * 设置模糊
+     * <p>尚存bug,其他地方存在相同的字体的话,相同字体出现在之前的话那么就不会模糊,出现在之后的话那会一起模糊</p>
+     * <p>以上bug关闭硬件加速即可</p>
+     *
+     * @param radius 模糊半径(需大于0)
+     * @param style  模糊样式<ul>
+     *               <li>{@link Blur#NORMAL}</li>
+     *               <li>{@link Blur#SOLID}</li>
+     *               <li>{@link Blur#OUTER}</li>
+     *               <li>{@link Blur#INNER}</li>
+     *               </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setBlur(@FloatRange(from = 0, fromInclusive = false) final float radius, final Blur style) {
+        this.blurRadius = radius;
+        this.style = style;
+        return this;
+    }
+
+    /**
+     * 设置着色器
+     *
+     * @param shader 着色器
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setShader(@NonNull final Shader shader) {
+        this.shader = shader;
+        return this;
+    }
+
+    /**
+     * 设置阴影
+     *
+     * @param radius      阴影半径
+     * @param dx          x轴偏移量
+     * @param dy          y轴偏移量
+     * @param shadowColor 阴影颜色
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setShadow(@FloatRange(from = 0, fromInclusive = false) final float radius,
+                               final float dx,
+                               final float dy,
+                               final int shadowColor) {
+        this.shadowRadius = radius;
+        this.shadowDx = dx;
+        this.shadowDy = dy;
+        this.shadowColor = shadowColor;
+        return this;
+    }
+
+
+    /**
+     * 设置样式
+     *
+     * @param spans 样式
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils setSpans(@NonNull final Object... spans) {
+        if (spans.length > 0) {
+            this.spans = spans;
+        }
+        return this;
+    }
+
+    /**
+     * 追加样式字符串
+     *
+     * @param text 样式字符串文本
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils append(@NonNull final CharSequence text) {
+        apply(mTypeCharSequence);
+        mText = text;
+        return this;
+    }
+
+    /**
+     * 追加一行
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendLine() {
+        apply(mTypeCharSequence);
+        mText = LINE_SEPARATOR;
+        return this;
+    }
+
+    /**
+     * 追加一行样式字符串
+     *
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendLine(@NonNull final CharSequence text) {
+        apply(mTypeCharSequence);
+        mText = text + LINE_SEPARATOR;
+        return this;
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param bitmap 图片位图
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@NonNull final Bitmap bitmap) {
+        return appendImage(bitmap, ALIGN_BOTTOM);
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param bitmap 图片位图
+     * @param align  对齐
+     *               <ul>
+     *               <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *               <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *               <li>{@link Align#ALIGN_BASELINE}基线对齐</li>
+     *               <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *               </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@NonNull final Bitmap bitmap, @Align final int align) {
+        apply(mTypeImage);
+        this.imageBitmap = bitmap;
+        this.alignImage = align;
+        return this;
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param drawable 图片资源
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@NonNull final Drawable drawable) {
+        return appendImage(drawable, ALIGN_BOTTOM);
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param drawable 图片资源
+     * @param align    对齐
+     *                 <ul>
+     *                 <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *                 <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *                 <li>{@link Align#ALIGN_BASELINE}基线对齐</li>
+     *                 <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *                 </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@NonNull final Drawable drawable, @Align final int align) {
+        apply(mTypeImage);
+        this.imageDrawable = drawable;
+        this.alignImage = align;
+        return this;
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param uri 图片uri
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@NonNull final Uri uri) {
+        return appendImage(uri, ALIGN_BOTTOM);
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param uri   图片uri
+     * @param align 对齐
+     *              <ul>
+     *              <li>{@link Align#ALIGN_TOP}顶部对齐</li>
+     *              <li>{@link Align#ALIGN_CENTER}居中对齐</li>
+     *              <li>{@link Align#ALIGN_BASELINE}基线对齐</li>
+     *              <li>{@link Align#ALIGN_BOTTOM}底部对齐</li>
+     *              </ul>
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@NonNull final Uri uri, @Align final int align) {
+        apply(mTypeImage);
+        this.imageUri = uri;
+        this.alignImage = align;
+        return this;
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param resourceId 图片资源id
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@DrawableRes final int resourceId) {
+        return appendImage(resourceId, ALIGN_BOTTOM);
+    }
+
+    /**
+     * 追加图片
+     *
+     * @param resourceId 图片资源id
+     * @param align      对齐
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendImage(@DrawableRes final int resourceId, @Align final int align) {
+        apply(mTypeImage);
+        this.imageResourceId = resourceId;
+        this.alignImage = align;
+        return this;
+    }
+
+    /**
+     * 追加空白
+     *
+     * @param size 间距
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendSpace(@IntRange(from = 0) final int size) {
+        return appendSpace(size, Color.TRANSPARENT);
+    }
+
+    /**
+     * 追加空白
+     *
+     * @param size  间距
+     * @param color 颜色
+     * @return {@link SpanUtils}
+     */
+    public SpanUtils appendSpace(@IntRange(from = 0) final int size, @ColorInt final int color) {
+        apply(mTypeSpace);
+        spaceSize = size;
+        spaceColor = color;
+        return this;
+    }
+
+    private void apply(final int type) {
+        applyLast();
+        mType = type;
+    }
+
+    /**
+     * 创建样式字符串
+     *
+     * @return 样式字符串
+     */
+    public SpannableStringBuilder create() {
+        applyLast();
+        return mBuilder;
+    }
+
+    /**
+     * 设置上一次的样式
+     */
+    private void applyLast() {
+        if (mType == mTypeCharSequence) {
+            updateCharCharSequence();
+        } else if (mType == mTypeImage) {
+            updateImage();
+        } else if (mType == mTypeSpace) {
+            updateSpace();
+        }
+        setDefault();
+    }
+
+    private void updateCharCharSequence() {
+        if (mText.length() == 0) {
+            return;
+        }
+        int start = mBuilder.length();
+        mBuilder.append(mText);
+        int end = mBuilder.length();
+        if (foregroundColor != COLOR_DEFAULT) {
+            mBuilder.setSpan(new ForegroundColorSpan(foregroundColor), start, end, flag);
+        }
+        if (backgroundColor != COLOR_DEFAULT) {
+            mBuilder.setSpan(new BackgroundColorSpan(backgroundColor), start, end, flag);
+        }
+        if (first != -1) {
+            mBuilder.setSpan(new LeadingMarginSpan.Standard(first, rest), start, end, flag);
+        }
+        if (quoteColor != COLOR_DEFAULT) {
+            mBuilder.setSpan(new CustomQuoteSpan(quoteColor, stripeWidth, quoteGapWidth), start, end, flag);
+        }
+        if (bulletColor != COLOR_DEFAULT) {
+            mBuilder.setSpan(new CustomBulletSpan(bulletColor, bulletRadius, bulletGapWidth), start, end, flag);
+        }
+        if (iconMarginGapWidth != -1) {
+            if (iconMarginBitmap != null) {
+                mBuilder.setSpan(new CustomIconMarginSpan(iconMarginBitmap, iconMarginGapWidth, alignIconMargin), start, end, flag);
+            } else if (iconMarginDrawable != null) {
+                mBuilder.setSpan(new CustomIconMarginSpan(iconMarginDrawable, iconMarginGapWidth, alignIconMargin), start, end, flag);
+            } else if (iconMarginUri != null) {
+                mBuilder.setSpan(new CustomIconMarginSpan(iconMarginUri, iconMarginGapWidth, alignIconMargin), start, end, flag);
+            } else if (iconMarginResourceId != -1) {
+                mBuilder.setSpan(new CustomIconMarginSpan(iconMarginResourceId, iconMarginGapWidth, alignIconMargin), start, end, flag);
+            }
+        }
+        if (fontSize != -1) {
+            mBuilder.setSpan(new AbsoluteSizeSpan(fontSize, fontSizeIsDp), start, end, flag);
+        }
+        if (proportion != -1) {
+            mBuilder.setSpan(new RelativeSizeSpan(proportion), start, end, flag);
+        }
+        if (xProportion != -1) {
+            mBuilder.setSpan(new ScaleXSpan(xProportion), start, end, flag);
+        }
+        if (lineHeight != -1) {
+            mBuilder.setSpan(new CustomLineHeightSpan(lineHeight, alignLine), start, end, flag);
+        }
+        if (isStrikethrough) {
+            mBuilder.setSpan(new StrikethroughSpan(), start, end, flag);
+        }
+        if (isUnderline) {
+            mBuilder.setSpan(new UnderlineSpan(), start, end, flag);
+        }
+        if (isSuperscript) {
+            mBuilder.setSpan(new SuperscriptSpan(), start, end, flag);
+        }
+        if (isSubscript) {
+            mBuilder.setSpan(new SubscriptSpan(), start, end, flag);
+        }
+        if (isBold) {
+            mBuilder.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
+        }
+        if (isItalic) {
+            mBuilder.setSpan(new StyleSpan(Typeface.ITALIC), start, end, flag);
+        }
+        if (isBoldItalic) {
+            mBuilder.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, flag);
+        }
+        if (fontFamily != null) {
+            mBuilder.setSpan(new TypefaceSpan(fontFamily), start, end, flag);
+        }
+        if (typeface != null) {
+            mBuilder.setSpan(new CustomTypefaceSpan(typeface), start, end, flag);
+        }
+        if (alignment != null) {
+            mBuilder.setSpan(new AlignmentSpan.Standard(alignment), start, end, flag);
+        }
+        if (clickSpan != null) {
+            mBuilder.setSpan(clickSpan, start, end, flag);
+        }
+        if (url != null) {
+            mBuilder.setSpan(new URLSpan(url), start, end, flag);
+        }
+        if (blurRadius != -1) {
+            mBuilder.setSpan(new MaskFilterSpan(new BlurMaskFilter(blurRadius, style)), start, end, flag);
+        }
+        if (shader != null) {
+            mBuilder.setSpan(new ShaderSpan(shader), start, end, flag);
+        }
+        if (shadowRadius != -1) {
+            mBuilder.setSpan(new ShadowSpan(shadowRadius, shadowDx, shadowDy, shadowColor), start, end, flag);
+        }
+        if (spans != null) {
+            for (Object span : spans) {
+                mBuilder.setSpan(span, start, end, flag);
+            }
+        }
+    }
+
+    private void updateImage() {
+        int start = mBuilder.length();
+        mBuilder.append("<img>");
+        int end = start + 5;
+        if (imageBitmap != null) {
+            mBuilder.setSpan(new CustomImageSpan(imageBitmap, alignImage), start, end, flag);
+        } else if (imageDrawable != null) {
+            mBuilder.setSpan(new CustomImageSpan(imageDrawable, alignImage), start, end, flag);
+        } else if (imageUri != null) {
+            mBuilder.setSpan(new CustomImageSpan(imageUri, alignImage), start, end, flag);
+        } else if (imageResourceId != -1) {
+            mBuilder.setSpan(new CustomImageSpan(imageResourceId, alignImage), start, end, flag);
+        }
+    }
+
+    private void updateSpace() {
+        int start = mBuilder.length();
+        mBuilder.append("< >");
+        int end = start + 3;
+        mBuilder.setSpan(new SpaceSpan(spaceSize, spaceColor), start, end, flag);
+    }
+
+    /**
+     * 行高
+     */
+    class CustomLineHeightSpan extends CharacterStyle
+            implements android.text.style.LineHeightSpan {
+
+        private final int height;
+
+        static final int ALIGN_CENTER = 2;
+
+        static final int ALIGN_TOP = 3;
+
+        final int mVerticalAlignment;
+
+        CustomLineHeightSpan(int height, int verticalAlignment) {
+            this.height = height;
+            mVerticalAlignment = verticalAlignment;
+        }
+
+        @Override
+        public void chooseHeight(final CharSequence text, final int start, final int end, final int spanstartv, final int v, final Paint.FontMetricsInt fm) {
+            int need = height - (v + fm.descent - fm.ascent - spanstartv);
+            if (need > 0) {
+                if (mVerticalAlignment == ALIGN_TOP) {
+                    fm.descent += need;
+                } else if (mVerticalAlignment == ALIGN_CENTER) {
+                    fm.descent += need / 2;
+                    fm.ascent -= need / 2;
+                } else {
+                    fm.ascent -= need;
+                }
+            }
+            need = height - (v + fm.bottom - fm.top - spanstartv);
+            if (need > 0) {
+                if (mVerticalAlignment == ALIGN_TOP) {
+                    fm.top += need;
+                } else if (mVerticalAlignment == ALIGN_CENTER) {
+                    fm.bottom += need / 2;
+                    fm.top -= need / 2;
+                } else {
+                    fm.top -= need;
+                }
+            }
+        }
+
+        @Override
+        public void updateDrawState(final TextPaint tp) {
+
+        }
+    }
+
+    /**
+     * 空格
+     */
+    class SpaceSpan extends ReplacementSpan {
+
+        private final int width;
+        private final int color;
+
+        private SpaceSpan(final int width) {
+            this(width, Color.TRANSPARENT);
+        }
+
+        private SpaceSpan(final int width, final int color) {
+            super();
+            this.width = width;
+            this.color = color;
+        }
+
+        @Override
+        public int getSize(@NonNull final Paint paint, final CharSequence text,
+                           @IntRange(from = 0) final int start,
+                           @IntRange(from = 0) final int end,
+                           @Nullable final Paint.FontMetricsInt fm) {
+            return width;
+        }
+
+        @Override
+        public void draw(@NonNull final Canvas canvas, final CharSequence text,
+                         @IntRange(from = 0) final int start,
+                         @IntRange(from = 0) final int end,
+                         final float x, final int top, final int y, final int bottom,
+                         @NonNull final Paint paint) {
+            Paint.Style style = paint.getStyle();
+            int color = paint.getColor();
+
+            paint.setStyle(Paint.Style.FILL);
+            paint.setColor(this.color);
+
+            canvas.drawRect(x, top, x + width, bottom, paint);
+
+            paint.setStyle(style);
+            paint.setColor(color);
+        }
+    }
+
+    /**
+     * 引用
+     */
+    class CustomQuoteSpan implements LeadingMarginSpan {
+
+        private final int color;
+        private final int stripeWidth;
+        private final int gapWidth;
+
+        private CustomQuoteSpan(final int color, final int stripeWidth, final int gapWidth) {
+            super();
+            this.color = color;
+            this.stripeWidth = stripeWidth;
+            this.gapWidth = gapWidth;
+        }
+
+        @Override
+        public int getLeadingMargin(final boolean first) {
+            return stripeWidth + gapWidth;
+        }
+
+        @Override
+        public void drawLeadingMargin(final Canvas c, final Paint p, final int x, final int dir,
+                                      final int top, final int baseline, final int bottom,
+                                      final CharSequence text, final int start, final int end,
+                                      final boolean first, final Layout layout) {
+            Paint.Style style = p.getStyle();
+            int color = p.getColor();
+
+            p.setStyle(Paint.Style.FILL);
+            p.setColor(this.color);
+
+            c.drawRect(x, top, x + dir * stripeWidth, bottom, p);
+
+            p.setStyle(style);
+            p.setColor(color);
+        }
+    }
+
+    /**
+     * 列表项
+     */
+    class CustomBulletSpan implements LeadingMarginSpan {
+
+        private final int color;
+        private final int radius;
+        private final int gapWidth;
+
+        private Path sBulletPath = null;
+
+        private CustomBulletSpan(final int color, final int radius, final int gapWidth) {
+            this.color = color;
+            this.radius = radius;
+            this.gapWidth = gapWidth;
+        }
+
+        @Override
+        public int getLeadingMargin(final boolean first) {
+            return 2 * radius + gapWidth;
+        }
+
+        @Override
+        public void drawLeadingMargin(final Canvas c, final Paint p, final int x, final int dir,
+                                      final int top, final int baseline, final int bottom,
+                                      final CharSequence text, final int start, final int end,
+                                      final boolean first, final Layout l) {
+            if (((Spanned) text).getSpanStart(this) == start) {
+                Paint.Style style = p.getStyle();
+                int oldColor = 0;
+                oldColor = p.getColor();
+                p.setColor(color);
+                p.setStyle(Paint.Style.FILL);
+                if (c.isHardwareAccelerated()) {
+                    if (sBulletPath == null) {
+                        sBulletPath = new Path();
+                        // Bullet is slightly better to avoid aliasing artifacts on mdpi devices.
+                        sBulletPath.addCircle(0.0f, 0.0f, radius, Path.Direction.CW);
+                    }
+                    c.save();
+                    c.translate(x + dir * radius, (top + bottom) / 2.0f);
+                    c.drawPath(sBulletPath, p);
+                    c.restore();
+                } else {
+                    c.drawCircle(x + dir * radius, (top + bottom) / 2.0f, radius, p);
+                }
+                p.setColor(oldColor);
+                p.setStyle(style);
+            }
+        }
+    }
+
+    class CustomIconMarginSpan implements LeadingMarginSpan, android.text.style.LineHeightSpan {
+        Bitmap mBitmap;
+
+        static final int ALIGN_CENTER = 2;
+
+        static final int ALIGN_TOP = 3;
+
+        final int mVerticalAlignment;
+
+        private int mPad;
+        private int totalHeight;
+        private int lineHeight;
+        private int need0;
+        private int need1;
+        private boolean flag;
+
+        private CustomIconMarginSpan(final Bitmap b, final int pad, final int verticalAlignment) {
+            mBitmap = b;
+            mPad = pad;
+            mVerticalAlignment = verticalAlignment;
+        }
+
+        private CustomIconMarginSpan(final Drawable drawable, final int pad, final int verticalAlignment) {
+            mBitmap = drawable2Bitmap(drawable);
+            mPad = pad;
+            mVerticalAlignment = verticalAlignment;
+        }
+
+        private CustomIconMarginSpan(final Uri uri, final int pad, final int verticalAlignment) {
+            mBitmap = uri2Bitmap(uri);
+            mPad = pad;
+            mVerticalAlignment = verticalAlignment;
+        }
+
+        private CustomIconMarginSpan(final int resourceId, final int pad, final int verticalAlignment) {
+            mBitmap = resource2Bitmap(resourceId);
+            mPad = pad;
+            mVerticalAlignment = verticalAlignment;
+        }
+
+        private Bitmap drawable2Bitmap(final Drawable drawable) {
+            if (drawable instanceof BitmapDrawable) {
+                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+                if (bitmapDrawable.getBitmap() != null) {
+                    return bitmapDrawable.getBitmap();
+                }
+            }
+            Bitmap bitmap;
+            if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
+                bitmap = Bitmap.createBitmap(1, 1,
+                        drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
+            } else {
+                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
+                        drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
+            }
+            Canvas canvas = new Canvas(bitmap);
+            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+            drawable.draw(canvas);
+            return bitmap;
+        }
+
+        private Bitmap uri2Bitmap(final Uri uri) {
+            try {
+                return MediaStore.Images.Media.getBitmap(MyApplication.getInstance().getApplicationContext().getContentResolver(), uri);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+            }
+        }
+
+        private Bitmap resource2Bitmap(final int resourceId) {
+            Drawable drawable = ContextCompat.getDrawable(MyApplication.getInstance().getApplicationContext(), resourceId);
+            Canvas canvas = new Canvas();
+            Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+            canvas.setBitmap(bitmap);
+            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+            drawable.draw(canvas);
+            return bitmap;
+        }
+
+        @Override
+        public int getLeadingMargin(final boolean first) {
+            return mBitmap.getWidth() + mPad;
+        }
+
+        @Override
+        public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
+                                      int top, int baseline, int bottom,
+                                      CharSequence text, int start, int end,
+                                      boolean first, Layout layout) {
+            int st = ((Spanned) text).getSpanStart(this);
+            int itop = layout.getLineTop(layout.getLineForOffset(st));
+
+            if (dir < 0) {
+                x -= mBitmap.getWidth();
+            }
+
+            int delta = totalHeight - mBitmap.getHeight();
+
+            if (delta > 0) {
+                if (mVerticalAlignment == ALIGN_TOP) {
+                    c.drawBitmap(mBitmap, x, itop, p);
+                } else if (mVerticalAlignment == ALIGN_CENTER) {
+                    c.drawBitmap(mBitmap, x, itop + delta / 2, p);
+                } else {
+                    c.drawBitmap(mBitmap, x, itop + delta, p);
+                }
+            } else {
+                c.drawBitmap(mBitmap, x, itop, p);
+            }
+        }
+
+        @Override
+        public void chooseHeight(CharSequence text, int start, int end,
+                                 int istartv, int v, Paint.FontMetricsInt fm) {
+            if (lineHeight == 0) {
+                lineHeight = v - istartv;
+            }
+            if (need0 == 0 && end == ((Spanned) text).getSpanEnd(this)) {
+                int ht = mBitmap.getHeight();
+                need0 = ht - (v + fm.descent - fm.ascent - istartv);
+                need1 = ht - (v + fm.bottom - fm.top - istartv);
+                totalHeight = v - istartv + lineHeight;
+                return;
+            }
+            if (need0 > 0 || need1 > 0) {
+                if (mVerticalAlignment == ALIGN_TOP) {
+                    // the rest space should be filled with the end of line
+                    if (end == ((Spanned) text).getSpanEnd(this)) {
+                        if (need0 > 0) {
+                            fm.descent += need0;
+                        }
+                        if (need1 > 0) {
+                            fm.bottom += need1;
+                        }
+                    }
+                } else if (mVerticalAlignment == ALIGN_CENTER) {
+                    if (start == ((Spanned) text).getSpanStart(this)) {
+                        if (need0 > 0) {
+                            fm.ascent -= need0 / 2;
+                        }
+                        if (need1 > 0) {
+                            fm.top -= need1 / 2;
+                        }
+                    } else {
+                        if (!flag) {
+                            if (need0 > 0) {
+                                fm.ascent += need0 / 2;
+                            }
+                            if (need1 > 0) {
+                                fm.top += need1 / 2;
+                            }
+                            flag = true;
+                        }
+                    }
+                    if (end == ((Spanned) text).getSpanEnd(this)) {
+                        if (need0 > 0) {
+                            fm.descent += need0 / 2;
+                        }
+                        if (need1 > 0) {
+                            fm.bottom += need1 / 2;
+                        }
+                    }
+                } else {
+                    // the top space should be filled with the first of line
+                    if (start == ((Spanned) text).getSpanStart(this)) {
+                        if (need0 > 0) {
+                            fm.ascent -= need0;
+                        }
+                        if (need1 > 0) {
+                            fm.top -= need1;
+                        }
+                    } else {
+                        if (!flag) {
+                            if (need0 > 0) {
+                                fm.ascent += need0;
+                            }
+                            if (need1 > 0) {
+                                fm.top += need1;
+                            }
+                            flag = true;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressLint("ParcelCreator")
+    class CustomTypefaceSpan extends TypefaceSpan {
+
+        private final Typeface newType;
+
+        private CustomTypefaceSpan(final Typeface type) {
+            super("");
+            newType = type;
+        }
+
+        @Override
+        public void updateDrawState(final TextPaint textPaint) {
+            apply(textPaint, newType);
+        }
+
+        @Override
+        public void updateMeasureState(final TextPaint paint) {
+            apply(paint, newType);
+        }
+
+        private void apply(final Paint paint, final Typeface tf) {
+            int oldStyle;
+            Typeface old = paint.getTypeface();
+            if (old == null) {
+                oldStyle = 0;
+            } else {
+                oldStyle = old.getStyle();
+            }
+
+            int fake = oldStyle & ~tf.getStyle();
+            if ((fake & Typeface.BOLD) != 0) {
+                paint.setFakeBoldText(true);
+            }
+
+            if ((fake & Typeface.ITALIC) != 0) {
+                paint.setTextSkewX(-0.25f);
+            }
+
+            paint.getShader();
+
+            paint.setTypeface(tf);
+        }
+    }
+
+    class CustomImageSpan extends CustomDynamicDrawableSpan {
+        private Drawable mDrawable;
+        private Uri mContentUri;
+        private int mResourceId;
+
+        private CustomImageSpan(final Bitmap b, final int verticalAlignment) {
+            super(verticalAlignment);
+            mDrawable = new BitmapDrawable(MyApplication.getInstance().getApplicationContext().getResources(), b);
+            mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
+        }
+
+        private CustomImageSpan(final Drawable d, final int verticalAlignment) {
+            super(verticalAlignment);
+            mDrawable = d;
+            mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
+        }
+
+        private CustomImageSpan(final Uri uri, final int verticalAlignment) {
+            super(verticalAlignment);
+            mContentUri = uri;
+        }
+
+        private CustomImageSpan(@DrawableRes final int resourceId, final int verticalAlignment) {
+            super(verticalAlignment);
+            mResourceId = resourceId;
+        }
+
+        @Override
+        public Drawable getDrawable() {
+            Drawable drawable = null;
+            if (mDrawable != null) {
+                drawable = mDrawable;
+            } else if (mContentUri != null) {
+                Bitmap bitmap;
+                try {
+                    InputStream is = MyApplication.getInstance().getApplicationContext().getContentResolver().openInputStream(mContentUri);
+                    bitmap = BitmapFactory.decodeStream(is);
+                    drawable = new BitmapDrawable(MyApplication.getInstance().getApplicationContext().getResources(), bitmap);
+                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+                    if (is != null) {
+                        is.close();
+                    }
+                } catch (Exception e) {
+                    Log.e("sms", "Failed to loaded content " + mContentUri, e);
+                }
+            } else {
+                try {
+                    drawable = ContextCompat.getDrawable(MyApplication.getInstance().getApplicationContext(), mResourceId);
+                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+                } catch (Exception e) {
+                    Log.e("sms", "Unable to find resource: " + mResourceId);
+                }
+            }
+            return drawable;
+        }
+    }
+
+    abstract class CustomDynamicDrawableSpan extends ReplacementSpan {
+
+        static final int ALIGN_BOTTOM = 0;
+
+        static final int ALIGN_BASELINE = 1;
+
+        static final int ALIGN_CENTER = 2;
+
+        static final int ALIGN_TOP = 3;
+
+        final int mVerticalAlignment;
+
+        private CustomDynamicDrawableSpan() {
+            mVerticalAlignment = ALIGN_BOTTOM;
+        }
+
+        private CustomDynamicDrawableSpan(final int verticalAlignment) {
+            mVerticalAlignment = verticalAlignment;
+        }
+
+        public abstract Drawable getDrawable();
+
+        @Override
+        public int getSize(@NonNull final Paint paint, final CharSequence text,
+                           final int start, final int end,
+                           final Paint.FontMetricsInt fm) {
+            Drawable d = getCachedDrawable();
+            Rect rect = d.getBounds();
+            final int fontHeight = (int) (paint.getFontMetrics().descent - paint.getFontMetrics().ascent);
+            if (fm != null) { // this is the fucking code which I waste 3 days
+                if (rect.height() > fontHeight) {
+                    if (mVerticalAlignment == ALIGN_TOP) {
+                        fm.descent += rect.height() - fontHeight;
+                    } else if (mVerticalAlignment == ALIGN_CENTER) {
+                        fm.ascent -= (rect.height() - fontHeight) / 2;
+                        fm.descent += (rect.height() - fontHeight) / 2;
+                    } else {
+                        fm.ascent -= rect.height() - fontHeight;
+                    }
+                }
+            }
+            return rect.right;
+        }
+
+        @Override
+        public void draw(@NonNull final Canvas canvas, final CharSequence text,
+                         final int start, final int end, final float x,
+                         final int top, final int y, final int bottom, @NonNull final Paint paint) {
+            Drawable d = getCachedDrawable();
+            Rect rect = d.getBounds();
+            canvas.save();
+            final float fontHeight = paint.getFontMetrics().descent - paint.getFontMetrics().ascent;
+            int transY = bottom - rect.bottom;
+            if (rect.height() < fontHeight) { // this is the fucking code which I waste 3 days
+                if (mVerticalAlignment == ALIGN_BASELINE) {
+                    transY -= paint.getFontMetricsInt().descent;
+                } else if (mVerticalAlignment == ALIGN_CENTER) {
+                    transY -= (fontHeight - rect.height()) / 2;
+                } else if (mVerticalAlignment == ALIGN_TOP) {
+                    transY -= fontHeight - rect.height();
+                }
+            }
+            canvas.translate(x, transY);
+            d.draw(canvas);
+            canvas.restore();
+        }
+
+        private Drawable getCachedDrawable() {
+            WeakReference<Drawable> wr = mDrawableRef;
+            Drawable d = null;
+            if (wr != null) {
+                d = wr.get();
+            }
+            if (d == null) {
+                d = getDrawable();
+                mDrawableRef = new WeakReference<>(d);
+            }
+            return getDrawable();
+        }
+
+        private WeakReference<Drawable> mDrawableRef;
+    }
+
+    class ShaderSpan extends CharacterStyle implements UpdateAppearance {
+        private Shader mShader;
+
+        private ShaderSpan(final Shader shader) {
+            this.mShader = shader;
+        }
+
+        @Override
+        public void updateDrawState(final TextPaint tp) {
+            tp.setShader(mShader);
+        }
+    }
+
+    class ShadowSpan extends CharacterStyle implements UpdateAppearance {
+        private float radius;
+        private float dx, dy;
+        private int shadowColor;
+
+        private ShadowSpan(final float radius, final float dx, final float dy, final int shadowColor) {
+            this.radius = radius;
+            this.dx = dx;
+            this.dy = dy;
+            this.shadowColor = shadowColor;
+        }
+
+        @Override
+        public void updateDrawState(final TextPaint tp) {
+            tp.setShadowLayer(radius, dx, dy, shadowColor);
+        }
+    }
+}

+ 18 - 1
app_core/common/src/main/java/com/core/utils/ToastUtil.java

@@ -1,18 +1,21 @@
 package com.core.utils;
 
+import android.app.Activity;
 import android.content.Context;
 import android.graphics.Color;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.Log;
 import android.view.Gravity;
+import android.view.ViewGroup;
 import android.widget.EditText;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.core.app.R;
 import com.common.data.StringUtil;
+import com.core.app.R;
 import com.core.widget.crouton.Crouton;
+import com.core.widget.crouton.Style;
 
 public class ToastUtil {
 
@@ -90,4 +93,18 @@ public class ToastUtil {
         Crouton.makeText(context, context.getString(resId));
     }
 
+    public static void showToast(Context context, String message, ViewGroup viewGroup) {
+        if (context == null || StringUtil.isEmpty(message)) {
+            return;
+        }
+        Crouton.makeText((Activity) context, message, Style.holoGreenLight, 1000, viewGroup).show();
+    }
+
+    public static void showToast(Context context, int resId, ViewGroup viewGroup) {
+        if (context == null) {
+            return;
+        }
+        Crouton.makeText((Activity) context, context.getString(resId), Style.holoGreenLight, 1000, viewGroup).show();
+    }
+
 }

+ 3 - 3
app_core/common/src/main/res/drawable/bg_green_btn.xml

@@ -3,21 +3,21 @@
     <item android:state_pressed="true">
         <shape>
             <solid android:color="@color/btn_orange_press" />
-            <corners android:radius="8dp" />
+            <corners android:radius="1dp" />
             <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
         </shape>
     </item>
     <item android:state_enabled="false">
         <shape>
             <solid android:color="@color/btn_orange_press" />
-            <corners android:radius="8dp" />
+            <corners android:radius="1dp" />
             <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
         </shape>
     </item>
     <item>
         <shape>
             <solid android:color="@color/light_green" />
-            <corners android:radius="8dp" />
+            <corners android:radius="1dp" />
             <padding android:bottom="0.5dp" android:left="0.5dp" android:right="0.5dp" android:top="0.5dp" />
         </shape>
     </item>

+ 1 - 2
app_core/common/src/main/res/layout/activity_register_select.xml

@@ -4,8 +4,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_gravity="center"
-    android:orientation="vertical"
-    tools:context="com.xzjmyk.pm.activity.ui.account.RegisterSelectActivity">
+    android:orientation="vertical">
     <de.hdodenhof.circleimageview.CircleImageView
         android:id="@+id/iv_head"
         android:layout_width="90dp"

+ 12 - 27
app_core/network/src/main/java/com/me/network/app/http/rx/ResultSubscriber.java

@@ -2,7 +2,6 @@ package com.me.network.app.http.rx;
 
 
 import java.io.IOException;
-import java.net.ConnectException;
 import java.net.SocketTimeoutException;
 
 import retrofit2.adapter.rxjava.HttpException;
@@ -23,11 +22,11 @@ public class ResultSubscriber<T> extends Subscriber<T> {
         if (listener != null) {
             if (listener instanceof Result2Listener) {
                 this.result2Listener = (Result2Listener<T>) listener;
-            }
-            if (listener instanceof ResultTagListener) {
+            } else if (listener instanceof ResultTagListener) {
                 this.mResultTagListener = (ResultTagListener<T>) listener;
+            } else {
+                this.resultListener = listener;
             }
-            this.resultListener = listener;
         }
     }
 
@@ -46,13 +45,7 @@ public class ResultSubscriber<T> extends Subscriber<T> {
     @Override
     public void onError(Throwable e) {
         if (result2Listener != null) {
-            if (e instanceof SocketTimeoutException) {
-//				Logger.e("SocketTimeoutException");
-                result2Listener.onFailure(e);
-            } else if (e instanceof ConnectException) {
-//				Logger.e("ConnectException");
-                result2Listener.onFailure(e);
-            } else if (e instanceof HttpException) {
+            if (e instanceof HttpException) {
                 HttpException he = (HttpException) e;
                 try {
                     result2Listener.onFailure(he.response().errorBody().string());
@@ -60,16 +53,10 @@ public class ResultSubscriber<T> extends Subscriber<T> {
                     e1.printStackTrace();
                 }
             } else {
-                resultListener.onResponse((T) e);
+                result2Listener.onFailure((T) e);
             }
-        } else if (mResultTagListener != null){
-            if (e instanceof SocketTimeoutException) {
-//				Logger.e("SocketTimeoutException");
-                mResultTagListener.onError(e);
-            } else if (e instanceof ConnectException) {
-//				Logger.e("ConnectException");
-                mResultTagListener.onError(e);
-            } else if (e instanceof HttpException) {
+        } else if (mResultTagListener != null) {
+            if (e instanceof HttpException) {
                 HttpException he = (HttpException) e;
                 try {
                     mResultTagListener.onError(he.response().errorBody().string());
@@ -77,9 +64,9 @@ public class ResultSubscriber<T> extends Subscriber<T> {
                     e1.printStackTrace();
                 }
             } else {
-                resultListener.onResponse((T) e);
+                mResultTagListener.onError((T) e);
             }
-        }else {
+        } else {
             if (e instanceof HttpException) {
                 try {
                     resultListener.onResponse((T) ((HttpException) e).response().errorBody().string());
@@ -88,12 +75,7 @@ public class ResultSubscriber<T> extends Subscriber<T> {
                 }
             } else if (e instanceof SocketTimeoutException) {
                 resultListener.onResponse((T) e);
-            } else if (e instanceof ConnectException) {
-                resultListener.onResponse((T) e);
-            } else {
-                resultListener.onResponse((T) e);
             }
-
         }
     }
 
@@ -102,6 +84,9 @@ public class ResultSubscriber<T> extends Subscriber<T> {
         if (resultListener != null) {
             resultListener.onResponse(t);
         }
+        if (result2Listener != null) {
+            result2Listener.onResponse(t);
+        }
         if (mResultTagListener != null) {
             // TODO: 2017/11/13 实现带tag的回调方法
             mResultTagListener.onSuccess(0, t);

+ 4 - 4
app_modular/appworks/src/main/java/com/uas/appworks/activity/CityIndustryFuncSetActivity.java

@@ -73,8 +73,8 @@ public class CityIndustryFuncSetActivity extends BaseMVPActivity<WorkPlatPresent
     private void obtainCityIndustryService() {
         Map<String, Object> params = new HashMap<>();
         params.put("kind", "cc");
-        params.put("client_type", "cc");
-        params.put("access_token", "123456");
+//        params.put("client_type", "cc");
+//        params.put("access_token", "123456");
 
         LinkedHashMap<String, Object> header = new LinkedHashMap<>();
         header.put("Cookie", "JSESSIONID=" + CommonUtil.getSharedPreferences(ct, "sessionId"));
@@ -92,8 +92,8 @@ public class CityIndustryFuncSetActivity extends BaseMVPActivity<WorkPlatPresent
     private void obtainCityIndustryConfig() {
         Map<String, Object> params = new HashMap<>();
         params.put("serve_id", "52");
-        params.put("client_type", "cc");
-        params.put("access_token", "123456");
+//        params.put("client_type", "cc");
+//        params.put("access_token", "123456");
 
         LinkedHashMap<String, Object> header = new LinkedHashMap<>();
         header.put("Cookie", "JSESSIONID=" + CommonUtil.getSharedPreferences(ct, "sessionId"));

+ 101 - 33
app_modular/appworks/src/main/java/com/uas/appworks/activity/CityIndustryServiceMainActivity.java

@@ -5,12 +5,14 @@ import android.content.Intent;
 import android.graphics.Color;
 import android.os.Handler;
 import android.os.Message;
-import android.support.design.widget.AppBarLayout;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.widget.NestedScrollView;
 import android.support.v7.widget.DefaultItemAnimator;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.Toolbar;
+import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Gravity;
@@ -31,12 +33,14 @@ import com.common.data.JSONUtil;
 import com.core.base.activity.BaseMVPActivity;
 import com.core.net.http.http.Request;
 import com.core.utils.CommonUtil;
+import com.core.utils.SpanUtils;
 import com.core.utils.StatusBarUtil;
 import com.core.widget.RecycleViewDivider;
 import com.scwang.smartrefresh.layout.api.RefreshHeader;
 import com.scwang.smartrefresh.layout.api.RefreshLayout;
 import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
 import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener;
+import com.scwang.smartrefresh.layout.util.DensityUtil;
 import com.uas.appworks.R;
 import com.uas.appworks.adapter.CityIndustryCircleFuncAdapter;
 import com.uas.appworks.adapter.CityIndustryNewsListAdapter;
@@ -64,19 +68,23 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
     private final int ANNOUNCE_LOOP_FLAG = 0x01;
     private final int GET_DEFAULT_SERVICE = 0x02;
 
-    private AppBarLayout mAppBarLayout;
+    //    private AppBarLayout mAppBarLayout;
     private RecyclerView mFuncRecyclerView, mNewsRecyclerView;
     private Toolbar mToolbar;
     private TextSwitcher mAnnounceTextSwitcher;
     private Banner mBanner;
+    private NestedScrollView mNestedScrollView;
     private RefreshLayout mRefreshLayout;
     private ImageView mBackImageView;
+    private FrameLayout mToastLayout;
     private View mFuncLine;
     private List<CityIndustryAnnounceBean> mCityIndustryAnnounceBeans;
     private int mSwitcherCount = 0;
     private CityIndustryCircleFuncAdapter mCityIndustryFuncAdapter;
     private List<CityIndustryServiceBean> mServesBeans;
     private CityIndustryNewsListAdapter mCityIndustryNewsListAdapter;
+    private int mScrollY = 0;
+    private SpanUtils mSpanUtils;
 
     private Handler mHandler = new Handler() {
         @Override
@@ -86,8 +94,10 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
                 // 广告
                 case ANNOUNCE_LOOP_FLAG:
                     int size = mCityIndustryAnnounceBeans.size();
-                    mAnnounceTextSwitcher.setText(mCityIndustryAnnounceBeans.get(mSwitcherCount % size).getTitle()
-                            + " " + mCityIndustryAnnounceBeans.get(mSwitcherCount % size).getContent());
+                    mSpanUtils = new SpanUtils();
+                    SpannableStringBuilder announce = mSpanUtils.append(mCityIndustryAnnounceBeans.get(mSwitcherCount % size).getTitle() + "  ").setForegroundColor(Color.RED)
+                            .append(mCityIndustryAnnounceBeans.get(mSwitcherCount % size).getContent()).setForegroundColor(Color.BLACK).create();
+                    mAnnounceTextSwitcher.setText(announce);
                     mSwitcherCount++;
                     if (mSwitcherCount == size) {
                         mSwitcherCount = 0;
@@ -112,14 +122,16 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
         setSupportActionBar(mToolbar);
         StatusBarUtil.setPaddingSmart(this, mToolbar);
 
-        mAppBarLayout = $(R.id.city_industry_service_main_appbar);
+//        mAppBarLayout = $(R.id.city_industry_service_main_appbar);
         mBackImageView = $(R.id.city_industry_service_main_back_iv);
         mFuncRecyclerView = $(R.id.city_industry_service_main_func_rv);
         mNewsRecyclerView = $(R.id.city_industry_service_main_news_rv);
         mAnnounceTextSwitcher = $(R.id.city_industry_service_main_announce_ts);
         mBanner = $(R.id.city_industry_service_main_banner);
+        mNestedScrollView = $(R.id.city_industry_service_main_nsv);
         mRefreshLayout = $(R.id.city_industry_service_main_refreshlayout);
         mFuncLine = $(R.id.city_industry_service_main_func_line);
+        mToastLayout = $(R.id.city_industry_service_main_toast);
 
         RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
         viewPool.setMaxRecycledViews(0, 10);
@@ -141,7 +153,6 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
 
         mCityIndustryNewsListAdapter = new CityIndustryNewsListAdapter(this);
         mNewsRecyclerView.setAdapter(mCityIndustryNewsListAdapter);
-
     }
 
     @Override
@@ -158,19 +169,38 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
             }
         });
 
-        mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
+        mNestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
+            private int lastScrollY = 0;
+            private int h = DensityUtil.dp2px(144);
+            private int color = ContextCompat.getColor(getApplicationContext(), R.color.antionbarcolor) & 0x00ffffff;
+
+            @Override
+            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+                if (lastScrollY < h) {
+                    scrollY = Math.min(h, scrollY);
+                    mScrollY = scrollY > h ? h : scrollY;
+                    mToolbar.setBackgroundColor(((255 * (mScrollY) / h) << 24) | color);
+                }
+                lastScrollY = scrollY;
+            }
+        });
+
+        /*mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
             @Override
             public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                 int totalScrollRange = appBarLayout.getTotalScrollRange();
                 int measuredHeight = mToolbar.getMeasuredHeight();
+                Log.d("appbarscroll", "totalScrollRange->" + totalScrollRange);
+                Log.d("appbarscroll", "verticalOffset->" + Math.abs(verticalOffset));
+                Log.d("appbarscroll", "measuredHeight->" + measuredHeight);
                 if (totalScrollRange <= ((Math.abs(verticalOffset)) + measuredHeight)) {
-                    mToolbar.setBackgroundColor(getResources().getColor(R.color.antionbarcolor));
+                    mToolbar.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.antionbarcolor));
                 } else {
                     mToolbar.setBackgroundColor(Color.TRANSPARENT);
                 }
 
             }
-        });
+        });*/
 
         mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() {
             @Override
@@ -187,7 +217,15 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
         mRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
             @Override
             public void onRefresh(final RefreshLayout refreshLayout) {
-                getDefaultService();
+                if (CommonUtil.isNetWorkConnected(ct)) {
+                    getDefaultService();
+                } else {
+                    toast(R.string.networks_out, mToastLayout);
+//                    Toast.makeText(ct, R.string.networks_out, Toast.LENGTH_LONG).show();
+                    if (refreshLayout.isRefreshing()) {
+                        mRefreshLayout.finishRefresh();
+                    }
+                }
             }
         });
 
@@ -210,22 +248,20 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
 
     @Override
     protected void initData() {
-        mRefreshLayout.autoRefresh(200, 1f);
+        mRefreshLayout.autoRefresh(400, 1f);
 
         initTextSwitcher();
 
         mBanner.setImageLoader(new BannerImageLoader());
         mBanner.setImages(Arrays.asList(R.drawable.ic_city_industry_loop1, R.drawable.ic_city_industry_loop2, R.drawable.ic_city_industry_loop3));
         mBanner.start();
-
-        mCityIndustryFuncAdapter.notifyDataSetChanged();
     }
 
     private void getDefaultService() {
         Map<String, Object> params = new HashMap<>();
         params.put("kind", "cc");
-        params.put("client_type", "cc");
-        params.put("access_token", "123456");
+//        params.put("client_type", "cc");
+//        params.put("access_token", "123456");
 
         LinkedHashMap<String, Object> header = new LinkedHashMap<>();
         header.put("Cookie", "JSESSIONID=" + CommonUtil.getSharedPreferences(ct, "sessionId"));
@@ -263,7 +299,7 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
                 TextView textView = new TextView(getApplicationContext());
                 textView.setSingleLine();
                 textView.setTextSize(14);//字号
-                textView.setTextColor(Color.parseColor("#ff3333"));
+                textView.setTextColor(Color.parseColor("#000000"));
                 textView.setEllipsize(TextUtils.TruncateAt.END);
                 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                         ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -277,7 +313,8 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
             @Override
             public void onClick(View view) {
                 int position = (mCityIndustryAnnounceBeans.size() + mSwitcherCount - 1) % mCityIndustryAnnounceBeans.size();
-                Toast.makeText(CityIndustryServiceMainActivity.this, mCityIndustryAnnounceBeans.get(position).getTitle(), Toast.LENGTH_SHORT).show();
+//                Toast.makeText(CityIndustryServiceMainActivity.this, mCityIndustryAnnounceBeans.get(position).getTitle(), Toast.LENGTH_SHORT).show();
+                toast(mCityIndustryAnnounceBeans.get(position).getTitle(), mToastLayout);
             }
         });
 
@@ -305,26 +342,35 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
                 }
                 String result = object.toString();
                 Log.d("citydefaultservice", result);
-                JSONObject resultObject = JSON.parseObject(result);
-                JSONArray serviceArray = resultObject.getJSONArray("serves");
-                if (serviceArray != null) {
+                if (JSONUtil.validate(result)) {
                     mServesBeans.clear();
-                    for (int i = 0; i < serviceArray.size(); i++) {
-                        JSONObject serviceObject = serviceArray.getJSONObject(i);
-                        if (serviceObject != null) {
-                            CityIndustryServiceBean cityIndustryServiceBean = new CityIndustryServiceBean();
-                            cityIndustryServiceBean.setSv_id(JSONUtil.getInt(serviceObject, "sv_id"));
-                            cityIndustryServiceBean.setSv_name(JSONUtil.getText(serviceObject, "sv_name"));
-                            cityIndustryServiceBean.setSv_logourl(JSONUtil.getText(serviceObject, "sv_logourl"));
-
-                            mServesBeans.add(cityIndustryServiceBean);
+                    JSONObject resultObject = JSON.parseObject(result);
+                    JSONArray serviceArray = resultObject.getJSONArray("serves");
+                    if (serviceArray != null) {
+                        for (int i = 0; i < serviceArray.size(); i++) {
+                            JSONObject serviceObject = serviceArray.getJSONObject(i);
+                            if (serviceObject != null) {
+                                CityIndustryServiceBean cityIndustryServiceBean = new CityIndustryServiceBean();
+                                cityIndustryServiceBean.setSv_id(JSONUtil.getInt(serviceObject, "sv_id"));
+                                cityIndustryServiceBean.setSv_name(JSONUtil.getText(serviceObject, "sv_name"));
+                                cityIndustryServiceBean.setSv_logourl(JSONUtil.getText(serviceObject, "sv_logourl"));
+
+                                mServesBeans.add(cityIndustryServiceBean);
+                            }
                         }
                     }
+
+                    CityIndustryServiceBean cityIndustryServiceBean = new CityIndustryServiceBean();
+                    cityIndustryServiceBean.setSv_name("全部服务");
+                    cityIndustryServiceBean.setSv_logourl("moreMenu");
+                    mServesBeans.add(cityIndustryServiceBean);
+                }
+                if (mServesBeans.size() == 0) {
+                    CityIndustryServiceBean cityIndustryServiceBean = new CityIndustryServiceBean();
+                    cityIndustryServiceBean.setSv_name("全部服务");
+                    cityIndustryServiceBean.setSv_logourl("moreMenu");
+                    mServesBeans.add(cityIndustryServiceBean);
                 }
-                CityIndustryServiceBean cityIndustryServiceBean = new CityIndustryServiceBean();
-                cityIndustryServiceBean.setSv_name("全部服务");
-                cityIndustryServiceBean.setSv_logourl("moreMenu");
-                mServesBeans.add(cityIndustryServiceBean);
 
                 mFuncRecyclerView.setVisibility(View.VISIBLE);
                 mFuncLine.setVisibility(View.VISIBLE);
@@ -339,9 +385,18 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
     public void requestError(int what, String errorMsg) {
         switch (what) {
             case GET_DEFAULT_SERVICE:
+                mServesBeans.clear();
                 if (mRefreshLayout.isRefreshing()) {
                     mRefreshLayout.finishRefresh();
                 }
+                CityIndustryServiceBean cityIndustryServiceBean = new CityIndustryServiceBean();
+                cityIndustryServiceBean.setSv_name("全部服务");
+                cityIndustryServiceBean.setSv_logourl("moreMenu");
+                mServesBeans.add(cityIndustryServiceBean);
+
+                mFuncRecyclerView.setVisibility(View.VISIBLE);
+                mFuncLine.setVisibility(View.VISIBLE);
+                mCityIndustryFuncAdapter.notifyDataSetChanged();
                 Toast.makeText(this, errorMsg, Toast.LENGTH_SHORT).show();
                 break;
             default:
@@ -349,11 +404,23 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
         }
     }
 
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mBanner.startAutoPlay();
+    }
+
     @Override
     protected void onResume() {
         super.onResume();
     }
 
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mBanner.stopAutoPlay();
+    }
+
     @Override
     protected void onDestroy() {
         super.onDestroy();
@@ -362,6 +429,7 @@ public class CityIndustryServiceMainActivity extends BaseMVPActivity<WorkPlatPre
     private class BannerImageLoader extends ImageLoader {
         @Override
         public void displayImage(Context context, Object path, ImageView imageView) {
+//            ImageLoaderUtil.getInstance().loadImage(path.toString(), imageView);
             imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
             imageView.setImageResource((Integer) path);
         }

+ 3 - 5
app_modular/appworks/src/main/java/com/uas/appworks/activity/CommonDataFormActivity.java

@@ -865,8 +865,8 @@ public class CommonDataFormActivity extends BaseActivity implements View.OnClick
 
         Map<String, Object> params = new HashMap<>();
         params.put("serve_id", mServeId);
-        params.put("client_type", "cc");
-        params.put("access_token", "123456");
+//        params.put("client_type", "cc");
+//        params.put("access_token", "123456");
         params.put("sessionId", CommonUtil.getSharedPreferences(ct, "sessionId"));
         LinkedHashMap<String, Object> headers = new LinkedHashMap<>();
         headers.put("Cookie", "JSESSIONID=" + CommonUtil.getSharedPreferences(ct, "sessionId"));
@@ -2661,12 +2661,10 @@ public class CommonDataFormActivity extends BaseActivity implements View.OnClick
         File waterBitmapToFile = new File(path);
         File file = ImageUtil.compressBitmapToFile(path, 100, 360, 480);
         RequestParams params = new RequestParams();
-//            params.addQueryStringParameter("master", CommonUtil.getSharedPreferences(MyApplication.getInstance().getApplicationContext(), "companyEnUu"));
-        params.addQueryStringParameter("master", "CITIES_CONTROL");
+        params.addQueryStringParameter("master", CommonUtil.getSharedPreferences(MyApplication.getInstance().getApplicationContext(), "erp_master"));
 //        params.addHeader("Cookie", "JSESSIONID=" + ApiConfig.getInstance(ApiUtils.getApiModel()).getmApiBase().getCookie());
         params.addHeader("Cookie", "JSESSIONID=" + CommonUtil.getSharedPreferences(ct, "sessionId"));
 //        params.addBodyParameter("em_code", CommonUtil.getSharedPreferences(MyApplication.getInstance().getApplicationContext(), "b2b_uu"));
-
 //        params.addBodyParameter("sessionId", sessionId);
 //        params.addBodyParameter("sessionUser", "U0807");
 //        params.addBodyParameter("access_token", "12321");

+ 6 - 6
app_modular/appworks/src/main/java/com/uas/appworks/model/WorkPlatModel.java

@@ -35,7 +35,7 @@ public class WorkPlatModel implements IWorkPlatModel {
 
     @Override
     public void uasRequest(Context context, final Request request, final WorkPlatCallback workCallback) {
-        int what = request.getWhat();
+        final int what = request.getWhat();
         if (what == Constants.LOAD_WORK_MENU_CACHE) {
             loadWorkMenuCache(context, workCallback, what);
         } else {
@@ -43,7 +43,7 @@ public class WorkPlatModel implements IWorkPlatModel {
                 throw new NullPointerException("Request is null");
             }
             if (ApiUtils.getApiModel() instanceof ApiPlatform) {
-                mHttpClient = new HttpClient.Builder(CommonUtil.getAppBaseUrl(BaseConfig.getContext())).build();
+                mHttpClient = new HttpClient.Builder(new ApiPlatform().getBaseUrl()).build();
                 mHttpClient.Api().send(new HttpClient.Builder()
                         .url(request.getUrl())
                         .addHeaders(request.getHeaders())
@@ -52,12 +52,12 @@ public class WorkPlatModel implements IWorkPlatModel {
                         .build(), new ResultSubscriber<Object>(new Result2Listener<Object>() {
                     @Override
                     public void onResponse(Object o) {
-                        workCallback.onSuccess(request.getWhat(), o.toString());
+                        workCallback.onSuccess(what, o.toString());
                     }
 
                     @Override
                     public void onFailure(Object t) {
-                        workCallback.onFail(request.getWhat(), t.toString());
+                        workCallback.onFail(what, t.toString());
                     }
                 }));
             } else {
@@ -70,12 +70,12 @@ public class WorkPlatModel implements IWorkPlatModel {
                         .build(), new ResultSubscriber<Object>(new Result2Listener<Object>() {
                     @Override
                     public void onResponse(Object o) {
-                        workCallback.onSuccess(request.getWhat(), o == null ? "" : o.toString());
+                        workCallback.onSuccess(what, o == null ? "" : o.toString());
                     }
 
                     @Override
                     public void onFailure(Object t) {
-                        workCallback.onFail(request.getWhat(), t == null ? "" : t.toString());
+                        workCallback.onFail(what, t == null ? "" : t.toString());
                     }
                 }));
             }

+ 2 - 2
app_modular/appworks/src/main/res/anim/announce_enter_bottom.xml

@@ -5,12 +5,12 @@
     android:zAdjustment="top"
     >
     <translate
-        android:duration="1000"
+        android:duration="600"
         android:fromYDelta="100%p"
         android:toYDelta="0" />
 
     <alpha
-        android:duration="600"
+        android:duration="400"
         android:fromAlpha="0.0"
         android:toAlpha="1.0"/>
 </set>

+ 2 - 2
app_modular/appworks/src/main/res/anim/announce_leave_top.xml

@@ -5,12 +5,12 @@
      android:zAdjustment="top"
     >
     <translate
-        android:duration="1000"
+        android:duration="600"
         android:fromYDelta="0"
         android:toYDelta="-100%p" />
 
     <alpha
-        android:duration="600"
+        android:duration="400"
         android:fromAlpha="1.0"
         android:toAlpha="0.0" />
 </set>

+ 140 - 139
app_modular/appworks/src/main/res/layout/activity_main_city_industry_service.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
@@ -14,174 +14,175 @@
         android:layout_height="match_parent"
         android:focusable="true"
         android:focusableInTouchMode="true"
-        app:srlEnableLoadmore="false">
+        app:srlEnableLoadmore="false"
+        app:srlEnablePreviewInEditMode="false">
 
         <com.scwang.smartrefresh.layout.header.ClassicsHeader
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:srlAccentColor="@android:color/darker_gray" />
 
-        <android.support.design.widget.CoordinatorLayout
+        <android.support.v4.widget.NestedScrollView
+            android:id="@+id/city_industry_service_main_nsv"
             android:layout_width="match_parent"
-            android:layout_height="match_parent">
-
-            <android.support.design.widget.AppBarLayout
-                android:id="@+id/city_industry_service_main_appbar"
+            android:layout_height="match_parent"
+            android:fillViewport="true"
+            android:orientation="vertical"
+            android:overScrollMode="never"
+            android:scrollbars="none"
+            app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+            <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:theme="@style/AppTheme.AppBarOverlay">
+                android:orientation="vertical">
 
-                <android.support.design.widget.CollapsingToolbarLayout
+                <com.youth.banner.Banner
+                    android:id="@+id/city_industry_service_main_banner"
                     android:layout_width="match_parent"
-                    android:layout_height="200dp"
-                    app:layout_scrollFlags="scroll|exitUntilCollapsed"
-                    app:titleEnabled="false">
-
-                    <com.youth.banner.Banner
-                        android:id="@+id/city_industry_service_main_banner"
-                        android:layout_width="match_parent"
-                        android:layout_height="match_parent"
-                        app:delay_time="3000"
-                        app:is_auto_play="true"
-                        app:layout_collapseMode="none"
-                        app:scroll_time="1000" />
-                </android.support.design.widget.CollapsingToolbarLayout>
-            </android.support.design.widget.AppBarLayout>
-
-            <android.support.v4.widget.NestedScrollView
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:fillViewport="true"
-                android:orientation="vertical"
-                app:layout_behavior="@string/appbar_scrolling_view_behavior">
+                    android:layout_height="220dp"
+                    app:delay_time="3000"
+                    app:is_auto_play="true"
+                    app:layout_collapseMode="none"
+                    app:layout_collapseParallaxMultiplier="0.5"
+                    app:scroll_time="1000" />
 
                 <LinearLayout
                     android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="vertical">
+                    android:layout_height="40dp"
+                    android:gravity="center_vertical"
+                    android:orientation="horizontal">
 
-                    <LinearLayout
+                    <ImageView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="10dp"
+                        android:src="@drawable/ic_city_industry_annoce" />
+
+                    <TextSwitcher
+                        android:id="@+id/city_industry_service_main_announce_ts"
                         android:layout_width="match_parent"
                         android:layout_height="40dp"
-                        android:gravity="center_vertical"
-                        android:orientation="horizontal">
-
-                        <ImageView
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_marginLeft="10dp"
-                            android:src="@drawable/ic_city_industry_annoce" />
-
-                        <TextSwitcher
-                            android:id="@+id/city_industry_service_main_announce_ts"
-                            android:layout_width="match_parent"
-                            android:layout_height="40dp"
-                            android:paddingLeft="10dp"
-                            android:textSize="12sp" />
-                    </LinearLayout>
-
-                    <View
-                        android:layout_width="match_parent"
-                        android:layout_height="6dp"
-                        android:background="@color/gray_light" />
+                        android:paddingLeft="10dp"
+                        android:textSize="12sp" />
+                </LinearLayout>
 
-                    <android.support.v7.widget.RecyclerView
-                        android:id="@+id/city_industry_service_main_func_rv"
-                        android:layout_width="match_parent"
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="6dp"
+                    android:background="@color/gray_light" />
+
+                <android.support.v7.widget.RecyclerView
+                    android:id="@+id/city_industry_service_main_func_rv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:background="@color/white"
+                    android:overScrollMode="never"
+                    android:paddingBottom="6dp"
+                    android:paddingTop="6dp"
+                    android:scrollbars="none"
+                    android:visibility="gone"
+                    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+
+                <View
+                    android:id="@+id/city_industry_service_main_func_line"
+                    android:layout_width="match_parent"
+                    android:layout_height="6dp"
+                    android:background="@color/gray_light"
+                    android:visibility="gone" />
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="40dp"
+                    android:gravity="center_vertical"
+                    android:orientation="horizontal"
+                    android:padding="10dp">
+
+                    <ImageView
+                        android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
-                        android:background="@color/white"
-                        android:overScrollMode="never"
-                        android:paddingBottom="6dp"
-                        android:paddingTop="6dp"
-                        android:scrollbars="none"
-                        android:visibility="gone"
-                        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
-
-                    <View
-                        android:id="@+id/city_industry_service_main_func_line"
-                        android:layout_width="match_parent"
-                        android:layout_height="6dp"
-                        android:background="@color/gray_light"
-                        android:visibility="gone" />
+                        android:src="@drawable/ic_city_industry_news" />
 
-                    <LinearLayout
-                        android:layout_width="match_parent"
-                        android:layout_height="40dp"
-                        android:gravity="center_vertical"
-                        android:orientation="horizontal"
-                        android:padding="10dp">
-
-                        <ImageView
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:src="@drawable/ic_city_industry_news" />
-
-                        <TextView
-                            android:layout_width="0dp"
-                            android:layout_height="wrap_content"
-                            android:layout_marginLeft="6dp"
-                            android:layout_weight="1"
-                            android:text="【新闻中心】" />
-
-                        <TextView
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:text="全部"
-                            android:textColor="@android:color/holo_blue_light" />
-                    </LinearLayout>
-
-                    <View
-                        android:layout_width="match_parent"
-                        android:layout_height="1dp"
-                        android:background="@color/gray_light" />
+                    <TextView
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="6dp"
+                        android:layout_weight="1"
+                        android:text="【新闻中心】" />
 
-                    <android.support.v7.widget.RecyclerView
-                        android:id="@+id/city_industry_service_main_news_rv"
-                        android:layout_width="match_parent"
+                    <TextView
+                        android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
-                        android:overScrollMode="never"
-                        android:scrollbars="none"
-                        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+                        android:text="全部"
+                        android:textColor="@android:color/holo_blue_light" />
                 </LinearLayout>
-            </android.support.v4.widget.NestedScrollView>
-        </android.support.design.widget.CoordinatorLayout>
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:background="@color/gray_light" />
+
+                <android.support.v7.widget.RecyclerView
+                    android:id="@+id/city_industry_service_main_news_rv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:overScrollMode="never"
+                    android:scrollbars="none"
+                    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+            </LinearLayout>
+        </android.support.v4.widget.NestedScrollView>
 
     </com.scwang.smartrefresh.layout.SmartRefreshLayout>
 
-    <android.support.v7.widget.Toolbar
-        android:id="@+id/city_industry_service_main_toolbar"
+
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="?attr/actionBarSize"
-        app:layout_collapseMode="pin">
-
-        <ImageView
-            android:id="@+id/city_industry_service_main_back_iv"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_gravity="left|center_vertical"
-            android:src="@drawable/ic_action_back" />
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:gravity="center_vertical"
-            android:orientation="horizontal">
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
 
-            <TextView
-                android:id="@+id/city_industry_service_main_area_tv"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="智慧产城"
-                android:textColor="@android:color/white"
-                android:textSize="18sp" />
+        <android.support.v7.widget.Toolbar
+            android:id="@+id/city_industry_service_main_toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"
+            app:layout_collapseMode="pin">
 
             <ImageView
+                android:id="@+id/city_industry_service_main_back_iv"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_gravity="left|center_vertical"
+                android:src="@drawable/ic_action_back" />
+
+            <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginLeft="6dp"
-                android:src="@drawable/ic_city_industry_option_spread" />
-        </LinearLayout>
+                android:layout_gravity="center"
+                android:gravity="center_vertical"
+                android:orientation="horizontal">
+
+                <TextView
+                    android:id="@+id/city_industry_service_main_area_tv"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="智慧产城"
+                    android:textColor="@android:color/white"
+                    android:textSize="18sp" />
+
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="6dp"
+                    android:src="@drawable/ic_city_industry_option_spread" />
+
+            </LinearLayout>
+        </android.support.v7.widget.Toolbar>
+
+        <FrameLayout
+            android:id="@+id/city_industry_service_main_toast"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"
+            android:focusable="false"
+            android:focusableInTouchMode="false" />
+    </LinearLayout>
 
-    </android.support.v7.widget.Toolbar>
-</RelativeLayout>
+</FrameLayout>

+ 1 - 1
version.gradle

@@ -46,7 +46,7 @@ ext {
             vlayoutVersion                      : '1.2.1',
             BaseRecyclerViewAdapterHelperVersion: '2.9.30',
             addSubUtilsVersion                  : '1.5.0',
-            bannerVersion                       : '1.4.9',
+            bannerVersion                       : '1.4.10',
             smartRefreshLayoutVersion           : '1.0.3'
     ]