优化卡顿问题

pull/5/head
fengyuecanzhu 4 years ago
parent 0cf2304b22
commit b22541db74
  1. 57
      app/src/main/java/xyz/fycz/myreader/application/App.java
  2. 9
      app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java
  3. 112
      app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseAdapter.java
  4. 66
      app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDetailedAdapter.java
  5. 62
      app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseDragAdapter.java
  6. 173
      app/src/main/java/xyz/fycz/myreader/ui/dialog/APPDownloadTip.java
  7. 32
      app/src/main/java/xyz/fycz/myreader/ui/fragment/BookcaseFragment.java
  8. 156
      app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java
  9. 64
      app/src/main/java/xyz/fycz/myreader/widget/NoScrollViewPager.java
  10. 2
      app/src/main/res/layout/activity_main.xml
  11. 2
      app/src/main/res/layout/activity_more_setting.xml
  12. 95
      app/src/main/res/layout/fragment_book_list.xml
  13. 1
      app/src/main/res/layout/gridview_book_detailed_item.xml
  14. 6
      app/src/main/res/menu/menu_book.xml
  15. 4
      app/src/main/res/values/strings.xml

@ -51,7 +51,6 @@ import xyz.fycz.myreader.common.URLCONST;
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 class App extends Application {
});
}
/**
* 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) {

@ -48,6 +48,7 @@ import xyz.fycz.myreader.util.help.StringHelper;
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 @@ public class MainActivity extends BaseActivity {
mMineFragment = (MineFragment) fragments.get(2);
}
public ViewPager getViewPagerMain() {
public NoScrollViewPager getViewPagerMain() {
return binding.viewPagerMain;
}
@ -250,10 +251,6 @@ public class MainActivity extends BaseActivity {
@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 class MainActivity extends BaseActivity {
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();

@ -4,11 +4,16 @@ import android.content.Context;
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 java.util.*;
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 @@ import xyz.fycz.myreader.widget.BadgeView;
* @author fengyue
* @date 2020/4/19 11:23
*/
public abstract class BookcaseAdapter extends DragAdapter {
public abstract class BookcaseAdapter extends RecyclerView.Adapter<BookcaseAdapter.ViewHolder> {
private final Map<String, Boolean> isLoading = new HashMap<>();
private final Map<String, Boolean> 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<Book> objects
, boolean editState, BookcasePresenter bookcasePresenter, boolean isGroup) {
@ -75,25 +81,10 @@ public abstract class BookcaseAdapter extends DragAdapter {
@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 abstract class BookcaseAdapter extends DragAdapter {
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 @@ public abstract class BookcaseAdapter extends DragAdapter {
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 abstract class BookcaseAdapter extends DragAdapter {
mCheckMap.put(book.getId(), false);
}
mCheckedCount = 0;
} else {
onDataMove();
}
this.mEditState = mEditState;
notifyDataSetChanged();
@ -173,6 +176,10 @@ public abstract class BookcaseAdapter extends DragAdapter {
return isLoading.get(bookID);
}
public ItemTouchCallback.OnItemTouchListener getItemTouchCallbackListener() {
return itemTouchCallbackListener;
}
public boolean unionChapterCathe(Book book) throws IOException {
ArrayList<Chapter> chapters = (ArrayList<Chapter>) mChapterService.findBookAllChapterByBookId(book.getId());
BufferedReader br = null;
@ -317,39 +324,52 @@ public abstract class BookcaseAdapter extends DragAdapter {
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<Chapter> chapters = (ArrayList<Chapter>) 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<Chapter> chapters = (ArrayList<Chapter>) 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) {

@ -8,16 +8,22 @@ import android.view.ViewGroup;
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<Book> 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 @@ public class BookcaseDetailedAdapter extends BookcaseAdapter {
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 @@ public class BookcaseDetailedAdapter extends BookcaseAdapter {
case 0:
if (!isGroup) {
book.setSortCode(0);
}else {
} else {
book.setGroupSort(0);
}
mBookService.updateEntity(book);
@ -230,12 +242,24 @@ public class BookcaseDetailedAdapter extends BookcaseAdapter {
}
}
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);
}
}
}

@ -6,8 +6,12 @@ import android.view.LayoutInflater;
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.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;
@ -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<Book> 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 @@ public class BookcaseDragAdapter extends BookcaseAdapter {
}
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 class BookcaseDragAdapter extends BookcaseAdapter {
case 1:
if (!isGroup) {
book.setSortCode(0);
}else {
} else {
book.setGroupSort(0);
}
mBookService.updateEntity(book);
@ -224,6 +244,14 @@ public class BookcaseDragAdapter extends BookcaseAdapter {
}
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);
}
}
}

@ -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 + "%]");
}
}

