diff --git a/app/src/main/java/xyz/fycz/myreader/application/App.java b/app/src/main/java/xyz/fycz/myreader/application/App.java index 91563d7b..402d0647 100644 --- a/app/src/main/java/xyz/fycz/myreader/application/App.java +++ b/app/src/main/java/xyz/fycz/myreader/application/App.java @@ -51,7 +51,6 @@ import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; import xyz.fycz.myreader.ui.activity.MainActivity; -import xyz.fycz.myreader.ui.dialog.APPDownloadTip; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.fragment.BookcaseFragment; import xyz.fycz.myreader.util.help.SSLSocketClient; @@ -369,62 +368,6 @@ public static void checkVersionByServer(final AppCompatActivity activity, final }); } - /** - * App自动升级 - * - * @param activity - * @param versionCode - */ - public void updateApp(final AppCompatActivity activity, final String url, final int versionCode, String message, - final boolean isForceUpdate, final BookcaseFragment mBookcaseFragment) { - //String version = (versionCode / 100 % 10) + "." + (versionCode / 10 % 10) + "." + (versionCode % 10); - String cancelTitle; - if (isForceUpdate) { - cancelTitle = "退出"; - } else { - cancelTitle = "忽略此版本"; - } - if (mBookcaseFragment == null) { - DialogCreator.createCommonDialog(activity, "发现新版本:", message, true, "取消", "立即更新", null, - (dialog, which) -> goDownload(activity, url)); - return; - } - - DialogCreator.createThreeButtonDialog(activity, "发现新版本:", message, !isForceUpdate, cancelTitle, "直接下载", - "浏览器下载", (dialog, which) -> { - if (isForceUpdate) { - activity.finish(); - } - }, (dialog, which) -> { - if (activity instanceof MainActivity) { - MainActivity mainActivity = (MainActivity) activity; - mainActivity.getViewPagerMain().setCurrentItem(0); - String filePath = APPCONST.UPDATE_APK_FILE_DIR + "FYReader.apk"; - if (apkInfo(filePath) == versionCode) { - mainActivity.installApk(FileUtils.getFile(filePath), isForceUpdate); - return; - } - } - if (url == null || "".equals(url)) { - ToastUtils.showError("获取链接失败,请前往浏览器下载!"); - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_VIEW); - intent.setData(Uri.parse(URLCONST.APP_DIR_UR)); - activity.startActivity(intent); - if (isForceUpdate) { - activity.finish(); - } - } else { - APPDownloadTip downloadTip = new APPDownloadTip(url, mBookcaseFragment, activity, isForceUpdate); - downloadTip.downloadApp(); - } - }, (dialog, which) -> { - goDownload(activity, url); - if (isForceUpdate) { - activity.finish(); - } - }); - } public void updateApp2(final AppCompatActivity activity, final String url, final int versionCode, String message, final boolean isForceUpdate) { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java index 47802c0a..51163dbb 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java @@ -48,6 +48,7 @@ import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.utils.AdUtils; import xyz.fycz.myreader.util.utils.GsonExtensionsKt; +import xyz.fycz.myreader.widget.NoScrollViewPager; import static androidx.fragment.app.FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT; @@ -231,7 +232,7 @@ private void reLoadFragment() { mMineFragment = (MineFragment) fragments.get(2); } - public ViewPager getViewPagerMain() { + public NoScrollViewPager getViewPagerMain() { return binding.viewPagerMain; } @@ -250,10 +251,6 @@ public boolean onCreateOptionsMenu(Menu menu) { @Override public boolean onPrepareOptionsMenu(Menu menu) { - boolean isEdit = mBookcaseFragment.getmBookcasePresenter() != null && mBookcaseFragment.getmBookcasePresenter().ismEditState(); - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - menu.findItem(R.id.action_refresh).setVisible(!isEdit); - } if (binding.viewPagerMain.getCurrentItem() == 0) { if (mBookcaseFragment.getmBookcasePresenter() != null && mBookcaseFragment.getmBookcasePresenter().ismEditState()) { menu.findItem(R.id.action_finish).setVisible(true); @@ -295,8 +292,6 @@ public boolean onOptionsItemSelected(MenuItem item) { getSupportActionBar().setSubtitle(groupName); }); } - } else if (itemId == R.id.action_refresh) { - mBookcaseFragment.getmBookcasePresenter().initNoReadNum(); } else if (itemId == R.id.action_edit) { if (mBookcaseFragment.getmBookcasePresenter().canEditBookcase()) { invalidateOptionsMenu(); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseAdapter.java b/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseAdapter.java index 7bd89b5e..caf0d85c 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseAdapter.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseAdapter.java @@ -4,11 +4,16 @@ import android.view.View; import android.widget.*; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import com.kongzue.dialogx.dialogs.BottomDialog; import com.kongzue.dialogx.dialogs.BottomMenu; import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener; import com.kongzue.dialogx.interfaces.OnMenuItemSelectListener; +import org.jetbrains.annotations.NotNull; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -20,6 +25,7 @@ import xyz.fycz.myreader.R; import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.common.APPCONST; +import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.MyAlertDialog; import xyz.fycz.myreader.widget.CoverImageView; @@ -38,7 +44,7 @@ * @author fengyue * @date 2020/4/19 11:23 */ -public abstract class BookcaseAdapter extends DragAdapter { +public abstract class BookcaseAdapter extends RecyclerView.Adapter { private final Map isLoading = new HashMap<>(); private final Map mCheckMap = new LinkedHashMap<>(); @@ -59,7 +65,7 @@ public abstract class BookcaseAdapter extends DragAdapter { App.getmContext().getResources().getString(R.string.menu_book_cache), App.getmContext().getResources().getString(R.string.menu_book_delete) }; - + protected ItemTouchCallback.OnItemTouchListener itemTouchCallbackListener; public BookcaseAdapter(Context context, int textViewResourceId, ArrayList objects , boolean editState, BookcasePresenter bookcasePresenter, boolean isGroup) { @@ -75,25 +81,10 @@ public BookcaseAdapter(Context context, int textViewResourceId, ArrayList @Override - public void onDataModelMove(int from, int to) { - Book b = list.remove(from); - list.add(to, b); - for (int i = 0; i < list.size(); i++) { - if (!isGroup) { - list.get(i).setSortCode(i); - }else { - list.get(i).setGroupSort(i); - } - } - mBookService.updateBooks(list); - } - - @Override - public int getCount() { + public int getItemCount() { return list.size(); } - @Override public Book getItem(int position) { return list.get(position); } @@ -103,6 +94,16 @@ public long getItemId(int position) { return !isGroup ? list.get(position).getSortCode() : list.get(position).getGroupSort(); } + public void onDataMove() { + for (int i = 0; i < list.size(); i++) { + if (!isGroup) { + list.get(i).setSortCode(i); + } else { + list.get(i).setGroupSort(i); + } + } + mBookService.updateBooks(list); + } public void remove(Book item) { list.remove(item); @@ -124,9 +125,9 @@ protected void showDeleteBookDialog(final Book book) { ToastUtils.showSuccess("书籍删除成功!"); mBookcasePresenter.init(); }, null); - }else { + } else { DialogCreator.createCommonDialog(mContext, "删除/移除书籍", "您是希望删除《" + book.getName() + "》及其所有缓存还是从分组中移除该书籍(不会删除书籍)呢?", - true, "删除书籍", "从分组中移除",(dialogInterface, i) -> { + true, "删除书籍", "从分组中移除", (dialogInterface, i) -> { remove(book); ToastUtils.showSuccess("书籍删除成功!"); mBookcasePresenter.init(); @@ -151,6 +152,8 @@ public void setmEditState(boolean mEditState) { mCheckMap.put(book.getId(), false); } mCheckedCount = 0; + } else { + onDataMove(); } this.mEditState = mEditState; notifyDataSetChanged(); @@ -173,6 +176,10 @@ public boolean isBookLoading(String bookID) { return isLoading.get(bookID); } + public ItemTouchCallback.OnItemTouchListener getItemTouchCallbackListener() { + return itemTouchCallbackListener; + } + public boolean unionChapterCathe(Book book) throws IOException { ArrayList chapters = (ArrayList) mChapterService.findBookAllChapterByBookId(book.getId()); BufferedReader br = null; @@ -317,39 +324,52 @@ public void onOneItemSelect(BottomMenu dialog, CharSequence text, int which) { selectedIndex = which; } }).setOkButton("确定", (baseDialog, v) -> { - switch (selectedIndex) { - case 0: - begin[0] = book.getHisttoryChapterNum(); - end[0] = book.getHisttoryChapterNum() + 50; - break; - case 1: - begin[0] = book.getHisttoryChapterNum() - 50; - end[0] = book.getHisttoryChapterNum() + 50; - break; - case 2: - begin[0] = book.getHisttoryChapterNum(); - end[0] = 99999; - break; - case 3: - begin[0] = 0; - end[0] = 99999; - break; - } - Thread downloadThread = new Thread(() -> { - ArrayList chapters = (ArrayList) mChapterService.findBookAllChapterByBookId(book.getId()); - mBookcasePresenter.addDownload(book, chapters, begin[0], end[0], false); - }); - mBookcasePresenter.getEs().submit(downloadThread); - return false; - }).setCancelButton(R.string.cancel); + switch (selectedIndex) { + case 0: + begin[0] = book.getHisttoryChapterNum(); + end[0] = book.getHisttoryChapterNum() + 50; + break; + case 1: + begin[0] = book.getHisttoryChapterNum() - 50; + end[0] = book.getHisttoryChapterNum() + 50; + break; + case 2: + begin[0] = book.getHisttoryChapterNum(); + end[0] = 99999; + break; + case 3: + begin[0] = 0; + end[0] = 99999; + break; + } + Thread downloadThread = new Thread(() -> { + ArrayList chapters = (ArrayList) mChapterService.findBookAllChapterByBookId(book.getId()); + mBookcasePresenter.addDownload(book, chapters, begin[0], end[0], false); + }); + mBookcasePresenter.getEs().submit(downloadThread); + return false; + }).setCancelButton(R.string.cancel); + } + + public void refreshBook(String chapterUrl){ + for (int i = 0; i < list.size(); i++) { + if (Objects.equals(list.get(i).getChapterUrl(), chapterUrl)) { + notifyItemChanged(i); + } + } } - static class ViewHolder { + + static class ViewHolder extends RecyclerView.ViewHolder { CheckBox cbBookChecked; CoverImageView ivBookImg; TextView tvBookName; BadgeView tvNoReadNum; ProgressBar pbLoading; + + public ViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + } } public void setOnBookCheckedListener(OnBookCheckedListener listener) { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDetailedAdapter.java b/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDetailedAdapter.java index 92f506d6..214e4d02 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDetailedAdapter.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDetailedAdapter.java @@ -8,16 +8,22 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; + import com.kongzue.dialogx.dialogs.BottomMenu; +import org.jetbrains.annotations.NotNull; + import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import xyz.fycz.myreader.R; import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.base.BitIntentDataManager; import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.ui.activity.ReadActivity; +import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.ui.activity.BookDetailedActivity; @@ -40,28 +46,34 @@ public class BookcaseDetailedAdapter extends BookcaseAdapter { public BookcaseDetailedAdapter(Context context, int textViewResourceId, ArrayList objects, boolean editState, BookcasePresenter bookcasePresenter, boolean isGroup) { super(context, textViewResourceId, objects, editState, bookcasePresenter, isGroup); + itemTouchCallbackListener = new ItemTouchCallback.OnItemTouchListener() { + @Override + public void onSwiped(int adapterPosition) { + + } + + @Override + public boolean onMove(int srcPosition, int targetPosition) { + Collections.swap(list, srcPosition, targetPosition); + notifyItemMoved(srcPosition, targetPosition); + notifyItemChanged(srcPosition); + notifyItemChanged(targetPosition); + return true; + } + }; } + @NonNull + @NotNull @Override - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null || convertView.getTag() instanceof BookcaseDragAdapter.ViewHolder) { - viewHolder = new ViewHolder(); - convertView = LayoutInflater.from(mContext).inflate(mResourceId, null); - viewHolder.cbBookChecked = convertView.findViewById(R.id.cb_book_select); - viewHolder.ivBookImg = convertView.findViewById(R.id.iv_book_img); - viewHolder.tvBookName = convertView.findViewById(R.id.tv_book_name); - viewHolder.tvNoReadNum = convertView.findViewById(R.id.tv_no_read_num); - viewHolder.tvBookAuthor = convertView.findViewById(R.id.tv_book_author); - viewHolder.tvHistoryChapter = convertView.findViewById(R.id.tv_book_history_chapter); - viewHolder.tvNewestChapter = convertView.findViewById(R.id.tv_book_newest_chapter); - viewHolder.llBookRead = convertView.findViewById(R.id.ll_book_read); - viewHolder.pbLoading = convertView.findViewById(R.id.pb_loading); - convertView.setTag(viewHolder); - } else { - viewHolder = (ViewHolder) convertView.getTag(); - } + public BookcaseAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(mContext).inflate(mResourceId, null)); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BookcaseAdapter.ViewHolder holder, int position) { + viewHolder = (ViewHolder) holder; initView(position); - return convertView; } private void initView(int position) { @@ -70,7 +82,7 @@ private void initView(int position) { book.setImgUrl(""); } ReadCrawler rc = ReadCrawlerUtil.getReadCrawler(book.getSource()); - viewHolder.ivBookImg.load(NetworkUtils.getAbsoluteURL(rc.getNameSpace(), book.getImgUrl()), book.getName(),book.getAuthor()); + viewHolder.ivBookImg.load(NetworkUtils.getAbsoluteURL(rc.getNameSpace(), book.getImgUrl()), book.getName(), book.getAuthor()); viewHolder.tvBookName.setText(book.getName()); @@ -189,7 +201,7 @@ private void initView(int position) { case 0: if (!isGroup) { book.setSortCode(0); - }else { + } else { book.setGroupSort(0); } mBookService.updateEntity(book); @@ -230,12 +242,24 @@ private void initView(int position) { } } - static class ViewHolder extends BookcaseAdapter.ViewHolder { TextView tvBookAuthor; TextView tvHistoryChapter; TextView tvNewestChapter; LinearLayout llBookRead; + + public ViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + cbBookChecked = itemView.findViewById(R.id.cb_book_select); + ivBookImg = itemView.findViewById(R.id.iv_book_img); + tvBookName = itemView.findViewById(R.id.tv_book_name); + tvNoReadNum = itemView.findViewById(R.id.tv_no_read_num); + tvBookAuthor = itemView.findViewById(R.id.tv_book_author); + tvHistoryChapter = itemView.findViewById(R.id.tv_book_history_chapter); + tvNewestChapter = itemView.findViewById(R.id.tv_book_newest_chapter); + llBookRead = itemView.findViewById(R.id.ll_book_read); + pbLoading = itemView.findViewById(R.id.pb_loading); + } } } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDragAdapter.java b/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDragAdapter.java index d5448559..95f0b917 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDragAdapter.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDragAdapter.java @@ -6,8 +6,12 @@ import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; + import com.kongzue.dialogx.dialogs.BottomMenu; +import org.jetbrains.annotations.NotNull; + import java.io.IOException; import java.util.ArrayList; @@ -16,6 +20,7 @@ import xyz.fycz.myreader.base.BitIntentDataManager; import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.ui.activity.ReadActivity; +import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.ui.activity.BookDetailedActivity; @@ -36,28 +41,43 @@ public class BookcaseDragAdapter extends BookcaseAdapter { App.getmContext().getResources().getString(R.string.menu_book_cache), App.getmContext().getResources().getString(R.string.menu_book_delete) }; + public BookcaseDragAdapter(Context context, int textViewResourceId, ArrayList objects, boolean editState, BookcasePresenter bookcasePresenter, boolean isGroup) { super(context, textViewResourceId, objects, editState, bookcasePresenter, isGroup); + itemTouchCallbackListener = new ItemTouchCallback.OnItemTouchListener() { + @Override + public void onSwiped(int adapterPosition) { + + } + + @Override + public boolean onMove(int srcPosition, int targetPosition) { + Book shelfBean = list.get(srcPosition); + list.remove(srcPosition); + list.add(targetPosition, shelfBean); + notifyItemMoved(srcPosition, targetPosition); + int start = srcPosition; + int end = targetPosition; + if (start > end) { + start = targetPosition; + end = srcPosition; + } + notifyItemRangeChanged(start, end - start + 1); + return true; + } + }; } + @Override + public BookcaseAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(mContext).inflate(mResourceId, null)); + } @Override - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null || convertView.getTag() instanceof BookcaseDetailedAdapter.ViewHolder) { - viewHolder = new ViewHolder(); - convertView = LayoutInflater.from(mContext).inflate(mResourceId, null); - viewHolder.cbBookChecked = convertView.findViewById(R.id.cb_book_select); - viewHolder.ivBookImg = convertView.findViewById(R.id.iv_book_img); - viewHolder.tvBookName = convertView.findViewById(R.id.tv_book_name); - viewHolder.tvNoReadNum = convertView.findViewById(R.id.tv_no_read_num); - viewHolder.pbLoading = convertView.findViewById(R.id.pb_loading); - convertView.setTag(viewHolder); - } else { - viewHolder = (ViewHolder) convertView.getTag(); - } + public void onBindViewHolder(@NonNull @NotNull BookcaseAdapter.ViewHolder holder, int position) { + viewHolder = (ViewHolder) holder; initView(position); - return convertView; } private void initView(int position) { @@ -67,7 +87,7 @@ private void initView(int position) { } ReadCrawler rc = ReadCrawlerUtil.getReadCrawler(book.getSource()); - viewHolder.ivBookImg.load(NetworkUtils.getAbsoluteURL(rc.getNameSpace(), book.getImgUrl()), book.getName(),book.getAuthor()); + viewHolder.ivBookImg.load(NetworkUtils.getAbsoluteURL(rc.getNameSpace(), book.getImgUrl()), book.getName(), book.getAuthor()); viewHolder.tvBookName.setText(book.getName()); @@ -179,7 +199,7 @@ public void run() { case 1: if (!isGroup) { book.setSortCode(0); - }else { + } else { book.setGroupSort(0); } mBookService.updateEntity(book); @@ -224,6 +244,14 @@ public void run() { } - class ViewHolder extends BookcaseAdapter.ViewHolder { + static class ViewHolder extends BookcaseAdapter.ViewHolder { + public ViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + cbBookChecked = itemView.findViewById(R.id.cb_book_select); + ivBookImg = itemView.findViewById(R.id.iv_book_img); + tvBookName = itemView.findViewById(R.id.tv_book_name); + tvNoReadNum = itemView.findViewById(R.id.tv_no_read_num); + pbLoading = itemView.findViewById(R.id.pb_loading); + } } } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/dialog/APPDownloadTip.java b/app/src/main/java/xyz/fycz/myreader/ui/dialog/APPDownloadTip.java deleted file mode 100644 index 5a10028d..00000000 --- a/app/src/main/java/xyz/fycz/myreader/ui/dialog/APPDownloadTip.java +++ /dev/null @@ -1,173 +0,0 @@ -package xyz.fycz.myreader.ui.dialog; - - -import android.annotation.SuppressLint; -import android.content.Intent; -import android.net.Uri; -import android.os.Handler; -import android.os.Message; -import android.view.View; -import androidx.appcompat.app.AppCompatActivity; - -import xyz.fycz.myreader.application.App; -import xyz.fycz.myreader.webapi.LanZousApi; -import xyz.fycz.myreader.webapi.ResultCallback; -import xyz.fycz.myreader.common.APPCONST; -import xyz.fycz.myreader.ui.activity.MainActivity; -import xyz.fycz.myreader.ui.fragment.BookcaseFragment; -import xyz.fycz.myreader.util.IOUtils; -import xyz.fycz.myreader.util.ToastUtils; -import xyz.fycz.myreader.util.utils.FileUtils; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -/** - * @author fengyue - * @date 2020/5/20 20:50 - */ - -public class APPDownloadTip { - - private String url; - private BookcaseFragment mBookcaseFragment; - private MainActivity activity; - private boolean isForceUpdate; - - public APPDownloadTip(String url, BookcaseFragment mBookcaseFragment, AppCompatActivity activity, boolean isForceUpdate) { - this.url = url; - this.mBookcaseFragment = mBookcaseFragment; - this.activity = (MainActivity) activity; - this.isForceUpdate = isForceUpdate; - } - - @SuppressLint("HandlerLeak") - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (!App.isDestroy(activity)) { - switch (msg.what) { - case 1: - mBookcaseFragment.getTvDownloadTip().setText("获取下载链接失败,请前往浏览器下载!"); - mBookcaseFragment.getRlDownloadTip().setVisibility(View.GONE); - break; - case 2: - mBookcaseFragment.getTvDownloadTip().setText("连接中..."); - break; - case 3: - updateDownloadPro((double) msg.obj); - break; - case 4: - mBookcaseFragment.getRlDownloadTip().setVisibility(View.GONE); - break; - } - } - } - }; - - public void downloadApp() { - mBookcaseFragment.getTvStopDownload().setVisibility(View.GONE); - mBookcaseFragment.getRlDownloadTip().setVisibility(View.VISIBLE); - mBookcaseFragment.getPbDownload().setProgress(0); - mBookcaseFragment.getTvDownloadTip().setText("正在获取下载链接..."); - LanZousApi.getUrl(url, new ResultCallback() { - @Override - public void onFinish(Object o, int code) { - final String downloadUrl = (String) o; - if (downloadUrl == null) { - error(); - return; - } - App.getApplication().newThread(() -> { - HttpURLConnection con = null; - InputStream is = null; - FileOutputStream fos = null; - File appFile = null; - try { - URL webUrl = new URL(downloadUrl); - mHandler.sendMessage(mHandler.obtainMessage(2)); - con = (HttpURLConnection) webUrl.openConnection(); - is = con.getInputStream(); - String filePath = APPCONST.UPDATE_APK_FILE_DIR + "FYReader.apk.temp"; - appFile = FileUtils.getFile(filePath); - fos = new FileOutputStream(appFile); - byte[] tem = new byte[1024]; - long alreadyLen = 0; - long fileLength = con.getContentLength(); - int len; - double progress; - while ((len = is.read(tem)) != -1) { - fos.write(tem, 0, len); - alreadyLen += len; - progress = alreadyLen * 1.0f * 100f / fileLength; - mHandler.sendMessage(mHandler.obtainMessage(3, progress)); - } - fos.flush(); - if (fileLength == appFile.length()) { - String newPath = filePath.replace(".temp", ""); - final File newFile = new File(newPath); - if (appFile.renameTo(newFile)) { - mHandler.sendMessage(mHandler.obtainMessage(4)); - DialogCreator.createCommonDialog(activity, "提示", "风月读书下载完成,安装包路径:" + newPath, - !isForceUpdate, "取消", "立即安装", (dialog, which) -> { - if (isForceUpdate) { - activity.finish(); - } - }, (dialog, which) -> activity.installProcess(newFile, isForceUpdate)); - activity.installProcess(newFile, isForceUpdate); - } else { - appFile.delete(); - error(); - } - } else { - appFile.delete(); - error(); - } - } catch (IOException e) { - if (appFile != null) { - appFile.delete(); - } - error(); - e.printStackTrace(); - } finally { - if (con != null) { - con.disconnect(); - } - IOUtils.close(is, fos); - } - }); - } - - @Override - public void onError(Exception e) { - error(); - } - }); - } - - - private void error() { - mHandler.sendMessage(mHandler.obtainMessage(1)); - ToastUtils.showError("获取下载链接失败,请前往浏览器下载!"); - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - activity.startActivity(intent); - if (isForceUpdate) { - activity.finish(); - } - } - - @SuppressLint({"SetTextI18n"}) - private void updateDownloadPro(double progress) { - mBookcaseFragment.getPbDownload().setProgress((int) progress); - //保留两位小数 - //mBookcaseFragment.getTvDownloadTip().setText("正在下载风月读书最新版本...[" + String.format("%.2f", progress) + "%]"); - mBookcaseFragment.getTvDownloadTip().setText("正在下载风月读书最新版本...[" + (int) progress + "%]"); - } - -} diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/BookcaseFragment.java b/app/src/main/java/xyz/fycz/myreader/ui/fragment/BookcaseFragment.java index 31af73d9..43978536 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/fragment/BookcaseFragment.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/BookcaseFragment.java @@ -14,9 +14,11 @@ import android.widget.TextView; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import xyz.fycz.myreader.databinding.FragmentBookListBinding; import xyz.fycz.myreader.databinding.FragmentBookcaseBinding; import xyz.fycz.myreader.ui.presenter.BookcasePresenter; import xyz.fycz.myreader.widget.custom.DragSortGridView; @@ -26,7 +28,7 @@ */ public class BookcaseFragment extends Fragment { - private FragmentBookcaseBinding binding; + private FragmentBookListBinding binding; private BookcasePresenter mBookcasePresenter; @@ -39,7 +41,7 @@ public BookcaseFragment() { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - binding = FragmentBookcaseBinding.inflate(inflater, container, false); + binding = FragmentBookListBinding.inflate(inflater, container, false); mBookcasePresenter = new BookcasePresenter(this); mBookcasePresenter.start(); return binding.getRoot(); @@ -52,8 +54,8 @@ public void onDestroyView() { } @Override - public void onResume() { - super.onResume(); + public void onStart() { + super.onStart(); mBookcasePresenter.init(); } @@ -61,28 +63,12 @@ public LinearLayout getLlNoDataTips() { return binding.llNoDataTips; } - public DragSortGridView getGvBook() { - return binding.gvBook; + public RecyclerView getRvBook() { + return binding.rvBookList; } public SmartRefreshLayout getSrlContent() { - return binding.srlContent; - } - - public RelativeLayout getRlDownloadTip() { - return binding.rlDownloadTip; - } - - public TextView getTvDownloadTip() { - return binding.tvDownloadTip; - } - - public TextView getTvStopDownload() { - return binding.tvStopDownload; - } - - public ProgressBar getPbDownload() { - return binding.pbDownload; + return binding.srlBookList; } public BookcasePresenter getmBookcasePresenter() { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java b/app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java index 56346254..2633e07a 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java @@ -9,6 +9,7 @@ import android.os.Build; import android.os.Handler; import android.os.Message; +import android.text.TextUtils; import android.view.Gravity; import android.view.MenuItem; import android.view.View; @@ -16,6 +17,9 @@ import android.widget.PopupMenu; import androidx.core.app.ActivityCompat; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; import com.kongzue.dialogx.dialogs.BottomMenu; @@ -31,12 +35,15 @@ import java.util.concurrent.Executors; import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import xyz.fycz.myreader.R; import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.application.SysManager; import xyz.fycz.myreader.base.BasePresenter; import xyz.fycz.myreader.base.observer.MyObserver; +import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback; import xyz.fycz.myreader.ui.dialog.BookGroupDialog; import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.utils.RxUtils; @@ -81,7 +88,8 @@ public class BookcasePresenter implements BasePresenter { private boolean isBookcaseStyleChange; private Setting mSetting; private final List errorLoadingBooks = new ArrayList<>(); - private int finishLoadBookCount = 0; + private int threadsNum = 6; + private int refreshIndex;//刷新书籍索引 // private int notifyId = 11; private ExecutorService es = Executors.newFixedThreadPool(1);//更新/下载线程池 @@ -106,6 +114,7 @@ public ExecutorService getEs() { private boolean isGroup; private MainActivity.OnGroupChangeListener ogcl; private final BookGroupDialog mBookGroupDia; + private ItemTouchCallback itemTouchCallback; public static final String CANCEL_ACTION = "cancelAction"; @@ -119,27 +128,13 @@ public ExecutorService getEs() { public void handleMessage(Message msg) { switch (msg.what) { case 1: - if (!App.isDestroy(mMainActivity)) { - App.runOnUiThread(() -> mBookcaseAdapter.notifyDataSetChanged()); - finishLoadBookCount++; - mBookcaseFragment.getSrlContent().finishRefresh(); - } break; case 2: - mBookcaseFragment.getSrlContent().finishRefresh(); break; case 3: - mBookcaseAdapter.notifyDataSetChanged(); break; case 4: - showErrorLoadingBooks(); - if (App.isDebug()) { - if (isFirstRefresh) { - initBook(); - isFirstRefresh = false; - } - downloadAll(false, false); - } + break; case 5: break; @@ -156,9 +151,6 @@ public void handleMessage(Message msg) { isDownloadFinish = true; break; case 10: - mBookcaseFragment.getTvDownloadTip().setText("正在初始化缓存任务..."); - mBookcaseFragment.getPbDownload().setProgress(0); - mBookcaseFragment.getRlDownloadTip().setVisibility(View.VISIBLE); break; case 11: ToastUtils.showInfo("正在后台缓存书籍,具体进度可查看通知栏!"); @@ -197,31 +189,16 @@ public void start() { synBookcaseToWeb(true); }*/ - //是否启用下拉刷新(默认启用) - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - mBookcaseFragment.getSrlContent().setEnableRefresh(false); - } //设置是否启用内容视图拖动效果 mBookcaseFragment.getSrlContent().setEnableHeaderTranslationContent(false); //设置刷新监听器 - mBookcaseFragment.getSrlContent().setOnRefreshListener(refreshlayout -> initNoReadNum()); + mBookcaseFragment.getSrlContent().setOnRefreshListener(listener -> initNoReadNum()); //搜索按钮监听器 mBookcaseFragment.getLlNoDataTips().setOnClickListener(view -> { Intent intent = new Intent(mBookcaseFragment.getContext(), SearchBookActivity.class); mBookcaseFragment.startActivity(intent); }); - //长按事件监听 - mBookcaseFragment.getGvBook().setOnItemLongClickListener((parent, view, position, id) -> false); - - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - //滑动监听器 - mBookcaseFragment.getGvBook().getmScrollView().setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { - if (!mBookcaseAdapter.ismEditState()) { - mBookcaseFragment.getSrlContent().setEnableRefresh(scrollY == 0); - } - }); - } //全选监听器 mBookcaseFragment.getmCbSelectAll().setOnClickListener(v -> { @@ -296,18 +273,18 @@ public void getData() { public void init() { initBook(); if (mBooks.size() == 0) { - mBookcaseFragment.getGvBook().setVisibility(View.GONE); + mBookcaseFragment.getSrlContent().setVisibility(View.GONE); mBookcaseFragment.getLlNoDataTips().setVisibility(View.VISIBLE); } else { if (mBookcaseAdapter == null || isBookcaseStyleChange) { switch (mSetting.getBookcaseStyle()) { case listMode: mBookcaseAdapter = new BookcaseDetailedAdapter(mMainActivity, R.layout.gridview_book_detailed_item, mBooks, false, this, isGroup); - mBookcaseFragment.getGvBook().setNumColumns(1); + mBookcaseFragment.getRvBook().setLayoutManager(new LinearLayoutManager(mMainActivity)); break; case threePalaceMode: mBookcaseAdapter = new BookcaseDragAdapter(mMainActivity, R.layout.gridview_book_item, mBooks, false, this, isGroup); - mBookcaseFragment.getGvBook().setNumColumns(3); + mBookcaseFragment.getRvBook().setLayoutManager(new GridLayoutManager(mMainActivity, 3)); break; } mBookcaseAdapter.setOnBookCheckedListener(isChecked -> { @@ -315,30 +292,19 @@ public void init() { //设置删除和加入分组按钮是否可用 setBtnClickable(mBookcaseAdapter.getmCheckedCount() > 0); }); - mBookcaseFragment.getGvBook().setDragModel(-1); - mBookcaseFragment.getGvBook().setTouchClashparent(mMainActivity.getViewPagerMain()); - mBookcaseFragment.getGvBook().setOnDragSelectListener(new DragSortGridView.OnDragSelectListener() { - @Override - public void onDragSelect(View mirror) { - if (mSetting.getBookcaseStyle() == BookcaseStyle.listMode) { - mirror.setBackgroundColor(mMainActivity.getResources().getColor(R.color.colorBackground)); - } else { - mirror.setScaleX(1.05f); - } - mirror.setScaleY(1.05f); - } - - @Override - public void onPutDown(View itemView) { - } - }); - mBookcaseFragment.getGvBook().setAdapter(mBookcaseAdapter); + itemTouchCallback = new ItemTouchCallback(); + itemTouchCallback.setViewPager(mMainActivity.getViewPagerMain()); + mBookcaseFragment.getRvBook().setAdapter(mBookcaseAdapter); + ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemTouchCallback); + itemTouchHelper.attachToRecyclerView(mBookcaseFragment.getRvBook()); + itemTouchCallback.setOnItemTouchListener(mBookcaseAdapter.getItemTouchCallbackListener()); + itemTouchCallback.setDragEnable(false); isBookcaseStyleChange = false; } else { mBookcaseAdapter.notifyDataSetChanged(); } mBookcaseFragment.getLlNoDataTips().setVisibility(View.GONE); - mBookcaseFragment.getGvBook().setVisibility(View.VISIBLE); + mBookcaseFragment.getSrlContent().setVisibility(View.VISIBLE); } } @@ -389,30 +355,32 @@ private void initBook() { } } - //检查书籍更新 public void initNoReadNum() { errorLoadingBooks.clear(); - finishLoadBookCount = 0; - for (Book book : mBooks) { - mBookcaseAdapter.getIsLoading().put(book.getId(), true); - } if (mBooks.size() > 0) { - mHandler.sendMessage(mHandler.obtainMessage(3)); - } - for (final Book book : mBooks) { - if ("本地书籍".equals(book.getType()) || book.getIsCloseUpdate()) { - mBookcaseAdapter.getIsLoading().put(book.getId(), false); - mHandler.sendMessage(mHandler.obtainMessage(1)); - continue; + mBookcaseAdapter.notifyDataSetChanged(); + threadsNum = SharedPreUtils.getInstance().getInt(App.getmContext().getString(R.string.threadNum), 8); + refreshIndex = -1; + for (int i = 0; i < threadsNum; i++) { + refreshBookshelf(); } - Thread update = new Thread(() -> { + } + } + + + private synchronized void refreshBookshelf() { + refreshIndex++; + if (refreshIndex < mBooks.size()) { + Book book = mBooks.get(refreshIndex); + if (!"本地书籍".equals(book.getType()) && !book.getIsCloseUpdate()) { + mBookcaseAdapter.getIsLoading().put(book.getId(), true); + mBookcaseAdapter.refreshBook(book.getChapterUrl()); final ArrayList mChapters = (ArrayList) mChapterService.findBookAllChapterByBookId(book.getId()); final ReadCrawler mReadCrawler = ReadCrawlerUtil.getReadCrawler(book.getSource()); BookApi.getBookChapters(book, mReadCrawler).flatMap(chapters -> Observable.create(emitter -> { int noReadNum = chapters.size() - book.getChapterTotalNum(); book.setNoReadNum(Math.max(noReadNum, 0)); book.setNewestChapterTitle(chapters.get(chapters.size() - 1).getTitle()); - mBookcaseAdapter.getIsLoading().put(book.getId(), false); mChapterService.updateAllOldChapterData(mChapters, chapters, book.getId()); mBookService.updateEntity(book); emitter.onNext(book); @@ -420,31 +388,39 @@ public void initNoReadNum() { })).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver() { @Override public void onNext(@NotNull Object o) { - mHandler.sendMessage(mHandler.obtainMessage(1)); + mBookcaseAdapter.getIsLoading().put(book.getId(), false); + mBookcaseFragment.getSrlContent().finishRefresh(); + mBookcaseAdapter.refreshBook(book.getChapterUrl()); + refreshBookshelf(); } @Override public void onError(Throwable e) { mBookcaseAdapter.getIsLoading().put(book.getId(), false); + mBookcaseFragment.getSrlContent().finishRefresh(); + mBookcaseAdapter.refreshBook(book.getChapterUrl()); errorLoadingBooks.add(book); - mHandler.sendMessage(mHandler.obtainMessage(1)); if (App.isDebug()) e.printStackTrace(); + refreshBookshelf(); } }); - }); - es.submit(update); - } - App.getApplication().newThread(() -> { - while (true) { - if (finishLoadBookCount == mBooks.size()) { - mHandler.sendMessage(mHandler.obtainMessage(4)); - mHandler.sendMessage(mHandler.obtainMessage(2)); - break; + } else { + refreshBookshelf(); + mBookcaseFragment.getSrlContent().finishRefresh(); + } + } else if (refreshIndex >= mBooks.size() + threadsNum - 1) { + showErrorLoadingBooks(); + if (App.isDebug()) { + if (isFirstRefresh) { + initBook(); + isFirstRefresh = false; } + downloadAll(false, false); } - }); + } } + /** * 显示更新失败的书籍信息 */ @@ -471,7 +447,6 @@ public boolean onOptionsItemSelected(MenuItem item) { editBookcase(true); return true; case R.id.action_styleChange: - mBookcaseFragment.getGvBook().getmScrollView().setScrollY(0); if (mSetting.getBookcaseStyle().equals(BookcaseStyle.listMode)) { mSetting.setBookcaseStyle(BookcaseStyle.threePalaceMode); ToastUtils.show("已切换为三列网格视图!"); @@ -552,11 +527,10 @@ public void showBookGroupMenu(View view) { private void editBookcase(boolean isEdit) { if (isEdit) { if (canEditBookcase()) { + mMainActivity.getViewPagerMain().setEnableScroll(false); mBookcaseFragment.getSrlContent().setEnableRefresh(false); + itemTouchCallback.setDragEnable(mSetting.getSortStyle() == 0); mBookcaseAdapter.setmEditState(true); - if (mSetting.getSortStyle() == 0) { - mBookcaseFragment.getGvBook().setDragModel(DragSortGridView.DRAG_BY_LONG_CLICK); - } mBookcaseFragment.getRlBookEdit().setVisibility(View.VISIBLE); mMainActivity.initMenuAnim(); mBookcaseFragment.getRlBookEdit().startAnimation(mMainActivity.getmBottomInAnim()); @@ -567,11 +541,9 @@ private void editBookcase(boolean isEdit) { ToastUtils.showWarring("当前无任何书籍,无法编辑书架!"); } } else { - if (mBookcaseFragment.getGvBook().getmScrollView().getScrollY() == 0 - && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mBookcaseFragment.getSrlContent().setEnableRefresh(true); - } - mBookcaseFragment.getGvBook().setDragModel(-1); + mMainActivity.getViewPagerMain().setEnableScroll(true); + mBookcaseFragment.getSrlContent().setEnableRefresh(true); + itemTouchCallback.setDragEnable(false); mBookcaseAdapter.setmEditState(false); mBookcaseFragment.getRlBookEdit().setVisibility(View.GONE); mMainActivity.initMenuAnim(); diff --git a/app/src/main/java/xyz/fycz/myreader/widget/NoScrollViewPager.java b/app/src/main/java/xyz/fycz/myreader/widget/NoScrollViewPager.java new file mode 100644 index 00000000..0658c457 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/widget/NoScrollViewPager.java @@ -0,0 +1,64 @@ +package xyz.fycz.myreader.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.viewpager.widget.ViewPager; + +/** + * @author fengyue + * @date 2021/6/2 19:57 + */ +//禁止左右滑动的viewpager +public class NoScrollViewPager extends ViewPager { + + private boolean enableScroll = true; + + public NoScrollViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NoScrollViewPager(Context context) { + super(context); + } + + //调用此方法 参数为false 即可禁止滑动 + public void setEnableScroll(boolean noScroll) { + this.enableScroll = noScroll; + } + + @Override + public void scrollTo(int x, int y) { +// if(noScroll){ //加上判断无法用 setCurrentItem 方法切换 + super.scrollTo(x, y); +// } + } + + @Override + public boolean onTouchEvent(MotionEvent arg0) { + if (!enableScroll) + return false; + else + return super.onTouchEvent(arg0); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent arg0) { + if (!enableScroll) + return false; + else + return super.onInterceptTouchEvent(arg0); + } + + @Override + public void setCurrentItem(int item, boolean smoothScroll) { + super.setCurrentItem(item, smoothScroll); + } + + @Override + public void setCurrentItem(int item) { + super.setCurrentItem(item); + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index bc31c7d7..d8e40029 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -43,7 +43,7 @@ - diff --git a/app/src/main/res/layout/fragment_book_list.xml b/app/src/main/res/layout/fragment_book_list.xml new file mode 100644 index 00000000..32bd14b1 --- /dev/null +++ b/app/src/main/res/layout/fragment_book_list.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + +