yanyi 7 лет назад
Родитель
Сommit
e589fffc8d
25 измененных файлов с 397 добавлено и 1264 удалено
  1. BIN
      .idea/caches/build_file_checksums.ser
  2. 27 3
      .idea/misc.xml
  3. 1 1
      .idea/vcs.xml
  4. 4 24
      README.md
  5. 2 2
      androidjava/bintrayUpload.gradle
  6. 1 1
      androidjava/build.gradle
  7. 0 2
      androidjava/src/main/java/com/mylove/baselib/activity/BaseActivity.java
  8. 18 0
      androidjava/src/main/java/com/mylove/baselib/application/BaseApplication.java
  9. 256 0
      androidjava/src/main/java/com/mylove/baselib/application/CrashHandler.java
  10. 0 66
      androidjava/src/main/java/com/mylove/baselib/widget/BaseView.java
  11. 0 49
      androidjava/src/main/java/com/mylove/baselib/widget/ScrollForRecycler.java
  12. 0 38
      androidjava/src/main/java/com/mylove/baselib/widget/ScrollTextView.java
  13. 0 346
      androidjava/src/main/java/com/mylove/baselib/widget/SmoothCheckBox.java
  14. 0 261
      androidjava/src/main/java/com/mylove/baselib/widget/TouchImageView.java
  15. 0 94
      androidjava/src/main/java/com/mylove/baselib/widget/VerticalScrollLayout.java
  16. 0 281
      androidjava/src/main/java/com/mylove/baselib/widget/VerticalScrollTextView.java
  17. 0 11
      androidjava/src/main/res/anim/anim_scroll_in.xml
  18. 0 11
      androidjava/src/main/res/anim/anim_scroll_out.xml
  19. 0 33
      androidjava/src/main/res/values/attrs.xml
  20. 1 2
      app/build.gradle
  21. 46 35
      app/src/main/java/com/mylove/basejava/MainActivity.java
  22. 11 0
      app/src/main/res/layout/head_layout.xml
  23. 12 0
      app/src/main/res/layout/item_head.xml
  24. 15 0
      app/src/main/res/layout/item_layout.xml
  25. 3 4
      app/src/main/res/layout/main_activity.xml

BIN
.idea/caches/build_file_checksums.ser


+ 27 - 3
.idea/misc.xml

@@ -1,31 +1,55 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="CheckStyle-IDEA">
+    <option name="configuration">
+      <map>
+        <entry key="checkstyle-version" value="8.10" />
+        <entry key="copy-libs" value="false" />
+        <entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
+        <entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
+        <entry key="scan-before-checkin" value="false" />
+        <entry key="scanscope" value="JavaOnly" />
+        <entry key="suppress-errors" value="false" />
+      </map>
+    </option>
+  </component>
+  <component name="CheckStyle-IDEA-workspace">
+    <option name="configuration">
+      <map>
+        <entry key="last-active-plugin-version" value="5.19.0" />
+      </map>
+    </option>
+  </component>
   <component name="NullableNotNullManager">
     <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
     <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
     <option name="myNullables">
       <value>
-        <list size="5">
+        <list size="7">
           <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
           <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
           <item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
           <item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
           <item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
+          <item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
         </list>
       </value>
     </option>
     <option name="myNotNulls">
       <value>
-        <list size="4">
+        <list size="6">
           <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
           <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
           <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
           <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+          <item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
         </list>
       </value>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">

+ 1 - 1
.idea/vcs.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+    <mapping directory="" vcs="Git" />
   </component>
 </project>

+ 4 - 24
README.md