@ -14,9 +14,11 @@ import android.widget.RelativeLayout;
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 @@ import xyz.fycz.myreader.widget.custom.DragSortGridView;
*/
public class BookcaseFragment extends Fragment {
private FragmentBookcaseBinding binding;
private FragmentBookListBinding binding;
private BookcasePresenter mBookcasePresenter;
@ -39,7 +41,7 @@ public class BookcaseFragment extends Fragment {
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 class BookcaseFragment extends Fragment {
}
@Override
public void onResume() {
super.onResume();
public void onStart() {
super.onStart();
mBookcasePresenter.init();
}
@ -61,28 +63,12 @@ public class BookcaseFragment extends Fragment {
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() {

@ -9,6 +9,7 @@ import android.graphics.BitmapFactory;
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.view.View;
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.ExecutorService;
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<Book> 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 class BookcasePresenter implements BasePresenter {
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 class BookcasePresenter implements BasePresenter {
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 class BookcasePresenter implements BasePresenter {
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 class BookcasePresenter implements BasePresenter {
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 class BookcasePresenter implements BasePresenter {
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 class BookcasePresenter implements BasePresenter {
//设置删除和加入分组按钮是否可用
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 @@ public class BookcasePresenter implements BasePresenter {
}
}
//检查书籍更新
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<Chapter> mChapters = (ArrayList<Chapter>) 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 class BookcasePresenter implements BasePresenter {
})).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<Object>() {
@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 class BookcasePresenter implements BasePresenter {
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 class BookcasePresenter implements BasePresenter {
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 @@ public class BookcasePresenter implements BasePresenter {
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();

@ -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);
}
}

@ -43,7 +43,7 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
<xyz.fycz.myreader.widget.NoScrollViewPager
android:id="@+id/view_pager_main"
android:layout_width="match_parent"
android:layout_height="0dp"

@ -432,7 +432,7 @@
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:text="@string/search_setting"
android:text="@string/thread_setting"
android:textColor="@color/textPrimary" />
</RelativeLayout>

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_no_data_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
app:srcCompat="@drawable/ic_vector_add_bookcase"
app:tint="@color/textSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="当前无任何书籍,点击添加"
android:textColor="@color/textSecondary"
android:textSize="16sp" />
</LinearLayout>
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/srl_book_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smartrefresh.header.MaterialHeader
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_book_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
<RelativeLayout
android:id="@+id/rl_book_edit"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_alignParentBottom="true"
android:background="@color/colorForeground"
android:gravity="center_vertical"
android:paddingEnd="10dp"
android:visibility="gone">
<CheckBox
android:id="@+id/book_selected_all"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:layout_marginStart="15dp"
android:text="全选"
android:textColor="@color/textSecondary"
android:textSize="15dp"
android:theme="@style/MyCheckBox" />
<Button
android:id="@+id/book_add_group"
android:layout_width="90dp"
android:layout_height="35dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="@drawable/selector_btn_add"
android:clickable="false"
android:enabled="false"
android:minWidth="110dp"
android:text="加入分组"
android:textColor="@color/selector_btn_file_add" />
<Button
android:id="@+id/book_btn_delete"
android:layout_width="90dp"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_marginEnd="15dp"
android:layout_toLeftOf="@id/book_add_group"
android:background="@drawable/selector_btn_add"
android:clickable="false"
android:enabled="false"
android:text="删除/移除"
android:textColor="@color/selector_btn_file_add" />
</RelativeLayout>
</RelativeLayout>

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/colorBackground"
android:id="@+id/rl_book_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"

@ -7,12 +7,6 @@
android:title="@string/finish"
app:showAsAction="always"
android:visible="false"/>
<item
android:visible="false"
android:id="@+id/action_refresh"
android:icon="@drawable/ic_refresh"
android:title="@string/refresh_books"
app:showAsAction="never"/>
<group android:id="@+id/bookcase_menu">
<item

@ -137,7 +137,7 @@
<string name="other_setting">其他设置</string>
<string name="open_store">开启书城</string>
<string name="open_bookstore_tip">打开软件时开启书城</string>
<string name="search_setting">搜索设置</string>
<string name="thread_setting">线程设置</string>
<string name="disable_source">禁用书源</string>
<string name="disable_source_tip">选择搜索时禁用的书源</string>
<string name="loading_tip">正在加载...</string>
@ -152,7 +152,7 @@
<string name="menu_change_group">分组切换</string>
<string name="menu_group_man">分组管理</string>
<string name="menu_group_setting">设置分组</string>
<string name="thread_num">搜索线程数</string>
<string name="thread_num">更新/搜索线程数</string>
<string name="cur_thread_num">当前线程数:%1$d</string>
<string name="newest_chapter">最新章节:%1$s</string>
<string name="source_title_num">书源:%1$s 共%2$d个源</string>

Loading…
Cancel
Save