From fe4fa5323fc075ca7fdf3d6c8cfd20cb0a7d45f8 Mon Sep 17 00:00:00 2001
From: nilupeng <qingingrunt2010@qq.com>
Date: Fri, 29 Jul 2022 10:29:50 +0000
Subject: [PATCH] 部分框架优化, 首页登录部分添加

---
 app/src/main/java/com/runt/open/mvvm/base/activities/BaseActivity.java                        |   89 +
 app/src/main/java/com/runt/open/mvvm/MyApplication.java                                       |   26 
 app/src/main/res/layout/item_msg.xml                                                          |   66 +
 app/src/main/java/com/runt/open/mvvm/retrofit/utils/RetrofitUtils.java                        |    3 
 app/src/main/java/com/runt/open/mvvm/widgets/CornerImageView.java                             |  163 +++
 app/src/main/java/com/runt/open/mvvm/base/model/LoadPageViewModel.java                        |   47 
 app/src/main/java/com/runt/open/mvvm/base/model/BaseViewModel.java                            |   23 
 app/src/main/java/com/runt/open/mvvm/retrofit/converter/DecryptGsonResponseBodyConverter.java |    6 
 app/src/main/java/com/runt/open/mvvm/base/model/ImpViewModel.java                             |    7 
 app/src/main/res/layout/activity_setting.xml                                                  |   79 +
 app/src/main/java/com/runt/open/mvvm/ui/web/WebViewActivity.java                              |   51 
 app/src/main/java/com/runt/open/mvvm/base/fragments/LoadPageFragment.java                     |   96 +
 app/src/main/java/com/runt/open/mvvm/ui/login/LoginViewModel.java                             |   28 
 app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeFragment.java                           |   30 
 app/src/main/res/layout/activity_main.xml                                                     |   30 
 app/src/main/java/com/runt/open/mvvm/ui/splash/SplashViewModel.java                           |   51 
 app/build.gradle                                                                              |   15 
 app/src/main/res/layout/activity_splash.xml                                                   |    4 
 app/src/main/java/com/runt/open/mvvm/util/DeviceUtil.java                                     |   57 +
 app/src/main/java/com/runt/open/mvvm/base/adapter/BaseAdapter.java                            |  146 +-
 app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java                           |  177 +++
 app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkListenear.java                       |   28 
 app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java                            |   79 -
 app/src/main/res/layout/activity_web.xml                                                      |    7 
 app/src/main/java/com/runt/open/mvvm/ui/main/home/MsgAdapter.java                             |   33 
 app/src/main/res/layout/fragment_mine.xml                                                     |  191 +++
 app/src/main/java/com/runt/open/mvvm/data/Results.java                                        |    6 
 app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkCost.java                            |   27 
 app/src/main/res/layout/fragment_service.xml                                                  |  126 ++
 app/src/main/java/com/runt/open/mvvm/retrofit/utils/HttpPrintUtils.java                       |   61 
 app/src/main/res/values/styles.xml                                                            |   27 
 app/src/main/java/com/runt/open/mvvm/base/activities/LoadPageActivity.java                    |   96 +
 app/src/main/java/com/runt/open/mvvm/data/PageResult.java                                     |    2 
 app/src/main/java/com/runt/open/mvvm/widgets/TitleBarView.java                                |   14 
 app/src/main/res/layout/refresh_recycler.xml                                                  |    2 
 app/src/main/java/com/runt/open/mvvm/util/HandleDate.java                                     |  216 ++++
 app/src/main/java/com/runt/open/mvvm/data/HttpApiResult.java                                  |    2 
 app/src/main/java/com/runt/open/mvvm/widgets/CircleImageView.java                             |  245 ++++
 app/src/main/java/com/runt/open/mvvm/base/fragments/BaseFragment.java                         |   44 
 app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineViewModel.java                          |   36 
 app/src/main/java/com/runt/open/mvvm/ui/main/home/Message.java                                |    8 
 app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java         |  143 +-
 app/src/main/java/com/runt/open/mvvm/data/ApkUpGradeResult.java                               |    2 
 app/src/main/AndroidManifest.xml                                                              |    3 
 app/src/main/java/com/runt/open/mvvm/ui/main/MainActivity.java                                |  153 ++
 app/src/main/java/com/runt/open/mvvm/retrofit/observable/HttpObserver.java                    |  113 -
 /dev/null                                                                                     |   25 
 app/src/main/java/com/runt/open/mvvm/base/activities/BaseTabActivity.java                     |    4 
 app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeViewModel.java                          |   19 
 app/src/main/java/com/runt/open/mvvm/base/fragments/BaseTabFragment.java                      |   20 
 app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java                        |   11 
 app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java                      |  138 +-
 app/src/main/java/com/runt/open/mvvm/ui/main/service/ServiceFragment.java                     |   63 +
 53 files changed, 2,474 insertions(+), 664 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index f46abb5..306004b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -18,16 +18,14 @@
     buildTypes {
         debug{
             minifyEnabled false
-            buildConfigField 'String','HOST_IP_ADDR','"http://192.168.100.82:8080/"'
-            buildConfigField 'String','ENVIRONMENT','"release"'
-            resValue "string", "app_name", "MVVM开源项目测试"
+            buildConfigField 'String','HOST_IP_ADDR','"http://192.168.110.116:8080/"'
+            resValue "string", "app_name", "MVVM OPEN TEST"
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
         release {
             minifyEnabled false
-            buildConfigField 'String','HOST_IP_ADDR','"http://192.168.100.82:8080/"'
-            buildConfigField 'String','ENVIRONMENT','"release"'
-            resValue "string", "app_name", "MVVM开源项目"
+            buildConfigField 'String','HOST_IP_ADDR','"http://192.168.100.82:8080/'
+            resValue "string", "app_name", "MVVM OPEN"
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
@@ -77,9 +75,8 @@
     implementation 'com.guolindev.permissionx:permissionx:1.6.0'    //权限依赖
     implementation 'com.github.bumptech.glide:glide:4.12.0'
     annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
-    implementation 'com.pangle.cn:ads-sdk-pro:4.0.2.2'//字节跳动  穿山甲广告
-    implementation 'com.tencent.bugly:crashreport:latest.release' //其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如2.1.9
-    implementation 'com.tencent.bugly:nativecrashreport:latest.release' //其中latest.release指代最新Bugly NDK版本号,也可以指定明确的版本号,例如3.0
     implementation 'com.facebook.rebound:rebound:0.3.6'//Rebound  “弹簧”动画效果的第三方工具包,由FaceBook
     implementation 'com.github.zhaolei9527:BottomMenu:v1.0.1'//底部菜单弹框
+    implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3'//图片选择
+    implementation 'com.github.wildma:PictureSelector:1.1.1'//图片选择裁切工具
 }
\ No newline at end of file
diff --git a/app/libs/alipaySdk-15.7.5.aar b/app/libs/alipaySdk-15.7.5.aar
deleted file mode 100644
index d977ea2..0000000
--- a/app/libs/alipaySdk-15.7.5.aar
+++ /dev/null
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4e8fded..f076df2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -30,6 +30,7 @@
         android:label="@string/app_name"
         android:supportsRtl="true"
         android:networkSecurityConfig="@xml/network_security_config"
+        tools:replace="android:theme"
         android:theme="@style/Theme.OpemMvvm" >
         <activity
             android:name=".ui.splash.SplashActivity"
@@ -41,7 +42,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name=".MainActivity"
+        <activity android:name=".ui.main.MainActivity"
             android:launchMode="singleTask"
             tools:ignore="WrongManifestParent"
             android:exported="true">
diff --git a/app/src/main/java/com/runt/open/mvvm/MainActivity.java b/app/src/main/java/com/runt/open/mvvm/MainActivity.java
deleted file mode 100644
index 1297088..0000000
--- a/app/src/main/java/com/runt/open/mvvm/MainActivity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.runt.open.mvvm;
-
-import android.Manifest;
-import android.content.Intent;
-
-import androidx.activity.result.ActivityResult;
-import androidx.activity.result.ActivityResultCallback;
-import androidx.activity.result.ActivityResultLauncher;
-import androidx.activity.result.contract.ActivityResultContracts;
-import androidx.navigation.NavController;
-import androidx.navigation.Navigation;
-import androidx.navigation.ui.NavigationUI;
-
-import com.permissionx.guolindev.PermissionX;
-import com.runt.open.mvvm.base.activities.BaseActivity;
-import com.runt.open.mvvm.data.PhoneDevice;
-import com.runt.open.mvvm.databinding.ActivityMainBinding;
-import com.runt.open.mvvm.listener.ResPonse;
-import com.runt.open.mvvm.ui.login.RegisterLoginActivity;
-import com.runt.open.mvvm.ui.main.MainViewModel;
-
-public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {
-
-    @Override
-    public void initViews() {
-        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
-        NavigationUI.setupWithNavController(binding.navView, navController);
-        checkPermission();
-        ActivityResultLauncher<Intent>  launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
-            @Override
-            public void onActivityResult(ActivityResult result) {
-                if(result.getResultCode() == RESULT_CODE_SUCESS){
-                    showToast("登录成功");
-                }
-            }
-        });
-        Intent intent = new Intent(mContext, RegisterLoginActivity.class);
-        launcher.launch(intent);
-    }
-
-    private void showPermissionDialog(){
-
-        showDialog("警告", "软件需要权限才能运行", "申请权限", "退出", new ResPonse() {
-            @Override
-            public void doSuccess(Object obj) {
-                checkPermission();
-            }
-
-            @Override
-            public void doError(Object obj) {
-                finish();
-                System.exit(0);
-            }
-        });
-    }
-    private void checkPermission(){
-        PermissionX.init(MainActivity.this)
-                .permissions(Manifest.permission.READ_PHONE_STATE)
-                .request((allGranted, grantedList, deniedList) -> {
-                    if(allGranted){
-                        PhoneDevice.setDevice(mContext);
-                    }else{
-                        showPermissionDialog();
-                    }
-
-                });
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/MyApplication.java b/app/src/main/java/com/runt/open/mvvm/MyApplication.java
index 30f98b9..2e7179a 100644
--- a/app/src/main/java/com/runt/open/mvvm/MyApplication.java
+++ b/app/src/main/java/com/runt/open/mvvm/MyApplication.java
@@ -8,9 +8,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.bytedance.sdk.openadsdk.TTAdConfig;
-import com.bytedance.sdk.openadsdk.TTAdConstant;
-import com.bytedance.sdk.openadsdk.TTAdSdk;
 import com.runt.open.mvvm.listener.CrashHandler;
 import com.runt.open.mvvm.util.MyLog;
 import com.scwang.smart.refresh.footer.ClassicsFooter;
@@ -21,7 +18,6 @@
 import com.scwang.smart.refresh.layout.api.RefreshLayout;
 import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator;
 import com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator;
-import com.tencent.bugly.crashreport.CrashReport;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -115,29 +111,7 @@
                 }
             }
         });