@@ -1,7 +1,7 @@
 # BaseJava
 java底层封装(本着能使开发android项目更简单、方便原则进行封装)[老版本(已停止维护)](https://github.com/BenYanYi/javalib)
 
- [推荐kotlin项目使用kotlin项目底层](https://github.com/love-yanyi/BaseKotlin)
+ [推荐kotlin项目使用kotlin项目底层](https://github.com/BenYanYi/BaseKotlin)
 
 <br/>
 
@@ -9,32 +9,11 @@ java底层封装(本着能使开发android项目更简单、方便原则进行
 ### 方法一
 #### module 下添加
 
-     implementation 'com.jakewharton:butterknife:+'
-     annotationProcessor 'com.jakewharton:butterknife-compiler:+'
+     implementation 'com.yanyi.benyanyi:androidjava:1.1.6'
      
-     implementation 'com.yanyi.benyanyi:androidjava:1.1.4'
-     
-### 方法二(已停止更新维护)
-#### module 下添加
-
-     implementation 'com.jakewharton:butterknife:+'
-     annotationProcessor 'com.jakewharton:butterknife-compiler:+'
-     implementation 'com.github.BenYanYi:BaseJava:1.0.4'
-
- #### 使用第二种方法需在project 下添加
-
-    allprojects {
-        repositories {
-            jcenter()
-            maven {
-                url 'https://jitpack.io'
-            }
-        }
-    }
-
 #### 感谢
 
-[glide](https://github.com/bumptech/glide),[gson](https://github.com/google/gson),[butterknife](https://github.com/JakeWharton/butterknife)
+[glide](https://github.com/bumptech/glide),[gson](https://github.com/google/gson)
 感谢以上开源库提供使用
 
 #### 介绍
@@ -71,6 +50,7 @@ java底层封装(本着能使开发android项目更简单、方便原则进行
 * 2018/10/10更新 1.1.3优化网络请求方法,详情看[OkHttp](https://github.com/BenYanYi/OkHttp)
 * 2018/10/22更新 1.1.4优化BaseActivity方法,添加退出当前应用时操作方法
 * 2018/12/27更新 1.1.5优化网络请求方法,详情看[OkHttp](https://github.com/BenYanYi/OkHttp),更改注解框架[BindView](https://github.com/BenYanYi/BindViewLib)
+* 2019/01/25更新 1.1.6更改注释框架,摒弃自定义控件,添加崩溃日志收集
 * ........
 
 <br/>

+ 2 - 2
androidjava/bintrayUpload.gradle

@@ -7,7 +7,7 @@ def siteUrl = 'https://github.com/BenYanYi/BaseJava' // 项目主页。
 def gitUrl = 'https://github.com/BenYanYi/BaseJava.git' // Git仓库的url。
 
 group = "com.yanyi.benyanyi"// 唯一包名,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的com.ansen.http就是这里配置的。
-version = "1.1.5"//项目引用的版本号,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的1.0.1就是这里配置的。
+version = "1.1.6"//项目引用的版本号,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的1.0.1就是这里配置的。
 install {
     repositories.mavenInstaller {
         // This generates POM.xml with proper parameters
@@ -15,7 +15,7 @@ install {
             project {
                 packaging 'aar'
                 // Add your description here
-                name '安卓快速开发框架,提高开发速度'
+                name '安卓'
                 url siteUrl
                 // Set your license
                 licenses {

+ 1 - 1
androidjava/build.gradle

@@ -41,7 +41,7 @@ dependencies {
     api 'com.yanyi.benyanyi:okhttplib:1.1.1'
     //log
     api 'com.yanyi.benyanyi:loglib:1.0.0'
-    api 'com.yanyi.benyanyi:permissionlib:1.0.1'
+    api 'com.yanyi.benyanyi:permissionlib:1.0.2'
     api 'com.readystatesoftware.systembartint:systembartint:1.0.3'
     api 'com.yanyi.benyanyi:viewbind:1.0.0'
 }

+ 0 - 2
androidjava/src/main/java/com/mylove/baselib/activity/BaseActivity.java

@@ -15,7 +15,6 @@ import android.view.KeyEvent;
 import android.view.MenuItem;
 import android.view.Window;
 import android.view.inputmethod.InputMethodManager;
-import android.widget.TextView;
 
 import com.google.gson.Gson;
 import com.mylove.baselib.R;
@@ -31,7 +30,6 @@ public abstract class BaseActivity extends AppCompatActivity {
     public Context mContext;
     public Activity mActivity;
     public Gson gson = new Gson();
-    public TextView rightTv;
     protected Toolbar mToolbar;
 
     @Override

+ 18 - 0
androidjava/src/main/java/com/mylove/baselib/application/BaseApplication.java

@@ -0,0 +1,18 @@
+package com.mylove.baselib.application;
+
+import android.app.Application;
+
+/**
+ * @author BenYanYi
+ * @date 2019/01/07 10:18
+ * @email ben@yanyi.red
+ * @overview
+ */
+public class BaseApplication extends Application {
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        CrashHandler.getInstance().init(this);
+    }
+}

+ 256 - 0
androidjava/src/main/java/com/mylove/baselib/application/CrashHandler.java

@@ -0,0 +1,256 @@
+package com.mylove.baselib.application;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Environment;
+import android.os.Looper;
+import android.widget.Toast;
+
+import com.mylove.loglib.JLog;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author BenYanYi
+ * @date 2019/01/02 14:39
+ * @email ben@yanyi.red
+ * @overview UncaughtException处理类, 当程序发生Uncaught异常的时候, 有该类来接管程序, 并记录发送错误报告.
+ */
+public class CrashHandler implements Thread.UncaughtExceptionHandler {
+    public static final String TAG = "CrashHandler";
+
+    //系统默认的UncaughtException处理类
+    private Thread.UncaughtExceptionHandler mDefaultHandler;
+    //CrashHandler实例
+    private static CrashHandler INSTANCE = new CrashHandler();
+    //程序的Context对象
+    private Context mContext;
+    //用来存储设备信息和异常信息
+    private Map<String, String> infos = new HashMap<String, String>();
+
+    //用于格式化日期,作为日志文件名的一部分
+    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
+
+    /**
+     * 保证只有一个CrashHandler实例
+     */
+    private CrashHandler() {
+    }
+
+    /**
+     * 获取CrashHandler实例 ,单例模式
+     */
+    public static CrashHandler getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * 初始化
+     *
+     * @param context
+     */
+    public void init(Context context) {
+        mContext = context;
+        //获取系统默认的UncaughtException处理器
+        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
+        //设置该CrashHandler为程序的默认处理器
+        Thread.setDefaultUncaughtExceptionHandler(this);
+    }
+
+    /**
+     * 当UncaughtException发生时会转入该函数来处理
+     */
+    @Override
+    public void uncaughtException(Thread thread, Throwable ex) {
+        if (!handleException(ex) && mDefaultHandler != null) {
+            //如果用户没有处理则让系统默认的异常处理器来处理
+            mDefaultHandler.uncaughtException(thread, ex);
+        } else {
+            try {
+                Thread.sleep(3000);
+            } catch (InterruptedException e) {
+                JLog.e(TAG, "error : ", e);
+            }
+            //退出程序
+            android.os.Process.killProcess(android.os.Process.myPid());
+            System.exit(1);
+        }
+    }
+
+    /**
+     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
+     *
+     * @param ex
+     * @return true:如果处理了该异常信息;否则返回false.
+     */
+    private boolean handleException(Throwable ex) {
+        if (ex == null) {
+            return false;
+        }
+        //使用Toast来显示异常信息
+        new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
+                Looper.loop();
+            }
+        }.start();
+        //收集设备参数信息
+        collectDeviceInfo(mContext);
+        //保存日志文件
+        saveCrashInfo2File(ex);
+        uploadExceptionToServer();//上传数据到服务器
+        return true;
+    }
+
+    /**
+     * 发送数据到服务器
+     */
+    private void uploadExceptionToServer() {
+//        classes
+    }
+
+    /**
+     * 设备的详细版本号,如:1.0.0,对应manifest或moude的build.gradle中的 versionName
+     */
+    private final String KEY_versionName = "versionName";
+    /**
+     * 设备大的版本号,如:1,对应manifest或moude的build.gradle中的 versionCode
+     */
+    private final String KEY_versionCode = "versionCode";
+    /**
+     * 系统的版本号,如:4.4.4
+     */
+    private final String KEY_osVersion = "osVersion";
+    /**
+     * 系统对应的SDK编码,如:19
+     */
+    private final String KEY_osSDKVersion = "osSDKVersion";
+    /**
+     * 手机制造厂商,如:HUAWEI
+     */
+    private final String KEY_phoneMaker = "phoneMaker";
+    /**
+     * 手机品牌,如:Honor
+     */
+    private final String KEY_BRAND = "brand";
+    /**
+     * 手机型号,如:Che1-CL10
+     */
+    private final String KEY_phoneModel = "phoneModel";
+    /**
+     * CPU架构,如:armeabi-v7a
+     */
+    private final String KEY_cupAbi = "cupAbi";
+
+    /**
+     * 收集设备参数信息
+     *
+     * @param ctx
+     */
+    public void collectDeviceInfo(Context ctx) {
+        try {
+            PackageManager pm = ctx.getPackageManager();// 获得包管理器
+            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
+                    PackageManager.GET_ACTIVITIES);// 得到该应用的信息,即主Activity
+            if (pi != null) {
+                String versionName = pi.versionName == null ? "null"
+                        : pi.versionName;
+                String versionCode = pi.versionCode + "";
+                infos.put(KEY_versionName, versionName);
+                infos.put(KEY_versionCode, versionCode);
+            }
+            infos.put(KEY_osVersion, Build.VERSION.RELEASE);
+            infos.put(KEY_osSDKVersion, "" + Build.VERSION.SDK_INT);
+            infos.put(KEY_phoneMaker, Build.MANUFACTURER);
+            infos.put(KEY_BRAND, Build.BRAND);
+            infos.put(KEY_phoneModel, Build.MODEL);
+            infos.put(KEY_cupAbi, Build.CPU_ABI);
+        } catch (PackageManager.NameNotFoundException e) {
+            JLog.e(TAG, "an error occured when collect package info", e);
+        }
+        Field[] fields = Build.class.getDeclaredFields();
+        for (Field field : fields) {
+            try {
+                field.setAccessible(true);
+                infos.put(field.getName(), field.get(null).toString());
+                JLog.d(TAG, field.getName() + " : " + field.get(null));
+            } catch (Exception e) {
+                JLog.e(TAG, "an error occured when collect crash info", e);
+            }
+        }
+    }
+
+    /**
+     * 保存错误信息到文件中
+     *
+     * @param ex
+     * @return 返回文件名称, 便于将文件传送到服务器
+     */
+    private String saveCrashInfo2File(Throwable ex) {
+
+        StringBuffer sb = new StringBuffer();
+        for (Map.Entry<String, String> entry : infos.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            sb.append(key + "=" + value + "\n");
+        }
+
+        Writer writer = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(writer);
+        ex.printStackTrace(printWriter);
+        Throwable cause = ex.getCause();
+        while (cause != null) {
+            cause.printStackTrace(printWriter);
+            cause = cause.getCause();
+        }
+        printWriter.close();
+        String result = writer.toString();
+        sb.append(result);
+        try {
+            long timestamp = System.currentTimeMillis();
+            String time = formatter.format(new Date());
+            String fileName = "crash-" + time + "-" + timestamp + ".log";
+            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                String path = isExistDir(mContext.getPackageName());
+                File file = new File(path, fileName);
+                FileOutputStream fos = new FileOutputStream(file);
+                fos.write(sb.toString().getBytes());
+                fos.close();
+            }
+            return fileName;
+        } catch (Exception e) {
+            JLog.e(TAG, "an error occured while writing file...", e);
+        }
+        return null;
+    }
+
+    /**
+     * @param saveDir
+     * @return
+     * @throws IOException 判断下载目录是否存在
+     */
+    private static String isExistDir(String saveDir) throws IOException {
+        // 下载位置
+        File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
+        if (!downloadFile.mkdirs()) {
+            downloadFile.createNewFile();
+        }
+        String savePath = downloadFile.getAbsolutePath();
+        return savePath;
+    }
+}

+ 0 - 66
androidjava/src/main/java/com/mylove/baselib/widget/BaseView.java

@@ -1,66 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * @author yanyi
- */
-
-abstract class BaseView extends View {
-    private MyThread myThread;
-
-    public BaseView(Context context) {
-        super(context);
-    }
-
-    public BaseView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (myThread == null) {
-            myThread = new MyThread();
-            myThread.start();
-        } else {
-            drawSub(canvas);
-        }
-    }
-
-    /**
-     * 绘制处理
-     * 在子类中要实现的方法
-     *
-     * @param canvas
-     */
-    abstract void drawSub(Canvas canvas);
-
-    abstract void logic();
-
-    private boolean running = true;
-
-    class MyThread extends Thread {
-        public void run() {
-            super.run();
-            while (running) {
-                logic();
-                postInvalidate();//在线程中更新绘制方法
-                try {
-                    sleep(30);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    protected void onDetachedFromWindow() {
-        running = false;
-        super.onDetachedFromWindow();
-    }
-}

+ 0 - 49
androidjava/src/main/java/com/mylove/baselib/widget/ScrollForRecycler.java

@@ -1,49 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-import android.widget.ScrollView;
-
-/**
- * @author yanyi
- */
-
-public class ScrollForRecycler extends ScrollView {
-    private int downX;
-    private int downY;
-    private int mTouchSlop;
-
-    public ScrollForRecycler(Context context) {
-        super(context);
-        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-    }
-
-    public ScrollForRecycler(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-    }
-
-    public ScrollForRecycler(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent e) {
-        int action = e.getAction();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                downX = (int) e.getRawX();
-                downY = (int) e.getRawY();
-                break;
-            case MotionEvent.ACTION_MOVE:
-                int moveY = (int) e.getRawY();
-                if (Math.abs(moveY - downY) > mTouchSlop) {
-                    return true;
-                }
-        }
-        return super.onInterceptTouchEvent(e);
-    }
-}

+ 0 - 38
androidjava/src/main/java/com/mylove/baselib/widget/ScrollTextView.java

@@ -1,38 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.content.Context;
-import android.support.v7.widget.AppCompatTextView;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-
-/**
- * @author yanyi
- * 横向自动滚动的文字
- */
-
-public class ScrollTextView extends AppCompatTextView {
-    public ScrollTextView(Context context) {
-        super(context);
-        initView();
-    }
-
-    public ScrollTextView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initView();
-    }
-
-    public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        initView();
-    }
-
-    private void initView() {
-        setEllipsize(TextUtils.TruncateAt.MARQUEE);
-        setMarqueeRepeatLimit(-1);
-        setSingleLine(true);
-    }
-
-    public boolean isFocused() {
-        return true;
-    }
-}

+ 0 - 346
androidjava/src/main/java/com/mylove/baselib/widget/SmoothCheckBox.java

@@ -1,346 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Point;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.LinearInterpolator;
-
-import com.mylove.baselib.R;
-
-/**
- * @author yanyi
- * 自定义圆形CheckBox
- * 动画持续时间  BenDuration
- * 边框宽度    BenStrikeWidth
- * 边框颜色    BenBorderColor
- * 选中状态的颜色 BenTrimColor
- * 对勾颜色    BenTickColor
- * 对勾宽度    BenTickWidth
- */
-public class SmoothCheckBox extends View implements View.OnClickListener {
-    // 动画持续时间
-    private long duration;
-    // 边框宽度
-    private float mStrokeWidth;
-    // 对勾宽度
-    private float mTickWidth;
-    // 内饰画笔
-    private Paint trimPaint;
-    // 边框画笔
-    private Paint borderPaint;
-    // 对勾画笔
-    private Paint tickPaint;
-    // 默认边框宽度
-    private float defaultStrikeWidth;
-    // 默认对勾宽度
-    private float defaultTickWidth;
-    // 宽度
-    private int mWidth;
-    // 高度
-    private int mHeight;
-    // 边框颜色
-    private int borderColor;
-    // 内饰颜色
-    private int trimColor;
-    // 对勾颜色
-    private int tickColor;
-    // 半径
-    private int mRadius;
-    // 中心点
-    private int center;
-    // 是否是选中
-    private boolean isChecked;
-    //对勾向下的长度
-    private float downLength;
-    //对勾向上的长度
-    private float upLength;
-    // 对勾的总长度
-    private float totalLength;
-    // 监听器
-    private OnCheckedChangeListener listener;
-
-    private ValueAnimator mValueAnimator;
-
-    private ValueAnimator mTickValueAnimator;
-
-    private float animatedValue;
-
-    private float tickValue;
-    // 对勾开始点
-    private Point startPoint = new Point();
-    // 对勾转折点
-    private Point breakPoint = new Point();
-    // 对勾结束点
-    private Point endPoint = new Point();
-
-    private static final String TAG = "SmoothCheckBox";
-
-    private static final String KEY_INSTANCE_STATE = "InstanceState";
-
-    private Path path = new Path();
-
-    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
-        this.listener = listener;
-    }
-
-    public SmoothCheckBox(Context context) {
-        this(context, null);
-    }
-
-    public SmoothCheckBox(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public SmoothCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.SmoothCheckBox);
-        duration = a.getInt(R.styleable.SmoothCheckBox_BenDuration, 600);
-
-        defaultStrikeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
-        mStrokeWidth = a.getDimension(R.styleable.SmoothCheckBox_BenStrikeWidth, defaultStrikeWidth);
-        defaultTickWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
-        mTickWidth = a.getDimension(R.styleable.SmoothCheckBox_BenTickWidth, defaultTickWidth);
-        borderColor = a.getColor(R.styleable.SmoothCheckBox_BenBorderColor, getResources().getColor(android.R.color.darker_gray));
-        trimColor = a.getColor(R.styleable.SmoothCheckBox_BenTrimColor, getResources().getColor(android.R.color.holo_green_light));
-        tickColor = a.getColor(R.styleable.SmoothCheckBox_BenTickColor, getResources().getColor(android.R.color.white));
-        a.recycle();
-
-        trimPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        trimPaint.setStyle(Paint.Style.FILL);
-        trimPaint.setColor(trimColor);
-
-        borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        borderPaint.setStrokeWidth(mStrokeWidth);
-        borderPaint.setColor(borderColor);
-        borderPaint.setStyle(Paint.Style.STROKE);
-
-        tickPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        tickPaint.setColor(tickColor);
-        tickPaint.setStyle(Paint.Style.STROKE);
-        tickPaint.setStrokeCap(Paint.Cap.ROUND);
-        tickPaint.setStrokeWidth(mTickWidth);
-
-        setOnClickListener(this);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        if (widthMode == MeasureSpec.EXACTLY) {
-            mWidth = widthSize;
-        } else {
-            mWidth = 40;
-        }
-
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        if (heightMode == MeasureSpec.EXACTLY) {
-            mHeight = heightSize;
-        } else {
-            mHeight = 40;
-        }
-        setMeasuredDimension(mWidth, mHeight);
-        int size = Math.min(mWidth, mHeight);
-        center = size / 2;
-        mRadius = (int) ((size - mStrokeWidth) / 2 / 1.2f);
-        startPoint.set(center * 14 / 30, center * 28 / 30);
-        breakPoint.set(center * 26 / 30, center * 40 / 30);
-        endPoint.set(center * 44 / 30, center * 20 / 30);
-
-        downLength = (float) Math.sqrt(Math.pow(startPoint.x - breakPoint.x, 2f) + Math.pow(startPoint.y - breakPoint.y, 2f));
-        upLength = (float) Math.sqrt(Math.pow(endPoint.x - breakPoint.x, 2f) + Math.pow(endPoint.y - breakPoint.y, 2f));
-        totalLength = downLength + upLength;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        canvas.save();
-        drawBorder(canvas);
-        drawTrim(canvas);
-        if (isChecked) {
-            drawTick(canvas);
-        }
-        canvas.restore();
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(KEY_INSTANCE_STATE, super.onSaveInstanceState());
-        bundle.putBoolean(KEY_INSTANCE_STATE, isChecked);
-        return bundle;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        if (state instanceof Bundle) {
-            Bundle bundle = (Bundle) state;
-            boolean isChecked = bundle.getBoolean(KEY_INSTANCE_STATE);
-            setChecked(isChecked);
-            super.onRestoreInstanceState(bundle.getParcelable(KEY_INSTANCE_STATE));
-            return;
-        }
-        super.onRestoreInstanceState(state);
-    }
-
-    // 切换状态
-    private void toggle() {
-        isChecked = !isChecked;
-        if (listener != null) {
-            listener.onCheckedChanged(this, isChecked);
-        }
-        if (isChecked) {
-            checkedAnimation();
-        } else {
-            uncheckedAnimation();
-        }
-    }
-
-    // 由未选中到选中的动画
-    private void checkedAnimation() {
-        animatedValue = 0f;
-        tickValue = 0f;
-        mValueAnimator = ValueAnimator.ofFloat(0f, 1.2f, 1f).setDuration(2 * duration / 5);
-        mValueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
-        mTickValueAnimator = ValueAnimator.ofFloat(0f, 1f).setDuration(3 * duration / 5);
-        mTickValueAnimator.setInterpolator(new LinearInterpolator());
-        mTickValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                tickValue = (float) valueAnimator.getAnimatedValue();
-                postInvalidate();
-            }
-        });
-        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                animatedValue = (float) valueAnimator.getAnimatedValue();
-                postInvalidate();
-            }
-        });
-        mValueAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mTickValueAnimator.start();
-                Log.i(TAG, " mTickValueAnimator.start();");
-            }
-        });
-        mValueAnimator.start();
-    }
-
-    // 由选中到未选中的动画
-    private void uncheckedAnimation() {
-        animatedValue = 0f;
-        mValueAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(2 * duration / 5);
-        mValueAnimator.setInterpolator(new AccelerateInterpolator());
-        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                animatedValue = (float) valueAnimator.getAnimatedValue();
-                postInvalidate();
-            }
-        });
-        mValueAnimator.start();
-    }
-
-    // 画对勾
-    private void drawTick(Canvas canvas) {
-        float temp = tickValue * totalLength;
-        if (Float.compare(tickValue, 0f) == 0) {
-            path.reset();
-            path.moveTo(startPoint.x, startPoint.y);
-        }
-        if (temp > downLength) {
-            path.moveTo(startPoint.x, startPoint.y);
-            path.lineTo(breakPoint.x, breakPoint.y);
-            path.lineTo((endPoint.x - breakPoint.x) * (temp - downLength) / upLength + breakPoint.x, (endPoint.y - breakPoint.y) * (temp - downLength) / upLength + breakPoint.y);
-        } else {
-            path.lineTo((breakPoint.x - startPoint.x) * temp / downLength + startPoint.x, (breakPoint.y - startPoint.y) * temp / downLength + startPoint.y);
-        }
-        canvas.drawPath(path, tickPaint);
-    }
-
-    // 画边框
-    private void drawBorder(Canvas canvas) {
-        float temp;
-        if (animatedValue > 1f) {
-            temp = animatedValue * mRadius;
-        } else {
-            temp = mRadius;
-        }
-        canvas.drawCircle(center, center, temp, borderPaint);
-    }
-
-    // 画checkbox内部
-    private void drawTrim(Canvas canvas) {
-        canvas.drawCircle(center, center, (mRadius - mStrokeWidth) * animatedValue, trimPaint);
-    }
-
-    @Override
-    public void onClick(View view) {
-        toggle();
-    }
-
-    /**
-     * 判断checkbox是否选中状态
-     *
-     * @return
-     */
-    public boolean isChecked() {
-        return isChecked;
-    }
-
-    /**
-     * 设置checkbox的状态
-     *
-     * @param isChecked 是否选中
-     */
-    public void setChecked(boolean isChecked) {
-        this.setChecked(isChecked, false);
-    }
-
-    /**
-     * 设置checkbox的状态
-     *
-     * @param isChecked   是否选中
-     * @param isAnimation 切换时是否有动画
-     */
-    public void setChecked(boolean isChecked, boolean isAnimation) {
-        this.isChecked = isChecked;
-        if (isAnimation) {
-            if (isChecked) {
-                checkedAnimation();
-            } else {
-                uncheckedAnimation();
-            }
-        } else {
-            animatedValue = isChecked ? 1f : 0f;
-            tickValue = 1f;
-            invalidate();
-        }
-        if (listener != null) {
-            listener.onCheckedChanged(this, isChecked);
-        }
-    }
-
-    public interface OnCheckedChangeListener {
-        void onCheckedChanged(SmoothCheckBox smoothCheckBox, boolean isChecked);
-    }
-}

+ 0 - 261
androidjava/src/main/java/com/mylove/baselib/widget/TouchImageView.java

@@ -1,261 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.widget.ImageView;
-
-/**
- * @author yanyi
- * 图片手势旋转与缩放
- */
-
-@SuppressLint("AppCompatCustomView")
-public class TouchImageView extends ImageView {
-    private static final float MIN_POINT_DISTINCT = 10F;
-    private Matrix matrix;
-    private Matrix cacheMatrix;  //缓存的matrix ,同时记录上一次滑动的位置
-    private float mPointDistinct = 1f;
-    private float mDegree;
-    private float rotate = 0F;// 旋转的角度
-
-    // We can be in one of these 3 states
-    float minScale = 1f;
-    float maxScale = 3f;
-    float[] m;
-
-
-    int viewWidth, viewHeight;
-    static final int CLICK = 3;
-    float saveScale = 1f;
-    protected float origWidth, origHeight;
-    int oldMeasuredWidth, oldMeasuredHeight;
-
-
-    ScaleGestureDetector mScaleDetector;
-
-    Context context;
-
-    enum Mode {
-        NONE, DOWN, MOVE
-    }
-
-    private Mode mode; //当前mode
-    private Context mContext;
-
-    private PointF mStart = new PointF();
-    private PointF mEnd = new PointF();
-
-    public TouchImageView(Context context) {
-        this(context, null);
-    }
-
-    public TouchImageView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TouchImageView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        this.mContext = context;
-        init();
-    }
-
-    private void init() {
-        matrix = new Matrix();
-        cacheMatrix = new Matrix();
-        mode = Mode.NONE;
-
-//        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
-        m = new float[9];
-        setImageMatrix(matrix);
-        setScaleType(ScaleType.MATRIX);
-    }
-
-    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
-        @Override
-        public boolean onScaleBegin(ScaleGestureDetector detector) {
-//            mode = ZOOM;
-            return true;
-        }
-
-        @Override
-        public boolean onScale(ScaleGestureDetector detector) {
-            float mScaleFactor = detector.getScaleFactor();
-            float origScale = saveScale;
-            saveScale *= mScaleFactor;
-            if (saveScale > maxScale) {
-                saveScale = maxScale;
-                mScaleFactor = maxScale / origScale;
-            } else if (saveScale < minScale) {
-                saveScale = minScale;
-                mScaleFactor = minScale / origScale;
-            }
-
-            if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)
-                matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);
-            else
-                matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
-
-            fixTrans();
-            return true;
-        }
-    }
-
-    @SuppressLint("ClickableViewAccessibility")
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        switch (event.getAction() & MotionEvent.ACTION_MASK) {
-            case MotionEvent.ACTION_DOWN:
-                cacheMatrix.set(matrix); //先拷贝一份到缓存
-                mode = Mode.DOWN;
-                mStart.set(event.getX(), event.getY());
-                break;
-            case MotionEvent.ACTION_POINTER_DOWN:
-                mPointDistinct = calSpacing(event);
-                if (mPointDistinct > MIN_POINT_DISTINCT) {
-                    cacheMatrix.set(matrix); //先拷贝一份到缓存
-                    calPoint(mEnd, event);
-                    mode = Mode.MOVE;
-                }
-                mDegree = calRotation(event);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                //单点触控的时候
-                if (mode == Mode.DOWN) {
-                    matrix.set(cacheMatrix);
-                    matrix.postTranslate(event.getX() - mStart.x, event.getY() - mStart.y);
-                } else if (mode == Mode.MOVE && event.getPointerCount() == 2) {  //只能2只手
-                    matrix.set(cacheMatrix);
-                    float move = calSpacing(event);
-                    if (move > MIN_POINT_DISTINCT) {
-                        float scale = move / mPointDistinct;
-                        matrix.postScale(scale, scale, mEnd.x, mEnd.y);
-
-                    }
-                    rotate = calRotation(event);
-                    float r = rotate - mDegree;
-                    matrix.postRotate(r, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
-                }
-
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_POINTER_UP:
-            case MotionEvent.ACTION_CANCEL:
-                mode = Mode.NONE;
-                break;
-
-        }
-
-        setImageMatrix(matrix);
-        return true;
-    }
-
-
-    private float calSpacing(MotionEvent event) {
-        float x = event.getX(0) - event.getX(1);
-        float y = event.getY(0) - event.getY(1);
-        return (float) Math.sqrt(x * x + y * y);
-    }
-
-    private void calPoint(PointF point, MotionEvent event) {
-        float x = event.getX(0) + event.getX(1);
-        float y = event.getY(0) + event.getY(1);
-        point.set(x / 2, y / 2);
-    }
-
-    private float calRotation(MotionEvent event) {
-        double deltaX = (event.getX(0) - event.getX(1));
-        double deltaY = (event.getY(0) - event.getY(1));
-        double radius = Math.atan2(deltaY, deltaX);
-        return (float) Math.toDegrees(radius);
-    }
-
-    public void reset() {
-        matrix.reset();
-        cacheMatrix.reset();
-        setImageMatrix(matrix);
-        invalidate();
-    }
-
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        viewWidth = MeasureSpec.getSize(widthMeasureSpec);
-        viewHeight = MeasureSpec.getSize(heightMeasureSpec);
-
-        //
-        // Rescales image on rotation
-        //
-        if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
-                || viewWidth == 0 || viewHeight == 0)
-            return;
-        oldMeasuredHeight = viewHeight;
-        oldMeasuredWidth = viewWidth;
-
-        if (saveScale == 1) {
-            //Fit to screen.
-            float scale;
-
-            Drawable drawable = getDrawable();
-            if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)
-                return;
-            int bmWidth = drawable.getIntrinsicWidth();
-            int bmHeight = drawable.getIntrinsicHeight();
-
-            Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);
-
-            float scaleX = (float) viewWidth / (float) bmWidth;
-            float scaleY = (float) viewHeight / (float) bmHeight;
-            scale = Math.min(scaleX, scaleY);
-            matrix.setScale(scale, scale);
-
-            // Center the image
-            float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);
-            float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);
-            redundantYSpace /= (float) 2;
-            redundantXSpace /= (float) 2;
-
-            matrix.postTranslate(redundantXSpace, redundantYSpace);
-
-            origWidth = viewWidth - 2 * redundantXSpace;
-            origHeight = viewHeight - 2 * redundantYSpace;
-            setImageMatrix(matrix);
-        }
-        fixTrans();
-    }
-
-    void fixTrans() {
-        matrix.getValues(m);
-        float transX = m[Matrix.MTRANS_X];
-        float transY = m[Matrix.MTRANS_Y];
-
-        float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);
-        float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);
-
-        if (fixTransX != 0 || fixTransY != 0)
-            matrix.postTranslate(fixTransX, fixTransY);
-    }
-
-    float getFixTrans(float trans, float viewSize, float contentSize) {
-        float minTrans, maxTrans;
-
-        if (contentSize <= viewSize) {
-            minTrans = 0;
-            maxTrans = viewSize - contentSize;
-        } else {
-            minTrans = viewSize - contentSize;
-            maxTrans = 0;
-        }
-
-        if (trans < minTrans)
-            return -trans + minTrans;
-        if (trans > maxTrans)
-            return -trans + maxTrans;
-        return 0;
-    }
-}

