diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6d5dd44..89482aa 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt b/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt
index 0cf6c85..2f0002d 100644
--- a/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt
+++ b/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt
@@ -1,5 +1,6 @@
package com.novel.read.activity
+import android.content.DialogInterface
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
@@ -169,16 +170,16 @@ class NovelSearchActivity : NovelBaseActivity() {
saveKey()
}
head_history.setOnClickListener { view ->
- DialogUtils.getInstance()
- .showAlertDialog(
- this@NovelSearchActivity,
- getString(R.string.clear_search)
- ) { dialogInterface, i ->
+
+ DialogUtils.getInstance().showAlertDialog(
+ this,
+ getString(R.string.clear_search),
+ dialogListener = DialogInterface.OnClickListener { dialog, which ->
LitePal.deleteAll(SearchListTable::class.java)
mHisList.clear()
mHisList.addAll(LitePal.order("saveTime desc").limit(5).find(SearchListTable::class.java))
mHisAdapter!!.notifyDataSetChanged()
- }
+ })
}
tv_cancel.setOnClickListener {
diff --git a/app/src/main/java/com/novel/read/utlis/Charset.java b/app/src/main/java/com/novel/read/utlis/Charset.java
index 186758d..3632774 100644
--- a/app/src/main/java/com/novel/read/utlis/Charset.java
+++ b/app/src/main/java/com/novel/read/utlis/Charset.java
@@ -12,7 +12,7 @@ public enum Charset {
private String mName;
public static final byte BLANK = 0x0a;
- private Charset(String name) {
+ Charset(String name) {
mName = name;
}
diff --git a/app/src/main/java/com/novel/read/utlis/CleanCacheUtils.java b/app/src/main/java/com/novel/read/utlis/CleanCacheUtils.java
deleted file mode 100644
index db06995..0000000
--- a/app/src/main/java/com/novel/read/utlis/CleanCacheUtils.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package com.novel.read.utlis;
-
-import android.content.Context;
-import android.os.Environment;
-
-import com.novel.read.model.db.BookChapterBean;
-import com.novel.read.model.db.CollBookBean;
-import com.novel.read.model.db.SearchListTable;
-
-import org.litepal.LitePal;
-
-import java.io.File;
-import java.math.BigDecimal;
-
-/**
- * @author: LiJun 390057892@qq.com
- * @date: 2018/4/11 16:00
- */
-
-public class CleanCacheUtils {
-
- private static CleanCacheUtils manager;
-
- public static CleanCacheUtils getInstance() {
- return manager == null ? (manager = new CleanCacheUtils()) : manager;
- }
-
- /**
- * @param context
- * @return
- * @throws Exception
- * 获取当前缓存
- */
- public String getTotalCacheSize(Context context) throws Exception {
- long cacheSize = getFolderSize(context.getCacheDir());
- if (Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)) {
- cacheSize += getFolderSize(context.getExternalCacheDir());
- }
- return getFormatSize(cacheSize);
- }
-
- /**
- * @param context
- * 删除缓存
- */
- public static void clearAllCache(Context context) {
- deleteDir(context.getCacheDir());
- if (Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)) {
- deleteDir(context.getExternalCacheDir());
- }
- }
-
- private static boolean deleteDir(File dir) {
- if (dir != null && dir.isDirectory()) {
- String[] children = dir.list();
- int size = 0;
- if (children != null) {
- size = children.length;
- for (int i = 0; i < size; i++) {
- boolean success = deleteDir(new File(dir, children[i]));
- if (!success) {
- return false;
- }
- }
- }
-
- }
- if (dir == null) {
- return true;
- } else {
-
- return dir.delete();
- }
- }
-
- // 获取文件
- // Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/
- // 目录,一般放一些长时间保存的数据
- // Context.getExternalCacheDir() -->
- // SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
- public static long getFolderSize(File file) throws Exception {
- long size = 0;
- try {
- File[] fileList = file.listFiles();
- int size2 = 0;
- if (fileList != null) {
- size2 = fileList.length;
- for (int i = 0; i < size2; i++) {
- // 如果下面还有文件
- if (fileList[i].isDirectory()) {
- size = size + getFolderSize(fileList[i]);
- } else {
- size = size + fileList[i].length();
- }
- }
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- return size;
- }
-
- /**
- * 格式化单位
- * 计算缓存的大小
- * @param size
- * @return
- */
- public static String getFormatSize(double size) {
- double kiloByte = size / 1024;
- if (kiloByte < 1) {
- // return size + "Byte";
- return "0K";
- }
-
- double megaByte = kiloByte / 1024;
- if (megaByte < 1) {
- BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
- return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
- .toPlainString() + "KB";
- }
-
- double gigaByte = megaByte / 1024;
- if (gigaByte < 1) {
- BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
- return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
- .toPlainString() + "MB";
- }
-
- double teraBytes = gigaByte / 1024;
- if (teraBytes < 1) {
- BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
- return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
- .toPlainString() + "GB";
- }
- BigDecimal result4 = new BigDecimal(teraBytes);
- return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
- + "TB";
- }
-
-
- /**
- * 清除缓存
- *
- * @param clearReadPos 是否删除阅读记录
- */
- public synchronized void clearCache(boolean clearReadPos, boolean clearCollect,Context context) {
- try {
- clearAllCache(context);
- // 删除搜索记录(SharePreference)
- if (clearReadPos) {
- LitePal.deleteAll(SearchListTable.class);
- }
- // 清空书架
- if (clearCollect) {
- LitePal.deleteAll(CollBookBean.class);
- LitePal.deleteAll(BookChapterBean.class);
- }
- } catch (Exception e) {
- }
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/utlis/CleanCacheUtils.kt b/app/src/main/java/com/novel/read/utlis/CleanCacheUtils.kt
new file mode 100644
index 0000000..0e15a1b
--- /dev/null
+++ b/app/src/main/java/com/novel/read/utlis/CleanCacheUtils.kt
@@ -0,0 +1,170 @@
+package com.novel.read.utlis
+
+import android.content.Context
+import android.os.Environment
+
+import com.novel.read.model.db.BookChapterBean
+import com.novel.read.model.db.CollBookBean
+import com.novel.read.model.db.SearchListTable
+
+import org.litepal.LitePal
+
+import java.io.File
+import java.math.BigDecimal
+
+/**
+ * @author: LiJun 390057892@qq.com
+ * @date: 2018/4/11 16:00
+ */
+
+class CleanCacheUtils {
+
+ /**
+ * @param context
+ * @return
+ * @throws Exception
+ * 获取当前缓存
+ */
+ @Throws(Exception::class)
+ fun getTotalCacheSize(context: Context): String {
+ var cacheSize = getFolderSize(context.cacheDir)
+ if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
+ cacheSize += getFolderSize(context.externalCacheDir)
+ }
+ return getFormatSize(cacheSize.toDouble())
+ }
+
+
+ /**
+ * 清除缓存
+ *
+ * @param clearReadPos 是否删除阅读记录
+ */
+ @Synchronized
+ fun clearCache(clearReadPos: Boolean, clearCollect: Boolean, context: Context) {
+ try {
+ clearAllCache(context)
+ // 删除搜索记录(SharePreference)
+ if (clearReadPos) {
+ LitePal.deleteAll(SearchListTable::class.java)
+ }
+ // 清空书架
+ if (clearCollect) {
+ LitePal.deleteAll(CollBookBean::class.java)
+ LitePal.deleteAll(BookChapterBean::class.java)
+ }
+ } catch (e: Exception) {
+ }
+
+ }
+
+ companion object {
+
+ private var instance: CleanCacheUtils? = null
+
+ @Synchronized
+ fun getInstance(): CleanCacheUtils {
+ if (instance == null) {
+ instance = CleanCacheUtils()
+ }
+ return instance as CleanCacheUtils
+ }
+
+ /**
+ * @param context
+ * 删除缓存
+ */
+ fun clearAllCache(context: Context) {
+ deleteDir(context.cacheDir)
+ if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
+ deleteDir(context.externalCacheDir)
+ }
+ }
+
+ private fun deleteDir(dir: File?): Boolean {
+ if (dir != null && dir.isDirectory) {
+ val children = dir.list()
+ var size = 0
+ if (children != null) {
+ size = children.size
+ for (i in 0 until size) {
+ val success = deleteDir(File(dir, children[i]))
+ if (!success) {
+ return false
+ }
+ }
+ }
+
+ }
+ return dir?.delete() ?: true
+ }
+
+ // 获取文件
+ // Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/
+ // 目录,一般放一些长时间保存的数据
+ // Context.getExternalCacheDir() -->
+ // SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
+ @Throws(Exception::class)
+ fun getFolderSize(file: File?): Long {
+ var size: Long = 0
+ try {
+ val fileList = file!!.listFiles()
+ var size2 = 0
+ if (fileList != null) {
+ size2 = fileList.size
+ for (i in 0 until size2) {
+ // 如果下面还有文件
+ if (fileList[i].isDirectory) {
+ size = size + getFolderSize(fileList[i])
+ } else {
+ size = size + fileList[i].length()
+ }
+ }
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ return size
+ }
+
+ /**
+ * 格式化单位
+ * 计算缓存的大小
+ * @param size
+ * @return
+ */
+ fun getFormatSize(size: Double): String {
+ val kiloByte = size / 1024
+ if (kiloByte < 1) {
+ // return size + "Byte";
+ return "0K"
+ }
+
+ val megaByte = kiloByte / 1024
+ if (megaByte < 1) {
+ val result1 = BigDecimal(java.lang.Double.toString(kiloByte))
+ return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
+ .toPlainString() + "KB"
+ }
+
+ val gigaByte = megaByte / 1024
+ if (gigaByte < 1) {
+ val result2 = BigDecimal(java.lang.Double.toString(megaByte))
+ return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
+ .toPlainString() + "MB"
+ }
+
+ val teraBytes = gigaByte / 1024
+ if (teraBytes < 1) {
+ val result3 = BigDecimal(java.lang.Double.toString(gigaByte))
+ return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
+ .toPlainString() + "GB"
+ }
+ val result4 = BigDecimal(teraBytes)
+ return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB"
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/novel/read/utlis/DialogUtils.java b/app/src/main/java/com/novel/read/utlis/DialogUtils.java
deleted file mode 100644
index f56ef7b..0000000
--- a/app/src/main/java/com/novel/read/utlis/DialogUtils.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.novel.read.utlis;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-
-/**
- * create by zlj on 2019/6/19
- * describe:
- */
-public class DialogUtils {
-
- private static DialogUtils dialogUtils;
-
- public static DialogUtils getInstance() {
- if (dialogUtils == null) {
- dialogUtils = new DialogUtils();
- }
- return dialogUtils;
- }
-
- private DialogUtils() { }
-
- public void showAlertDialog(Context context, String msg, DialogInterface.OnClickListener dialogListener) {
- // context = context.getApplicationContext();
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle("操作提示").setMessage(msg).setCancelable(false).setPositiveButton("确定", dialogListener).setNegativeButton("取消", new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
- AlertDialog alert = builder.create();
- alert.show();
- }
-}
diff --git a/app/src/main/java/com/novel/read/utlis/DialogUtils.kt b/app/src/main/java/com/novel/read/utlis/DialogUtils.kt
new file mode 100644
index 0000000..09e3b1a
--- /dev/null
+++ b/app/src/main/java/com/novel/read/utlis/DialogUtils.kt
@@ -0,0 +1,39 @@
+package com.novel.read.utlis
+
+import android.app.AlertDialog
+import android.content.Context
+import android.content.DialogInterface
+
+/**
+ * create by zlj on 2019/6/19
+ * describe:
+ */
+class DialogUtils private constructor() {
+
+ fun showAlertDialog(
+ context: Context,
+ msg: String,
+ dialogListener: DialogInterface.OnClickListener
+ ) {
+ // context = context.getApplicationContext();
+ val builder = AlertDialog.Builder(context)
+ builder.setTitle("操作提示").setMessage(msg).setCancelable(false)
+ .setPositiveButton("确定", dialogListener)
+ .setNegativeButton("取消") { dialog, id -> dialog.cancel() }
+ val alert = builder.create()
+ alert.show()
+ }
+
+ companion object {
+
+ private var instance: DialogUtils? = null
+
+ @Synchronized
+ fun getInstance(): DialogUtils {
+ if (instance == null) {
+ instance = DialogUtils()
+ }
+ return instance as DialogUtils
+ }
+ }
+}
diff --git a/app/src/main/java/com/novel/read/widget/page/PageMode.java b/app/src/main/java/com/novel/read/widget/page/PageMode.kt
similarity index 64%
rename from app/src/main/java/com/novel/read/widget/page/PageMode.java
rename to app/src/main/java/com/novel/read/widget/page/PageMode.kt
index 58dac4b..92d9ac7 100644
--- a/app/src/main/java/com/novel/read/widget/page/PageMode.java
+++ b/app/src/main/java/com/novel/read/widget/page/PageMode.kt
@@ -1,9 +1,9 @@
-package com.novel.read.widget.page;
+package com.novel.read.widget.page
/**
* Created by zlj
* 作用:翻页动画的模式
*/
-public enum PageMode {
+enum class PageMode {
SIMULATION, COVER, SLIDE, NONE, SCROLL
}
diff --git a/app/src/main/java/com/novel/read/widget/page/PageStyle.java b/app/src/main/java/com/novel/read/widget/page/PageStyle.java
deleted file mode 100644
index 86f5a3e..0000000
--- a/app/src/main/java/com/novel/read/widget/page/PageStyle.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.novel.read.widget.page;
-
-
-import androidx.annotation.ColorRes;
-
-import com.novel.read.R;
-
-/**
- * Created by zlj
- * 页面的展示风格。
- */
-public enum PageStyle {
- BG_0(R.color.read_font_one, R.color.read_bg_one),
- BG_1(R.color.read_font_two, R.color.read_bg_two),
-// BG_2(R.color.nb_read_font_3, R.color.nb_read_bg_3),
- BG_3(R.color.read_font_four, R.color.read_bg_four),
- BG_4(R.color.read_font_five, R.color.read_bg_five),
- NIGHT(R.color.read_font_night, R.color.read_bg_night),;
-
- private int fontColor;
- private int bgColor;
-
- PageStyle(@ColorRes int fontColor, @ColorRes int bgColor) {
- this.fontColor = fontColor;
- this.bgColor = bgColor;
- }
-
- public int getFontColor() {
- return fontColor;
- }
-
- public int getBgColor() {
- return bgColor;
- }
-}
diff --git a/app/src/main/java/com/novel/read/widget/page/PageStyle.kt b/app/src/main/java/com/novel/read/widget/page/PageStyle.kt
new file mode 100644
index 0000000..6082c79
--- /dev/null
+++ b/app/src/main/java/com/novel/read/widget/page/PageStyle.kt
@@ -0,0 +1,19 @@
+package com.novel.read.widget.page
+
+
+import androidx.annotation.ColorRes
+
+import com.novel.read.R
+
+/**
+ * Created by zlj
+ * 页面的展示风格。
+ */
+enum class PageStyle private constructor(@param:ColorRes val fontColor: Int, @param:ColorRes val bgColor: Int) {
+ BG_0(R.color.read_font_one, R.color.read_bg_one),
+ BG_1(R.color.read_font_two, R.color.read_bg_two),
+ // BG_2(R.color.nb_read_font_3, R.color.nb_read_bg_3),
+ BG_3(R.color.read_font_four, R.color.read_bg_four),
+ BG_4(R.color.read_font_five, R.color.read_bg_five),
+ NIGHT(R.color.read_font_night, R.color.read_bg_night)
+}
diff --git a/app/src/main/java/com/novel/read/widget/page/PageView.java b/app/src/main/java/com/novel/read/widget/page/PageView.java
index 8f72791..6b459a2 100644
--- a/app/src/main/java/com/novel/read/widget/page/PageView.java
+++ b/app/src/main/java/com/novel/read/widget/page/PageView.java
@@ -310,7 +310,7 @@ public class PageView extends View {
public void drawCurPage(boolean isUpdate) {
if (!isPrepare) return;
- if (!isUpdate){
+ if (!isUpdate) {
if (mPageAnim instanceof ScrollPageAnim) {
((ScrollPageAnim) mPageAnim).resetBitmap();
}
diff --git a/app/src/main/java/com/novel/read/widget/page/Void.java b/app/src/main/java/com/novel/read/widget/page/Void.java
deleted file mode 100644
index 73c6948..0000000
--- a/app/src/main/java/com/novel/read/widget/page/Void.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.novel.read.widget.page;
-
-public final class Void {
-}
diff --git a/app/src/main/java/com/novel/read/widget/page/Void.kt b/app/src/main/java/com/novel/read/widget/page/Void.kt
new file mode 100644
index 0000000..9f07962
--- /dev/null
+++ b/app/src/main/java/com/novel/read/widget/page/Void.kt
@@ -0,0 +1,3 @@
+package com.novel.read.widget.page
+
+class Void
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/CoverPageAnim.java b/app/src/main/java/com/novel/read/widget/page/anim/CoverPageAnim.java
deleted file mode 100644
index 2f69300..0000000
--- a/app/src/main/java/com/novel/read/widget/page/anim/CoverPageAnim.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package com.novel.read.widget.page.anim;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.GradientDrawable;
-import android.view.View;
-
-/**
- * Created by zlj
- * 覆盖动画
- */
-
-public class CoverPageAnim extends HorizonPageAnim {
-
- private Rect mSrcRect, mDestRect;
- private GradientDrawable mBackShadowDrawableLR;
-
- public CoverPageAnim(int w, int h, View view, OnPageChangeListener listener) {
- super(w, h, view, listener);
- mSrcRect = new Rect(0, 0, mViewWidth, mViewHeight);
- mDestRect = new Rect(0, 0, mViewWidth, mViewHeight);
- int[] mBackShadowColors = new int[] { 0x66000000,0x00000000};
- mBackShadowDrawableLR = new GradientDrawable(
- GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);
- mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);
- }
-
- @Override
- public void drawStatic(Canvas canvas) {
- if (isCancel){
- mNextBitmap = mCurBitmap.copy(Bitmap.Config.RGB_565, true);
- canvas.drawBitmap(mCurBitmap, 0, 0, null);
- }else {
- canvas.drawBitmap(mNextBitmap, 0, 0, null);
- }
- }
-
- @Override
- public void drawMove(Canvas canvas) {
-
- switch (mDirection){
- case NEXT:
- int dis = (int) (mViewWidth - mStartX + mTouchX);
- if (dis > mViewWidth){
- dis = mViewWidth;
- }
- //计算bitmap截取的区域
- mSrcRect.left = mViewWidth - dis;
- //计算bitmap在canvas显示的区域
- mDestRect.right = dis;
- canvas.drawBitmap(mNextBitmap,0,0,null);
- canvas.drawBitmap(mCurBitmap,mSrcRect,mDestRect,null);
- addShadow(dis,canvas);
- break;
- default:
- mSrcRect.left = (int) (mViewWidth - mTouchX);
- mDestRect.right = (int) mTouchX;
- canvas.drawBitmap(mCurBitmap,0,0,null);
- canvas.drawBitmap(mNextBitmap,mSrcRect,mDestRect,null);
- addShadow((int) mTouchX,canvas);
- break;
- }
- }
-
- //添加阴影
- public void addShadow(int left, Canvas canvas) {
- mBackShadowDrawableLR.setBounds(left, 0, left + 30 , mScreenHeight);
- mBackShadowDrawableLR.draw(canvas);
- }
-
- @Override
- public void startAnim() {
- super.startAnim();
- int dx = 0;
- switch (mDirection){
- case NEXT:
- if (isCancel){
- int dis = (int) ((mViewWidth - mStartX) + mTouchX);
- if (dis > mViewWidth){
- dis = mViewWidth;
- }
- dx = mViewWidth - dis;
- }else{
- dx = (int) -(mTouchX + (mViewWidth - mStartX));
- }
- break;
- default:
- if (isCancel){
- dx = (int) -mTouchX;
- }else{
- dx = (int) (mViewWidth - mTouchX);
- }
- break;
- }
-
- //滑动速度保持一致
- int duration = (400 * Math.abs(dx)) / mViewWidth;
- mScroller.startScroll((int) mTouchX, 0, dx, 0, duration);
- }
-}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/CoverPageAnim.kt b/app/src/main/java/com/novel/read/widget/page/anim/CoverPageAnim.kt
new file mode 100644
index 0000000..2a2795c
--- /dev/null
+++ b/app/src/main/java/com/novel/read/widget/page/anim/CoverPageAnim.kt
@@ -0,0 +1,97 @@
+package com.novel.read.widget.page.anim
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.graphics.drawable.GradientDrawable
+import android.view.View
+import com.novel.read.widget.page.PageAnimation
+
+/**
+ * Created by zlj
+ * 覆盖动画
+ */
+
+class CoverPageAnim(w: Int, h: Int, view: View, listener: PageAnimation.OnPageChangeListener) :
+ HorizonPageAnim(w, h, view, listener) {
+
+ private val mSrcRect: Rect
+ private val mDestRect: Rect
+ private val mBackShadowDrawableLR: GradientDrawable
+
+ init {
+ mSrcRect = Rect(0, 0, mViewWidth, mViewHeight)
+ mDestRect = Rect(0, 0, mViewWidth, mViewHeight)
+ val mBackShadowColors = intArrayOf(0x66000000, 0x00000000)
+ mBackShadowDrawableLR = GradientDrawable(
+ GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors
+ )
+ mBackShadowDrawableLR.gradientType = GradientDrawable.LINEAR_GRADIENT
+ }
+
+ override fun drawStatic(canvas: Canvas) {
+ if (isCancel) {
+ mNextBitmap = mCurBitmap.copy(Bitmap.Config.RGB_565, true)
+ canvas.drawBitmap(mCurBitmap, 0f, 0f, null)
+ } else {
+ canvas.drawBitmap(mNextBitmap, 0f, 0f, null)
+ }
+ }
+
+ override fun drawMove(canvas: Canvas) {
+
+ when (mDirection) {
+ PageAnimation.Direction.NEXT -> {
+ var dis = (mViewWidth - mStartX + mTouchX).toInt()
+ if (dis > mViewWidth) {
+ dis = mViewWidth
+ }
+ //计算bitmap截取的区域
+ mSrcRect.left = mViewWidth - dis
+ //计算bitmap在canvas显示的区域
+ mDestRect.right = dis
+ canvas.drawBitmap(mNextBitmap, 0f, 0f, null)
+ canvas.drawBitmap(mCurBitmap, mSrcRect, mDestRect, null)
+ addShadow(dis, canvas)
+ }
+ else -> {
+ mSrcRect.left = (mViewWidth - mTouchX).toInt()
+ mDestRect.right = mTouchX.toInt()
+ canvas.drawBitmap(mCurBitmap, 0f, 0f, null)
+ canvas.drawBitmap(mNextBitmap, mSrcRect, mDestRect, null)
+ addShadow(mTouchX.toInt(), canvas)
+ }
+ }
+ }
+
+ //添加阴影
+ fun addShadow(left: Int, canvas: Canvas) {
+ mBackShadowDrawableLR.setBounds(left, 0, left + 30, mScreenHeight)
+ mBackShadowDrawableLR.draw(canvas)
+ }
+
+ override fun startAnim() {
+ super.startAnim()
+ var dx = 0
+ when (mDirection) {
+ PageAnimation.Direction.NEXT -> if (isCancel) {
+ var dis = (mViewWidth - mStartX + mTouchX).toInt()
+ if (dis > mViewWidth) {
+ dis = mViewWidth
+ }
+ dx = mViewWidth - dis
+ } else {
+ dx = (-(mTouchX + (mViewWidth - mStartX))).toInt()
+ }
+ else -> if (isCancel) {
+ dx = (-mTouchX).toInt()
+ } else {
+ dx = (mViewWidth - mTouchX).toInt()
+ }
+ }
+
+ //滑动速度保持一致
+ val duration = 400 * Math.abs(dx) / mViewWidth
+ mScroller.startScroll(mTouchX.toInt(), 0, dx, 0, duration)
+ }
+}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/NonePageAnim.java b/app/src/main/java/com/novel/read/widget/page/anim/NonePageAnim.java
deleted file mode 100644
index 630e6b9..0000000
--- a/app/src/main/java/com/novel/read/widget/page/anim/NonePageAnim.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.novel.read.widget.page.anim;
-
-import android.graphics.Canvas;
-import android.view.View;
-
-/**
- * Created by zlj
- * 无
- */
-
-public class NonePageAnim extends HorizonPageAnim{
-
- public NonePageAnim(int w, int h, View view, OnPageChangeListener listener) {
- super(w, h, view, listener);
- }
-
- @Override
- public void drawStatic(Canvas canvas) {
- if (isCancel){
- canvas.drawBitmap(mCurBitmap, 0, 0, null);
- }else {
- canvas.drawBitmap(mNextBitmap, 0, 0, null);
- }
- }
-
- @Override
- public void drawMove(Canvas canvas) {
- if (isCancel){
- canvas.drawBitmap(mCurBitmap, 0, 0, null);
- }else {
- canvas.drawBitmap(mNextBitmap, 0, 0, null);
- }
- }
-
- @Override
- public void startAnim() {
- }
-}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/NonePageAnim.kt b/app/src/main/java/com/novel/read/widget/page/anim/NonePageAnim.kt
new file mode 100644
index 0000000..f574eb7
--- /dev/null
+++ b/app/src/main/java/com/novel/read/widget/page/anim/NonePageAnim.kt
@@ -0,0 +1,32 @@
+package com.novel.read.widget.page.anim
+
+import android.graphics.Canvas
+import android.view.View
+import com.novel.read.widget.page.PageAnimation
+
+/**
+ * Created by zlj
+ * 无
+ */
+
+class NonePageAnim(w: Int, h: Int, view: View, listener: PageAnimation.OnPageChangeListener) :
+ HorizonPageAnim(w, h, view, listener) {
+
+ override fun drawStatic(canvas: Canvas) {
+ if (isCancel) {
+ canvas.drawBitmap(mCurBitmap, 0f, 0f, null)
+ } else {
+ canvas.drawBitmap(mNextBitmap, 0f, 0f, null)
+ }
+ }
+
+ override fun drawMove(canvas: Canvas) {
+ if (isCancel) {
+ canvas.drawBitmap(mCurBitmap, 0f, 0f, null)
+ } else {
+ canvas.drawBitmap(mNextBitmap, 0f, 0f, null)
+ }
+ }
+
+ override fun startAnim() {}
+}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/ScrollPageAnim.java b/app/src/main/java/com/novel/read/widget/page/anim/ScrollPageAnim.java
deleted file mode 100644
index da8f47c..0000000
--- a/app/src/main/java/com/novel/read/widget/page/anim/ScrollPageAnim.java
+++ /dev/null
@@ -1,408 +0,0 @@
-package com.novel.read.widget.page.anim;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-
-import com.novel.read.widget.page.PageAnimation;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * Created by zlj
- * 原理:仿照ListView源码实现的上下滑动效果
- * 问题:
- * 1. 向上翻页,重复的问题 (完成)
- * 2. 滑动卡顿的问题。原因:由于绘制的数据过多造成的卡顿问题。 (主要是文字绘制需要的时长比较多) 解决办法:做文字缓冲
- * 3. 弱网环境下,显示的问题
- */
-public class ScrollPageAnim extends PageAnimation {
- private static final String TAG = "ScrollAnimation";
- // 滑动追踪的时间
- private static final int VELOCITY_DURATION = 1000;
- private VelocityTracker mVelocity;
-
- // 整个Bitmap的背景显示
- private Bitmap mBgBitmap;
-
- // 下一个展示的图片
- private Bitmap mNextBitmap;
-
- // 被废弃的图片列表
- private ArrayDeque mScrapViews;
- // 正在被利用的图片列表
- private ArrayList mActiveViews = new ArrayList<>(2);
-
- // 是否处于刷新阶段
- private boolean isRefresh = true;
-
- public ScrollPageAnim(int w, int h, int marginWidth, int marginHeight,
- View view, OnPageChangeListener listener) {
- super(w, h, marginWidth, marginHeight, view, listener);
- // 创建两个BitmapView
- initWidget();
- }
-
- private void initWidget() {
- mBgBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.RGB_565);
-
- mScrapViews = new ArrayDeque<>(2);
- for (int i = 0; i < 2; ++i) {
- BitmapView view = new BitmapView();
- view.bitmap = Bitmap.createBitmap(mViewWidth, mViewHeight, Bitmap.Config.RGB_565);
- view.srcRect = new Rect(0, 0, mViewWidth, mViewHeight);
- view.destRect = new Rect(0, 0, mViewWidth, mViewHeight);
- view.top = 0;
- view.bottom = view.bitmap.getHeight();
-
- mScrapViews.push(view);
- }
- onLayout();
- isRefresh = false;
- }
-
- // 修改布局,填充内容
- private void onLayout() {
- // 如果还没有开始加载,则从上到下进行绘制
- if (mActiveViews.size() == 0) {
- fillDown(0, 0);
- mDirection = Direction.NONE;
- } else {
- int offset = (int) (mTouchY - mLastY);
- // 判断是下滑还是上拉 (下滑)
- if (offset > 0) {
- int topEdge = mActiveViews.get(0).top;
- fillUp(topEdge, offset);
- }
- // 上拉
- else {
- // 底部的距离 = 当前底部的距离 + 滑动的距离 (因为上滑,得到的值肯定是负的)
- int bottomEdge = mActiveViews.get(mActiveViews.size() - 1).bottom;
- fillDown(bottomEdge, offset);
- }
- }
- }
-
- // 底部填充
- private Iterator downIt;
-
- /**
- * 创建View填充底部空白部分
- *
- * @param bottomEdge :当前最后一个View的底部,在整个屏幕上的位置,即相对于屏幕顶部的距离
- * @param offset :滑动的偏移量
- */
- private void fillDown(int bottomEdge, int offset) {
-
- downIt = mActiveViews.iterator();
- BitmapView view;
-
- // 进行删除
- while (downIt.hasNext()) {
- view = downIt.next();
- view.top = view.top + offset;
- view.bottom = view.bottom + offset;
- // 设置允许显示的范围
- view.destRect.top = view.top;
- view.destRect.bottom = view.bottom;
-
- // 判断是否越界了
- if (view.bottom <= 0) {
- // 添加到废弃的View中
- mScrapViews.add(view);
- // 从Active中移除
- downIt.remove();
- // 如果原先是从上加载,现在变成从下加载,则表示取消
- if (mDirection == Direction.UP) {
- mListener.pageCancel();
- mDirection = Direction.NONE;
- }
- }
- }
-
- // 滑动之后的最后一个 View 的距离屏幕顶部上的实际位置
- int realEdge = bottomEdge + offset;
-
- // 进行填充
- while (realEdge < mViewHeight && mActiveViews.size() < 2) {
- // 从废弃的Views中获取一个
- view = mScrapViews.getFirst();
-/* //擦除其Bitmap(重新创建会不会更好一点)
- eraseBitmap(view.bitmap,view.bitmap.getWidth(),view.bitmap.getHeight(),0,0);*/
- if (view == null) return;
-
- Bitmap cancelBitmap = mNextBitmap;
- mNextBitmap = view.bitmap;
-
- if (!isRefresh) {
- boolean hasNext = mListener.hasNext(); //如果不成功则无法滑动
-
- // 如果不存在next,则进行还原
- if (!hasNext) {
- mNextBitmap = cancelBitmap;
- for (BitmapView activeView : mActiveViews) {
- activeView.top = 0;
- activeView.bottom = mViewHeight;
- // 设置允许显示的范围
- activeView.destRect.top = activeView.top;
- activeView.destRect.bottom = activeView.bottom;
- }
- abortAnim();
- return;
- }
- }
-
- // 如果加载成功,那么就将View从ScrapViews中移除
- mScrapViews.removeFirst();
- // 添加到存活的Bitmap中
- mActiveViews.add(view);
- mDirection = Direction.DOWN;
-
- // 设置Bitmap的范围
- view.top = realEdge;
- view.bottom = realEdge + view.bitmap.getHeight();
- // 设置允许显示的范围
- view.destRect.top = view.top;
- view.destRect.bottom = view.bottom;
-
- realEdge += view.bitmap.getHeight();
- }
- }
-
- private Iterator upIt;
-
- /**
- * 创建View填充顶部空白部分
- *
- * @param topEdge : 当前第一个View的顶部,到屏幕顶部的距离
- * @param offset : 滑动的偏移量
- */
- private void fillUp(int topEdge, int offset) {
- // 首先进行布局的调整
- upIt = mActiveViews.iterator();
- BitmapView view;
- while (upIt.hasNext()) {
- view = upIt.next();
- view.top = view.top + offset;
- view.bottom = view.bottom + offset;
- //设置允许显示的范围
- view.destRect.top = view.top;
- view.destRect.bottom = view.bottom;
-
- // 判断是否越界了
- if (view.top >= mViewHeight) {
- // 添加到废弃的View中
- mScrapViews.add(view);
- // 从Active中移除
- upIt.remove();
-
- // 如果原先是下,现在变成从上加载了,则表示取消加载
-
- if (mDirection == Direction.DOWN) {
- mListener.pageCancel();
- mDirection = Direction.NONE;
- }
- }
- }
-
- // 滑动之后,第一个 View 的顶部距离屏幕顶部的实际位置。
- int realEdge = topEdge + offset;
-
- // 对布局进行View填充
- while (realEdge > 0 && mActiveViews.size() < 2) {
- // 从废弃的Views中获取一个
- view = mScrapViews.getFirst();
- if (view == null) return;
-
- // 判断是否存在上一章节
- Bitmap cancelBitmap = mNextBitmap;
- mNextBitmap = view.bitmap;
- if (!isRefresh) {
- boolean hasPrev = mListener.hasPrev(); // 如果不成功则无法滑动
- // 如果不存在next,则进行还原
- if (!hasPrev) {
- mNextBitmap = cancelBitmap;
- for (BitmapView activeView : mActiveViews) {
- activeView.top = 0;
- activeView.bottom = mViewHeight;
- // 设置允许显示的范围
- activeView.destRect.top = activeView.top;
- activeView.destRect.bottom = activeView.bottom;
- }
- abortAnim();
- return;
- }
- }
- // 如果加载成功,那么就将View从ScrapViews中移除
- mScrapViews.removeFirst();
- // 加入到存活的对象中
- mActiveViews.add(0, view);
- mDirection = Direction.UP;
- // 设置Bitmap的范围
- view.top = realEdge - view.bitmap.getHeight();
- view.bottom = realEdge;
-
- // 设置允许显示的范围
- view.destRect.top = view.top;
- view.destRect.bottom = view.bottom;
- realEdge -= view.bitmap.getHeight();
- }
- }
-
- /**
- * 对Bitmap进行擦除
- *
- * @param b
- * @param width
- * @param height
- * @param paddingLeft
- * @param paddingTop
- */
- private void eraseBitmap(Bitmap b, int width, int height,
- int paddingLeft, int paddingTop) {
- /* if (mInitBitmapPix == null) return;
- b.setPixels(mInitBitmapPix, 0, width, paddingLeft, paddingTop, width, height);*/
- }
-
- /**
- * 重置位移
- */
- public void resetBitmap() {
- isRefresh = true;
- // 将所有的Active加入到Scrap中
- for (BitmapView view : mActiveViews) {
- mScrapViews.add(view);
- }
- // 清除所有的Active
- mActiveViews.clear();
- // 重新进行布局
- onLayout();
- isRefresh = false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- int x = (int) event.getX();
- int y = (int) event.getY();
-
- // 初始化速度追踪器
- if (mVelocity == null) {
- mVelocity = VelocityTracker.obtain();
- }
-
- mVelocity.addMovement(event);
- // 设置触碰点
- setTouchPoint(x, y);
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- isRunning = false;
- // 设置起始点
- setStartPoint(x, y);
- // 停止动画
- abortAnim();
- break;
- case MotionEvent.ACTION_MOVE:
- mVelocity.computeCurrentVelocity(VELOCITY_DURATION);
- isRunning = true;
- // 进行刷新
- mView.postInvalidate();
- break;
- case MotionEvent.ACTION_UP:
- isRunning = false;
- // 开启动画
- startAnim();
- // 删除检测器
- mVelocity.recycle();
- mVelocity = null;
- break;
-
- case MotionEvent.ACTION_CANCEL:
- try {
- mVelocity.recycle(); // if velocityTracker won't be used should be recycled
- mVelocity = null;
- } catch (Exception e) {
- e.printStackTrace();
- }
- break;
- }
- return true;
- }
-
-
- BitmapView tmpView;
-
- @Override
- public void draw(Canvas canvas) {
- //进行布局
- onLayout();
-
- //绘制背景
- canvas.drawBitmap(mBgBitmap, 0, 0, null);
- //绘制内容
- canvas.save();
- //移动位置
- canvas.translate(0, mMarginHeight);
- //裁剪显示区域
- canvas.clipRect(0, 0, mViewWidth, mViewHeight);
-/* //设置背景透明
- canvas.drawColor(0x40);*/
- //绘制Bitmap
- for (int i = 0; i < mActiveViews.size(); ++i) {
- tmpView = mActiveViews.get(i);
- canvas.drawBitmap(tmpView.bitmap, tmpView.srcRect, tmpView.destRect, null);
- }
- canvas.restore();
- }
-
- @Override
- public synchronized void startAnim() {
- isRunning = true;
- mScroller.fling(0, (int) mTouchY, 0, (int) mVelocity.getYVelocity()
- , 0, 0, Integer.MAX_VALUE * -1, Integer.MAX_VALUE);
- }
-
- @Override
- public void scrollAnim() {
- if (mScroller.computeScrollOffset()) {
- int x = mScroller.getCurrX();
- int y = mScroller.getCurrY();
- setTouchPoint(x, y);
- if (mScroller.getFinalX() == x && mScroller.getFinalY() == y) {
- isRunning = false;
- }
- mView.postInvalidate();
- }
- }
-
- @Override
- public void abortAnim() {
- if (!mScroller.isFinished()) {
- mScroller.abortAnimation();
- isRunning = false;
- }
- }
-
- @Override
- public Bitmap getBgBitmap() {
- return mBgBitmap;
- }
-
- @Override
- public Bitmap getNextBitmap() {
- return mNextBitmap;
- }
-
- private static class BitmapView {
- Bitmap bitmap;
- Rect srcRect;
- Rect destRect;
- int top;
- int bottom;
- }
-}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/ScrollPageAnim.kt b/app/src/main/java/com/novel/read/widget/page/anim/ScrollPageAnim.kt
new file mode 100644
index 0000000..453ad2e
--- /dev/null
+++ b/app/src/main/java/com/novel/read/widget/page/anim/ScrollPageAnim.kt
@@ -0,0 +1,412 @@
+package com.novel.read.widget.page.anim
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.view.MotionEvent
+import android.view.VelocityTracker
+import android.view.View
+
+import com.novel.read.widget.page.PageAnimation
+
+import java.util.ArrayDeque
+import java.util.ArrayList
+
+/**
+ * Created by zlj
+ * 原理:仿照ListView源码实现的上下滑动效果
+ * 问题:
+ * 1. 向上翻页,重复的问题 (完成)
+ * 2. 滑动卡顿的问题。原因:由于绘制的数据过多造成的卡顿问题。 (主要是文字绘制需要的时长比较多) 解决办法:做文字缓冲
+ * 3. 弱网环境下,显示的问题
+ */
+class ScrollPageAnim(
+ w: Int, h: Int, marginWidth: Int, marginHeight: Int,
+ view: View, listener: PageAnimation.OnPageChangeListener
+) : PageAnimation(w, h, marginWidth, marginHeight, view, listener) {
+ private var mVelocity: VelocityTracker? = null
+
+ // 整个Bitmap的背景显示
+ private var mBgBitmap: Bitmap? = null
+
+ // 下一个展示的图片
+ private var mNextBitmap: Bitmap? = null
+
+ // 被废弃的图片列表
+ private var mScrapViews: ArrayDeque? = null
+ // 正在被利用的图片列表
+ private val mActiveViews = ArrayList(2)
+
+ // 是否处于刷新阶段
+ private var isRefresh = true
+
+ // 底部填充
+ private var downIt: MutableIterator? = null
+
+ private var upIt: MutableIterator? = null
+
+
+ private var tmpView: BitmapView? = null
+
+ init {
+ // 创建两个BitmapView
+ initWidget()
+ }
+
+ private fun initWidget() {
+ mBgBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.RGB_565)
+
+ mScrapViews = ArrayDeque(2)
+ for (i in 0..1) {
+ val view = BitmapView()
+ view.bitmap = Bitmap.createBitmap(mViewWidth, mViewHeight, Bitmap.Config.RGB_565)
+ view.srcRect = Rect(0, 0, mViewWidth, mViewHeight)
+ view.destRect = Rect(0, 0, mViewWidth, mViewHeight)
+ view.top = 0
+ view.bottom = view.bitmap!!.height
+
+ mScrapViews!!.push(view)
+ }
+ onLayout()
+ isRefresh = false
+ }
+
+ // 修改布局,填充内容
+ private fun onLayout() {
+ // 如果还没有开始加载,则从上到下进行绘制
+ if (mActiveViews.size == 0) {
+ fillDown(0, 0)
+ mDirection = PageAnimation.Direction.NONE
+ } else {
+ val offset = (mTouchY - mLastY).toInt()
+ // 判断是下滑还是上拉 (下滑)
+ if (offset > 0) {
+ val topEdge = mActiveViews[0].top
+ fillUp(topEdge, offset)
+ } else {
+ // 底部的距离 = 当前底部的距离 + 滑动的距离 (因为上滑,得到的值肯定是负的)
+ val bottomEdge = mActiveViews[mActiveViews.size - 1].bottom
+ fillDown(bottomEdge, offset)
+ }// 上拉
+ }
+ }
+
+ /**
+ * 创建View填充底部空白部分
+ *
+ * @param bottomEdge :当前最后一个View的底部,在整个屏幕上的位置,即相对于屏幕顶部的距离
+ * @param offset :滑动的偏移量
+ */
+ private fun fillDown(bottomEdge: Int, offset: Int) {
+
+ downIt = mActiveViews.iterator()
+ var view: BitmapView?
+
+ // 进行删除
+ while (downIt!!.hasNext()) {
+ view = downIt!!.next()
+ view.top = view.top + offset
+ view.bottom = view.bottom + offset
+ // 设置允许显示的范围
+ view.destRect!!.top = view.top
+ view.destRect!!.bottom = view.bottom
+
+ // 判断是否越界了
+ if (view.bottom <= 0) {
+ // 添加到废弃的View中
+ mScrapViews!!.add(view)
+ // 从Active中移除
+ downIt!!.remove()
+ // 如果原先是从上加载,现在变成从下加载,则表示取消
+ if (mDirection == PageAnimation.Direction.UP) {
+ mListener.pageCancel()
+ mDirection = PageAnimation.Direction.NONE
+ }
+ }
+ }
+
+ // 滑动之后的最后一个 View 的距离屏幕顶部上的实际位置
+ var realEdge = bottomEdge + offset
+
+ // 进行填充
+ while (realEdge < mViewHeight && mActiveViews.size < 2) {
+ // 从废弃的Views中获取一个
+ view = mScrapViews!!.first
+ /* //擦除其Bitmap(重新创建会不会更好一点)
+ eraseBitmap(view.bitmap,view.bitmap.getWidth(),view.bitmap.getHeight(),0,0);*/
+ if (view == null) return
+
+ val cancelBitmap = mNextBitmap
+ mNextBitmap = view.bitmap
+
+ if (!isRefresh) {
+ val hasNext = mListener.hasNext() //如果不成功则无法滑动
+
+ // 如果不存在next,则进行还原
+ if (!hasNext) {
+ mNextBitmap = cancelBitmap
+ for (activeView in mActiveViews) {
+ activeView.top = 0
+ activeView.bottom = mViewHeight
+ // 设置允许显示的范围
+ activeView.destRect!!.top = activeView.top
+ activeView.destRect!!.bottom = activeView.bottom
+ }
+ abortAnim()
+ return
+ }
+ }
+
+ // 如果加载成功,那么就将View从ScrapViews中移除
+ mScrapViews!!.removeFirst()
+ // 添加到存活的Bitmap中
+ mActiveViews.add(view)
+ mDirection = PageAnimation.Direction.DOWN
+
+ // 设置Bitmap的范围
+ view.top = realEdge
+ view.bottom = realEdge + view.bitmap!!.height
+ // 设置允许显示的范围
+ view.destRect!!.top = view.top
+ view.destRect!!.bottom = view.bottom
+
+ realEdge += view.bitmap!!.height
+ }
+ }
+
+ /**
+ * 创建View填充顶部空白部分
+ *
+ * @param topEdge : 当前第一个View的顶部,到屏幕顶部的距离
+ * @param offset : 滑动的偏移量
+ */
+ private fun fillUp(topEdge: Int, offset: Int) {
+ // 首先进行布局的调整
+ upIt = mActiveViews.iterator()
+ var view: BitmapView?
+ while (upIt!!.hasNext()) {
+ view = upIt!!.next()
+ view.top = view.top + offset
+ view.bottom = view.bottom + offset
+ //设置允许显示的范围
+ view.destRect!!.top = view.top
+ view.destRect!!.bottom = view.bottom
+
+ // 判断是否越界了
+ if (view.top >= mViewHeight) {
+ // 添加到废弃的View中
+ mScrapViews!!.add(view)
+ // 从Active中移除
+ upIt!!.remove()
+
+ // 如果原先是下,现在变成从上加载了,则表示取消加载
+
+ if (mDirection == PageAnimation.Direction.DOWN) {
+ mListener.pageCancel()
+ mDirection = PageAnimation.Direction.NONE
+ }
+ }
+ }
+
+ // 滑动之后,第一个 View 的顶部距离屏幕顶部的实际位置。
+ var realEdge = topEdge + offset
+
+ // 对布局进行View填充
+ while (realEdge > 0 && mActiveViews.size < 2) {
+ // 从废弃的Views中获取一个
+ view = mScrapViews!!.first
+ if (view == null) return
+
+ // 判断是否存在上一章节
+ val cancelBitmap = mNextBitmap
+ mNextBitmap = view.bitmap
+ if (!isRefresh) {
+ val hasPrev = mListener.hasPrev() // 如果不成功则无法滑动
+ // 如果不存在next,则进行还原
+ if (!hasPrev) {
+ mNextBitmap = cancelBitmap
+ for (activeView in mActiveViews) {
+ activeView.top = 0
+ activeView.bottom = mViewHeight
+ // 设置允许显示的范围
+ activeView.destRect!!.top = activeView.top
+ activeView.destRect!!.bottom = activeView.bottom
+ }
+ abortAnim()
+ return
+ }
+ }
+ // 如果加载成功,那么就将View从ScrapViews中移除
+ mScrapViews!!.removeFirst()
+ // 加入到存活的对象中
+ mActiveViews.add(0, view)
+ mDirection = PageAnimation.Direction.UP
+ // 设置Bitmap的范围
+ view.top = realEdge - view.bitmap!!.height
+ view.bottom = realEdge
+
+ // 设置允许显示的范围
+ view.destRect!!.top = view.top
+ view.destRect!!.bottom = view.bottom
+ realEdge -= view.bitmap!!.height
+ }
+ }
+
+ /**
+ * 对Bitmap进行擦除
+ *
+ * @param b
+ * @param width
+ * @param height
+ * @param paddingLeft
+ * @param paddingTop
+ */
+ private fun eraseBitmap(
+ b: Bitmap, width: Int, height: Int,
+ paddingLeft: Int, paddingTop: Int
+ ) {
+ /* if (mInitBitmapPix == null) return;
+ b.setPixels(mInitBitmapPix, 0, width, paddingLeft, paddingTop, width, height);*/
+ }
+
+ /**
+ * 重置位移
+ */
+ fun resetBitmap() {
+ isRefresh = true
+ // 将所有的Active加入到Scrap中
+ for (view in mActiveViews) {
+ mScrapViews!!.add(view)
+ }
+ // 清除所有的Active
+ mActiveViews.clear()
+ // 重新进行布局
+ onLayout()
+ isRefresh = false
+ }
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ val x = event.x.toInt()
+ val y = event.y.toInt()
+
+ // 初始化速度追踪器
+ if (mVelocity == null) {
+ mVelocity = VelocityTracker.obtain()
+ }
+
+ mVelocity!!.addMovement(event)
+ // 设置触碰点
+ setTouchPoint(x.toFloat(), y.toFloat())
+
+ when (event.action) {
+ MotionEvent.ACTION_DOWN -> {
+ isRunning = false
+ // 设置起始点
+ setStartPoint(x.toFloat(), y.toFloat())
+ // 停止动画
+ abortAnim()
+ }
+ MotionEvent.ACTION_MOVE -> {
+ mVelocity!!.computeCurrentVelocity(VELOCITY_DURATION)
+ isRunning = true
+ // 进行刷新
+ mView.postInvalidate()
+ }
+ MotionEvent.ACTION_UP -> {
+ isRunning = false
+ // 开启动画
+ startAnim()
+ // 删除检测器
+ mVelocity!!.recycle()
+ mVelocity = null
+ }
+
+ MotionEvent.ACTION_CANCEL -> try {
+ mVelocity!!.recycle() // if velocityTracker won't be used should be recycled
+ mVelocity = null
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+ return true
+ }
+
+ override fun draw(canvas: Canvas) {
+ //进行布局
+ onLayout()
+
+ //绘制背景
+ canvas.drawBitmap(mBgBitmap!!, 0f, 0f, null)
+ //绘制内容
+ canvas.save()
+ //移动位置
+ canvas.translate(0f, mMarginHeight.toFloat())
+ //裁剪显示区域
+ canvas.clipRect(0, 0, mViewWidth, mViewHeight)
+ /* //设置背景透明
+ canvas.drawColor(0x40);*/
+ //绘制Bitmap
+ for (i in mActiveViews.indices) {
+ tmpView = mActiveViews[i]
+ canvas.drawBitmap(tmpView!!.bitmap!!, tmpView!!.srcRect, tmpView!!.destRect!!, null)
+ }
+ canvas.restore()
+ }
+
+ @Synchronized
+ override fun startAnim() {
+ isRunning = true
+ mScroller.fling(
+ 0,
+ mTouchY.toInt(),
+ 0,
+ mVelocity!!.yVelocity.toInt(),
+ 0,
+ 0,
+ Integer.MAX_VALUE * -1,
+ Integer.MAX_VALUE
+ )
+ }
+
+ override fun scrollAnim() {
+ if (mScroller.computeScrollOffset()) {
+ val x = mScroller.currX
+ val y = mScroller.currY
+ setTouchPoint(x.toFloat(), y.toFloat())
+ if (mScroller.finalX == x && mScroller.finalY == y) {
+ isRunning = false
+ }
+ mView.postInvalidate()
+ }
+ }
+
+ override fun abortAnim() {
+ if (!mScroller.isFinished) {
+ mScroller.abortAnimation()
+ isRunning = false
+ }
+ }
+
+ override fun getBgBitmap(): Bitmap? {
+ return mBgBitmap
+ }
+
+ override fun getNextBitmap(): Bitmap? {
+ return mNextBitmap
+ }
+
+ private class BitmapView {
+ internal var bitmap: Bitmap? = null
+ internal var srcRect: Rect? = null
+ internal var destRect: Rect? = null
+ internal var top: Int = 0
+ internal var bottom: Int = 0
+ }
+
+ companion object {
+ private val TAG = "ScrollAnimation"
+ // 滑动追踪的时间
+ private val VELOCITY_DURATION = 1000
+ }
+}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/SimulationPageAnim.java b/app/src/main/java/com/novel/read/widget/page/anim/SimulationPageAnim.java
index 6f61405..9043830 100644
--- a/app/src/main/java/com/novel/read/widget/page/anim/SimulationPageAnim.java
+++ b/app/src/main/java/com/novel/read/widget/page/anim/SimulationPageAnim.java
@@ -47,17 +47,17 @@ public class SimulationPageAnim extends HorizonPageAnim {
boolean mIsRTandLB; // 是否属于右上左下
private float mMaxLength ;
- int[] mBackShadowColors;// 背面颜色组
- int[] mFrontShadowColors;// 前面颜色组
- GradientDrawable mBackShadowDrawableLR; // 有阴影的GradientDrawable
- GradientDrawable mBackShadowDrawableRL;
- GradientDrawable mFolderShadowDrawableLR;
- GradientDrawable mFolderShadowDrawableRL;
-
- GradientDrawable mFrontShadowDrawableHBT;
- GradientDrawable mFrontShadowDrawableHTB;
- GradientDrawable mFrontShadowDrawableVLR;
- GradientDrawable mFrontShadowDrawableVRL;
+ private int[] mBackShadowColors;// 背面颜色组
+ private int[] mFrontShadowColors;// 前面颜色组
+ private GradientDrawable mBackShadowDrawableLR; // 有阴影的GradientDrawable
+ private GradientDrawable mBackShadowDrawableRL;
+ private GradientDrawable mFolderShadowDrawableLR;
+ private GradientDrawable mFolderShadowDrawableRL;
+
+ private GradientDrawable mFrontShadowDrawableHBT;
+ private GradientDrawable mFrontShadowDrawableHTB;
+ private GradientDrawable mFrontShadowDrawableVLR;
+ private GradientDrawable mFrontShadowDrawableVRL;
Paint mPaint;
public SimulationPageAnim(int w, int h, View view, OnPageChangeListener listener) {
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/SlidePageAnim.java b/app/src/main/java/com/novel/read/widget/page/anim/SlidePageAnim.java
deleted file mode 100644
index 48bf949..0000000
--- a/app/src/main/java/com/novel/read/widget/page/anim/SlidePageAnim.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package com.novel.read.widget.page.anim;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.view.View;
-
-/**
- * Created by zlj
- */
-
-public class SlidePageAnim extends HorizonPageAnim {
- private Rect mSrcRect, mDestRect,mNextSrcRect,mNextDestRect;
-
- public SlidePageAnim(int w, int h, View view, OnPageChangeListener listener) {
- super(w, h, view, listener);
- mSrcRect = new Rect(0, 0, mViewWidth, mViewHeight);
- mDestRect = new Rect(0, 0, mViewWidth, mViewHeight);
- mNextSrcRect = new Rect(0, 0, mViewWidth, mViewHeight);
- mNextDestRect = new Rect(0, 0, mViewWidth, mViewHeight);
- }
-
- @Override
- public void drawStatic(Canvas canvas) {
- if (isCancel){
- canvas.drawBitmap(mCurBitmap, 0, 0, null);
- }else {
- canvas.drawBitmap(mNextBitmap, 0, 0, null);
- }
- }
-
- @Override
- public void drawMove(Canvas canvas) {
- int dis = 0;
- switch (mDirection){
- case NEXT:
- //左半边的剩余区域
- dis = (int) (mScreenWidth - mStartX + mTouchX);
- if (dis > mScreenWidth){
- dis = mScreenWidth;
- }
- //计算bitmap截取的区域
- mSrcRect.left = mScreenWidth - dis;
- //计算bitmap在canvas显示的区域
- mDestRect.right = dis;
- //计算下一页截取的区域
- mNextSrcRect.right = mScreenWidth - dis;
- //计算下一页在canvas显示的区域
- mNextDestRect.left = dis;
-
- canvas.drawBitmap(mNextBitmap,mNextSrcRect,mNextDestRect,null);
- canvas.drawBitmap(mCurBitmap,mSrcRect,mDestRect,null);
- break;
- default:
- dis = (int) (mTouchX - mStartX);
- if (dis < 0){
- dis = 0;
- mStartX = mTouchX;
- }
- mSrcRect.left = mScreenWidth - dis;
- mDestRect.right = dis;
-
- //计算下一页截取的区域
- mNextSrcRect.right = mScreenWidth - dis;
- //计算下一页在canvas显示的区域
- mNextDestRect.left = dis;
-
- canvas.drawBitmap(mCurBitmap,mNextSrcRect,mNextDestRect,null);
- canvas.drawBitmap(mNextBitmap,mSrcRect,mDestRect,null);
- break;
- }
- }
-
- @Override
- public void startAnim() {
- super.startAnim();
- int dx = 0;
- switch (mDirection){
- case NEXT:
- if (isCancel){
- int dis = (int)((mScreenWidth - mStartX) + mTouchX);
- if (dis > mScreenWidth){
- dis = mScreenWidth;
- }
- dx = mScreenWidth - dis;
- }else{
- dx = (int) -(mTouchX + (mScreenWidth - mStartX));
- }
- break;
- default:
- if (isCancel){
- dx = (int)-Math.abs(mTouchX - mStartX);
- }else{
- dx = (int) (mScreenWidth - (mTouchX - mStartX));
- }
- break;
- }
- //滑动速度保持一致
- int duration = (400 * Math.abs(dx)) / mScreenWidth;
- mScroller.startScroll((int) mTouchX, 0, dx, 0, duration);
- }
-}
diff --git a/app/src/main/java/com/novel/read/widget/page/anim/SlidePageAnim.kt b/app/src/main/java/com/novel/read/widget/page/anim/SlidePageAnim.kt
new file mode 100644
index 0000000..d9a01cf
--- /dev/null
+++ b/app/src/main/java/com/novel/read/widget/page/anim/SlidePageAnim.kt
@@ -0,0 +1,92 @@
+package com.novel.read.widget.page.anim
+
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.view.View
+import com.novel.read.widget.page.PageAnimation
+
+/**
+ * Created by zlj
+ */
+
+class SlidePageAnim(w: Int, h: Int, view: View, listener: PageAnimation.OnPageChangeListener) :
+ HorizonPageAnim(w, h, view, listener) {
+
+ private val mSrcRect: Rect = Rect(0, 0, mViewWidth, mViewHeight)
+ private val mDestRect: Rect = Rect(0, 0, mViewWidth, mViewHeight)
+ private val mNextSrcRect: Rect = Rect(0, 0, mViewWidth, mViewHeight)
+ private val mNextDestRect: Rect = Rect(0, 0, mViewWidth, mViewHeight)
+
+ override fun drawStatic(canvas: Canvas) {
+ if (isCancel) {
+ canvas.drawBitmap(mCurBitmap, 0f, 0f, null)
+ } else {
+ canvas.drawBitmap(mNextBitmap, 0f, 0f, null)
+ }
+ }
+
+ override fun drawMove(canvas: Canvas) {
+ var dis = 0
+ when (mDirection) {
+ PageAnimation.Direction.NEXT -> {
+ //左半边的剩余区域
+ dis = (mScreenWidth - mStartX + mTouchX).toInt()
+ if (dis > mScreenWidth) {
+ dis = mScreenWidth
+ }
+ //计算bitmap截取的区域
+ mSrcRect.left = mScreenWidth - dis
+ //计算bitmap在canvas显示的区域
+ mDestRect.right = dis
+ //计算下一页截取的区域
+ mNextSrcRect.right = mScreenWidth - dis
+ //计算下一页在canvas显示的区域
+ mNextDestRect.left = dis
+
+ canvas.drawBitmap(mNextBitmap, mNextSrcRect, mNextDestRect, null)
+ canvas.drawBitmap(mCurBitmap, mSrcRect, mDestRect, null)
+ }
+ else -> {
+ dis = (mTouchX - mStartX).toInt()
+ if (dis < 0) {
+ dis = 0
+ mStartX = mTouchX
+ }
+ mSrcRect.left = mScreenWidth - dis
+ mDestRect.right = dis
+
+ //计算下一页截取的区域
+ mNextSrcRect.right = mScreenWidth - dis
+ //计算下一页在canvas显示的区域
+ mNextDestRect.left = dis
+
+ canvas.drawBitmap(mCurBitmap, mNextSrcRect, mNextDestRect, null)
+ canvas.drawBitmap(mNextBitmap, mSrcRect, mDestRect, null)
+ }
+ }
+ }
+
+ override fun startAnim() {
+ super.startAnim()
+ var dx = 0
+ when (mDirection) {
+ PageAnimation.Direction.NEXT -> if (isCancel) {
+ var dis = (mScreenWidth - mStartX + mTouchX).toInt()
+ if (dis > mScreenWidth) {
+ dis = mScreenWidth
+ }
+ dx = mScreenWidth - dis
+ } else {
+ dx = (-(mTouchX + (mScreenWidth - mStartX))).toInt()
+ }
+ else -> if (isCancel) {
+ dx = (-Math.abs(mTouchX - mStartX)).toInt()
+ } else {
+ dx = (mScreenWidth - (mTouchX - mStartX)).toInt()
+ }
+ }
+ //滑动速度保持一致
+ val duration = 400 * Math.abs(dx) / mScreenWidth
+ mScroller.startScroll(mTouchX.toInt(), 0, dx, 0, duration)
+ }
+}