-        CrashReport.initCrashReport(getApplicationContext(), "8d88679ae9", false);//注册bugly
-        TTAdConfig.Builder builder = new TTAdConfig.Builder()
-                .appId("5106813")
-                .useTextureView(true) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
-                .appName(getString(R.string.app_name))
-                .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
-                .allowShowNotify(true) //是否允许sdk展示通知栏提示
-                .allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
-                .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI) //允许直接下载的网络状态集合
-                .supportMultiProcess(true) //是否支持多进程,true支持
-                .asyncInit(true) ;//异步初始化sdk,开启可减少初始化耗时
-        //.httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
-        TTAdSdk.init(this, builder.build(), new TTAdSdk.InitCallback() {
-            @Override
-            public void success() {
-                MyLog.i(TAG,"TTAdSdk success");
-            }
 
-            @Override
-            public void fail(int i, String s) {
-                MyLog.e(TAG,"TTAdSdk fail");
-            }
-        });
         CrashHandler crashHandler = CrashHandler.getInstance();
         crashHandler.init(getApplicationContext(), new CrashHandler.CrashListener() {
             @Override
diff --git a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseActivity.java b/app/src/main/java/com/runt/open/mvvm/base/activities/BaseActivity.java
index 1629d1c..a7d4c8d 100644
--- a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseActivity.java
+++ b/app/src/main/java/com/runt/open/mvvm/base/activities/BaseActivity.java
@@ -3,13 +3,17 @@
 import android.Manifest;
 import android.app.AlertDialog;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
@@ -23,12 +27,14 @@
 import androidx.lifecycle.ViewModelProvider;
 import androidx.viewbinding.ViewBinding;
 
+import com.permissionx.guolindev.PermissionX;
 import com.runt.open.mvvm.MyApplication;
 import com.runt.open.mvvm.R;
 import com.runt.open.mvvm.base.model.BaseViewModel;
 import com.runt.open.mvvm.base.model.ViewModelFactory;
 import com.runt.open.mvvm.listener.ResPonse;
 import com.runt.open.mvvm.util.PreferencesUtils;
+import com.runt.open.mvvm.widgets.TitleBarView;
 
 import java.io.File;
 import java.lang.reflect.Method;
@@ -41,13 +47,12 @@
  * activity 封装
  * Created by Administrator on 2021/10/27 0027.
  */
-public abstract class BaseActivity<B extends ViewBinding,VM extends BaseViewModel> extends AppCompatActivity {
+public abstract class BaseActivity<VB extends ViewBinding,VM extends BaseViewModel> extends AppCompatActivity {
 
-    protected  B binding;
-    protected  VM viewModel;
+    protected  VB mBinding;
+    protected  VM mViewModel;
     protected String TAG ;
     public final String[] FILE_PERMISSIONS = new String []{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
-    public final String[] LOCATION_PERMISSIONS = new String []{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION};
     public final String[] CAMERA_PERMISSIONS = new String[]{ FILE_PERMISSIONS[0],FILE_PERMISSIONS[1], Manifest.permission.CAMERA};
     public final String[] CAMERA_RECORD_PERMISSIONS = new String[]{ FILE_PERMISSIONS[0],FILE_PERMISSIONS[1], Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO};
 
@@ -83,6 +88,7 @@
             RESULT_CODE_SUCESS = 4046/*成功*/,
             RESULT_CODE_CANCEL = 4043/*取消*/;
     protected Context mContext;
+    TitleBarView titleBarView;
 
 
     @Override
@@ -93,15 +99,17 @@
         setStatusBarTextColor(true);
         final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
         try {
-            Class<B> entityClass = (Class<B>) type.getActualTypeArguments()[0];
+            Class<VB> entityClass = (Class<VB>) type.getActualTypeArguments()[0];
             Method method = entityClass.getMethod("inflate", LayoutInflater.class);//get method from name "inflate";
-            binding = (B) method.invoke(entityClass,getLayoutInflater());//execute method to create a objct of viewbind;
+            mBinding = (VB) method.invoke(entityClass,getLayoutInflater());//execute method to create a objct of viewbind;
+            titleBarView = (TitleBarView) mBinding.getClass().getDeclaredField("titleBar").get(mBinding);
+            titleBarView.setLeftClick(v -> onBackPressed());
         } catch (Exception e) {
             e.printStackTrace();
         }
         Class<VM> vmClass = (Class<VM>) type.getActualTypeArguments()[1];
-        viewModel = new ViewModelProvider(this,getViewModelFactory()).get(vmClass);
-        setContentView(binding.getRoot());
+        mViewModel = new ViewModelProvider(this,getViewModelFactory()).get(vmClass);
+        setContentView(mBinding.getRoot());
         mContext = this;
         try {
             //设置坚屏 一定要放到try catch里面,否则会崩溃
@@ -110,13 +118,34 @@
         }
         TAG = this.getClass().getSimpleName();
         initViews();
+        mViewModel.onCreate(this);
+        loadData();
     }
 
     public abstract void initViews();
 
+    public abstract void loadData();
 
     public boolean isNull(Object object){
         return object == null || object.toString().trim().equals("") || object.equals("null");
+    }
+
+    protected void setTitle(String text){
+        titleBarView.setTitleText(text);
+    }
+
+    protected void onTitleLeftClick(){
+        onBackKeyDown();
+    }
+
+    protected void setTitleRight(String text){
+        titleBarView.setRightText(text);
+        titleBarView.setRightDra(null);
+    }
+
+    protected void setTitleRight(Drawable drawable){
+        titleBarView.setRightText(null);
+        titleBarView.setRightDra(drawable);
     }
 
 
@@ -125,11 +154,29 @@
      * 显示弹框
      * @param title
      * @param msg
+     * @param resPonse
+     */
+    public void showDialog(String title,String msg,ResPonse resPonse){
+        showDialog(title,msg,"确认","取消",resPonse);
+    }
+
+    public void showInputDialog(String title,String msg,String hint,ResPonse resPonse){
+        showInputDialog(title,msg,hint,"确认","取消",resPonse);
+    }
+
+    public void showInputDialog(String title, String msg, String hint,String btnOk,String btnCancel,final  ResPonse resPonse){
+        showDialog(title,msg,hint,btnOk,btnCancel,resPonse,true);
+    }
+
+    /**
+     * 显示弹框
+     * @param title
+     * @param msg
      * @param btnOk
      * @param btnCancel
      * @param resPonse
      */
-    public void showDialog(String title, String msg, String btnOk,String btnCancel,final ResPonse resPonse){
+    public void showDialog(String title, String msg, String btnOk,String btnCancel,final  ResPonse resPonse){
         showDialog(title,msg,null,btnOk,btnCancel,resPonse,false);
     }
 
@@ -215,6 +262,9 @@
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
 
         setStatusBarTextColor(isBlack);
+        final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) titleBarView.getLayoutParams();
+        layoutParams.topMargin = layoutParams.topMargin+getStatusBarHeight();
+        titleBarView.setLayoutParams(layoutParams);
     }
 
     /**
@@ -343,7 +393,7 @@
         }
     }
     public void showToast(String message){
-        Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
+        runOnUiThread(() -> Toast.makeText(mContext,message,Toast.LENGTH_SHORT).show());
     }
 
     public void showToast(@StringRes int msg){
@@ -371,6 +421,25 @@
         return false;
     }
 
+    /**
+     * 拨打电话(直接拨打电话)
+     * @param phoneNum 电话号码
+     */
+    public void callPhone(String phoneNum){
+        PermissionX.init(this)
+                .permissions(Manifest.permission.CALL_PHONE)
+                .request((allGranted, grantedList, deniedList) -> {
+                    if(allGranted){
+                        Intent intent = new Intent(Intent.ACTION_CALL);
+                        Uri data = Uri.parse("tel:" + phoneNum);
+                        intent.setData(data);
+                        startActivity(intent);
+                    }else{
+                        showToast("权限被拒绝");
+                    }
+                });
+    }
+
 
     public boolean getBooleanUserPrefrence(String key){
         return PreferencesUtils.getBoolean(this,key,false,PreferencesUtils.USER);
diff --git a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseLoadPageActivity.java b/app/src/main/java/com/runt/open/mvvm/base/activities/BaseLoadPageActivity.java
deleted file mode 100644
index 9e2695a..0000000
--- a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseLoadPageActivity.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.runt.open.mvvm.base.activities;
-
-import android.os.Bundle;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewbinding.ViewBinding;
-
-import com.runt.open.mvvm.base.adapter.BaseAdapter;
-import com.runt.open.mvvm.base.model.BaseLoadPageViewModel;
-import com.runt.open.mvvm.data.BasePageResult;
-import com.runt.open.mvvm.databinding.RefreshRecyclerBinding;
-import com.scwang.smart.refresh.footer.ClassicsFooter;
-import com.scwang.smart.refresh.header.ClassicsHeader;
-import com.scwang.smart.refresh.layout.SmartRefreshLayout;
-import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.HashMap;
-
-/**
- * Created by Administrator on 2021/11/4 0004.
- */
-public abstract class BaseLoadPageActivity<B extends ViewBinding,VM extends BaseLoadPageViewModel,A extends BaseAdapter,D extends BasePageResult>
-        extends BaseTitleBarActivity<B,VM>  implements OnRefreshLoadMoreListener {
-
-    protected SmartRefreshLayout smartRefresh;
-    protected RecyclerView recycler;
-    final String TAG = "RecyclerFragment";
-    protected A adapter;//适配器
-    protected String url;//请求地址
-    protected HashMap param;//参数
-    protected int page=1;
-    protected final int SIZE = 10;
-    protected boolean isRefresh = false;//是否正在刷新
-    
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        try {
-            Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
-            this.adapter = entityClass.newInstance();//实例化泛型
-            String smartStr = "smartRefresh";
-            smartRefresh = (SmartRefreshLayout) binding.getClass().getField(smartStr).get(binding);
-            recycler =  (RecyclerView) binding.getClass().getDeclaredField("recycler").get(binding);
-        } catch (NoSuchFieldException e) {
-            try {
-                RefreshRecyclerBinding includeRefreshRecycler = (RefreshRecyclerBinding) binding.getClass().getDeclaredField ("includeRefreshRecycler").get(binding);
-                smartRefresh = includeRefreshRecycler.smartRefresh;
-                recycler =  includeRefreshRecycler.recycler;
-            } catch (Exception e2) {
-                e2.printStackTrace();
-            }
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (InstantiationException e) {
-            e.printStackTrace();
-        }
-        smartRefresh.setRefreshHeader(new ClassicsHeader(mContext));
-        smartRefresh.setRefreshFooter(new ClassicsFooter(mContext));
-        smartRefresh.setOnRefreshLoadMoreListener(this);
-        recycler.setLayoutManager(new LinearLayoutManager(mContext));
-        recycler.setAdapter(adapter);
-    }
-
-    private void finishFreshLoadmore(D result){
-        if(result.code == 200){
-
-            smartRefresh.setEnableRefresh(true);
-            smartRefresh.finishRefresh();
-            if(page == 1){
-                adapter.getData().clear();
-                adapter.setData(result.rows);
-            }else{
-                adapter.getData().addAll(result.rows);
-                adapter.notifyDataSetChanged();
-            }
-            if(result.total <= adapter.getData().size()// 总数是否已经加载完
-                    || result.rows.size() < SIZE // 最后一页数据的数量一般不满size
-            ){//判断是否没有数据了
-                smartRefresh.finishLoadMoreWithNoMoreData();
-            }else {
-                smartRefresh.finishLoadMore();
-            }
-        }else{
-            smartRefresh.setEnableRefresh(true);
-            smartRefresh.finishRefresh();
-            smartRefresh.finishLoadMore();
-        }
-    }
-
-    public A getAdapter() {
-        return adapter;
-    }
-}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTabActivity.java b/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTabActivity.java
index c14ee7b..e02d83c 100644
--- a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTabActivity.java
+++ b/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTabActivity.java
@@ -35,8 +35,8 @@
         //设置当前可见Item左右可见page数,次范围内不会被销毁
         //禁用预加载
         try {
-            viewPager2 = (ViewPager2) binding.getClass().getDeclaredField("viewPager2").get(binding);
-            tabLayout = (TabLayout) binding.getClass().getDeclaredField("tabLayout").get(binding);
+            viewPager2 = (ViewPager2) mBinding.getClass().getDeclaredField("viewPager2").get(mBinding);
+            tabLayout = (TabLayout) mBinding.getClass().getDeclaredField("tabLayout").get(mBinding);
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         } catch (NoSuchFieldException e) {
diff --git a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTitleBarActivity.java b/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTitleBarActivity.java
deleted file mode 100644
index 414103e..0000000
--- a/app/src/main/java/com/runt/open/mvvm/base/activities/BaseTitleBarActivity.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.runt.open.mvvm.base.activities;
-
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-import androidx.viewbinding.ViewBinding;
-
-import com.runt.open.mvvm.base.model.BaseViewModel;
-import com.runt.open.mvvm.widgets.TitleBarView;
-
-/**
- * 带有标题栏的activity封装
- * Created by Administrator on 2021/11/2 0002.
- */
-public abstract class BaseTitleBarActivity<B extends ViewBinding,VM extends BaseViewModel> extends BaseActivity<B,VM> {
-    TitleBarView titleBarView;
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        try {
-            titleBarView = (TitleBarView) binding.getClass().getDeclaredField("titleBar").get(binding);
-            titleBarView.setLeftClick(v -> onTitleLeftClick());
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (NoSuchFieldException e) {
-            e.printStackTrace();
-        }
-    }
-
-    protected void setTitle(String text){
-        titleBarView.setTitleText(text);
-    }
-    
-    protected void onTitleLeftClick(){
-        onBackKeyDown();
-    }
-
-    protected void setTitleRight(String text){
-        titleBarView.setRightText(text);
-        titleBarView.setRightDra(null);
-    }
-
-    protected void setTitleRight(Drawable drawable){
-        titleBarView.setRightText(null);
-        titleBarView.setRightDra(drawable);
-    }
-
-    @Override
-    public void setStatusBarTransparent(boolean isBlack) {
-        super.setStatusBarTransparent(isBlack);
-        final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) titleBarView.getLayoutParams();
-        layoutParams.topMargin = layoutParams.topMargin+getStatusBarHeight();
-        titleBarView.setLayoutParams(layoutParams);
-
-    }
-}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/activities/LoadPageActivity.java b/app/src/main/java/com/runt/open/mvvm/base/activities/LoadPageActivity.java
new file mode 100644
index 0000000..58a319a
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/base/activities/LoadPageActivity.java
@@ -0,0 +1,96 @@
+package com.runt.open.mvvm.base.activities;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Observer;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewbinding.ViewBinding;
+
+import com.runt.open.mvvm.R;
+import com.runt.open.mvvm.base.adapter.BaseAdapter;
+import com.runt.open.mvvm.base.model.LoadPageViewModel;
+import com.scwang.smart.refresh.footer.ClassicsFooter;
+import com.scwang.smart.refresh.header.ClassicsHeader;
+import com.scwang.smart.refresh.layout.SmartRefreshLayout;
+import com.scwang.smart.refresh.layout.api.RefreshLayout;
+import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by Administrator on 2021/11/4 0004.
+ */
+public abstract class LoadPageActivity<VB extends ViewBinding,VM extends LoadPageViewModel,A extends BaseAdapter,RESULT>
+        extends BaseActivity<VB,VM>  implements OnRefreshLoadMoreListener {
+    protected int page;
+    protected SmartRefreshLayout refresh;
+    //适配器
+    protected A adapter;
+
+    @Override
+    public void initViews() {
+        try {
+            Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
+            this.adapter = entityClass.newInstance();//实例化泛型
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        refresh.setRefreshHeader(new ClassicsHeader(mContext));
+        refresh.setRefreshFooter(new ClassicsFooter(mContext));
+        refresh.setOnRefreshLoadMoreListener(this);
+        RecyclerView recycler = mBinding.getRoot().findViewById(R.id.recycler);
+        recycler.setLayoutManager(new LinearLayoutManager(mContext));
+        recycler.setAdapter(adapter);
+        refresh = mBinding.getRoot().findViewById(R.id.refresh);
+        refresh.setOnRefreshLoadMoreListener(this);
+        mViewModel.getLiveData().observe(this, (Observer<List<RESULT>>) list -> {
+            adapter.showNull = true;
+            if(page == 0){
+                adapter.setData(list);
+            }else{
+                adapter.addData(list);
+            }
+            refresh.finishRefresh();
+            //加载完毕
+            if(list.size() < 10 || page > 0 && list.size() == 0){
+                refresh.finishLoadMoreWithNoMoreData();
+            }else{
+                refresh.finishLoadMore();
+            }
+        });
+        mViewModel.getLiveFailed().observe(this, o -> {
+            refresh.finishRefresh();
+            refresh.finishLoadMore();
+            //校正page数值
+            int size = adapter.getData().size();
+            if(size/mViewModel.SIZE+1 < page){
+                page--;
+            }
+        });
+    }
+
+    @Override
+    public void loadData() {
+        refresh.autoRefresh();
+    }
+
+    protected abstract Map requestParams();
+
+    @Override
+    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+        page = 0;
+        mViewModel.requestData(page,requestParams());
+    }
+
+    @Override
+    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
+        page++;
+        mViewModel.requestData(page,requestParams());
+    }
+
+    public A getAdapter() {
+        return adapter;
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/adapter/BaseAdapter.java b/app/src/main/java/com/runt/open/mvvm/base/adapter/BaseAdapter.java
index d022444..755f0ee 100644
--- a/app/src/main/java/com/runt/open/mvvm/base/adapter/BaseAdapter.java
+++ b/app/src/main/java/com/runt/open/mvvm/base/adapter/BaseAdapter.java
@@ -1,6 +1,6 @@
 package com.runt.open.mvvm.base.adapter;
 
-import android.graphics.drawable.Drawable;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
@@ -8,7 +8,6 @@
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.viewbinding.ViewBinding;
 
-import com.runt.open.mvvm.base.activities.BaseActivity;
 import com.runt.open.mvvm.databinding.LayoutNullBinding;
 import com.runt.open.mvvm.util.DeviceUtil;
 
@@ -23,47 +22,73 @@
  *  T  数据类型
  *  V 适配器视图
  */
-public abstract class BaseAdapter<B extends ViewBinding,T> extends RecyclerView.Adapter {
+public abstract class BaseAdapter<DATA, VB extends ViewBinding> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
 
-    protected List<T> mData = new ArrayList<>();
+    protected List<DATA> dataList = new ArrayList<>();
+    protected OnItemClickListener<DATA> onItemClickListener;
+    public boolean showNull;
+    public float defaultMarginBottom,lastMarginBottom;
 
-    protected Drawable nullDrawable;
-    protected String nullTxt="暂无数据";
-    protected String TAG = "BaseAdapter";
-    protected BaseActivity activity;
-
-    public BaseAdapter(){
+    public interface  OnItemClickListener<DATA>{
+        void onItemClick(int position,DATA data);
     }
 
-    public BaseAdapter(@NonNull List<T> data){
-        mData = data;
+    public class ViewBindHolder extends RecyclerView.ViewHolder  {
+        ViewBinding binding;
+        public ViewBindHolder(ViewBinding binding) {
+            super(binding.getRoot());
+            this.binding = binding;
+        }
     }
 
-    public List<T> getData() {
-        return mData;
+    public void setOnItemClickListener(OnItemClickListener<DATA> onItemClickListener) {
+        this.onItemClickListener = onItemClickListener;
     }
 
-    public void setData(@NonNull List<T> data){
-        mData = data;
+    public void setData(List<DATA> list){
+        if(dataList != list) {
+            dataList.clear();
+            if (list != null) {
+                dataList.addAll(list);
+            }
+        }
         notifyDataSetChanged();
+    }
+
+    public void addData(DATA data){
+        if(data != null){
+            dataList.add(data);
+        }
+        notifyDataSetChanged();
+    }
+
+    public void addData(List<DATA> list){
+        if (list != null && list.size() > 0) {
+            this.dataList.addAll(list);
+        }
+        notifyDataSetChanged();
+    }
+
+    public List<DATA> getData() {
+        return dataList;
     }
 
     @NonNull
     @Override
-    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+    public ViewBindHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
         if(viewType == 1 ){
             // get genericity "B"
-            Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
             try {
-               /* for(Method method: entityClass.getMethods()){
+                Class<VB> entityClass = (Class<VB>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
+                /*for(Method method: entityClass.getMethods()){
                     StringBuilder sb = new StringBuilder();
                     for(Class type : method.getParameterTypes()){
                         sb.append(type.getSimpleName()+",");
                     }
-                    Log.e(TAG,String.format("method:%s,return:%s,param:%s",method.getName(),method.getReturnType().getSimpleName(),sb.toString()));
+                    Log.e("BaseAdapter",String.format("method:%s,return:%s,param:%s",method.getName(),method.getReturnType().getSimpleName(),sb.toString()));
                 }*/
                 Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate";
-                B vBind = (B) method.invoke(entityClass,LayoutInflater.from(parent.getContext()),parent,false);//execute method to create a objct of viewbind;
+                VB vBind = (VB) method.invoke(entityClass,LayoutInflater.from(parent.getContext()),parent,false);//execute method to create a objct of viewbind;
                 return new ViewBindHolder(vBind);
             } catch (SecurityException e) {
                 e.printStackTrace();
@@ -80,19 +105,24 @@
                 e.printStackTrace();
             }
         }
-        return new NullViewHolder( LayoutNullBinding.inflate(LayoutInflater.from(parent.getContext()),parent,false));
+        return new ViewBindHolder( LayoutNullBinding.inflate( LayoutInflater.from(parent.getContext()), parent, false ) );
     }
 
     @Override
     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
-        //MyLog.i(TAG,"onBindViewHolder position:"+position+" "+mData.size()+" "+getItemViewType(position));
-        if(activity == null){
-            activity = (BaseActivity) holder.itemView.getContext();
-        }
-        if(getItemViewType(position)==0){
-            bindView((NullViewHolder) holder);
-        }else {
-            bindView((ViewBindHolder) holder, mData.size() == 0 ? null : mData.get(position), position);
+        ViewBindHolder bindHolder = (ViewBindHolder) holder;
+        if(getItemViewType(position) == 0 || bindHolder.binding instanceof LayoutNullBinding){
+            onBindEmptyView((LayoutNullBinding) bindHolder.binding);
+        }else{
+            if (onItemClickListener != null) {
+                bindHolder.binding.getRoot().setOnClickListener(view -> {
+                    if(onItemClickListener != null){
+                        onItemClickListener.onItemClick(position,getItem(position));
+                    }
+                });
+            }
+            onBindView((VB) bindHolder.binding, position, getItem(position));
+            setBottomMargin(bindHolder,position);
         }
     }
 
@@ -102,7 +132,7 @@
      * @param position
      */
     protected void setBottomMargin(ViewBindHolder holder, int position){
-        setBottomMargin(holder,position,23);
+        setBottomMargin(holder,position,lastMarginBottom);
     }
 
     /**
@@ -111,56 +141,54 @@
      * @param position  位置
      * @param dp        间距
      */
-    protected void setBottomMargin(RecyclerView.ViewHolder holder, int position,int dp){
-        setBottomMargin(holder,position,dp,0);
+    protected void setBottomMargin(RecyclerView.ViewHolder holder, int position,float dp){
+        setBottomMargin(holder,position,dp,defaultMarginBottom);
     }
-    protected void setBottomMargin(RecyclerView.ViewHolder holder, int position, int dp, int defaultDp){
+
+    protected void setBottomMargin(RecyclerView.ViewHolder holder, int position, float dp, float defaultDp){
         ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams) holder.itemView.getLayoutParams();
-        if(position == mData.size() -1){
+        if(position == dataList.size() -1){
             params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, DeviceUtil.convertDpToPixel(dp,holder.itemView.getContext()));
         }else{
             params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, DeviceUtil.convertDpToPixel(defaultDp,holder.itemView.getContext()));
         }
     }
-    protected abstract void bindView(ViewBindHolder holder,T data,int position);
 
 
-    protected void bindView(NullViewHolder holder){
-
-    }
-
+    /**
+     * 空数据支持
+     * @return
+     */
     @Override
     public int getItemCount() {
-        //默认显示空视图,若不显示空视图则重写该方法,返回mData.size()
-        return mData == null || mData.size() == 0 ?1:mData.size();
+        return (showNull && dataList.size() == 0 )? 1 : dataList.size();
     }
 
-
+    /**
+     * 当下标为0,数据集合为0 返回0(意味当前应显示空数据视图))
+     * @param position
+     * @return
+     */
     @Override
     public int getItemViewType(int position) {
-        //当下标为0,数据集合为0 返回0(意味当前应显示空数据视图))
-        //MyLog.i(TAG,"getItemViewType position:"+position+" mdata:"+mData.size()+" "+(position ==0 && mData.size()==0));
-        return position == 0 && mData.size()==0?0:1;
+        return  (showNull && position == 0 && dataList.size() == 0)? 0 : 1;
     }
 
-    public class ViewBindHolder extends RecyclerView.ViewHolder{
-        public B binding;
-        public ViewBindHolder( B binding) {
-            super(binding.getRoot());
-            this.binding = binding;
+    public DATA getItem(int position){
+        if(position >= dataList.size()){
+            return null;
+        }else {
+            return dataList.get(position);
         }
     }
+
+    protected abstract void onBindView(VB binding, int position, DATA data);
+
     /**
      * 空数据显示
-     * Created by Administrator on 2021/10/28 0028.
      */
-    public class NullViewHolder extends RecyclerView.ViewHolder {
-        LayoutNullBinding binding;
+    protected void onBindEmptyView(LayoutNullBinding emptyBinding){
+        Log.e("baseAdapter"," emptyBinding:"+emptyBinding);
 
-        public NullViewHolder(LayoutNullBinding binding) {
-            super(binding.getRoot());
-            this.binding = binding;
-        }
     }
-
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseFragment.java b/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseFragment.java
index 04fab76..5918601 100644
--- a/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseFragment.java
+++ b/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseFragment.java
@@ -7,11 +7,11 @@
 
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
-import androidx.lifecycle.ViewModel;
 import androidx.lifecycle.ViewModelProvider;
 import androidx.viewbinding.ViewBinding;
 
 import com.runt.open.mvvm.base.activities.BaseActivity;
+import com.runt.open.mvvm.base.model.BaseViewModel;
 import com.runt.open.mvvm.base.model.ViewModelFactory;
 
 import java.lang.reflect.Method;
@@ -21,11 +21,22 @@
  * fragment 封装
  * Created by Administrator on 2021/10/28 0028.
  */
-public abstract class BaseFragment<B extends ViewBinding,VM extends ViewModel> extends Fragment {
+public abstract class BaseFragment<VB extends ViewBinding,VM extends BaseViewModel> extends Fragment {
 
-    protected BaseActivity activity;
-    protected  B binding;
-    protected  VM viewModel;
+    protected BaseActivity mActivity;
+    protected  VB mBinding;
+    protected  VM mViewModel;
+    public static final int REQUEST_CODE_LOGOUT = 20009,/*退出*/
+            REQUEST_CODE_ORDER = 10010,/*订单详情*/
+            REQUEST_CODE_LOGIN = 20010,/*登录*/
+            REQUEST_CODE_SCAN = 20011/*扫描请求*/,
+            REQUEST_CODE_PIC = 20012,/*选择图片*/
+            REQUEST_CODE_PERMISSION = 20013,/*请求权限*/
+            REQUEST_CODE_SIGN = 20014,/*签到*/
+            REQUEST_CODE_WITHDRAW = 22014,/*提现*/
+            RESULT_CODE_FAILD = 4044/*失败*/,
+            RESULT_CODE_SUCESS = 4046/*成功*/,
+            RESULT_CODE_CANCEL = 4043/*取消*/;
 
     @Nullable
     @Override
@@ -33,17 +44,23 @@
         // get genericity "B"
         try {
             final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
-            Class<B> entityClass = (Class<B>) type.getActualTypeArguments()[0];
+            Class<VB> entityClass = (Class<VB>) type.getActualTypeArguments()[0];
             Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate";
-            binding = (B) method.invoke(entityClass,inflater,container,false);//execute method to create a objct of viewbind;
+            mBinding = (VB) method.invoke(entityClass,inflater,container,false);//execute method to create a objct of viewbind;
             Class<VM> vmClass = (Class<VM>) type.getActualTypeArguments()[1];
-            viewModel = new ViewModelProvider(this,getViewModelFactory()).get(vmClass);
+            mViewModel = new ViewModelProvider(this,getViewModelFactory()).get(vmClass);
         } catch (Exception e) {
             e.printStackTrace();
         }
-        return binding.getRoot();
+        initViews();
+        return mBinding.getRoot();
     }
 
+    public void setOnClickListener(View.OnClickListener click,int... ids){
+        for (int id: ids){
+            getActivity().findViewById(id).setOnClickListener(click);
+        }
+    }
     public ViewModelProvider.Factory getViewModelFactory(){
         return ViewModelFactory.getInstance();
     }
@@ -51,16 +68,19 @@
     @Override
     public void onActivityCreated(@Nullable Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        activity = (BaseActivity) getActivity();
-        initViews();
+        mActivity = (BaseActivity) getActivity();
+        mViewModel.onCreate(mActivity);
+        loadData();
     }
 
     public abstract void initViews();
 
+    public abstract void loadData();
+
     @Override
     public void onDestroyView() {
         super.onDestroyView();
-        binding = null;
+        mBinding = null;
     }
 
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseLoadPageFragment.java b/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseLoadPageFragment.java
deleted file mode 100644
index 71cb4f2..0000000
--- a/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseLoadPageFragment.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.runt.open.mvvm.base.fragments;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewbinding.ViewBinding;
-
-import com.runt.open.mvvm.base.adapter.BaseAdapter;
-import com.runt.open.mvvm.base.model.BaseLoadPageViewModel;
-import com.runt.open.mvvm.data.BasePageResult;
-import com.runt.open.mvvm.databinding.RefreshRecyclerBinding;
-import com.scwang.smart.refresh.footer.ClassicsFooter;
-import com.scwang.smart.refresh.header.ClassicsHeader;
-import com.scwang.smart.refresh.layout.SmartRefreshLayout;
-import com.scwang.smart.refresh.layout.api.RefreshLayout;
-import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.HashMap;
-
-/**
- * 分页fragment 封装
- * Created by Administrator on 2021/11/3 0003.
- */
-public abstract class BaseLoadPageFragment<B extends ViewBinding,VM extends BaseLoadPageViewModel,A extends BaseAdapter,D extends BasePageResult> extends BaseFragment<B,VM>
-        implements OnRefreshLoadMoreListener {
-    protected SmartRefreshLayout smartRefresh;
-    protected RecyclerView recycler;
-    final String TAG = "RecyclerFragment";
-    protected A adapter;//适配器
-    protected String url;//请求地址
-    protected HashMap param;//参数
-    protected int page=1;
-    protected final int SIZE = 10;
-    protected boolean isRefresh = false;//是否正在刷新
-
-    @Override
-    public void initViews() {
-        try {
-            Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
-            this.adapter = entityClass.newInstance();//实例化泛型
-            String smartStr = "smartRefresh";
-            smartRefresh = (SmartRefreshLayout) binding.getClass().getField(smartStr).get(binding);
-            recycler =  (RecyclerView) binding.getClass().getDeclaredField("recycler").get(binding);
-        } catch (NoSuchFieldException e) {
-            try {
-                RefreshRecyclerBinding includeRefreshRecycler = (RefreshRecyclerBinding) binding.getClass().getDeclaredField ("includeRefreshRecycler").get(binding);
-                smartRefresh = includeRefreshRecycler.smartRefresh;
-                recycler =  includeRefreshRecycler.recycler;
-            } catch (Exception e2) {
-                e2.printStackTrace();
-            }
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (java.lang.InstantiationException e) {
-            e.printStackTrace();
-        }
-        smartRefresh.setRefreshHeader(new ClassicsHeader(getContext()));
-        smartRefresh.setRefreshFooter(new ClassicsFooter(getContext()));
-        smartRefresh.setOnRefreshLoadMoreListener(this);
-        recycler.setLayoutManager(new LinearLayoutManager(getContext()));
-        recycler.setAdapter(adapter);
-    }
-
-    @Override
-    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
-        page++;
-        viewModel.onLoadMore();
-    }
-
-    @Override
-    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
-        page = 1;
-        viewModel.onRefresh();
-    }
-
-    private void finishFreshLoadmore(D result){
-        if(result.code == 200){
-
-            smartRefresh.setEnableRefresh(true);
-            smartRefresh.finishRefresh();
-            if(page == 1){
-                adapter.getData().clear();
-                adapter.setData(result.rows);
-            }else{
-                adapter.getData().addAll(result.rows);
-                adapter.notifyDataSetChanged();
-            }
-            if(result.total <= adapter.getData().size()// 总数是否已经加载完
-                    || result.rows.size() < SIZE // 最后一页数据的数量一般不满size
-            ){//判断是否没有数据了
-                smartRefresh.finishLoadMoreWithNoMoreData();
-            }else {
-                smartRefresh.finishLoadMore();
-            }
-        }else{
-            smartRefresh.setEnableRefresh(true);
-            smartRefresh.finishRefresh();
-            smartRefresh.finishLoadMore();
-        }
-    }
-
-    public A getAdapter() {
-        return adapter;
-    }
-}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseTabFragment.java b/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseTabFragment.java
index f482d6b..bf6878f 100644
--- a/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseTabFragment.java
+++ b/app/src/main/java/com/runt/open/mvvm/base/fragments/BaseTabFragment.java
@@ -1,12 +1,12 @@
 package com.runt.open.mvvm.base.fragments;
 
-import androidx.lifecycle.ViewModel;
 import androidx.viewbinding.ViewBinding;
 import androidx.viewpager2.widget.ViewPager2;
 
 import com.google.android.material.tabs.TabLayout;
 import com.google.android.material.tabs.TabLayoutMediator;
 import com.runt.open.mvvm.base.adapter.FragmentAdapter;
+import com.runt.open.mvvm.base.model.BaseViewModel;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -16,7 +16,7 @@
  * 带有tablayout fragment封装
  * Created by Administrator on 2021/11/3 0003.
  */
-public abstract class BaseTabFragment<B extends ViewBinding,VM extends ViewModel> extends BaseFragment<B,VM> {
+public abstract class BaseTabFragment<B extends ViewBinding,VM extends BaseViewModel> extends BaseFragment<B,VM> {
 
     TabLayout tabLayout;
     FragmentAdapter fragmentAdapter;
@@ -25,28 +25,30 @@
 
     @Override
     public void initViews() {
-
-        fragmentAdapter = new FragmentAdapter(activity);
-        fragmentAdapter.setFragments(initFragments());
         setTabTitles(initTabTitles());
         //设置当前可见Item左右可见page数,次范围内不会被销毁
         //禁用预加载
         try {
-            viewPager2 = (ViewPager2) binding.getClass().getDeclaredField("viewPager2").get(binding);
-            tabLayout = (TabLayout) binding.getClass().getDeclaredField("tabLayout").get(binding);
+            viewPager2 = (ViewPager2) mBinding.getClass().getDeclaredField("viewPager2").get(mBinding);
+            tabLayout = (TabLayout) mBinding.getClass().getDeclaredField("tabLayout").get(mBinding);
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         } catch (NoSuchFieldException e) {
             e.printStackTrace();
         }
-        ;
         viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
-        viewPager2.setAdapter(fragmentAdapter);
         viewPager2.setCurrentItem(0);
         viewPager2.setUserInputEnabled(false); //true:滑动,false:禁止滑动
         new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> tab.setText(tabTitles.get(position))).attach();
     }
 
+    @Override
+    public void loadData() {
+        fragmentAdapter = new FragmentAdapter(mActivity);
+        fragmentAdapter.setFragments(initFragments());
+        viewPager2.setAdapter(fragmentAdapter);
+    }
+
     protected abstract List<String> initTabTitles();
 
     protected abstract List<BaseFragment> initFragments();
diff --git a/app/src/main/java/com/runt/open/mvvm/base/fragments/LoadPageFragment.java b/app/src/main/java/com/runt/open/mvvm/base/fragments/LoadPageFragment.java
new file mode 100644
index 0000000..d0489f1
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/base/fragments/LoadPageFragment.java
@@ -0,0 +1,96 @@
+package com.runt.open.mvvm.base.fragments;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Observer;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewbinding.ViewBinding;
+
+import com.runt.open.mvvm.R;
+import com.runt.open.mvvm.base.adapter.BaseAdapter;
+import com.runt.open.mvvm.base.model.LoadPageViewModel;
+import com.scwang.smart.refresh.footer.ClassicsFooter;
+import com.scwang.smart.refresh.header.ClassicsHeader;
+import com.scwang.smart.refresh.layout.SmartRefreshLayout;
+import com.scwang.smart.refresh.layout.api.RefreshLayout;
+import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 分页fragment 封装
+ * Created by Administrator on 2021/11/3 0003.
+ */
+public abstract class LoadPageFragment<VB extends ViewBinding,VM extends LoadPageViewModel,A extends BaseAdapter,RESULT> extends BaseFragment<VB,VM>  implements OnRefreshLoadMoreListener {
+
+    protected int page;
+    protected SmartRefreshLayout refresh;
+    //适配器
+    protected A adapter;
+
+    @Override
+    public void initViews() {
+        try {
+            Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
+            this.adapter = entityClass.newInstance();//实例化泛型
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        RecyclerView recycler = mBinding.getRoot().findViewById(R.id.recycler);
+        recycler.setLayoutManager(new LinearLayoutManager(getContext()));
+        recycler.setAdapter(adapter);
+        refresh = mBinding.getRoot().findViewById(R.id.refresh);
+        refresh.setRefreshHeader(new ClassicsHeader(getContext()));
+        refresh.setRefreshFooter(new ClassicsFooter(getContext()));
+        refresh.setOnRefreshLoadMoreListener(this);
+        mViewModel.getLiveData().observe(this, (Observer<List<RESULT>>) list -> {
+            adapter.showNull = true;
+            if(page == 0){
+                adapter.setData(list);
+            }else{
+                adapter.addData(list);
+            }
+            refresh.finishRefresh();
+            //加载完毕
+            if(list.size() < 10 || page > 0 && list.size() == 0){
+                refresh.finishLoadMoreWithNoMoreData();
+            }else{
+                refresh.finishLoadMore();
+            }
+        });
+        mViewModel.getLiveFailed().observe(this, o -> {
+            refresh.finishRefresh();
+            refresh.finishLoadMore();
+            //校正page数值
+            int size = adapter.getData().size();
+            if(size/mViewModel.SIZE+1 < page){
+                page--;
+            }
+        });
+    }
+
+    @Override
+    public void loadData() {
+        refresh.autoRefresh();
+    }
+
+    protected abstract Map requestParams();
+
+    @Override
+    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+        page = 0;
+        mViewModel.requestData(page,requestParams());
+    }
+
+    @Override
+    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
+        page++;
+        mViewModel.requestData(page,requestParams());
+    }
+
+    public A getAdapter() {
+        return adapter;
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/model/BaseLoadPageViewModel.java b/app/src/main/java/com/runt/open/mvvm/base/model/BaseLoadPageViewModel.java
deleted file mode 100644
index 150ef54..0000000
--- a/app/src/main/java/com/runt/open/mvvm/base/model/BaseLoadPageViewModel.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.runt.open.mvvm.base.model;
-
-/**
- * 分页
- * Created by Administrator on 2021/11/3 0003.
- */
-public abstract class BaseLoadPageViewModel extends BaseViewModel {
-
-    public abstract void onRefresh();
-
-    public abstract void onLoadMore();
-
-}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/model/BaseViewModel.java b/app/src/main/java/com/runt/open/mvvm/base/model/BaseViewModel.java
index 3c172a9..de2ed52 100644
--- a/app/src/main/java/com/runt/open/mvvm/base/model/BaseViewModel.java
+++ b/app/src/main/java/com/runt/open/mvvm/base/model/BaseViewModel.java
@@ -1,13 +1,15 @@
 package com.runt.open.mvvm.base.model;
 
-import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.ViewModel;
 
-import com.runt.open.mvvm.data.LoadingCmd;
+import com.runt.open.mvvm.base.activities.BaseActivity;
 import com.runt.open.mvvm.retrofit.AndroidScheduler;
+import com.runt.open.mvvm.retrofit.api.CommonApiCenter;
 import com.runt.open.mvvm.retrofit.observable.HttpObserver;
+import com.runt.open.mvvm.retrofit.utils.RetrofitUtils;
 
 import io.reactivex.Observable;
+import io.reactivex.functions.Consumer;
 import io.reactivex.schedulers.Schedulers;
 
 /**
@@ -15,10 +17,11 @@
  */
 public class BaseViewModel extends ViewModel {
 
-    MutableLiveData<LoadingCmd> loadLive = new MutableLiveData<>();
+    protected BaseActivity mActivity;
+    protected CommonApiCenter commonApi = RetrofitUtils.getInstance().getCommonApi();
 
-    public MutableLiveData<LoadingCmd> getLoadLive() {
-        return loadLive;
+    public void onCreate(BaseActivity activity) {
+        this.mActivity = activity;
     }
 
     /**
@@ -43,11 +46,17 @@
     public <T> void httpObserverOnLoading(Observable<T> observable, HttpObserver observer){
         observable.subscribeOn(Schedulers.io())//指定网络请求在io后台线程中进行
                 .doOnSubscribe(disposable -> {
-                             loadLive.setValue(new LoadingCmd(LoadingCmd.CMD.LOADING,"请求数据中..."));
+                    mActivity.showLoadingDialog("");
                 })
                 .observeOn(AndroidScheduler.mainThread())
+                .doOnError(new Consumer<Throwable>() {
+                    @Override
+                    public void accept(Throwable throwable) throws Exception {
+
+                    }
+                })
                 .doOnComplete(() -> {
-                    loadLive.postValue(new LoadingCmd(LoadingCmd.CMD.DISSMISS));
+                    mActivity.dissmissLoadingDialog();
                 })
                 .subscribe(observer);
     }
diff --git a/app/src/main/java/com/runt/open/mvvm/base/model/ImpViewModel.java b/app/src/main/java/com/runt/open/mvvm/base/model/ImpViewModel.java
new file mode 100644
index 0000000..985f772
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/base/model/ImpViewModel.java
@@ -0,0 +1,7 @@
+package com.runt.open.mvvm.base.model;
+
+/**
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/7/27.
+ */
+public class ImpViewModel extends BaseViewModel{
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/base/model/LoadPageViewModel.java b/app/src/main/java/com/runt/open/mvvm/base/model/LoadPageViewModel.java
new file mode 100644
index 0000000..5560ad5
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/base/model/LoadPageViewModel.java
@@ -0,0 +1,47 @@
+package com.runt.open.mvvm.base.model;
+
+import androidx.lifecycle.MutableLiveData;
+
+import com.runt.open.mvvm.data.HttpApiResult;
+import com.runt.open.mvvm.data.PageResult;
+import com.runt.open.mvvm.retrofit.observable.HttpObserver;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 分页
+ * Created by Administrator on 2021/11/3 0003.
+ */
+public abstract class LoadPageViewModel<RESULT extends PageResult> extends BaseViewModel {
+
+    public final int SIZE = 10;
+    private MutableLiveData<List> liveData = new MutableLiveData<>();
+    private MutableLiveData liveFailed = new MutableLiveData();
+
+    protected abstract String requestUrl();
+
+    public void requestData(int page,Map param){
+        httpObserverOn( commonApi.getPageData(requestUrl(), page, SIZE, param), new HttpObserver<RESULT>() {
+
+            @Override
+            protected void onSuccess(RESULT data) {
+                liveData.postValue(data.rows);
+            }
+
+            @Override
+            protected void onFailed(HttpApiResult httpResult) {
+                mActivity.showToast(httpResult.msg);
+                liveFailed.postValue(1);
+            }
+        });
+    }
+
+    public MutableLiveData<List> getLiveData(){
+        return liveData;
+    }
+
+    public MutableLiveData getLiveFailed() {
+        return liveFailed;
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/data/ApkUpGradeResult.java b/app/src/main/java/com/runt/open/mvvm/data/ApkUpGradeResult.java
index 6b9d44a..f23882e 100644
--- a/app/src/main/java/com/runt/open/mvvm/data/ApkUpGradeResult.java
+++ b/app/src/main/java/com/runt/open/mvvm/data/ApkUpGradeResult.java
@@ -3,7 +3,7 @@
 /**
  * Created by Administrator on 2021/11/15 0015.
  */
-public class ApkUpGradeResult extends BaseApiResult<ApkUpGradeResult.AppInfo>{
+public class ApkUpGradeResult extends HttpApiResult<ApkUpGradeResult.AppInfo> {
 
     public class AppInfo {
         //以下为声明的参数
diff --git a/app/src/main/java/com/runt/open/mvvm/data/BaseApiResult.java b/app/src/main/java/com/runt/open/mvvm/data/HttpApiResult.java
similarity index 86%
rename from app/src/main/java/com/runt/open/mvvm/data/BaseApiResult.java
rename to app/src/main/java/com/runt/open/mvvm/data/HttpApiResult.java
index 8ddd410..7e499c8 100644
--- a/app/src/main/java/com/runt/open/mvvm/data/BaseApiResult.java
+++ b/app/src/main/java/com/runt/open/mvvm/data/HttpApiResult.java
@@ -5,7 +5,7 @@
 /**
  * Created by Administrator on 2021/10/28 0028.
  */
-public class BaseApiResult<D extends Object> implements Serializable {
+public class HttpApiResult<D extends Object> implements Serializable {
 
     public String msg;
     public int code = 200;
diff --git a/app/src/main/java/com/runt/open/mvvm/data/LoadingCmd.java b/app/src/main/java/com/runt/open/mvvm/data/LoadingCmd.java
deleted file mode 100644
index 1752dea..0000000
--- a/app/src/main/java/com/runt/open/mvvm/data/LoadingCmd.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.runt.open.mvvm.data;
-
-/**
- * My father is Object, ites purpose of 
- *
- * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/1/28.
- */
-public class LoadingCmd {
-    public CMD code;public String msg;
-
-    public LoadingCmd(CMD code) {
-        this(code,"");
-    }
-
-    public LoadingCmd(CMD code, String msg) {
-        this.code = code;
-        this.msg = msg;
-    }
-
-    public enum CMD{LOADING,DISSMISS}
-}
diff --git a/app/src/main/java/com/runt/open/mvvm/data/BasePageResult.java b/app/src/main/java/com/runt/open/mvvm/data/PageResult.java
similarity index 86%
rename from app/src/main/java/com/runt/open/mvvm/data/BasePageResult.java
rename to app/src/main/java/com/runt/open/mvvm/data/PageResult.java
index 6eba4d3..ddf11bd 100644
--- a/app/src/main/java/com/runt/open/mvvm/data/BasePageResult.java
+++ b/app/src/main/java/com/runt/open/mvvm/data/PageResult.java
@@ -5,7 +5,7 @@
 /**
  * Created by Administrator on 2021/10/28 0028.
  */
-public class BasePageResult<T> extends BaseApiResult<String>{
+public class PageResult<T> extends HttpApiResult<String> {
     public int pages;
     public int total;
     public int pageNum;
diff --git a/app/src/main/java/com/runt/open/mvvm/data/Results.java b/app/src/main/java/com/runt/open/mvvm/data/Results.java
index fc55568..0d17e8a 100644
--- a/app/src/main/java/com/runt/open/mvvm/data/Results.java
+++ b/app/src/main/java/com/runt/open/mvvm/data/Results.java
@@ -1,6 +1,7 @@
 package com.runt.open.mvvm.data;
 
 import com.runt.open.mvvm.ui.login.UserBean;
+import com.runt.open.mvvm.ui.main.home.Message;
 
 /**
  * My father is Object, ites purpose of
@@ -9,8 +10,9 @@
  */
 public class Results {
 
-    public static class LoggedInUser extends BaseApiResult<UserBean> { }
+    public static class LoggedInUser extends HttpApiResult<UserBean> { }
 
-    public static class StringApiResult extends BaseApiResult<String>{ }
+    public static class StringApiResult extends HttpApiResult<String> { }
 
+    public class MessageResult extends PageResult<Message>{}
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java b/app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java
index 6d271e4..b0d62f4 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java
@@ -2,11 +2,14 @@
 
 import android.util.Log;
 
+import com.runt.open.mvvm.MyApplication;
 import com.runt.open.mvvm.retrofit.net.NetWorkCost;
 import com.runt.open.mvvm.retrofit.net.NetWorkListenear;
 import com.runt.open.mvvm.retrofit.utils.HttpPrintUtils;
-import com.runt.open.mvvm.util.GsonUtils;
+import com.runt.open.mvvm.util.DeviceUtil;
 
+import org.json.JSONArray;
+import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.EOFException;
@@ -14,6 +17,7 @@
 import java.net.URLDecoder;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 
 import okhttp3.FormBody;
@@ -38,47 +42,69 @@
 
     final String TAG = "HttpLogging";
 
-    public HttpLoggingInterceptor() {
-    }
+    private boolean printLog ;
 
+    public HttpLoggingInterceptor(){
+        this(true);
+    }
+    public HttpLoggingInterceptor(boolean printLog) {
+        this.printLog = printLog;
+    }
 
     @Override
     public Response intercept(Chain chain) throws IOException {
 
-        Request request = chain.request();
-        int hashCode = request.hashCode();
-        ArrayList<String> logArrays = getRequestLog(request);
-        int position = logArrays.size() +2;
-        Response response;
+        Request requestTemp = chain.request();
+        int hashCode = requestTemp.hashCode();
+        if(printLog) {
+            Log.d(TAG, "hashcode:" + hashCode);
+        }
+        Request.Builder requestBuild = requestTemp.newBuilder()
+                .addHeader("appVersion", DeviceUtil.getAppVersionName(MyApplication.getApplication()))
+                .addHeader("os", DeviceUtil.isHarmonyOS()? "harmony" : "android");
+        Request request = requestBuild.build().newBuilder().build();
+        ArrayList<String> logArrays = new ArrayList<>();
+        Response response = null;
         try {
-            request = encryptRequest(request);//加密
+            logArrays.addAll(getRequestLog(request));
+            int position = logArrays.size() +2;
+            //request = encryptRequest(request);//加密
             response = chain.proceed(request);
             logArrays.addAll(getResponseLog(response));
-            Log.d(TAG,"hashcode:"+hashCode);
             NetWorkCost netWorkCost = NetWorkListenear.workCostMap.get(hashCode);
             if(netWorkCost != null) {
-                String cost = String.format("dns:%s,secure:%s,connect:%s,requestH:%s,requestB:%s,responseH:%s,responseB:%s", convertTimes(netWorkCost.dns), convertTimes(netWorkCost.secure), convertTimes(netWorkCost.connect), convertTimes(netWorkCost.requestHeader), convertTimes(netWorkCost.requestBody), convertTimes(netWorkCost.resposeHeader), convertTimes(netWorkCost.resposeBody));
-                logArrays.add(position, "<-- costtimes : " + convertTimes(netWorkCost.total) + " (" + cost + ')');
+                logArrays.add(position, "<-- costtimes : " + netWorkCost);
             }
             NetWorkListenear.workCostMap.remove(hashCode);
             new Thread(){
                 @Override
                 public void run() {
-                    HttpPrintUtils.getInstance().printLog(logArrays, true);//线程安全方法,需在新线程执行,避免阻塞当前线程,导致程序无响应
+                    if(printLog) {
+                        HttpPrintUtils.getInstance().printLog(logArrays, true);//线程安全方法,需在新线程执行,避免阻塞当前线程,导致程序无响应
+                    }
                 }
             }.start();
+        } catch (JSONException e) {
+            if(response == null){
+                response = chain.proceed(request);
+            }
+            e.printStackTrace();
         } catch (Exception e) {
             logArrays.add("<-- response url:" + URLDecoder.decode(request.url().toString(), "UTF-8"));
             NetWorkCost netWorkCost = NetWorkListenear.workCostMap.get(hashCode);
-            String cost = String.format("dns:%s,secure:%s,connect:%s,requestH:%s,requestB:%s,responseH:%s,responseB:%s",  convertTimes(netWorkCost.dns) ,convertTimes(netWorkCost.secure) , convertTimes(netWorkCost.connect),convertTimes(netWorkCost.requestHeader),convertTimes(netWorkCost.requestBody) ,convertTimes(netWorkCost.resposeHeader),convertTimes(netWorkCost.resposeBody)    );
-            logArrays.add("<-- costtimes : "+convertTimes(netWorkCost.total)+" (" +cost + ')');
+            if (netWorkCost != null) {
+                netWorkCost.total = new Date().getTime() - netWorkCost.total;
+                logArrays.add("<-- costtimes : " + netWorkCost);
+            }
             NetWorkListenear.workCostMap.remove(hashCode);
             logArrays.add("<-- response failed " + e.getLocalizedMessage());
             logArrays.add("<--                 " + e.toString());
             new Thread(){
                 @Override
                 public void run() {
-                    HttpPrintUtils.getInstance().printLog(logArrays, false);//线程安全方法,需在新线程执行,避免阻塞当前线程,导致程序无响应
+                    if(printLog) {
+                        HttpPrintUtils.getInstance().printLog(logArrays, false);//线程安全方法,需在新线程执行,避免阻塞当前线程,导致程序无响应
+                    }
                 }
             }.start();
             throw e;//抛出异常,用于请求接收信息
@@ -86,7 +112,7 @@
         return response;
     }
 
-    private ArrayList<String> getRequestLog(Request request) throws IOException {
+    private ArrayList<String> getRequestLog(Request request) throws IOException, JSONException {
         RequestBody requestBody = request.body();
         ArrayList<String> logArrays = new ArrayList<>();
         String requestStartMessage = "--> " + request.method() + ' ' + URLDecoder.decode(request.url().toString() ,"UTF-8")+ ' ' ;
@@ -120,22 +146,28 @@
                     String str=buffer1.readString(charset).replaceAll("%(?![0-9a-fA-F]{2})","%25");
                     param.put(part.headers().get(part.headers().name(0)),URLDecoder.decode(str, "UTF-8"));
                 }
-                logArrays.add(GsonUtils.retractJson(new JSONObject(param).toString()));
+                logArrays.add(new JSONObject(param).toString(4));
             }else if(requestBody instanceof FormBody){
                 logArrays.add("---------->REQUEST BODY[FormBody]<----------");
                 FormBody body = (FormBody) requestBody;
                 for(int i = 0 ; i < body.size() ; i ++ ){
                     param.put(body.name(i),body.value(i));
                 }
-                logArrays.add(GsonUtils.retractJson(new JSONObject(param).toString()));
+                logArrays.add(new JSONObject(param).toString(4));
             }else{
                 Buffer buffer = new Buffer();
                 requestBody.writeTo(buffer);
                 logArrays.add("---------->REQUEST BODY<----------");
                 String str = buffer.readString(charset);
                 try{
-                    logArrays.add(GsonUtils.retractJson(URLDecoder.decode(str, "UTF-8")));
-                }catch (Exception e){
+                    str = URLDecoder.decode(str, "UTF-8");
+                }catch (Exception e){}
+
+                if(str.indexOf("[") == 0){
+                    logArrays.add(new JSONArray(str).toString(4));
+                }else if(str.indexOf("{") == 0){
+                    logArrays.add(new JSONObject(str).toString(4));
+                }else{
                     logArrays.add(str);
                 }
             }
@@ -147,7 +179,7 @@
     }
 
 
-    private ArrayList<String> getResponseLog(Response response) throws IOException {
+    private ArrayList<String> getResponseLog(Response response) throws IOException, JSONException {
         ArrayList<String> logArrays = new ArrayList<>();
         ResponseBody responseBody = response.body();
         long contentLength = responseBody.contentLength();
@@ -173,7 +205,7 @@
             if (isPlaintext(buffer)) {
                 logArrays.add("---------->RESPONSE BODY<----------");
                 if (contentLength != 0) {
-                    logArrays.add(retractJson(buffer.clone().readString(charset)));
+                    logArrays.add(new JSONObject(buffer.clone().readString((charset))).toString(4));
                 }
 
                 logArrays.add("<-- END HTTP (" + buffer.size() + "-byte body)");
@@ -183,57 +215,6 @@
         return logArrays;
     }
 
-    /**
-     * 字符串缩进
-     * @param json
-     * @return
-     */
-    private String retractJson(String json){
-        int level = 0 ;
-        StringBuffer jsonForMatStr = new StringBuffer();
-        for(int index=0;index<json.length();index++)//将字符串中的字符逐个按行输出
-        {
-            //获取s中的每个字符
-            char c = json.charAt(index);
-            //          System.out.println(s.charAt(index));
-
-            //level大于0并且jsonForMatStr中的最后一个字符为\n,jsonForMatStr加入\t
-            if (level > 0 && '\n' == jsonForMatStr.charAt(jsonForMatStr.length() - 1)) {
-                jsonForMatStr.append(getLevelStr(level));
-                //                System.out.println("123"+jsonForMatStr);
-            }
-            //遇到"{"和"["要增加空格和换行,遇到"}"和"]"要减少空格,以对应,遇到","要换行
-            switch (c) {
-                case '{':
-                case '[':
-                    jsonForMatStr.append(c + "\n");
-                    level++;
-                    break;
-                case ',':
-                    jsonForMatStr.append(c + "\n");
-                    break;
-                case '}':
-                case ']':
-                    jsonForMatStr.append("\n");
-                    level--;
-                    jsonForMatStr.append(getLevelStr(level));
-                    jsonForMatStr.append(c);
-                    break;
-                default:
-                    jsonForMatStr.append(c);
-                    break;
-            }
-        }
-        return jsonForMatStr.toString();
-    }
-
-    private  String getLevelStr(int level) {
-        StringBuffer levelStr = new StringBuffer();
-        for (int levelI = 0; levelI < level; levelI++) {
-            levelStr.append("\t");//\t或空格
-        }
-        return levelStr.toString();
-    }
 
     /**
      * Returns true if the body in question probably contains human readable text. Uses a small sample
@@ -263,18 +244,4 @@
         String contentEncoding = headers.get("Content-Encoding");
         return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
     }
-
-    private String convertTimes(long ms){
-        String m = null,s=null;
-        final int utilS = 1000;
-        final int utilM = utilS*60;
-        if(ms/utilM>0){
-            m = ms/utilM+"m";
-        }
-        if(ms%utilM/utilS>0){
-            s = ms%utilM/utilS+"s";
-        }
-        return (m!=null?m:"")+(s!=null?s:"")+ms%utilS+"ms";
-    }
-
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java b/app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java
index fef1d1e..5376e58 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java
@@ -1,17 +1,21 @@
 package com.runt.open.mvvm.retrofit.api;
 
 
-
 import com.runt.open.mvvm.data.ApkUpGradeResult;
 
 import java.util.Map;
 
 import io.reactivex.Observable;
+import okhttp3.MultipartBody;
+import okhttp3.ResponseBody;
+import retrofit2.Call;
 import retrofit2.http.Field;
 import retrofit2.http.FieldMap;
 import retrofit2.http.FormUrlEncoded;
 import retrofit2.http.GET;
+import retrofit2.http.Multipart;
 import retrofit2.http.POST;
+import retrofit2.http.Part;
 import retrofit2.http.Query;
 import retrofit2.http.QueryMap;
 import retrofit2.http.Url;
@@ -62,5 +66,10 @@
     @GET("system/appupgrade/tourist/get/2")
     Observable<ApkUpGradeResult> getAppUpdate();
 
+    @POST("updateName")
+    Observable<ApkUpGradeResult> updateName(@Field("username") String name);
 
+    @Multipart
+    @POST("updatehead")
+    Call<ResponseBody> updateHead(@Part MultipartBody.Part file);
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/converter/DecryptGsonResponseBodyConverter.java b/app/src/main/java/com/runt/open/mvvm/retrofit/converter/DecryptGsonResponseBodyConverter.java
index 4213ddc..befdc29 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/converter/DecryptGsonResponseBodyConverter.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/converter/DecryptGsonResponseBodyConverter.java
@@ -2,7 +2,7 @@
 
 import android.util.Log;
 
-import com.runt.open.mvvm.data.BaseApiResult;
+import com.runt.open.mvvm.data.HttpApiResult;
 import com.runt.open.mvvm.util.GsonUtils;
 import com.google.gson.Gson;
 import com.google.gson.JsonIOException;
@@ -51,13 +51,13 @@
             response = decryptJsonStr(val);//解密
         } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
             e.printStackTrace();
-            BaseApiResult apiResult = new BaseApiResult<>();
+            HttpApiResult apiResult = new HttpApiResult<>();
             apiResult.code = 412;
             apiResult.msg = "解密数据出错"+e.getMessage();
             response = new Gson().toJson(apiResult);
         } catch (JSONException e) {
             e.printStackTrace();
-            BaseApiResult apiResult = new BaseApiResult<>();
+            HttpApiResult apiResult = new HttpApiResult<>();
             apiResult.code = 414;
             apiResult.msg = "非标准json";
             response = new Gson().toJson(apiResult);
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkCost.java b/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkCost.java
index afc660a..7131f87 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkCost.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkCost.java
@@ -11,4 +11,31 @@
 
     //网络消耗时间
     public long dns,connect,total,secure,requestHeader,requestBody,resposeHeader,resposeBody;
+
+    @Override
+    public String toString() {
+        return "NetWorkCost{" +
+                "total=" + convertTimes(total) +
+                ", dns=" + convertTimes(dns) +
+                ", connect=" + convertTimes(connect) +
+                ", secure=" + convertTimes(secure) +
+                ", requestHeader=" + convertTimes(requestHeader) +
+                ", requestBody=" + convertTimes(requestBody) +
+                ", resposeHeader=" + convertTimes(resposeHeader) +
+                ", resposeBody=" + convertTimes(resposeBody) +
+                '}';
+    }
+
+    private String convertTimes(long ms){
+        String m = null,s=null;
+        final int utilS = 1000;
+        final int utilM = utilS*60;
+        if(ms/utilM>0){
+            m = ms/utilM+"m";
+        }
+        if(ms%utilM/utilS>0){
+            s = ms%utilM/utilS+"s";
+        }
+        return (m!=null?m:"")+(s!=null?s:"")+ms%utilS+"ms";
+    }
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkListenear.java b/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkListenear.java
index 6f49237..0d824a6 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkListenear.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/net/NetWorkListenear.java
@@ -27,13 +27,14 @@
  * @purpose Created by Runt (qingingrunt2010@qq.com) on 2021-7-9.
  */
 
+
 public class NetWorkListenear extends EventListener {
 
     private static final String TAG = "NetworkEventListener";
     final Charset UTF8 = Charset.forName("UTF-8");
     public static Map<Integer, NetWorkCost> workCostMap = new HashMap<>();
 
-    public static Factory get(){
+    public static Factory get() {
         Factory factory = new Factory() {
             @NotNull
             @Override
@@ -47,11 +48,11 @@
     @Override
     public void callStart(@NotNull Call call) {
         super.callStart(call);
-        //mRequestId = mNextRequestId.getAndIncrement() + "";
         //getAndAdd,在多线程下使用cas保证原子性
+        //Log.d(TAG, "callStart hashcode:"+call.request().hashCode());
         NetWorkCost netWorkCost = new NetWorkCost();
         netWorkCost.total = new Date().getTime();
-        workCostMap.put(call.request().hashCode(),netWorkCost);
+        workCostMap.put(call.request().hashCode(), netWorkCost);
     }
 
     @Override
@@ -65,7 +66,7 @@
     public void dnsEnd(@NotNull Call call, @NotNull String domainName, @NotNull List<InetAddress> inetAddressList) {
         super.dnsEnd(call, domainName, inetAddressList);
         //Log.d(TAG, "dnsEnd");
-        workCostMap.get(call.request().hashCode()).dns = new Date().getTime()  - workCostMap.get(call.request().hashCode()).dns;
+        workCostMap.get(call.request().hashCode()).dns = new Date().getTime() - workCostMap.get(call.request().hashCode()).dns;
     }
 
     @Override
@@ -100,9 +101,10 @@
     @Override
     public void connectFailed(@NotNull Call call, @NotNull InetSocketAddress inetSocketAddress, @NotNull Proxy proxy, @Nullable Protocol protocol, @NotNull IOException ioe) {
         super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe);
-        workCostMap.get(call.request().hashCode()).connect = new Date().getTime() - workCostMap.get(call.request().hashCode()).connect;
-        workCostMap.get(call.request().hashCode()).total = new Date().getTime() - workCostMap.get(call.request().hashCode()).total;
-        //Log.d(TAG, "connectFailed");
+        NetWorkCost workCost = workCostMap.get(call.request().hashCode());
+        workCost.connect = new Date().getTime() - workCost.connect;
+        workCost.total = new Date().getTime() - workCost.total;
+        //Log.d(TAG, "connectFailed hashcode:"+call.request().hashCode() +" "+workCost);
     }
 
     @Override
@@ -158,16 +160,20 @@
     public void responseBodyEnd(@NotNull Call call, long byteCount) {
         super.responseBodyEnd(call, byteCount);
         //Log.d(TAG, "responseBodyEnd");
-        workCostMap.get(call.request().hashCode()).resposeBody = new Date().getTime() - workCostMap.get(call.request().hashCode()).resposeBody;
-        workCostMap.get(call.request().hashCode()).total = new Date().getTime() - workCostMap.get(call.request().hashCode()).total;
+        NetWorkCost workCost = workCostMap.get(call.request().hashCode());
+        workCost.resposeBody = new Date().getTime() - workCost.resposeBody;
+        workCost.total = new Date().getTime() - workCost.total;
     }
 
 
     @Override
     public void callFailed(@NotNull Call call, @NotNull IOException ioe) {
         super.callFailed(call, ioe);
-        workCostMap.get(call.request().hashCode()).total = new Date().getTime() - workCostMap.get(call.request().hashCode()).total;
-        //Log.d(TAG, "callFailed");
+        NetWorkCost workCost = workCostMap.get(call.request().hashCode());
+        if (workCost != null) {
+            workCost.total = new Date().getTime() - workCost.total;
+        }
+        //Log.d(TAG, "callFailed hashcode:"+call.request().hashCode() +" "+workCost);
     }
 
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/observable/HttpObserver.java b/app/src/main/java/com/runt/open/mvvm/retrofit/observable/HttpObserver.java
index 3a4ac2c..a99f74e 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/observable/HttpObserver.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/observable/HttpObserver.java
@@ -1,96 +1,71 @@
 package com.runt.open.mvvm.retrofit.observable;
 
-import android.accounts.NetworkErrorException;
 import android.util.Log;
 
-import androidx.annotation.NonNull;
-import androidx.lifecycle.MutableLiveData;
+import com.google.gson.Gson;
+import com.runt.open.mvvm.data.HttpApiResult;
 
-
-import com.runt.open.mvvm.data.BaseApiResult;
-
-import java.io.IOException;
-import java.lang.reflect.ParameterizedType;
+import java.net.ConnectException;
 import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.util.concurrent.TimeoutException;
+import java.util.regex.Pattern;
 
-import io.reactivex.SingleObserver;
-import io.reactivex.observers.DisposableObserver;
-import retrofit2.Response;
+import io.reactivex.Observer;
+import io.reactivex.disposables.Disposable;
+import retrofit2.adapter.rxjava2.HttpException;
 
 /**
  * 网络请求观察
  * Created by Administrator on 2021/11/11 0011.
  */
-public abstract class HttpObserver<M extends BaseApiResult> extends DisposableObserver<Response<M>> implements SingleObserver<Response<M>> {
+public abstract class HttpObserver<RESULT> implements Observer<HttpApiResult<RESULT>> {
 
     final String TAG = "HttpObserver";
 
-    MutableLiveData<M> resultLive;
-
-    public HttpObserver(MutableLiveData<M> resultLive) {
-        this.resultLive = resultLive;
-    }
-
-
     @Override
-    public void onNext(Response<M> response) {
-        onExcuted(response);
+    public void onSubscribe(Disposable d) {
+        Log.d(TAG,"onSubscribe "+hashCode());
     }
 
     @Override
-    public void onError(Throwable throwable) {
-        Log.i("subscribe","onError");
-
-        try {
-            Log.e(TAG,this.getClass().getSimpleName()+" mes:"+throwable.getMessage());
-            Class<M> entityClass = (Class<M>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-            M t = entityClass.newInstance();//实例化一个泛型
-            t.code = 410;
-            if( throwable instanceof SocketTimeoutException){
-                t.msg = "服务请求超时,请稍候再试";//设置错误信息
-            }else  if( throwable instanceof NetworkErrorException){
-                t.msg = "网络连接不畅,请检查您的网络设置";//设置错误信息
-            }else{
-                t.msg = throwable.getMessage();//设置错误信息
-            }
-            resultLive.setValue(t);
-        } catch (ClassCastException e) {
-            e.printStackTrace();
-            M t = (M) new BaseApiResult<String>();
-            t.code = 409;
-            t.msg = "实例化对象未指定泛型实体类";
-            resultLive.setValue(t);
-        } catch (Exception e) {
-            e.printStackTrace();
-            M t = (M) new BaseApiResult<String>();
-            t.code = 409;
-            t.msg = e.getMessage();
-            resultLive.setValue(t);
-        }
-    }
-
-    @Override
-    public void onSuccess(Response<M> response) {
-        onExcuted(response);
-    }
-
-    private void onExcuted(@NonNull Response<M> response){
-
-        if(response.body() != null){
-            resultLive.setValue(response.body());
+    public void onNext(HttpApiResult<RESULT> httpResult) {
+        Log.d(TAG,"onNext "+httpResult);
+        if (httpResult != null && httpResult.code == 0) {
+            onSuccess(httpResult.data);
         }else{
-            try {
-                String error = response.errorBody().string();
-                Log.i("subscribe","onExcuted "+error);
-                onError(new Throwable(error));
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
+            onFailed(httpResult);//接口返回错误
         }
     }
+
+    @Override
+    public void onError(Throwable e) {
+        e.printStackTrace();
+        Log.e(TAG,"onError "+e.getMessage()+" "+hashCode());
+        int code = 600;
+        String msg = "网络请求失败,请检查网络或稍后重试";
+        if( e instanceof ConnectException || e instanceof TimeoutException
+                || e instanceof SocketTimeoutException || e instanceof UnknownHostException){
+            code = 601;
+            msg = "网络请求失败,请检查网络或稍后重试";
+        }else if( e instanceof HttpException){
+            String regEx = "[^0-9]";
+            Log.i(TAG,"code:"+ Pattern.compile(regEx).matcher(e.getMessage()).replaceAll(""));
+            String error = Pattern.compile(regEx).matcher(e.getMessage()).replaceAll("");
+            code = error.length()>0?Integer.parseInt(error):500;
+            msg = error.length()>0?"服务器请求失败":"登录信息验证失败";
+        }
+        HttpApiResult httpResult = new Gson().fromJson("{'code':"+code+",'msg':'"+msg+"'}", HttpApiResult.class);
+        onFailed(httpResult);
+    }
+
     @Override
     public void onComplete() {
-        Log.i("subscribe","onComplete");
+        Log.i(TAG,"onComplete "+hashCode());
     }
 
+    protected abstract void onSuccess(RESULT data);
+
+    protected void onFailed(HttpApiResult httpResult){}
+
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/utils/HttpPrintUtils.java b/app/src/main/java/com/runt/open/mvvm/retrofit/utils/HttpPrintUtils.java
index 53dd3b0..7743709 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/utils/HttpPrintUtils.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/utils/HttpPrintUtils.java
@@ -1,26 +1,20 @@
 package com.runt.open.mvvm.retrofit.utils;
 
-import com.runt.open.mvvm.BuildConfig;
-import com.runt.open.mvvm.util.GsonUtils;
-import com.runt.open.mvvm.util.MyLog;
+import android.util.Log;
 
-import java.io.EOFException;
 import java.util.ArrayList;
-
-import okio.Buffer;
 
 /**
  * My father is Object, ites purpose of 单例模式  保证synchronized方法的线程安全性
  *
  * @purpose Created by Runt (qingingrunt2010@qq.com) on 2021-5-13.
  */
-
 public class HttpPrintUtils {
     String TAG = "HttpPrintUtils";
     static HttpPrintUtils instance;
     public static  HttpPrintUtils getInstance(){
         if(instance == null){
-           instance = new HttpPrintUtils();
+            instance = new HttpPrintUtils();
         }
         return instance;
     }
@@ -76,14 +70,12 @@
         logArrays.add("┗"+getEmptyStr((length-end.length())/2,"━")+end+getEmptyStr((length-end.length())/2,"━")+"┛\n");
         logArrays.add(" \n\n\n");
         //Logger.DEFAULT.log(sb.toString());//打印log,避免多个log语句,导致log输出时其他线程的log输出切入此输出阵列内
-        if(BuildConfig.DEBUG) {
-            for(int i = 0 ; i < logArrays.size() ; i ++ ){
-                String str = logArrays.get(i);
-                if (info) {
-                    MyLog.i(TAG , str.replace("\n","")+" "+logArrays.size()+" "+i);
-                } else {
-                    MyLog.e(TAG , str.replace("\n","")+" "+logArrays.size()+" "+i);
-                }
+        for(int i = 0 ; i < logArrays.size() ; i ++ ){
+            String str = logArrays.get(i);
+            if (info) {
+                Log.i(TAG , str.replace("\n","")+" "+logArrays.size()+" "+i);
+            } else {
+                Log.e(TAG , str.replace("\n","")+" "+logArrays.size()+" "+i);
             }
         }
     }
@@ -102,16 +94,12 @@
                 s = s.substring(0,totalLength*3)+"...";
             }
             s = s.replace("\t","    ");//缩进替换空格
-            if(s.indexOf("\":{\"")>-1 || s.indexOf("\":[{\"")>-1 || s.indexOf("\":[[")>-1){//内容非校正缩进,且为json字符规范
-                splitStr(s.substring(0,s.indexOf("\":")+2)+ GsonUtils.retractJson(s.substring(s.indexOf("\":")+2)),totalLength,list);
+            if(s.length()> totalLength){
+                outOflength(s,totalLength,list);
             }else {
-                if(s.length()> totalLength){
-                    outOflength(s,totalLength,list);
-                }else {
-                    logStr = "┃      " + s + getEmptyStr((totalLength - 16 - s.length()), " ");
-                    //处理中文间距,保证打印无偏差
-                    list.add(logStr + getEmptyStr((totalLength - logStr.length() - 1 - hasCNchar(logStr)), " ") + "┃ "/*+logStr.length()+" "+logStr.getBytes().length+" "+(" ").getBytes().length +" "+hasCNchar(s)*/ + "\n");
-                }
+                logStr = "┃      " + s + getEmptyStr((totalLength - 16 - s.length()), " ");
+                //处理中文间距,保证打印无偏差
+                list.add(logStr + getEmptyStr((totalLength - logStr.length() - 1 - hasCNchar(logStr)), " ") + "┃ "/*+logStr.length()+" "+logStr.getBytes().length+" "+(" ").getBytes().length +" "+hasCNchar(s)*/ + "\n");
             }
         }
     }
@@ -182,29 +170,6 @@
             sb.append(space);
         }
         return sb.toString();
-    }
-    /**
-     * Returns true if the body in question probably contains human readable text. Uses a small sample
-     * of code points to detect unicode control characters commonly used in binary file signatures.
-     */
-    static boolean isPlaintext(Buffer buffer) {
-        try {
-            Buffer prefix = new Buffer();
-            long byteCount = buffer.size() < 64 ? buffer.size() : 64;
-            buffer.copyTo(prefix, 0, byteCount);
-            for (int i = 0; i < 16; i++) {
-                if (prefix.exhausted()) {
-                    break;
-                }
-                int codePoint = prefix.readUtf8CodePoint();
-                if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
-                    return false;
-                }
-            }
-            return true;
-        } catch (EOFException e) {
-            return false; // Truncated UTF-8 sequence.
-        }
     }
 
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/retrofit/utils/RetrofitUtils.java b/app/src/main/java/com/runt/open/mvvm/retrofit/utils/RetrofitUtils.java
index df2ae38..134853b 100644
--- a/app/src/main/java/com/runt/open/mvvm/retrofit/utils/RetrofitUtils.java
+++ b/app/src/main/java/com/runt/open/mvvm/retrofit/utils/RetrofitUtils.java
@@ -23,7 +23,6 @@
  */
 
 public class RetrofitUtils {
-    public static String HOST_IP_ADDR;
     static RetrofitUtils instance;
     Retrofit retrofit/*log输出,驼峰转换*/,unHumpRetrofit/*log输出,不强制驼峰转换*/,
             unLogRetrofit/*log不输出,驼峰转换*/,unLogHumpRetorfit/*log不输出,不强制驼峰转换*/;
@@ -108,7 +107,7 @@
                 //设置OKHttpClient
                 .client(client)
                 //设置baseUrl,注意,baseUrl必须后缀"/"
-                .baseUrl(BuildConfig.ENVIRONMENT.equals("develop")?HOST_IP_ADDR:BuildConfig.HOST_IP_ADDR)
+                .baseUrl(BuildConfig.HOST_IP_ADDR+"api/v1/")
                 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                 .build();
     }
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/login/LoginViewModel.java b/app/src/main/java/com/runt/open/mvvm/ui/login/LoginViewModel.java
index eda4bd3..b83f332 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/login/LoginViewModel.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/login/LoginViewModel.java
@@ -29,7 +29,12 @@
     MutableLiveData<Results.StringApiResult> verifyResult = new MutableLiveData<>();
     MutableLiveData<Results.StringApiResult> resetResult = new MutableLiveData<>();
     MutableLiveData<Results.StringApiResult> registerResult = new MutableLiveData<>();
-
+    HttpObserver<Results.LoggedInUser> logginObserver = new HttpObserver<Results.LoggedInUser>(){
+        @Override
+        protected void onSuccess(Results.LoggedInUser data) {
+            loginResult.setValue(data);
+        }
+    };
     public MutableLiveData<Results.LoggedInUser> getLoginResult() {
         return loginResult;
     }
@@ -46,7 +51,7 @@
     public void login(String username, String password) {
         // can be launched in a separate asynchronous job
         final Observable<Results.LoggedInUser> userObservable = loginApi.login(username, password);
-        httpObserverOnLoading(userObservable,new HttpObserver<Results.LoggedInUser>(loginResult){});
+        httpObserverOnLoading(userObservable,logginObserver);
     }
 
     /**
@@ -55,8 +60,7 @@
      * @param code
      */
     public void loginByCode(String phone,String code){
-        httpObserverOnLoading(loginApi.loginByCode(phone,code),
-                new HttpObserver<Results.LoggedInUser>(loginResult){});
+        httpObserverOnLoading(loginApi.loginByCode(phone,code),logginObserver);
     }
 
     /**
@@ -66,7 +70,7 @@
      * @param pass
      */
     public void resetPwd(String phone,String sms,String pass){
-        httpObserverOnLoading(loginApi.resetLoginPwd(phone, sms, pass), new HttpObserver<Results.StringApiResult>(resetResult) {});
+        httpObserverOnLoading(loginApi.resetLoginPwd(phone, sms, pass),logginObserver);
     }
 
     /**
@@ -76,7 +80,12 @@
      * @param pass
      */
     public void register(String phone,String sms,String pass){
-        httpObserverOnLoading(loginApi.register(phone, sms, pass), new HttpObserver<Results.StringApiResult>(resetResult) {});
+        httpObserverOnLoading(loginApi.register(phone, sms, pass), new HttpObserver<Results.StringApiResult>(){
+            @Override
+            protected void onSuccess(Results.StringApiResult data) {
+                resetResult.setValue(data);
+            }
+        });
     }
 
     /**
@@ -110,7 +119,12 @@
      */
     public void getVerifyCode(String url,String phone){
         String time = new Date().getTime()+"";
-        httpObserverOnLoading(loginApi.getVerifyCode(url, phone, randomString(phone, time), time), new HttpObserver<Results.StringApiResult>(verifyResult){});
+        httpObserverOnLoading(loginApi.getVerifyCode(url, phone, randomString(phone, time), time), new HttpObserver<Results.StringApiResult>(){
+            @Override
+            protected void onSuccess(Results.StringApiResult data) {
+                verifyResult.setValue(data);
+            }
+        });
     }
 
     /**
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java b/app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java
index ab84fd8..224b886 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java
@@ -29,30 +29,23 @@
 
     @Override
     public void initViews() {
-        binding.txtGetVerify.setOnClickListener(onclick);
-        binding.txtForgot.setOnClickListener(onclick);
-        binding.txtLogin.setOnClickListener(onclick);
-        binding.txtRegister.setOnClickListener(onclick);
-        binding.txtPrivacy.setOnClickListener(onclick);
-        long getTime = getLongProjectPrefrence(VERIFY_CODE);
-        long cha = new Date().getTime() - getTime;
-        if(cha <1000*60){
-            CodeTimer codeTimer = new CodeTimer(cha, 1000, binding.txtGetVerify);
-            codeTimer.startUp();
-        }
-        changeView();
-        binding.editPhone.setText(getStringProjectPrefrence(Configuration.KEY_USERNAME));
-        viewModel.getVerifyResult().observe(this, stringApiResult -> {
+        mBinding.txtGetVerify.setOnClickListener(onclick);
+        mBinding.txtForgot.setOnClickListener(onclick);
+        mBinding.txtLogin.setOnClickListener(onclick);
+        mBinding.txtRegister.setOnClickListener(onclick);
+        mBinding.txtPrivacy.setOnClickListener(onclick);
+        mBinding.editPhone.setText(getStringProjectPrefrence(Configuration.KEY_USERNAME));
+        mViewModel.getVerifyResult().observe(this, stringApiResult -> {
            if(stringApiResult.code == 200){
 
            }else{
                showToast(stringApiResult.msg);
            }
         });
-        viewModel.getLoginResult().observe(this,loggedInUser -> {
+        mViewModel.getLoginResult().observe(this, loggedInUser -> {
             if(loggedInUser.code == 200){
                 putBooleanProjectPrefrence(Configuration.IS_LOGIN,true);
-                putStringProjectPrefrence(Configuration.KEY_USERNAME,binding.editPhone.getText().toString());
+                putStringProjectPrefrence(Configuration.KEY_USERNAME, mBinding.editPhone.getText().toString());
 
                 UserBean user = new Gson().fromJson(new Gson().toJson(loggedInUser.data) ,UserBean.class);
                 UserBean.setUser(user);
@@ -67,6 +60,17 @@
         });
     }
 
+    @Override
+    public void loadData() {
+        long getTime = getLongProjectPrefrence(VERIFY_CODE);
+        long cha = new Date().getTime() - getTime;
+        if(cha <1000*60){
+            CodeTimer codeTimer = new CodeTimer(cha, 1000, mBinding.txtGetVerify);
+            codeTimer.startUp();
+        }
+        changeView();
+    }
+
     CustomClickListener onclick = new CustomClickListener() {
         @Override
         protected void onSingleClick(View view) {
@@ -76,16 +80,16 @@
                     break;
                 case R.id.txt_get_verify:
 
-                    String phone = binding.editPhone.getText().toString();
+                    String phone = mBinding.editPhone.getText().toString();
                     if(!verifyPhone(phone)){//验证手机
                         return;
                     }
                     if(type==2){//获取注册验证码
-                        viewModel.getRegisterSMS(phone);
+                        mViewModel.getRegisterSMS(phone);
                     }else if(type ==1){
-                        viewModel.getForgetSMS( phone);
+                        mViewModel.getForgetSMS( phone);
                     }else if(type == -1){
-                        viewModel.getLoginSMS( phone);
+                        mViewModel.getLoginSMS( phone);
                     }
                     break;
                 case R.id.txt_privacy:
@@ -116,53 +120,53 @@
      * 修改页面布局
      */
     private void changeView(){
-        binding.button.setEnabled(true);
-        binding.txtRegister.setVisibility(View.VISIBLE);
-        binding.checkbox.setVisibility(View.GONE);
-        binding.txtPrivacy.setVisibility(View.GONE);
+        mBinding.button.setEnabled(true);
+        mBinding.txtRegister.setVisibility(View.VISIBLE);
+        mBinding.checkbox.setVisibility(View.GONE);
+        mBinding.txtPrivacy.setVisibility(View.GONE);
         switch (type){
             case -1://短信登录
-                binding.editVerifyCode.setVisibility(View.VISIBLE);
-                binding.txtGetVerify.setVisibility(View.VISIBLE);
-                binding.editPass.setVisibility(View.GONE);
-                binding.editPassRepeat.setVisibility(View.GONE);
-                binding.txtForgot.setVisibility(View.VISIBLE);
-                binding.txtLogin.setText(getResources().getString(R.string.login));
-                binding.button.setText(getResources().getString(R.string.login));
-                binding.checkbox.setVisibility(View.VISIBLE);
-                binding.txtPrivacy.setVisibility(View.VISIBLE);
+                mBinding.editVerifyCode.setVisibility(View.VISIBLE);
+                mBinding.txtGetVerify.setVisibility(View.VISIBLE);
+                mBinding.editPass.setVisibility(View.GONE);
+                mBinding.editPassRepeat.setVisibility(View.GONE);
+                mBinding.txtForgot.setVisibility(View.VISIBLE);
+                mBinding.txtLogin.setText(getResources().getString(R.string.login));
+                mBinding.button.setText(getResources().getString(R.string.login));
+                mBinding.checkbox.setVisibility(View.VISIBLE);
+                mBinding.txtPrivacy.setVisibility(View.VISIBLE);
                 break;
             case 0://登录
-                binding.editVerifyCode.setVisibility(View.GONE);
-                binding.txtGetVerify.setVisibility(View.GONE);
-                binding.editPass.setVisibility(View.VISIBLE);
-                binding.editPassRepeat.setVisibility(View.GONE);
-                binding.txtForgot.setVisibility(View.VISIBLE);
-                binding.txtLogin.setText(getResources().getString(R.string.msg_login));
-                binding.button.setText(getResources().getString(R.string.login));
+                mBinding.editVerifyCode.setVisibility(View.GONE);
+                mBinding.txtGetVerify.setVisibility(View.GONE);
+                mBinding.editPass.setVisibility(View.VISIBLE);
+                mBinding.editPassRepeat.setVisibility(View.GONE);
+                mBinding.txtForgot.setVisibility(View.VISIBLE);
+                mBinding.txtLogin.setText(getResources().getString(R.string.msg_login));
+                mBinding.button.setText(getResources().getString(R.string.login));
                 break;
             case 1://忘记密码
-                binding.txtForgot.setVisibility(View.INVISIBLE);
-                binding.editVerifyCode.setVisibility(View.VISIBLE);
-                binding.txtGetVerify.setVisibility(View.VISIBLE);
-                binding.editPass.setVisibility(View.VISIBLE);
-                binding.editPassRepeat.setVisibility(View.VISIBLE);
-                binding.txtLogin.setText(getResources().getString(R.string.login));
-                binding.button.setText(getResources().getString(R.string.str_confirm));
+                mBinding.txtForgot.setVisibility(View.INVISIBLE);
+                mBinding.editVerifyCode.setVisibility(View.VISIBLE);
+                mBinding.txtGetVerify.setVisibility(View.VISIBLE);
+                mBinding.editPass.setVisibility(View.VISIBLE);
+                mBinding.editPassRepeat.setVisibility(View.VISIBLE);
+                mBinding.txtLogin.setText(getResources().getString(R.string.login));
+                mBinding.button.setText(getResources().getString(R.string.str_confirm));
                 break;
             case 2://注册
-                binding.checkbox.setVisibility(View.VISIBLE);
-                binding.txtPrivacy.setVisibility(View.VISIBLE);
-                binding.txtRegister.setVisibility(View.INVISIBLE);
-                binding.editVerifyCode.setVisibility(View.VISIBLE);
-                binding.txtGetVerify.setVisibility(View.VISIBLE);
-                binding.editPass.setVisibility(View.VISIBLE);
-                binding.editPassRepeat.setVisibility(View.VISIBLE);
-                binding.txtLogin.setText(getResources().getString(R.string.login));
-                binding.button.setText(getResources().getString(R.string.register));
+                mBinding.checkbox.setVisibility(View.VISIBLE);
+                mBinding.txtPrivacy.setVisibility(View.VISIBLE);
+                mBinding.txtRegister.setVisibility(View.INVISIBLE);
+                mBinding.editVerifyCode.setVisibility(View.VISIBLE);
+                mBinding.txtGetVerify.setVisibility(View.VISIBLE);
+                mBinding.editPass.setVisibility(View.VISIBLE);
+                mBinding.editPassRepeat.setVisibility(View.VISIBLE);
+                mBinding.txtLogin.setText(getResources().getString(R.string.login));
+                mBinding.button.setText(getResources().getString(R.string.register));
                 break;
         }
-        clearText(binding.editPassRepeat,binding.editPass,binding.editPhone,binding.editVerifyCode);
+        clearText(mBinding.editPassRepeat, mBinding.editPass, mBinding.editPhone, mBinding.editVerifyCode);
     }
 
     private void clearText(EditText... editTextes){
@@ -178,10 +182,10 @@
      * 提交数据
      */
     public void submit(){
-        String phone = binding.editPhone.getText().toString();
-        String pass = binding.editPass .getText().toString();
-        String veriCode = binding.editVerifyCode.getText().toString();
-        String invite = binding.editPassRepeat.getText().toString();
+        String phone = mBinding.editPhone.getText().toString();
+        String pass = mBinding.editPass .getText().toString();
+        String veriCode = mBinding.editVerifyCode.getText().toString();
+        String invite = mBinding.editPassRepeat.getText().toString();
         if(!verifyPhone(phone)){//验证手机
             return;
         }
@@ -191,17 +195,17 @@
                     showToast(R.string.input_verify_code);
                     return;
                 }
-                if(!binding.checkbox.isChecked()){
+                if(!mBinding.checkbox.isChecked()){
                     showToast("请阅读并勾选《隐私条款》");
                     return;
                 }
-                viewModel.loginByCode(phone,veriCode);
+                mViewModel.loginByCode(phone,veriCode);
                 break;
             case 0:
                 if(!verifyPassWord(pass)){//验证密码
                     return;
                 }
-                viewModel.login(phone,pass);
+                mViewModel.login(phone,pass);
                 break;
             case 1:
                 if(!verifyPassWord(pass)){//验证密码
@@ -220,7 +224,7 @@
                     showToast(R.string.str_new_verify_failed);
                     return;
                 }
-                viewModel.resetPwd(phone,veriCode,pass);
+                mViewModel.resetPwd(phone,veriCode,pass);
                 break;
             case 2://注册
                 if(!verifyPassWord(pass)){//验证密码
@@ -230,11 +234,11 @@
                     showToast(R.string.input_verify_code);
                     return;
                 }
-                if(!binding.checkbox.isChecked()){
+                if(!mBinding.checkbox.isChecked()){
                     showToast("请阅读并勾选《隐私条款》");
                     return;
                 }
-                viewModel.register(phone,veriCode,pass);
+                mViewModel.register(phone,veriCode,pass);
                 break;
         }
     }
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/MainActivity.java b/app/src/main/java/com/runt/open/mvvm/ui/main/MainActivity.java
new file mode 100644
index 0000000..090cfa4
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/MainActivity.java
@@ -0,0 +1,153 @@
+package com.runt.open.mvvm.ui.main;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.view.KeyEvent;
+import android.view.View;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.viewpager2.widget.ViewPager2;
+
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+import com.permissionx.guolindev.PermissionX;
+import com.runt.open.mvvm.R;
+import com.runt.open.mvvm.base.activities.BaseActivity;
+import com.runt.open.mvvm.base.adapter.FragmentAdapter;
+import com.runt.open.mvvm.base.fragments.BaseFragment;
+import com.runt.open.mvvm.data.PhoneDevice;
+import com.runt.open.mvvm.databinding.ActivityMainBinding;
+import com.runt.open.mvvm.listener.CustomClickListener;
+import com.runt.open.mvvm.listener.ResPonse;
+import com.runt.open.mvvm.ui.login.RegisterLoginActivity;
+import com.runt.open.mvvm.ui.login.UserBean;
+import com.runt.open.mvvm.ui.main.home.HomeFragment;
+import com.runt.open.mvvm.ui.main.mine.MineFragment;
+import com.runt.open.mvvm.ui.main.service.ServiceFragment;
+
+import java.util.Arrays;
+
+public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {
+
+    private BaseFragment[] fragments = {new HomeFragment(),new ServiceFragment(),new MineFragment()} ;
+    ActivityResultLauncher<Intent>  loginLaunch = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+        if(result.getResultCode() == RESULT_CODE_SUCESS){
+            fragments[2].loadData();//登录后重新刷新
+        }else if(result.getResultCode() != RESULT_CODE_SUCESS){
+            mBinding.viewPager2.setCurrentItem(0);
+        }
+    });
+
+    @Override
+    public void initViews() {
+
+        mBinding.titleBar.setRightDra(getResources().getDrawable(R.mipmap.icon_white_setting));
+        mBinding.titleBar.setRightClick(new CustomClickListener() {
+            @Override
+            protected void onSingleClick(View view) {
+                //startActivityForResult(new Intent(mContext,SettingActivity.class),REQUEST_CODE_LOGOUT);//打开设置
+            }
+        });
+        final FragmentAdapter fragmentAdapter = new FragmentAdapter(this);
+        fragmentAdapter.setFragments(Arrays.asList(fragments));
+        //设置当前可见Item左右可见page数,次范围内不会被销毁
+        //禁用预加载
+        mBinding.viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
+        mBinding.viewPager2.setAdapter(fragmentAdapter);
+        mBinding.viewPager2.setCurrentItem(0);
+        mBinding.viewPager2.setUserInputEnabled(false); //true:滑动,false:禁止滑动
+        mBinding.viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
+
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+                setTitleStr(position);
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+                mBinding.navView.getMenu().getItem(position).setChecked(true);
+                if(position == 2 && UserBean.getUser() == null){
+                    loginLaunch.launch(new Intent(mContext, RegisterLoginActivity.class));
+                }
+            }
+        });
+        ColorStateList csl = getResources().getColorStateList(R.color.home_nav_color);
+        mBinding.navView.setItemTextColor(csl);//设置文本颜色
+        mBinding.navView.setItemIconTintList(csl);//图标着色
+        mBinding.navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);//监听
+
+    }
+
+    @Override
+    public void loadData() {
+        checkPermission();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
+            backExit();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    /**
+     * 底部导航监听
+     */
+    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = item -> {
+        for(int i = 0 ; i < mBinding.navView.getMenu().size() ; i ++){
+            if(item.getItemId() == mBinding.navView.getMenu().getItem(i).getItemId()){
+                mBinding.viewPager2.setCurrentItem(i);
+                return true;
+            }
+        }
+        return false;
+    };
+
+    /**
+     * 设置标题
+     * @param position
+     */
+    private void setTitleStr(int position){
+        switch (position){
+            case 0:
+                setTitle("资讯");
+                break;
+            case 1:
+                setTitle("服务");
+                break;
+            case 2:
+                setTitle("个人中心");
+                break;
+        }
+    }
+    private void showPermissionDialog(){
+
+        showDialog("警告", "软件需要权限才能运行", "申请权限", "退出", new ResPonse() {
+            @Override
+            public void doSuccess(Object obj) {
+                checkPermission();
+            }
+
+            @Override
+            public void doError(Object obj) {
+                finish();
+                System.exit(0);
+            }
+        });
+    }
+    private void checkPermission(){
+        PermissionX.init(MainActivity.this)
+                .permissions(Manifest.permission.READ_PHONE_STATE)
+                .request((allGranted, grantedList, deniedList) -> {
+                    if(allGranted){
+                        PhoneDevice.setDevice(mContext);
+                    }else{
+                        showPermissionDialog();
+                    }
+
+                });
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/dashboard/DashboardFragment.java b/app/src/main/java/com/runt/open/mvvm/ui/main/dashboard/DashboardFragment.java
deleted file mode 100644
index 5f93e54..0000000
--- a/app/src/main/java/com/runt/open/mvvm/ui/main/dashboard/DashboardFragment.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.runt.open.mvvm.ui.main.dashboard;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.Observer;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.runt.open.mvvm.databinding.FragmentDashboardBinding;
-
-public class DashboardFragment extends Fragment {
-
-    private DashboardViewModel dashboardViewModel;
-    private FragmentDashboardBinding binding;
-
-    public View onCreateView(@NonNull LayoutInflater inflater,
-                             ViewGroup container, Bundle savedInstanceState) {
-        dashboardViewModel =
-                new ViewModelProvider(this).get(DashboardViewModel.class);
-
-        binding = FragmentDashboardBinding.inflate(inflater, container, false);
-        View root = binding.getRoot();
-
-        final TextView textView = binding.textDashboard;
-        dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
-            @Override
-            public void onChanged(@Nullable String s) {
-                textView.setText(s);
-            }
-        });
-        return root;
-    }
-
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-        binding = null;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/dashboard/DashboardViewModel.java b/app/src/main/java/com/runt/open/mvvm/ui/main/dashboard/DashboardViewModel.java
deleted file mode 100644
index b2d3f43..0000000
--- a/app/src/main/java/com/runt/open/mvvm/ui/main/dashboard/DashboardViewModel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.runt.open.mvvm.ui.main.dashboard;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
-
-public class DashboardViewModel extends ViewModel {
-
-    private MutableLiveData<String> mText;
-
-    public DashboardViewModel() {
-        mText = new MutableLiveData<>();
-        mText.setValue("This is dashboard fragment");
-    }
-
-    public LiveData<String> getText() {
-        return mText;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeFragment.java b/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeFragment.java
index 2a93b5b..7e944e6 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeFragment.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeFragment.java
@@ -1,33 +1,17 @@
 package com.runt.open.mvvm.ui.main.home;
 
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
+import com.runt.open.mvvm.base.fragments.LoadPageFragment;
+import com.runt.open.mvvm.databinding.RefreshRecyclerBinding;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.Observer;
-import androidx.lifecycle.ViewModelProvider;
+import java.util.HashMap;
+import java.util.Map;
 
-import com.runt.open.mvvm.base.fragments.BaseFragment;
-import com.runt.open.mvvm.databinding.FragmentHomeBinding;
-
-public class HomeFragment extends BaseFragment<FragmentHomeBinding,HomeViewModel> {
-
+public class HomeFragment extends LoadPageFragment<RefreshRecyclerBinding,HomeViewModel,MsgAdapter,Message> {
 
 
     @Override
-    public void initViews() {
-        final TextView textView = binding.textHome;
-        viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
-            @Override
-            public void onChanged(@Nullable String s) {
-                textView.setText(s);
-            }
-        });
+    protected Map requestParams() {
+        return new HashMap();
     }
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeViewModel.java b/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeViewModel.java
index 34dbdc4..1d83123 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeViewModel.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/home/HomeViewModel.java
@@ -1,19 +1,12 @@
 package com.runt.open.mvvm.ui.main.home;
 
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
+import com.runt.open.mvvm.base.model.LoadPageViewModel;
+import com.runt.open.mvvm.data.Results;
 
-public class HomeViewModel extends ViewModel {
+public class HomeViewModel extends LoadPageViewModel<Results.MessageResult> {
 
-    private MutableLiveData<String> mText;
-
-    public HomeViewModel() {
-        mText = new MutableLiveData<>();
-        mText.setValue("This is home fragment");
-    }
-
-    public LiveData<String> getText() {
-        return mText;
+    @Override
+    protected String requestUrl() {
+        return "getMsgList";
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/home/Message.java b/app/src/main/java/com/runt/open/mvvm/ui/main/home/Message.java
new file mode 100644
index 0000000..4aede0c
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/home/Message.java
@@ -0,0 +1,8 @@
+package com.runt.open.mvvm.ui.main.home;
+
+/**
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/7/27.
+ */
+public class Message {
+    public String content,cTime,title;
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/home/MsgAdapter.java b/app/src/main/java/com/runt/open/mvvm/ui/main/home/MsgAdapter.java
new file mode 100644
index 0000000..c13fc9e
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/home/MsgAdapter.java
@@ -0,0 +1,33 @@
+package com.runt.open.mvvm.ui.main.home;
+
+import android.view.View;
+
+import com.runt.open.mvvm.base.adapter.BaseAdapter;
+import com.runt.open.mvvm.databinding.ItemMsgBinding;
+import com.runt.open.mvvm.listener.CustomClickListener;
+import com.runt.open.mvvm.util.HandleDate;
+
+import java.util.Date;
+
+/**
+ * My father is Object, ites purpose of
+ *
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-8-21.
+ */
+
+public class MsgAdapter extends BaseAdapter<Message, ItemMsgBinding> {
+
+    @Override
+    protected void onBindView(ItemMsgBinding binding, int position, Message message) {
+        binding.txtDetail.setText(message.content);
+        Date date = new Date(message.cTime);
+        binding.txtTime.setText(HandleDate.getTimeStateNew(date));
+        binding.txtTitle.setText(message.title);
+        binding.getRoot().setOnClickListener(new CustomClickListener() {
+            @Override
+            protected void onSingleClick(View view) {
+                //context.startActivity(new Intent(context, MsgDetailActivity.class).putExtra("id", data.get("id").toString()));
+            }
+        });
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java b/app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java
new file mode 100644
index 0000000..d06e356
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java
@@ -0,0 +1,177 @@
+package com.runt.open.mvvm.ui.main.mine;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.view.View;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.RequestOptions;
+import com.permissionx.guolindev.PermissionX;
+import com.runt.open.mvvm.BuildConfig;
+import com.runt.open.mvvm.R;
+import com.runt.open.mvvm.base.fragments.BaseFragment;
+import com.runt.open.mvvm.databinding.FragmentMineBinding;
+import com.runt.open.mvvm.listener.ResPonse;
+import com.runt.open.mvvm.retrofit.observable.HttpObserver;
+import com.runt.open.mvvm.ui.login.UserBean;
+import com.runt.open.mvvm.util.MyLog;
+import com.wildma.pictureselector.PictureSelector;
+
+import java.io.File;
+
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * My father is Object, ites purpose of
+ *
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-9-15.
+ */
+
+public class MineFragment extends BaseFragment<FragmentMineBinding,MineViewModel> implements View.OnClickListener {
+
+    private final  String TAG = "MineFragment";
+
+    @Override
+    public void initViews() {
+    }
+
+    @Override
+    public void loadData() {
+        if(UserBean.getUser() != null){
+            RequestOptions options = new RequestOptions()
+                    .placeholder(R.mipmap.default_head)//图片加载出来前,显示的图片
+                    .fallback(R.mipmap.default_head) //url为空的时候,显示的图片
+                    .error(R.mipmap.default_head);//图片加载失败后,显示的图片
+            Glide.with(getContext()).load(BuildConfig.HOST_IP_ADDR +UserBean.getUser().getHead()).apply(options).into(mBinding.img);
+            mBinding.txtName.setText(UserBean.getUser().getUsername());
+            mBinding.txtCoin.setText(UserBean.getUser().getCoin()+"");
+            mBinding.txtSigns.setText(UserBean.getUser().getSign()+"");
+            mBinding.linGroup.setVisibility(View.VISIBLE);
+        }else{
+            Glide.with(getContext()).load(R.mipmap.default_head).into(mBinding.img);
+            mBinding.txtName.setText("未登录");
+            mBinding.linGroup.setVisibility(View.GONE);
+        }
+        setOnClickListener(this,R.id.lin_sign,R.id.lin_coin,R.id.img,R.id.txt_name);
+    }
+
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()){
+            case R.id.img:
+                openAlthum();
+                break;
+            case R.id.txt_name://名称
+                mViewModel.updateName(new HttpObserver() {
+                    @Override
+                    protected void onSuccess(Object data) {
+                        UserBean.getUser().setUsername(data.toString());
+                        mBinding.txtName.setText(data.toString());
+
+                    }
+                });
+                break;
+           /* case R.id.lin_coin://金币
+                new BottomMenuFragment(getActivity())
+                        .addMenuItems(new MenuItem("查看记录"))
+                        .addMenuItems(new MenuItem("申请提现"))
+                        .setOnItemClickListener(new BottomMenuFragment.OnItemClickListener() {
+                            @Override
+                            public void onItemClick(TextView menu_item, int position) {
+                                if(position == 0){
+                                    startActivity(new Intent(mActivity, CoinRecordActivity.class) );
+                                }else {
+                                    if(mActivity.isNull(UserBean.getUser().getAlipay())){
+                                        mActivity.showDialog("设置支付宝", "您还没有设置支付宝账号", "设置", "取消", new ResPonse() {
+                                            @Override
+                                            public void doSuccess(Object obj) {
+                                                startActivity(new Intent(mActivity, CoinSettingActivity.class) );
+                                            }
+                                        });
+                                    }else if(mActivity.isNull(UserBean.getUser().getRealname())){
+                                        mActivity.showDialog("设置真实姓名", "您还没有设置真实姓名", "设置", "取消", new ResPonse() {
+                                            @Override
+                                            public void doSuccess(Object obj) {
+                                                startActivity(new Intent(mActivity, CoinSettingActivity.class) );
+                                            }
+                                        });
+                                    }else{
+                                        startActivityForResult(new Intent(mActivity, WithDrawActivity.class),REQUEST_CODE_WITHDRAW );
+                                    }
+                                }
+                            }
+                        })
+                        .show();
+                break;
+            case R.id.lin_sign://签到
+                startActivityForResult(new Intent(getContext(), SignInActivity.class),REQUEST_CODE_SIGN);
+                break;*/
+        }
+    }
+
+
+    /**
+     * 打开相册
+     */
+    public void openAlthum(){
+        PermissionX.init(this)
+                .permissions(mActivity.CAMERA_PERMISSIONS)
+                .request((allGranted, grantedList, deniedList) -> {
+                    if(allGranted){
+                        PictureSelector
+                                .create(this, PictureSelector.SELECT_REQUEST_CODE)
+                                .selectPicture(true, 300, 300, 20, 20);
+                    }else{
+                        mActivity.showDialog("警告", "软件需要权限才能运行", "申请权限", "取消", new ResPonse() {
+                            @Override
+                            public void doSuccess(Object obj) {
+                                openAlthum();
+                            }
+
+                            @Override
+                            public void doError(Object obj) {
+                            }
+                        });
+                    }
+
+                });
+    }
+
+
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        /*结果回调*/
+        if (requestCode == PictureSelector.SELECT_REQUEST_CODE) {
+            if (data != null) {
+                String picturePath = data.getStringExtra(PictureSelector.PICTURE_PATH);
+                MyLog.i("mineActivity","picturePath:"+picturePath);
+                final  File file = new File(picturePath);
+                mViewModel.updateHead(file).enqueue(new Callback<ResponseBody>() {
+                    @Override
+                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
+                        /*UserBean.getUser().setHead(obj.toString());
+                        file.delete();
+                        Glide.with(getContext()).load(BuildConfig.HOST_IP_ADDR+UserBean.getUser().getHead()) .into(mBinding.img); //获取选取的图片*/
+
+                    }
+
+                    @Override
+                    public void onFailure(Call<ResponseBody> call, Throwable t) {
+                        file.delete();
+                    }
+                });
+            }
+        }else if(requestCode == REQUEST_CODE_SIGN && resultCode == Activity.RESULT_OK){
+            loadData();
+        }else if(requestCode == REQUEST_CODE_WITHDRAW && resultCode == Activity.RESULT_OK){
+            loadData();
+        }
+    }
+
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineViewModel.java b/app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineViewModel.java
new file mode 100644
index 0000000..0dfb04b
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineViewModel.java
@@ -0,0 +1,36 @@
+package com.runt.open.mvvm.ui.main.mine;
+
+import com.runt.open.mvvm.base.model.BaseViewModel;
+import com.runt.open.mvvm.listener.ResPonse;
+import com.runt.open.mvvm.retrofit.observable.HttpObserver;
+import com.runt.open.mvvm.ui.login.UserBean;
+
+import java.io.File;
+
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.RequestBody;
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+
+/**
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/7/27.
+ */
+public class MineViewModel extends BaseViewModel {
+
+    public void updateName(HttpObserver observer){
+        if(UserBean.getUser().getPhone().equals(UserBean.getUser().getUsername())) {
+            mActivity.showInputDialog("输入名称", UserBean.getUser().getUsername(), "名称只能修改一次", new ResPonse() {
+                @Override
+                public void doSuccess(Object obj) {
+                    httpObserverOnLoading(commonApi.updateName(obj.toString()), observer);
+                }
+            });
+        }
+    }
+
+    public Call<ResponseBody> updateHead(File file){
+        return commonApi.updateHead(MultipartBody.Part.createFormData("head",file.getName(), RequestBody.create(MediaType.parse("text/plain"), file)));
+    }
+
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/notifications/NotificationsFragment.java b/app/src/main/java/com/runt/open/mvvm/ui/main/notifications/NotificationsFragment.java
deleted file mode 100644
index 29970e8..0000000
--- a/app/src/main/java/com/runt/open/mvvm/ui/main/notifications/NotificationsFragment.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.runt.open.mvvm.ui.main.notifications;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.Observer;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.runt.open.mvvm.databinding.FragmentNotificationsBinding;
-
-public class NotificationsFragment extends Fragment {
-
-    private NotificationsViewModel notificationsViewModel;
-    private FragmentNotificationsBinding binding;
-
-    public View onCreateView(@NonNull LayoutInflater inflater,
-                             ViewGroup container, Bundle savedInstanceState) {
-        notificationsViewModel =
-                new ViewModelProvider(this).get(NotificationsViewModel.class);
-
-        binding = FragmentNotificationsBinding.inflate(inflater, container, false);
-        View root = binding.getRoot();
-
-        final TextView textView = binding.textNotifications;
-        notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
-            @Override
-            public void onChanged(@Nullable String s) {
-                textView.setText(s);
-            }
-        });
-        return root;
-    }
-
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-        binding = null;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/notifications/NotificationsViewModel.java b/app/src/main/java/com/runt/open/mvvm/ui/main/notifications/NotificationsViewModel.java
deleted file mode 100644
index 7e47f94..0000000
--- a/app/src/main/java/com/runt/open/mvvm/ui/main/notifications/NotificationsViewModel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.runt.open.mvvm.ui.main.notifications;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
-
-public class NotificationsViewModel extends ViewModel {
-
-    private MutableLiveData<String> mText;
-
-    public NotificationsViewModel() {
-        mText = new MutableLiveData<>();
-        mText.setValue("This is notifications fragment");
-    }
-
-    public LiveData<String> getText() {
-        return mText;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/main/service/ServiceFragment.java b/app/src/main/java/com/runt/open/mvvm/ui/main/service/ServiceFragment.java
new file mode 100644
index 0000000..13e0191
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/ui/main/service/ServiceFragment.java
@@ -0,0 +1,63 @@
+package com.runt.open.mvvm.ui.main.service;
+
+import android.view.View;
+
+import com.runt.open.mvvm.R;
+import com.runt.open.mvvm.base.activities.BaseActivity;
+import com.runt.open.mvvm.base.fragments.BaseFragment;
+import com.runt.open.mvvm.base.model.ImpViewModel;
+import com.runt.open.mvvm.databinding.FragmentServiceBinding;
+import com.runt.open.mvvm.listener.ResPonse;
+
+/**
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/7/27.
+ */
+public class ServiceFragment extends BaseFragment<FragmentServiceBinding, ImpViewModel> implements View.OnClickListener {
+
+    @Override
+    public void initViews() {
+
+    }
+
+    @Override
+    public void loadData() {
+
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()){
+            case R.id.lin_uav:
+                mActivity.showDialog("联系服务商", "即将拨打服务商电话", "拨打","取消",new ResPonse() {
+                    @Override
+                    public void doSuccess(Object obj) {
+                        mActivity.callPhone("15048325741");
+                    }
+                });
+                break;
+            case R.id.lin_bozhong:
+                showDialog();
+                break;
+            case R.id.lin_yumi:
+                showDialog();
+                break;
+            case R.id.lin_xiaomai:
+                showDialog();
+                break;
+        }
+    }
+
+    public void showDialog(){
+        ((BaseActivity)getActivity()).showDialog("暂无服务商", "如果您是相关服务商可致电入住", "入住","取消",new ResPonse() {
+            @Override
+            public void doSuccess(Object obj) {
+                mActivity.showDialog("联系平台", "即将拨打平台电话", "拨打","取消",new ResPonse() {
+                    @Override
+                    public void doSuccess(Object obj) {
+                        mActivity.callPhone("13000000000");
+                    }
+                });
+            }
+        });
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java b/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java
index 988e8b6..bb5fa8f 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java
@@ -2,18 +2,12 @@
 
 import android.content.Intent;
 import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.View;
 import android.view.WindowManager;
 
-import androidx.annotation.NonNull;
-import androidx.lifecycle.Observer;
-
-import com.bytedance.sdk.openadsdk.TTSplashAd;
-import com.runt.open.mvvm.MainActivity;
 import com.runt.open.mvvm.base.activities.BaseActivity;
+import com.runt.open.mvvm.base.model.ImpViewModel;
 import com.runt.open.mvvm.databinding.ActivitySplashBinding;
+import com.runt.open.mvvm.ui.main.MainActivity;
 
 
 /**
@@ -21,73 +15,26 @@
  *
  * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-4-16.
  */
-public class SplashActivity extends BaseActivity<ActivitySplashBinding,SplashViewModel> {
+public class SplashActivity extends BaseActivity<ActivitySplashBinding, ImpViewModel> {
 
     final String TAG = "WelcomeActivity";
-
-    Handler handler = new Handler(){
-        boolean started = false;
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            super.handleMessage(msg);
-            if(!started) {//确保该语句只执行一次
-                started = true;
-                Intent intent = new Intent(mContext, MainActivity.class);
-                startActivity(intent);
-                finish();
-            }
-        }
-    };
-
     @Override
     public void initViews() {
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                 WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
         hideBottomUIMenu();
-        viewModel.getSplashAd().observe(this, new Observer<TTSplashAd>() {
-            @Override
-            public void onChanged(TTSplashAd ttSplashAd) {
-                binding.splashAdContainer.addView(ttSplashAd.getSplashView());
-                //设置SplashView的交互监听器
-                ttSplashAd.setSplashInteractionListener(new TTSplashAd.AdInteractionListener() {
-                    @Override
-                    public void onAdClicked(View view, int type) {
-                        Log.d(TAG, "onAdClicked");
-                    }
-
-                    @Override
-                    public void onAdShow(View view, int type) {
-                        Log.d(TAG, "onAdShow");
-                    }
-
-                    @Override
-                    public void onAdSkip() {
-                        Log.d(TAG, "onAdSkip");
-                        handler.sendMessage(new Message());
-
-                    }
-
-                    @Override
-                    public void onAdTimeOver() {
-                        Log.d(TAG, "onAdTimeOver");
-                        handler.sendMessage(new Message());
-                    }
-                });
-            }
-        });
-        viewModel.getTimeOut().observe(this, new Observer<Integer>() {
-            @Override
-            public void onChanged(Integer integer) {
-                handler.sendMessage(new Message());
-            }
-        });
-        viewModel.applyTdAd(mContext);;//请求广告
     }
-
 
     @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        binding.splashAdContainer.removeAllViews();
+    public void loadData() {
+        new Handler().postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                Intent intent = new Intent(mContext, MainActivity.class);
+                startActivity(intent);
+                finish();
+            }
+        },2000);
     }
+
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashViewModel.java b/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashViewModel.java
index 61e73d0..5d1c2c7 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashViewModel.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/splash/SplashViewModel.java
@@ -1,15 +1,9 @@
 package com.runt.open.mvvm.ui.splash;
 
-import android.content.Context;
 import android.os.Handler;
-import android.util.Log;
 
 import androidx.lifecycle.MutableLiveData;
 
-import com.bytedance.sdk.openadsdk.AdSlot;
-import com.bytedance.sdk.openadsdk.TTAdNative;
-import com.bytedance.sdk.openadsdk.TTAdSdk;
-import com.bytedance.sdk.openadsdk.TTSplashAd;
 import com.runt.open.mvvm.base.model.BaseViewModel;
 
 import java.util.Date;
@@ -22,12 +16,8 @@
     final String TAG = "SplashViewModel";
     long cTime = new Date().getTime(),limitTime = 2000;
 
-    private MutableLiveData<TTSplashAd> splashAd = new MutableLiveData<>();
     private MutableLiveData<Integer> timeOut = new MutableLiveData<>();
 
-    public MutableLiveData<TTSplashAd> getSplashAd() {
-        return splashAd;
-    }
 
     public MutableLiveData<Integer> getTimeOut() {
         return timeOut;
@@ -42,46 +32,5 @@
         },limitTime);
     }
 
-    /**
-     * 请求广告
-     * @param context
-     */
-    public void applyTdAd(Context context){
-        countdown();
-        TTAdNative mTTAdNative = TTAdSdk.getAdManager().createAdNative(context);
-        AdSlot adSlot = new AdSlot.Builder()
-                .setCodeId("887382769")//广告id
-                .setSupportDeepLink(true)
-                .setImageAcceptedSize(1080,1920)
-                //模板广告需要设置期望个性化模板广告的大小,单位dp,代码位是否属于个性化模板广告,请在穿山甲平台查看
-                //.setExpressViewAcceptedSize(expressViewWidth, expressViewHeight)
-                .build();
-        mTTAdNative.loadSplashAd(adSlot,new TTAdNative.SplashAdListener() {
-            @Override
-            public void onError(int i, String s) {
-                Log.i(TAG,"code:"+i+" message:"+s);
-            }
-
-            @Override
-            public void onTimeout() {
-                Log.i(TAG,"超时");
-            }
-
-            @Override
-            public void onSplashAdLoad(TTSplashAd ttSplashAd) {
-                Log.d(TAG, "开屏广告请求成功");
-
-                long waitTime = limitTime - (new Date().getTime() - cTime);
-                if(waitTime > 0){//是否超过限定时间  没有超时则继续
-                    new Handler().postDelayed(new Runnable() {
-                        @Override
-                        public void run() {
-                            splashAd.setValue(ttSplashAd);
-                        }
-                    }, waitTime > 0 ? waitTime : 0);
-                }
-            }
-        });
-    }
 
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/ui/web/WebViewActivity.java b/app/src/main/java/com/runt/open/mvvm/ui/web/WebViewActivity.java
index d41521c..f27491f 100644
--- a/app/src/main/java/com/runt/open/mvvm/ui/web/WebViewActivity.java
+++ b/app/src/main/java/com/runt/open/mvvm/ui/web/WebViewActivity.java
@@ -33,59 +33,64 @@
         initCompent();
     }
 
+    @Override
+    public void loadData() {
+
+    }
+
 
     int count = 100;
     int index = 100;
     private void initCompent(){
-        binding.browser.getSettings().setJavaScriptEnabled(true);
-        binding.browser.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
+        mBinding.browser.getSettings().setJavaScriptEnabled(true);
+        mBinding.browser.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
         //跳转至拼接好的地址
         //mBaseHandler.sendMessage(msg);//http://192.168.5.156:8080/MyFinance/gd16/1.html
-        binding.browser.loadUrl(url);
-        binding.browser.setWebViewClient(new myWebViewClient());
-        binding.browser.setWebChromeClient(new WebChromeClient(){
+        mBinding.browser.loadUrl(url);
+        mBinding.browser.setWebViewClient(new myWebViewClient());
+        mBinding.browser.setWebChromeClient(new WebChromeClient(){
 
             @Override
             public void onProgressChanged(WebView view,final int newProgress) {
                 MyLog.i("onProgressChanged","--newProgress:--"+newProgress);
-                MyLog.i("onProgressChanged","--binding.viewProgressbar:--"+binding.viewProgressbar.getWidth());
+                MyLog.i("onProgressChanged","--binding.viewProgressbar:--"+ mBinding.viewProgressbar.getWidth());
                 final LayoutAnimationController.AnimationParameters animation= new LayoutAnimationController.AnimationParameters();   //得到一个LayoutAnimationController对象;
                 animation.index =index++ ;
                 animation.count = count++ ;
                 if (newProgress == 100) {
-                    MyAnimations.hideAnimaInSitu(binding.linProgressbar);
-                    MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),0,0,0,binding.viewProgressbar);
+                    MyAnimations.hideAnimaInSitu(mBinding.linProgressbar);
+                    MyAnimations.makeViewMove(mBinding.viewProgressbar.getTranslationX(),0,0,0, mBinding.viewProgressbar);
                     new Handler().postDelayed(new Runnable() {
                         @Override
                         public void run() {
-                            binding.linProgressbar.setVisibility(View.GONE);
+                            mBinding.linProgressbar.setVisibility(View.GONE);
                         }
                     },MyAnimations.ANIMA_TIME);
                 } else {
 
-                    if (View.VISIBLE != binding.linProgressbar.getVisibility()) {
-                        MyAnimations.showAnimaInSitu(binding.linProgressbar);
+                    if (View.VISIBLE != mBinding.linProgressbar.getVisibility()) {
+                        MyAnimations.showAnimaInSitu(mBinding.linProgressbar);
                         if(linProgressWidth==0){
-                            final ViewTreeObserver vto = binding.linProgressbar.getViewTreeObserver();
+                            final ViewTreeObserver vto = mBinding.linProgressbar.getViewTreeObserver();
                             vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                                 public boolean onPreDraw() {
-                                    linProgressWidth = binding.linProgressbar.getMeasuredWidth();
-                                    binding.viewProgressbar.setTranslationX(0-linProgressWidth);
-                                    binding.linProgressbar.getViewTreeObserver().removeOnPreDrawListener(this);
+                                    linProgressWidth = mBinding.linProgressbar.getMeasuredWidth();
+                                    mBinding.viewProgressbar.setTranslationX(0-linProgressWidth);
+                                    mBinding.linProgressbar.getViewTreeObserver().removeOnPreDrawListener(this);
                                     return true;
                                 }
                             });
                         }else{
-                            binding.viewProgressbar.setTranslationX(0-linProgressWidth);
+                            mBinding.viewProgressbar.setTranslationX(0-linProgressWidth);
                         }
 
                     }
                     if(linProgressWidth!=0){
-                        MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),0-linProgressWidth+linProgressWidth/100*newProgress,0,0,binding.viewProgressbar,MyAnimations.ANIMA_TIME*3);
+                        MyAnimations.makeViewMove(mBinding.viewProgressbar.getTranslationX(),0-linProgressWidth+linProgressWidth/100*newProgress,0,0, mBinding.viewProgressbar,MyAnimations.ANIMA_TIME*3);
                         new Handler().postDelayed(new Runnable() {
                             @Override
                             public void run() {
-                                MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),binding.viewProgressbar.getTranslationX()+300,0,0,binding.viewProgressbar,MyAnimations.ANIMA_TIME*10);
+                                MyAnimations.makeViewMove(mBinding.viewProgressbar.getTranslationX(), mBinding.viewProgressbar.getTranslationX()+300,0,0, mBinding.viewProgressbar,MyAnimations.ANIMA_TIME*10);
                             }
                         },MyAnimations.ANIMA_TIME*3);
                     }
@@ -96,9 +101,9 @@
 
         });
 
-        binding.browser.getSettings().setSavePassword(false);
+        mBinding.browser.getSettings().setSavePassword(false);
         //Toast.makeText(mContext,"进入浏览器",Toast.LENGTH_SHORT).show();
-        String Scale = String.valueOf(binding.browser.getScale());
+        String Scale = String.valueOf(mBinding.browser.getScale());
         MyLog.i("Runt","--Scale:--"+Scale);
         int screenDensity=getResources().getDisplayMetrics().densityDpi;
         MyLog.i("Runt", "--screenDensity:--"+String.valueOf(screenDensity));  //60-160-240
@@ -147,12 +152,12 @@
     }
 
     private void hideProgressBar(){
-        MyAnimations.hideAnimaInSitu(binding.linProgressbar);
-        MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),0,0,0,binding.viewProgressbar);
+        MyAnimations.hideAnimaInSitu(mBinding.linProgressbar);
+        MyAnimations.makeViewMove(mBinding.viewProgressbar.getTranslationX(),0,0,0, mBinding.viewProgressbar);
         new Handler().postDelayed(new Runnable() {
             @Override
             public void run() {
-                binding.linProgressbar.setVisibility(View.GONE);
+                mBinding.linProgressbar.setVisibility(View.GONE);
             }
         },MyAnimations.ANIMA_TIME*2);
     }
diff --git a/app/src/main/java/com/runt/open/mvvm/util/DeviceUtil.java b/app/src/main/java/com/runt/open/mvvm/util/DeviceUtil.java
index 58761bb..fc5a85c 100644
--- a/app/src/main/java/com/runt/open/mvvm/util/DeviceUtil.java
+++ b/app/src/main/java/com/runt/open/mvvm/util/DeviceUtil.java
@@ -371,4 +371,61 @@
         }
         return "";
     }
+
+    /**
+     * check the system is harmony os
+     *
+     * @return true if it is harmony os
+     */
+    public static boolean isHarmonyOS() {
+        try {
+            Class clz = Class.forName("com.huawei.system.BuildEx");
+            Method method = clz.getMethod("getOsBrand");
+            return "harmony".equals(method.invoke(clz));
+        } catch (ClassNotFoundException e) {
+            Log.e(TAG, "occured ClassNotFoundException");
+        } catch (NoSuchMethodException e) {
+            Log.e(TAG, "occured NoSuchMethodException");
+        } catch (Exception e) {
+            Log.e(TAG, "occur other problem");
+        }
+        return false;
+    }
+
+    /**
+     * 获取鸿蒙系统版本号
+     */
+    public static String getHarmonyOsVersion() {
+        if (isHarmonyOS()) {
+            try {
+                Class cls = Class.forName("android.os.SystemProperties");
+                Method method = cls.getMethod("get", String.class);
+                return method.invoke(cls, "ro.huawei.build.display.id").toString();
+                //android.os.Build.DISPLAY
+            } catch ( Exception e) {
+            }
+        }
+        return "-1";
+    }
+
+    /**
+     * 获取属性
+     * @param property
+     * @param defaultValue
+     * @return
+     */
+    private static String getProp(String property, String defaultValue) {
+        try {
+            Class spClz = Class.forName("android.os.SystemProperties");
+            Method method = spClz.getDeclaredMethod("get", String.class);
+            String value = (String) method.invoke(spClz, property);
+            if (TextUtils.isEmpty(value)) {
+                return defaultValue;
+            }
+            return value;
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        return defaultValue;
+    }
 }
diff --git a/app/src/main/java/com/runt/open/mvvm/util/HandleDate.java b/app/src/main/java/com/runt/open/mvvm/util/HandleDate.java
new file mode 100644
index 0000000..98e9010
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/util/HandleDate.java
@@ -0,0 +1,216 @@
+package com.runt.open.mvvm.util;
+
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/7/27.
+ */
+public class HandleDate {
+
+    private static SimpleDateFormat secondsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static SimpleDateFormat timesdf = new SimpleDateFormat("HH:mm:ss");
+    private static SimpleDateFormat datesdf = new SimpleDateFormat("yyyy-MM-dd");
+    private static SimpleDateFormat hoursdf = new SimpleDateFormat("yyyy-MM-dd HH");
+    private static SimpleDateFormat minutesdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+
+    /**
+     * 获取当前时间的String类型
+     */
+    public static long getDateToLong() {
+        return new Date().getTime();
+    }
+
+    /**
+     * 获取指定时间的long类型
+     */
+    public static long getDateToLong(Date date) {
+
+        return date.getTime();
+    }
+
+    /**
+     * 获取指定时间的long类型
+     *
+     * @throws ParseException
+     */
+    public static long getDateToLong(String datestr) throws ParseException {
+
+        return datesdf.parse(datestr).getTime();
+    }
+
+    /**
+     * 将long类型的时间转换成只有日期的int类型
+     */
+    public static int getDateToInt(long datetime) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        Date date = getLongToDate(datetime);
+        String format = sdf.format(date);
+        return Integer.parseInt(format);
+    }
+
+    /**
+     * 将指定long类型的日期转换为date
+     */
+    public static Date getLongToDate(Long datetime) {
+        return new Date(datetime);
+    }
+
+    /**
+     * 将指定long类型的日期转换为string时间精确到秒
+     */
+    public static String getLongToSecond(Long datetime) {
+        Date date = new Date(datetime);
+        return secondsdf.format(date);
+    }
+
+    /**
+     * 将指定long类型的日期转换为string时间 只显示 时分秒
+     */
+    public static String getLongToTime(Long datetime) {
+        String datestr = "";
+        Date date = null;
+        try {
+            date = new Date(datetime);
+            datestr = timesdf.format(date);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return datestr;
+    }
+
+    /**
+     * 将指定long类型的日期转换为string时间只显示日期
+     */
+    public static String getLongToDatestr(Long datetime) {
+        String datestr = "";
+        Date date = null;
+        try {
+            date = new Date(datetime);
+            datestr = datesdf.format(date);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return datestr;
+    }
+
+    /**
+     * 将指定long类型的日期转换为string时间精确到小时
+     */
+    public static String getLongToHour(Long datetime) {
+        String datestr = "";
+        Date date = null;
+        try {
+            date = new Date(datetime);
+            datestr = hoursdf.format(date);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return datestr;
+    }
+
+    /**
+     * 将指定long类型的日期转换为string日期
+     */
+    public static String getLongToSimpleDate(Long datetime) {
+        String datestr = "";
+        Date date = null;
+        try {
+            date = new Date(datetime);
+            datestr = datesdf.format(date);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return datestr;
+    }
+
+    /**
+     * 根据毫秒时间戳来格式化字符串 今天显示今天、昨天显示昨天、前天显示前天. 早于前天的显示具体年-月-日,如2017-06-12;
+     *
+     * @param timeStamp 毫秒值
+     * @return 今天 昨天 前天 或者 yyyy-MM-dd HH:mm:ss类型字符串
+     */
+    public static String format(long timeStamp) {
+        long curTimeMillis = System.currentTimeMillis();
+        Date curDate = new Date(curTimeMillis);
+        int todayHoursSeconds = curDate.getHours() * 60 * 60;
+        int todayMinutesSeconds = curDate.getMinutes() * 60;
+        int todaySeconds = curDate.getSeconds();
+        int todayMillis = (todayHoursSeconds + todayMinutesSeconds + todaySeconds) * 1000;
+        long todayStartMillis = curTimeMillis - todayMillis;
+        if (timeStamp >= todayStartMillis) {
+            return "今天";
+        }
+        int oneDayMillis = 24 * 60 * 60 * 1000;
+        long yesterdayStartMilis = todayStartMillis - oneDayMillis;
+        if (timeStamp >= yesterdayStartMilis) {
+            return "昨天";
+        }
+        long yesterdayBeforeStartMilis = yesterdayStartMilis - oneDayMillis;
+        if (timeStamp >= yesterdayBeforeStartMilis) {
+            return "前天";
+        }
+        //	        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        return sdf.format(new Date(timeStamp));
+    }
+
+    /**
+     * 根据时间戳来判断当前的时间是几天前,几分钟,刚刚
+     *
+     * @param long_time
+     * @return
+     */
+
+    public static String getTimeStateNew(String long_time) {
+        String long_by_13 = "1000000000000";
+        String long_by_10 = "1000000000";
+        if (Long.valueOf(long_time) / Long.valueOf(long_by_13) < 1) {
+            if (Long.valueOf(long_time) / Long.valueOf(long_by_10) >= 1) {
+                long_time = long_time + "000";
+            }
+        }
+        return getTimeStateNew(long_time);
+    }
+    public static String getTimeStateNew(Date long_time) {
+        return getTimeStateNew(long_time.getTime() );
+    }
+    public static String getTimeStateNew(Long long_time) {
+        Timestamp time = new Timestamp(Long.valueOf(long_time));
+        Timestamp now = new Timestamp(System.currentTimeMillis());
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        //	     System.out.println("传递过来的时间:"+format.format(time));
+        //	     System.out.println("现在的时间:"+format.format(now));
+        long day_conver = 1000 * 60 * 60 * 24;
+        long hour_conver = 1000 * 60 * 60;
+        long min_conver = 1000 * 60;
+        long time_conver = now.getTime() - time.getTime();
+        long temp_conver;
+        //	     System.out.println("天数:"+time_conver/day_conver);
+        if ((time_conver / day_conver) < 3) {
+            temp_conver = time_conver / day_conver;
+            if (temp_conver <= 2 && temp_conver >= 1) {
+                return temp_conver + "天前";
+            } else {
+                temp_conver = (time_conver / hour_conver);
+                if (temp_conver >= 1) {
+                    return temp_conver + "小时前";
+                } else {
+                    temp_conver = (time_conver / min_conver);
+                    if (temp_conver >= 1) {
+                        return temp_conver + "分钟前";
+                    } else {
+                        return "刚刚";
+                    }
+                }
+            }
+        } else {
+            return format.format(time);
+        }
+    }
+
+
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/widgets/CircleImageView.java b/app/src/main/java/com/runt/open/mvvm/widgets/CircleImageView.java
new file mode 100644
index 0000000..fece7e8
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/widgets/CircleImageView.java
@@ -0,0 +1,245 @@
+package com.runt.open.mvvm.widgets;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import com.runt.open.mvvm.R;
+
+
+/**
+ * My father is Object, ites purpose of 圆形图片带阴影
+ *
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-2-23.
+ */
+@SuppressLint("AppCompatCustomView")
+public class CircleImageView extends ImageView {
+
+    private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
+
+    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
+    private static final int COLORDRAWABLE_DIMENSION = 1;
+
+    private static final int DEFAULT_BORDER_WIDTH = 0;
+    private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
+
+    private final RectF mDrawableRect = new RectF();
+    private final RectF mBorderRect = new RectF();
+
+    private final Matrix mShaderMatrix = new Matrix();
+    private final Paint mBitmapPaint = new Paint();
+    private final Paint mBorderPaint = new Paint();
+
+    private int mBorderColor = DEFAULT_BORDER_COLOR;
+    private int mBorderWidth = DEFAULT_BORDER_WIDTH;
+
+    private Bitmap mBitmap;
+    private BitmapShader mBitmapShader;
+    private int mBitmapWidth;
+    private int mBitmapHeight;
+
+    private float mDrawableRadius;
+    private float mBorderRadius;
+
+    private boolean mReady;
+    private boolean mSetupPending;
+
+    public CircleImageView(Context context) {
+        super(context);
+    }
+
+    public CircleImageView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        super.setScaleType(SCALE_TYPE);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
+
+        mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
+        mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
+
+        a.recycle();
+
+        mReady = true;
+
+        if (mSetupPending) {
+            setup();
+            mSetupPending = false;
+        }
+    }
+
+    @Override
+    public ScaleType getScaleType() {
+        return SCALE_TYPE;
+    }
+
+    @Override
+    public void setScaleType(ScaleType scaleType) {
+        if (scaleType != SCALE_TYPE) {
+            throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (getDrawable() == null) {
+            return;
+        }
+
+        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
+        if(getBorderWidth()>0) {
+            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
+        }
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        setup();
+    }
+
+    public int getBorderColor() {
+        return mBorderColor;
+    }
+
+    public void setBorderColor(int borderColor) {
+        if (borderColor == mBorderColor) {
+            return;
+        }
+
+        mBorderColor = borderColor;
+        mBorderPaint.setColor(mBorderColor);
+        invalidate();
+    }
+
+    public int getBorderWidth() {
+        return mBorderWidth;
+    }
+
+    public void setBorderWidth(int borderWidth) {
+        if (borderWidth == mBorderWidth) {
+            return;
+        }
+
+        mBorderWidth = borderWidth;
+        setup();
+    }
+
+    @Override
+    public void setImageBitmap(Bitmap bm) {
+        super.setImageBitmap(bm);
+        mBitmap = bm;
+        setup();
+    }
+
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        super.setImageDrawable(drawable);
+        mBitmap = getBitmapFromDrawable(drawable);
+        setup();
+    }
+
+    @Override
+    public void setImageResource(int resId) {
+        super.setImageResource(resId);
+        mBitmap = getBitmapFromDrawable(getDrawable());
+        setup();
+    }
+
+    private Bitmap getBitmapFromDrawable(Drawable drawable) {
+        if (drawable == null) {
+            return null;
+        }
+
+        if (drawable instanceof BitmapDrawable) {
+            return ((BitmapDrawable) drawable).getBitmap();
+        }
+
+        try {
+            Bitmap bitmap;
+
+            if (drawable instanceof ColorDrawable) {
+                bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
+            } else {
+                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
+            }
+
+            Canvas canvas = new Canvas(bitmap);
+            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+            drawable.draw(canvas);
+            return bitmap;
+        } catch (OutOfMemoryError e) {
+            return null;
+        }
+    }
+
+    private void setup() {
+        if (!mReady) {
+            mSetupPending = true;
+            return;
+        }
+
+        if (mBitmap == null) {
+            return;
+        }
+
+        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+
+        mBitmapPaint.setAntiAlias(true);
+        mBitmapPaint.setShader(mBitmapShader);
+
+        mBorderPaint.setStyle(Paint.Style.STROKE);
+        mBorderPaint.setAntiAlias(true);
+        mBorderPaint.setColor(mBorderColor);
+        mBorderPaint.setStrokeWidth(mBorderWidth);
+
+        mBitmapHeight = mBitmap.getHeight();
+        mBitmapWidth = mBitmap.getWidth();
+
+        mBorderRect.set(0, 0, getWidth(), getHeight());
+        mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
+
+        mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);
+        mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
+
+        updateShaderMatrix();
+        invalidate();
+    }
+
+    private void updateShaderMatrix() {
+        float scale;
+        float dx = 0;
+        float dy = 0;
+
+        mShaderMatrix.set(null);
+
+        if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
+            scale = mDrawableRect.height() / (float) mBitmapHeight;
+            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
+        } else {
+            scale = mDrawableRect.width() / (float) mBitmapWidth;
+            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
+        }
+
+        mShaderMatrix.setScale(scale, scale);
+        mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);
+
+        mBitmapShader.setLocalMatrix(mShaderMatrix);
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/widgets/CornerImageView.java b/app/src/main/java/com/runt/open/mvvm/widgets/CornerImageView.java
new file mode 100644
index 0000000..a9be0cb
--- /dev/null
+++ b/app/src/main/java/com/runt/open/mvvm/widgets/CornerImageView.java
@@ -0,0 +1,163 @@
+package com.runt.open.mvvm.widgets;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatImageView;
+
+
+/**
+ * My father is Object, ites purpose of  圆角
+ *
+ * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-6-18.
+ */
+public class CornerImageView extends AppCompatImageView {
+
+    private int cornerSize = 30;
+
+    private Paint paint;
+
+    public CornerImageView(Context context) {
+
+        super(context);
+
+        paint = new Paint();
+
+        paint.setColor(Color.WHITE);
+
+        paint.setAntiAlias(true);//消除锯齿
+
+    }
+
+    public CornerImageView(Context context, @Nullable AttributeSet attrs) {
+
+        super(context, attrs);
+
+        paint = new Paint();
+
+        paint.setColor(Color.WHITE);
+
+        paint.setAntiAlias(true);//消除锯齿
+
+    }
+
+    @Override
+
+    public void draw(Canvas canvas) {
+
+        super.draw(canvas);
+
+        drawLeftTop(canvas);
+
+        drawRightTop(canvas);
+
+        drawLeftBottom(canvas);
+
+        drawRightBottom(canvas);
+
+    }
+
+    private void drawLeftTop(Canvas canvas) {
+
+        Path path = new Path();
+
+        path.moveTo(0, cornerSize);
+
+        path.lineTo(0, 0);
+
+        path.lineTo(cornerSize, 0);
+
+        path.arcTo(new RectF(0, 0, cornerSize * 2, cornerSize * 2), -90, -90);
+
+        path.close();
+
+        canvas.drawPath(path, paint);
+
+    }
+
+    private void drawLeftBottom(Canvas canvas) {
+
+        Path path = new Path();
+
+        path.moveTo(0, getHeight() - cornerSize);
+
+        path.lineTo(0, getHeight());
+
+        path.lineTo(cornerSize, getHeight());
+
+        path.arcTo(new RectF(0, // x
+
+                getHeight() - cornerSize * 2,// y
+
+                cornerSize * 2,// x
+
+                getHeight()// getWidth()// y
+
+        ), 90, 90);
+
+        path.close();
+
+        canvas.drawPath(path, paint);
+
+    }
+
+    private void drawRightBottom(Canvas canvas) {
+
+        Path path = new Path();
+
+        path.moveTo(getWidth() - cornerSize, getHeight());
+
+        path.lineTo(getWidth(), getHeight());
+
+        path.lineTo(getWidth(), getHeight() - cornerSize);
+
+        RectF oval = new RectF(getWidth() - cornerSize * 2, getHeight()
+
+                - cornerSize * 2, getWidth(), getHeight());
+
+        path.arcTo(oval, 0, 90);
+
+        path.close();
+
+        canvas.drawPath(path, paint);
+
+    }
+
+    private void drawRightTop(Canvas canvas) {
+
+        Path path = new Path();
+
+        path.moveTo(getWidth(), cornerSize);
+
+        path.lineTo(getWidth(), 0);
+
+        path.lineTo(getWidth() - cornerSize, 0);
+
+        path.arcTo(new RectF(getWidth() - cornerSize * 2, 0, getWidth(),
+
+                0 + cornerSize * 2), -90, 90);
+
+        path.close();
+
+        canvas.drawPath(path, paint);
+
+    }
+
+    public int getCornerSize() {
+
+        return cornerSize;
+
+    }
+
+    public void setCornerSize(int cornerSize) {
+
+        this.cornerSize = cornerSize;
+
+    }
+}
diff --git a/app/src/main/java/com/runt/open/mvvm/widgets/TitleBarView.java b/app/src/main/java/com/runt/open/mvvm/widgets/TitleBarView.java
index 746b72a..df3fd5a 100644
--- a/app/src/main/java/com/runt/open/mvvm/widgets/TitleBarView.java
+++ b/app/src/main/java/com/runt/open/mvvm/widgets/TitleBarView.java
@@ -67,6 +67,14 @@
         rightTextSize = array.getDimension(R.styleable.TitleBarView_rightTextSize, DimensionUtils.convertSpToPixel(getContext(),14));
         rightPadding = array.getDimension(R.styleable.TitleBarView_rightDrawablePadding,10);
 
+        int leftTint = array.getColor(R.styleable.TitleBarView_leftTint,-1);
+        if(leftTint != -1) {
+            setTint(leftDra,leftTint);
+        }
+        int rightTint = array.getColor(R.styleable.TitleBarView_rightTint,-1);
+        if(rightTint != -1) {
+            setTint(rightDra,rightTint);
+        }
         textPaint = new Paint();
         textPaint.setAntiAlias(true); // 是否抗锯齿
         //mTextPaint.setAlpha(50); // 设置alpha不透明度,范围为0~255
@@ -253,4 +261,10 @@
         float height2 = fm.bottom - fm.top + fm.leading;//行高
         return (int) height2;
     }
+
+    private void setTint(Drawable drawable, @ColorInt int color){
+        if(drawable!= null){
+            drawable.setTint(color);
+        }
+    }
 }
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 964ea3f..deb81e7 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -2,19 +2,25 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     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"
     android:id="@+id/container"
     android:layout_width="match_parent"
     android:layout_height="match_parent" >
 
     <com.runt.open.mvvm.widgets.TitleBarView
         android:id="@+id/title_bar"
-        android:layout_width="match_parent"
-        android:layout_height="?attr/actionBarSize"
-        android:background="@color/white"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent" />
+        style="@style/titlebar"
+        tools:ignore="MissingConstraints"
+        app:titleText="标题" />
 
+    <androidx.viewpager2.widget.ViewPager2
+        android:id="@+id/view_pager_2"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintTop_toBottomOf="@id/title_bar"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/nav_view" />
     <com.google.android.material.bottomnavigation.BottomNavigationView
         android:id="@+id/nav_view"
         android:layout_width="0dp"
@@ -27,17 +33,5 @@
         app:layout_constraintRight_toRightOf="parent"
         app:menu="@menu/bottom_nav_menu"/>
 
-    <fragment
-        android:id="@+id/nav_host_fragment_activity_main"
-        android:name="androidx.navigation.fragment.NavHostFragment"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:defaultNavHost="true"
-        app:layout_constraintBottom_toTopOf="@id/nav_view"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:navGraph="@navigation/mobile_navigation"
-    />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
new file mode 100644
index 0000000..6159993
--- /dev/null
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout 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"
+    android:background="@color/white"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <com.runt.open.mvvm.widgets.TitleBarView
+        android:id="@+id/title_bar"
+        style="@style/titlebar"
+        tools:ignore="MissingConstraints"
+        app:titleText="设置"
+        app:leftDrawable="@mipmap/icon_white_back"
+        app:leftTint="@color/black"/>
+
+    <TextView
+        android:id="@+id/version"
+        app:layout_constraintTop_toBottomOf="@id/title_bar"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        android:background="@drawable/bg_white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="left"
+        android:text="@string/str_version"
+        android:textColor="@color/txt_color"
+        android:textSize="@dimen/title_size"
+        android:padding="15dp" />
+    <TextView
+        android:id="@+id/about"
+        app:layout_constraintTop_toBottomOf="@id/version"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        android:background="@drawable/bg_white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:drawableRight="@mipmap/arrow_right"
+        android:gravity="left"
+        android:text="关于我们"
+        android:textColor="@color/txt_color"
+        android:textSize="@dimen/title_size"
+        android:padding="15dp" />
+    <View
+        app:layout_constraintTop_toBottomOf="@id/title_bar"
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:background="@color/color_gray8" />
+    <View
+        app:layout_constraintTop_toBottomOf="@id/version"
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:background="@color/color_gray8" />
+    <View
+        app:layout_constraintTop_toBottomOf="@id/about"
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:background="@color/color_gray8" />
+
+    <View
+        app:layout_constraintBottom_toTopOf="@id/logout"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@color/color_gray8" />
+    <TextView
+        android:id="@+id/logout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        android:background="@drawable/bg_white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:text="@string/logout"
+        android:textColor="@color/txt_color"
+        android:textSize="@dimen/title_size"
+        android:padding="15dp" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml
index 70a0b97..ad20990 100644
--- a/app/src/main/res/layout/activity_splash.xml
+++ b/app/src/main/res/layout/activity_splash.xml
@@ -13,9 +13,5 @@
         android:scaleType="centerCrop"
         />
 
-    <FrameLayout
-        android:id="@+id/splash_ad_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"   />
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_web.xml b/app/src/main/res/layout/activity_web.xml
index c3ad397..34531b1 100644
--- a/app/src/main/res/layout/activity_web.xml
+++ b/app/src/main/res/layout/activity_web.xml
@@ -1,15 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout 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"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <com.runt.open.mvvm.widgets.TitleBarView
         android:id="@+id/title_bar"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        style="@style/titlebar" />
+        style="@style/titlebar"
+        tools:ignore="MissingConstraints" />
 
     <LinearLayout
         android:id="@+id/lin_progressbar"
diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml
deleted file mode 100644
index 53e0e0c..0000000
--- a/app/src/main/res/layout/fragment_dashboard.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    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"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".ui.main.dashboard.DashboardFragment" >
-
-    <TextView
-        android:id="@+id/text_dashboard"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
-        android:layout_marginTop="8dp"
-        android:layout_marginEnd="8dp"
-        android:textAlignment="center"
-        android:textSize="20sp"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent" />
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
deleted file mode 100644
index 02db4bd..0000000
--- a/app/src/main/res/layout/fragment_home.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    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"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".ui.main.home.HomeFragment" >
-
-    <TextView
-        android:id="@+id/text_home"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
-        android:layout_marginTop="8dp"
-        android:layout_marginEnd="8dp"
-        android:textAlignment="center"
-        android:textSize="20sp"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent" />
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml
new file mode 100644
index 0000000..c3dc06a
--- /dev/null
+++ b/app/src/main/res/layout/fragment_mine.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:background="@color/white"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:ignore="MissingDefaultResource">
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="0.5dp"
+                android:background="@color/color_gray8"  />
+            <LinearLayout
+                android:id="@+id/lin_name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:background="@drawable/bg_white" >
+
+                <ImageView
+                    android:id="@+id/img_top_bg"
+                    android:layout_width="match_parent"
+                    android:layout_height="200dp"
+                    android:scaleType="centerCrop"
+                    android:src="@mipmap/user_back"/>
+
+                <com.runt.open.mvvm.widgets.CircleImageView
+                    android:id="@+id/img"
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_marginTop="-50dp"
+                    android:scaleType="centerCrop"
+                    android:src="@mipmap/default_head"  />
+                <TextView
+                    android:id="@+id/txt_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_marginTop="10dp"
+                    android:text="名称"
+                    android:textSize="20sp"
+                    android:textColor="@color/txt_normal"/>
+                <TextView
+                    android:id="@+id/txt_user_sign"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_marginTop="10dp"
+                    android:paddingLeft="15dp"
+                    android:paddingRight="15dp"
+                    android:gravity="center"
+                    android:text="签名"
+                    android:textSize="16sp"
+                    android:visibility="gone"
+                    android:drawablePadding="20dp"
+                    android:textColor="@color/txt_enable"/>
+
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_margin="15dp"
+                    android:visibility="gone"
+                    android:orientation="horizontal">
+
+                    <TextView
+                        style="@style/user_txt_left"
+                        android:drawableLeft="@mipmap/location_e"
+                        android:text="所在地:"/>
+                    <TextView
+                        android:id="@+id/txt_address"
+                        style="@style/user_txt_value"
+                        android:text="北京"/>
+
+                </LinearLayout>
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="15dp"
+                    android:visibility="gone"
+                    android:orientation="horizontal">
+
+                    <TextView
+                        style="@style/user_txt_left"
+                        android:drawableLeft="@mipmap/birth"
+                        android:text="年龄:"/>
+                    <TextView
+                        android:id="@+id/txt_age"
+                        style="@style/user_txt_value"
+                        android:text="11"/>
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/lin_group"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:background="@drawable/white_corner_border"
+                    android:layout_margin="@dimen/default_margin_lr"
+                    android:elevation="5dp">
+
+
+                    <LinearLayout
+                        android:id="@+id/lin_coin"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical"
+                        android:paddingTop="20dp"
+                        android:paddingBottom="20dp"
+                        android:gravity="center"
+                        android:layout_weight="1">
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="我的金币"
+                            android:textSize="18sp"
+                            android:drawableLeft="@mipmap/icon_coin"
+                            android:drawablePadding="10dp"
+                            android:textColor="@color/txt_normal"/>
+
+                        <TextView
+                            android:id="@+id/txt_coin"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="10dp"
+                            android:textSize="25sp"
+                            android:text="0"
+                            android:textColor="@color/txt_normal"/>
+
+
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:id="@+id/lin_sign"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical"
+                        android:paddingTop="20dp"
+                        android:paddingBottom="20dp"
+                        android:gravity="center"
+                        android:layout_weight="1">
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="连续签到"
+                            android:textSize="18sp"
+                            android:drawableLeft="@mipmap/sign"
+                            android:drawablePadding="10dp"
+                            android:textColor="@color/txt_normal"/>
+
+                        <TextView
+                            android:id="@+id/txt_signs"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="10dp"
+                            android:textSize="25sp"
+                            android:text="0"
+                            android:textColor="@color/txt_normal"/>
+
+
+                    </LinearLayout>
+
+                </LinearLayout>
+
+
+
+            </LinearLayout>
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="0.5dp"
+                android:background="@color/color_gray8" />
+
+        </LinearLayout>
+    </ScrollView>
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
deleted file mode 100644
index 448150a..0000000
--- a/app/src/main/res/layout/fragment_notifications.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    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"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".ui.main.notifications.NotificationsFragment" >
-
-    <TextView
-        android:id="@+id/text_notifications"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
-        android:layout_marginTop="8dp"
-        android:layout_marginEnd="8dp"
-        android:textAlignment="center"
-        android:textSize="20sp"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent" />
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_service.xml b/app/src/main/res/layout/fragment_service.xml
new file mode 100644
index 0000000..811fd79
--- /dev/null
+++ b/app/src/main/res/layout/fragment_service.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:background="@color/white"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:ignore="MissingDefaultResource">
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:background="@color/cut_off_line" />
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="20dp"
+            android:orientation="vertical">
+
+            <RelativeLayout
+                android:id="@+id/lin_uav"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="1dp"
+                android:layout_margin="10dp"
+                android:gravity="center_vertical">
+
+                <com.runt.open.mvvm.widgets.CornerImageView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:adjustViewBounds="true"
+                    android:src="@mipmap/bg_uav" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/white"
+                    android:textSize="20sp"
+                    android:textStyle="bold"
+                    android:layout_marginTop="15dp"
+                    android:layout_marginLeft="15dp"
+                    android:text="无人机喷洒农药/化肥" />
+
+
+            </RelativeLayout>
+
+            <RelativeLayout
+                android:id="@+id/lin_yumi"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="1dp"
+                android:layout_margin="10dp"
+                android:gravity="center_vertical">
+
+                <com.runt.open.mvvm.widgets.CornerImageView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:adjustViewBounds="true"
+                    android:src="@mipmap/bg_yumi" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/white"
+                    android:textSize="20sp"
+                    android:textStyle="bold"
+                    android:layout_marginTop="15dp"
+                    android:layout_marginLeft="15dp"
+                    android:text="玉米收割" />
+
+
+            </RelativeLayout>
+            <RelativeLayout
+                android:id="@+id/lin_bozhong"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="1dp"
+                android:layout_margin="10dp"
+                android:gravity="center_vertical">
+
+                <com.runt.open.mvvm.widgets.CornerImageView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:adjustViewBounds="true"
+                    android:src="@mipmap/bg_bozhong" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/white"
+                    android:textSize="20sp"
+                    android:textStyle="bold"
+                    android:layout_marginTop="15dp"
+                    android:layout_marginLeft="15dp"
+                    android:text="播种/施肥" />
+            </RelativeLayout>
+            <RelativeLayout
+                android:id="@+id/lin_xiaomai"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="1dp"
+                android:layout_margin="10dp"
+                android:gravity="center_vertical">
+
+                <com.runt.open.mvvm.widgets.CornerImageView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:adjustViewBounds="true"
+                    android:src="@mipmap/bg_xiaomai" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textColor="@color/white"
+                    android:textSize="20sp"
+                    android:textStyle="bold"
+                    android:layout_marginTop="15dp"
+                    android:layout_marginLeft="15dp"
+                    android:text="小麦收割" />
+            </RelativeLayout>
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_msg.xml b/app/src/main/res/layout/item_msg.xml
new file mode 100644
index 0000000..96d8fc7
--- /dev/null
+++ b/app/src/main/res/layout/item_msg.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="20dp"
+        android:paddingBottom="20dp"
+        android:paddingLeft="@dimen/default_margin_lr"
+        android:paddingRight="@dimen/default_margin_lr"
+        android:background="@drawable/bg_white"
+        android:gravity="center"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:gravity="bottom" >
+
+            <TextView
+                android:id="@+id/txt_title"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:textStyle="bold"
+                android:textSize="@dimen/title_size"
+                android:text="挖鼻通知" />
+            <TextView
+                android:id="@+id/txt_time"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:alpha="0.6"
+                android:text="02-11" />
+
+        </LinearLayout>
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/txt_detail"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dp"
+            android:alpha="0.6"
+            android:text="l;ajs;ldjf;ljas;ldfjasdfasdfasdfasdf很垃圾乐山大佛了计算的;了时代峻峰拉三等奖了可接受的来精神的分了就l;asjdflkjl;asjdf;lkajsdf"
+            android:singleLine="true"/>
+
+
+
+    </LinearLayout>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:background="@color/cut_off_line" />
+    <LinearLayout
+        android:id="@+id/lin_ad"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" ></LinearLayout>
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/refresh_recycler.xml b/app/src/main/res/layout/refresh_recycler.xml
index fceabe9..f7b6d8e 100644
--- a/app/src/main/res/layout/refresh_recycler.xml
+++ b/app/src/main/res/layout/refresh_recycler.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <com.scwang.smart.refresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/smart_refresh"
+    android:id="@+id/refresh"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
deleted file mode 100644
index 97a20ea..0000000
--- a/app/src/main/res/navigation/mobile_navigation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<navigation 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"
-    android:id="@+id/mobile_navigation"
-    app:startDestination="@+id/navigation_home">
-
-    <fragment
-        android:id="@+id/navigation_home"
-        android:name="com.runt.open.mvvm.ui.main.home.HomeFragment"
-        android:label="@string/title_home"
-        tools:layout="@layout/fragment_home" />
-
-    <fragment
-        android:id="@+id/navigation_dashboard"
-        android:name="com.runt.open.mvvm.ui.main.dashboard.DashboardFragment"
-        android:label="@string/title_dashboard"
-        tools:layout="@layout/fragment_dashboard" />
-
-    <fragment
-        android:id="@+id/navigation_notifications"
-        android:name="com.runt.open.mvvm.ui.main.notifications.NotificationsFragment"
-        android:label="@string/title_notifications"
-        tools:layout="@layout/fragment_notifications" />
-</navigation>
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 4884702..6bab23f 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -11,6 +11,8 @@
         <attr name="rightText" format="string" />
         <attr name="rightTextSize" format="dimension" />
         <attr name="rightTextColor" format="color" />
+        <attr name="leftTint" format="color" />
+        <attr name="rightTint" format="color" />
     </declare-styleable>
 
 
@@ -77,6 +79,31 @@
     </style>
 
 
+    <style name="user_txt_left">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">18sp</item>
+        <item name="android:textColor">@color/txt_enable</item>
+        <item name="android:drawablePadding">10dp</item>
+        <item name="android:layout_marginRight">10dp</item>
+    </style>
+    <style name="tip_txt_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">@dimen/title_height</item>
+        <item name="android:onClick">onTypeClick</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">@color/txt_normal</item>
+        <item name="android:drawableRight">@drawable/check_selector</item>
+        <item name="android:gravity">center_vertical</item>
+    </style>
+    <style name="user_txt_value">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">18sp</item>
+        <item name="android:textColor">@color/txt_normal</item>
+    </style>
+
+
     <style name="btn_normal">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>

--
Gitblit v1.9.1