+ 0 - 94
androidjava/src/main/java/com/mylove/baselib/widget/VerticalScrollLayout.java

@@ -1,94 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.ListAdapter;
-import android.widget.ViewFlipper;
-
-import com.mylove.baselib.R;
-
-/**
- * @author yanyi
- * 自动滚动布局
- */
-
-public class VerticalScrollLayout extends ViewFlipper {
-    private ListAdapter mAdapter;
-    private int interval = 2000;
-    /**
-     * 动画时间
-     */
-    private int animDuration = 500;
-
-    public VerticalScrollLayout(Context context) {
-        this(context, null);
-    }
-
-    public VerticalScrollLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init(attrs);
-    }
-
-    private void init(AttributeSet attrs) {
-        TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.VerticalScrollLayout);
-        animDuration = array.getInt(R.styleable.VerticalScrollLayout_VAnimDuration, animDuration);
-        boolean isSetAnimDuration = array.getBoolean(R.styleable.VerticalScrollLayout_VIsCusDuration, false);
-        interval = array.getInt(R.styleable.VerticalScrollLayout_VSleepTime, interval);
-        array.recycle();
-        setFlipInterval(interval);
-        Animation animIn = AnimationUtils.loadAnimation(getContext(), R.anim.anim_scroll_in);
-        Animation animOut = AnimationUtils.loadAnimation(getContext(), R.anim.anim_scroll_out);
-        if (isSetAnimDuration) {
-            animIn.setDuration(animDuration);
-            animOut.setDuration(animDuration);
-        }
-        setInAnimation(animIn);
-        setOutAnimation(animOut);
-    }
-
-    private DataSetObserver mDataObserver = new DataSetObserver() {
-
-        @Override
-        public void onChanged() {
-            setupChildren();
-        }
-
-        @Override
-        public void onInvalidated() {
-            setupChildren();
-        }
-
-    };
-
-    public void setAdapter(ListAdapter adapter) {
-        if (mAdapter != null) {
-            mAdapter.unregisterDataSetObserver(mDataObserver);
-        }
-
-        mAdapter = adapter;
-
-        if (mAdapter != null) {
-            mAdapter.registerDataSetObserver(mDataObserver);
-        }
-        setupChildren();
-    }
-
-    private void setupChildren() {
-        if (mAdapter == null || mAdapter.getCount() == 0) return;
-        removeAllViews();
-        for (int i = 0; i < mAdapter.getCount(); i++) {
-            View child = mAdapter.getView(i, null, this);
-            if (child == null) {
-                throw new NullPointerException("View can't be null");
-            } else {
-                addView(child);
-            }
-        }
-        startFlipping();
-    }
-}

+ 0 - 281
androidjava/src/main/java/com/mylove/baselib/widget/VerticalScrollTextView.java

@@ -1,281 +0,0 @@
-package com.mylove.baselib.widget;
-
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.os.Handler;
-import android.os.Message;
-import android.support.annotation.IntRange;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.ViewGroup;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.mylove.baselib.R;
-
-import java.lang.ref.WeakReference;
-import java.util.List;
-
-/**
- * @author yanyi
- * 竖直方向自动滚动文字
- */
-
-public class VerticalScrollTextView extends RelativeLayout {
-    /**
-     * 默认轮播时间间隔:3s
-     */
-    private final static int SLEEP_TIME = 3000;
-
-    /**
-     * 默认动画执行时间:1s
-     */
-    private final static int ANIM_DURATION = 1000;
-
-    /**
-     * 轮播时间间隔
-     */
-    private int sleepTime = SLEEP_TIME;
-
-    /**
-     * 动画执行时间
-     */
-    private int animDuration = ANIM_DURATION;
-    private boolean mSingleLine;
-    private int mTextColor;
-    private int mTextSize;
-    /**
-     * 滚动方向
-     */
-    private int scrollOrientation;
-
-    private List<String> mDataSource;
-
-    private TextView mTvContentTop;
-
-    private TextView mTvContentBottom;
-
-    /**
-     * 是否运行轮播图
-     */
-    protected boolean mIsRun;
-
-    /**
-     * 自动轮播使用的handler
-     */
-    private Handler mHandler;
-
-    /**
-     * 当前轮播的项索引
-     */
-    private int mCurrentItemIndex;
-    private int heightSize;
-
-    public VerticalScrollTextView(Context context) {
-        super(context);
-
-        init(context);
-    }
-
-    public VerticalScrollTextView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.VerticalScrollTextView);
-        sleepTime = array.getInt(R.styleable.VerticalScrollTextView_sleepTime, SLEEP_TIME);
-        animDuration = array.getInt(R.styleable.VerticalScrollTextView_animDuration, ANIM_DURATION);
-        scrollOrientation = array.getInt(R.styleable.VerticalScrollTextView_scrollOrientation, 0);
-        mTextSize = array.getDimensionPixelSize(R.styleable.VerticalScrollTextView_textSize,
-                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
-                        12, getResources().getDisplayMetrics()));
-        mTextColor = array.getColor(R.styleable.VerticalScrollTextView_textColor, Color.BLACK);
-        mSingleLine = array.getBoolean(R.styleable.VerticalScrollTextView_singleLine, true);
-        array.recycle();
-
-        init(context);
-    }
-
-    private void init(Context context) {
-        initTextView(context);
-        RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams
-                (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-        lp1.addRule(RelativeLayout.CENTER_VERTICAL);
-
-        addView(mTvContentTop, lp1);
-        addView(mTvContentBottom, lp1);
-
-        mHandler = new SliderScrollHandler(this);
-    }
-
-    private void initTextView(Context context) {
-        mTvContentTop = new TextView(context);
-        mTvContentTop.setTextColor(mTextColor);
-        mTvContentTop.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
-        mTvContentTop.setSingleLine(mSingleLine);
-
-        mTvContentBottom = new TextView(context);
-        mTvContentBottom.setTextColor(mTextColor);
-        mTvContentBottom.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
-        mTvContentBottom.setSingleLine(mSingleLine);
-        if (mSingleLine) {
-            mTvContentTop.setEllipsize(TextUtils.TruncateAt.END);
-
-            mTvContentBottom.setEllipsize(TextUtils.TruncateAt.END);
-        }
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        heightSize = getMeasuredHeight();
-    }
-
-    /**
-     * 重置
-     */
-    private void resetData() {
-        if (mDataSource == null || mDataSource.size() == 0) {
-            return;
-        }
-
-        String normal = mDataSource.get(0);
-
-        if (normal != null) {
-            mTvContentTop.setText(normal);
-        }
-    }
-
-    /**
-     * 滚动
-     */
-    private void autoSlider() {
-        if (mDataSource == null || mDataSource.size() < 2) {
-            return;
-        }
-
-        String normal = mDataSource.get(mCurrentItemIndex);
-
-        if (normal != null) {
-            mTvContentTop.setText(normal);
-        }
-
-        if (mCurrentItemIndex == mDataSource.size() - 1) {
-            mCurrentItemIndex = 0;
-        } else {
-            mCurrentItemIndex = mCurrentItemIndex + 1;
-        }
-
-        String next = mDataSource.get(mCurrentItemIndex);
-
-        if (next != null) {
-            mTvContentBottom.setText(next);
-        }
-        startTopAnim();
-        startBottomAnim();
-    }
-
-    private void startTopAnim() {
-        int value = -heightSize;  //默认朝上
-        if (scrollOrientation != 0) {
-            //朝下
-            value = heightSize;
-        }
-
-        ObjectAnimator.ofFloat(mTvContentTop, "translationY", 0F, value)
-                // 设置执行时间(1000ms)
-                .setDuration(animDuration)
-                // 开始动画
-                .start();
-    }
-
-    private void startBottomAnim() {
-        int value = heightSize;  //默认朝上
-        if (scrollOrientation != 0) {
-            //朝下
-            value = -heightSize;
-        }
-
-        ObjectAnimator.ofFloat(mTvContentBottom, "translationY", value, 0F)
-                // 设置执行时间(1000ms)
-                .setDuration(animDuration)
-                // 开始动画
-                .start();
-    }
-
-    /**
-     * 轮播滚动Handler
-     */
-    private static class SliderScrollHandler extends Handler {
-        private WeakReference<VerticalScrollTextView> mSliderView;
-
-        SliderScrollHandler(VerticalScrollTextView sliderView) {
-            mSliderView = new WeakReference<>(sliderView);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-            switch (msg.what) {
-                case 0:
-                    VerticalScrollTextView sliderView = mSliderView.get();
-                    if (sliderView != null && mSliderView.get().mIsRun) {
-                        sliderView.autoSlider();
-                        //重复
-                        this.sendEmptyMessageDelayed(0, mSliderView.get().sleepTime);
-                    }
-                    break;
-            }
-        }
-    }
-
-    public void setDataSource(List<String> dataSource) {
-        this.mDataSource = dataSource;
-        mCurrentItemIndex = 0;
-        resetData();
-    }
-
-    /**
-     * Description: 开始轮播
-     */
-    public void startPlay() {
-        if (mHandler != null) {
-            mIsRun = true;
-            mHandler.removeCallbacksAndMessages(null);
-            mHandler.sendEmptyMessageDelayed(0, sleepTime);
-        }
-    }
-
-    /**
-     * Description: 暂停轮播
-     */
-    public void stopPlay() {
-        if (mHandler != null) {
-            mIsRun = false;
-            mHandler.removeCallbacksAndMessages(null);
-        }
-    }
-
-    /**
-     * 设置轮播的间隔时间
-     *
-     * @param sleepTime 单位:毫秒
-     */
-    public void setSleepTime(int sleepTime) {
-        this.sleepTime = sleepTime;
-    }
-
-    /**
-     * 设置动画执行时间
-     *
-     * @param animDuration 单位:毫秒
-     */
-    public void setAnimDuration(int animDuration) {
-        this.animDuration = animDuration;
-    }
-
-    public void setScrollOrientation(@IntRange(from = 0, to = 1) int scrollOrientation) {
-        this.scrollOrientation = scrollOrientation;
-    }
-}

+ 0 - 11
androidjava/src/main/res/anim/anim_scroll_in.xml

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-    <translate
-        android:duration="300"
-        android:fromYDelta="100%p"
-        android:toYDelta="0"/>
-    <alpha
-        android:duration="500"
-        android:fromAlpha="0.0"
-        android:toAlpha="1.0"/>
-</set>

+ 0 - 11
androidjava/src/main/res/anim/anim_scroll_out.xml

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-    <translate
-        android:duration="400"
-        android:fromYDelta="0"
-        android:toYDelta="-100%p"/>
-    <alpha
-        android:duration="500"
-        android:fromAlpha="1.0"
-        android:toAlpha="0.0"/>
-</set>

+ 0 - 33
androidjava/src/main/res/values/attrs.xml

@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <declare-styleable name="VerticalScrollTextView">
-        <attr name="sleepTime" format="integer" />
-        <attr name="animDuration" format="integer" />
-        <attr name="textSize" format="dimension" />
-        <attr name="textColor" format="color" />
-        <attr name="singleLine" format="boolean" />
-        <attr name="scrollOrientation">
-            <enum name="up" value="0" />
-            <enum name="down" value="1" />
-        </attr>
-    </declare-styleable>
-    <declare-styleable name="VerticalScrollLayout">
-        <attr name="VAnimDuration" format="integer" />
-        <attr name="VSleepTime" format="integer" />
-        <attr name="VIsCusDuration" format="boolean" />
-    </declare-styleable>
-    <declare-styleable name="SmoothCheckBox">
-        <!-- 动画持续时间 -->
-        <attr name="BenDuration" format="integer" />
-        <!-- 边框宽度 -->
-        <attr name="BenStrikeWidth" format="dimension|reference" />
-        <!-- 边框颜色 -->
-        <attr name="BenBorderColor" format="color|reference" />
-        <!-- 选中状态的颜色 -->
-        <attr name="BenTrimColor" format="color|reference" />
-        <!-- 对勾颜色 -->
-        <attr name="BenTickColor" format="color|reference" />
-        <!-- 对勾宽度 -->
-        <attr name="BenTickWidth" format="dimension|reference" />
-    </declare-styleable>
-</resources>

+ 1 - 2
app/build.gradle

@@ -24,7 +24,6 @@ dependencies {
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'com.android.support.test:runner:1.0.2'
     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
-    implementation 'com.jakewharton:butterknife:8.8.1'
-    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
     implementation project(':androidjava')
+    implementation 'com.android.support:recyclerview-v7:28.0.0'
 }

+ 46 - 35
app/src/main/java/com/mylove/basejava/MainActivity.java

@@ -1,53 +1,64 @@
 package com.mylove.basejava;
 
-import android.os.Environment;
+import android.os.Bundle;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
 
-import com.mylove.baselib.activity.permission.BasePermissionsActivity;
-import com.mylove.loglib.JLog;
-import com.mylove.okhttp.OkHttpUtil;
-import com.mylove.okhttp.OnDownloadListener;
-import com.yanyi.permissionlib.PermissionType;
+import com.mylove.baselib.activity.BaseActivity;
+import com.mylove.baselib.adapter.CommonRecyclerAdapter;
+import com.mylove.baselib.viewholder.RecyclerHolder;
+import com.mylove.viewbind.BindView;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @author myLove
  */
-public class MainActivity extends BasePermissionsActivity {
+public class MainActivity extends BaseActivity {
+
+    @BindView(R.id.recycler)
+    RecyclerView recyclerView;
+    private CommonRecyclerAdapter<String> mAdapter;
+    private List<String> oList = new ArrayList<>();
+    private CommonRecyclerAdapter<Integer> adapter;
+    private List<Integer> mList = new ArrayList<>();
+
     @Override
-    protected String[] setPermissions() {
-        return new String[]{PermissionType.STORAGE};
+    protected int setLayoutID() {
+        return R.layout.main_activity;
     }
 
     @Override
-    protected void allPermissionSuccess() {
-        String url = "http://www.yanyi.red/bluetooth/dfu_pkg0904.zip";
-        String filePath = Environment.getExternalStorageDirectory().toString() + "/dectector/dfu/";
-        JLog.init(true);
-        JLog.d(filePath);
-        OkHttpUtil.getInstance(mContext).downloadFile(url).download(filePath, new OnDownloadListener() {
+    protected void init(Bundle savedInstanceState) {
+        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+        mAdapter = new CommonRecyclerAdapter<String>(mContext, oList, R.layout.item_layout) {
             @Override
-            public void onDownloading(int progress) {
-                JLog.d("进度" + progress + "%");
-            }
-
-            @Override
-            public void onCompleted() {
+            public void convert(RecyclerHolder mHolder, String item, int position, boolean isScrolling) {
 
             }
-
+        };
+        recyclerView.setAdapter(mAdapter);
+        View mView = LayoutInflater.from(mContext).inflate(R.layout.head_layout, null);
+        RecyclerView mRecycler = mView.findViewById(R.id.mrecycler);
+        mRecycler.setLayoutManager(new LinearLayoutManager(mContext));
+        adapter = new CommonRecyclerAdapter<Integer>(mContext, mList, R.layout.item_head) {
             @Override
-            public <T> void onSuccess(T message) {
-                JLog.i("文件地址" + message);
+            public void convert(RecyclerHolder mHolder, Integer item, int position, boolean isScrolling) {
+                mHolder.setImageResource(R.id.img, item);
             }
-
-            @Override
-            public void onFailure(Throwable t) {
-                JLog.e(t.getMessage());
-            }
-        });
-    }
-
-    @Override
-    protected int setLayoutID() {
-        return R.layout.main_activity;
+        };
+        mRecycler.setAdapter(adapter);
+        mAdapter.addHeaderView(mView);
+        for (int i = 0; i < 10; i++) {
+            oList.add("哈哈哈" + i);
+        }
+        for (int i = 0; i < 5; i++) {
+            mList.add(R.mipmap.ic_launcher);
+        }
+        adapter.notifyDataSetChanged(mList);
+        mAdapter.notifyDataSetChanged(oList);
     }
 }

+ 11 - 0
app/src/main/res/layout/head_layout.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/mrecycler"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</LinearLayout>

+ 12 - 0
app/src/main/res/layout/item_head.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <ImageView
+        android:id="@+id/img"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</LinearLayout>

+ 15 - 0
app/src/main/res/layout/item_layout.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/comm_gray"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/padding1"
+        android:background="@color/comm_white"
+        android:padding="@dimen/length10" />
+</LinearLayout>

+ 3 - 4
app/src/main/res/layout/main_activity.xml

@@ -7,9 +7,8 @@
 
     <include layout="@layout/comm_toolbar" />
 
-    <TextView
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/recycler"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:gravity="center"
-        android:text="Hello World" />
+        android:layout_height="wrap_content" />
 </LinearLayout>