From e82030a0bc80e81b2a263096f63c85eb4f66772b Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Mon, 17 Jan 2022 13:38:37 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/gradle.xml | 3 +- .idea/misc.xml | 2 +- .../ui/activity/SearchBookActivity.java | 269 +++++++++++++----- .../xyz/fycz/myreader/widget/TagGroup.java | 47 ++- .../main/res/layout/activity_search_book.xml | 230 +++++++++------ app/src/main/res/values/colors.xml | 3 +- app/src/main/res/values/strings.xml | 5 + app/src/main/res/values/styles.xml | 1 + 8 files changed, 401 insertions(+), 159 deletions(-) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index bf2bb41..eb20a8e 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,7 +4,7 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index e709b95..74eac7a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -21,7 +21,7 @@ - + diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java index a424aa8..6dccc43 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java @@ -49,6 +49,7 @@ import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.SearchHistory; import xyz.fycz.myreader.greendao.entity.rule.BookSource; +import xyz.fycz.myreader.greendao.service.BookService; import xyz.fycz.myreader.greendao.service.SearchHistoryService; import xyz.fycz.myreader.model.SearchEngine; import xyz.fycz.myreader.model.mulvalmap.ConMVMap; @@ -65,6 +66,7 @@ import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.RxUtils; import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil; import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; +import xyz.fycz.myreader.widget.TagGroup; /** * @author fengyue @@ -76,14 +78,17 @@ public class SearchBookActivity extends BaseActivity { private SearchAdapter mSearchBookAdapter; private String searchKey;//搜索关键字 - private List mSearchHistories = new ArrayList<>(); - private List mSuggestions = new ArrayList<>(); - private List mHotKeys = new ArrayList<>(); + private List mSearchHistories; + private List mCurHistories = new ArrayList<>(); + private final List mBookcase = new ArrayList<>(); + private List mBooks; + private final List mSuggestions = new ArrayList<>(); + private final List mHotKeys = new ArrayList<>(); + private final List mBookcaseNames = new ArrayList<>(); + private final List mHistoryNames = new ArrayList<>(); private SearchHistoryService mSearchHistoryService; - private SearchHistoryAdapter mSearchHistoryAdapter; - private int allThreadCount; private SearchEngine searchEngine; @@ -96,13 +101,19 @@ public class SearchBookActivity extends BaseActivity { private Disposable sugDis; - private boolean showBooks; + private Disposable hisDis; + private Disposable caseDis; + + private boolean showBooks; private static String[] suggestion = {"第一序列", "大道朝天", "伏天氏", "终极斗罗", "我师兄实在太稳健了", "烂柯棋缘", "诡秘之主", "不朽凡人", "圣墟", "我是至尊", "龙王传说", "太古神王", "一念永恒", "雪鹰领主", "大主宰"}; private boolean showHot; + private boolean foldBookcase; + private boolean foldSuggest; + private boolean foldHistory; @Override protected void bindView() { @@ -120,7 +131,7 @@ public class SearchBookActivity extends BaseActivity { @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); - if (hasFocus && binding.etSearchKey.getText().length() == 0){ + if (hasFocus && binding.etSearchKey.getText().length() == 0) { App.getHandler().postDelayed(() -> { binding.etSearchKey.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); @@ -134,7 +145,11 @@ public class SearchBookActivity extends BaseActivity { super.initData(savedInstanceState); mSetting = SysManager.getSetting(); mSearchHistoryService = SearchHistoryService.getInstance(); + mBooks = BookService.getInstance().getAllBooksNoHide(); showHot = !App.isDebug(); + foldBookcase = SharedPreUtils.getInstance().getBoolean("foldBookcase"); + foldSuggest = SharedPreUtils.getInstance().getBoolean("foldSuggest"); + foldHistory = SharedPreUtils.getInstance().getBoolean("foldHistory"); searchEngine = new SearchEngine(); searchEngine.setOnSearchListener(new SearchEngine.OnSearchListener() { @Override @@ -189,18 +204,13 @@ public class SearchBookActivity extends BaseActivity { } binding.rgSearchFilter.setOnCheckedChangeListener((group, checkedId) -> { - int searchFilter; - switch (checkedId) { - case R.id.rb_all_search: - default: - searchFilter = 0; - break; - case R.id.rb_fuzzy_search: - searchFilter = 1; - break; - case R.id.rb_precise_search: - searchFilter = 2; - break; + int searchFilter = 0; + if (checkedId == R.id.rb_all_search) { + searchFilter = 0; + } else if (checkedId == R.id.rb_fuzzy_search) { + searchFilter = 1; + } else if (checkedId == R.id.rb_precise_search) { + searchFilter = 2; } mSetting.setSearchFilter(searchFilter); SysManager.saveSetting(mSetting); @@ -225,6 +235,8 @@ public class SearchBookActivity extends BaseActivity { if (StringHelper.isEmpty(searchKey)) { search(); } + searchBookcase(); + initHistoryList(); initSuggestionList(); } @@ -237,6 +249,32 @@ public class SearchBookActivity extends BaseActivity { stopSearch(); search(); }); + + binding.tgBookcase.setVisibility(foldBookcase ? View.GONE : View.VISIBLE); + binding.tvFlattenBookcase.setText(foldBookcase ? R.string.unfold : R.string.fold); + binding.tgSuggestBook.setVisibility(foldSuggest ? View.GONE : View.VISIBLE); + binding.tvFlattenSuggest.setText(foldSuggest ? R.string.unfold : R.string.fold); + binding.tgHistoryBooks.setVisibility(foldHistory ? View.GONE : View.VISIBLE); + binding.tvFlattenHistory.setText(foldHistory ? R.string.unfold : R.string.fold); + + binding.rlBookcaseBar.setOnClickListener(v -> { + foldBookcase = !foldBookcase; + binding.tgBookcase.setVisibility(foldBookcase ? View.GONE : View.VISIBLE); + binding.tvFlattenBookcase.setText(foldBookcase ? R.string.unfold : R.string.fold); + SharedPreUtils.getInstance().putBoolean("foldBookcase", foldBookcase); + }); + binding.rlSuggestBar.setOnClickListener(v -> { + foldSuggest = !foldSuggest; + binding.tgSuggestBook.setVisibility(foldSuggest ? View.GONE : View.VISIBLE); + binding.tvFlattenSuggest.setText(foldSuggest ? R.string.unfold : R.string.fold); + SharedPreUtils.getInstance().putBoolean("foldSuggest", foldSuggest); + }); + binding.rlHistoryBar.setOnClickListener(v -> { + foldHistory = !foldHistory; + binding.tgHistoryBooks.setVisibility(foldHistory ? View.GONE : View.VISIBLE); + binding.tvFlattenHistory.setText(foldHistory ? R.string.unfold : R.string.fold); + SharedPreUtils.getInstance().putBoolean("foldHistory", foldHistory); + }); initHistoryList(); } @@ -244,35 +282,43 @@ public class SearchBookActivity extends BaseActivity { protected void initClick() { super.initClick(); - //换一批点击事件 - binding.llRefreshSuggestBooks.setOnClickListener(new RenewSuggestionBook()); - //搜索按钮点击事件 binding.tvSearchConform.setOnClickListener(view -> search()); //suggestion搜索事件 - binding.tgSuggestBook.setOnTagClickListener(tag -> { + binding.tgSuggestBook.setOnTagClickListener((tag, pos) -> { binding.etSearchKey.setText(tag); binding.etSearchKey.setSelection(tag.length()); search(); }); //历史记录搜索事件 - binding.lvHistoryList.setOnItemClickListener((parent, view, position, id) -> { - binding.etSearchKey.setText(mSearchHistories.get(position).getContent()); - binding.etSearchKey.setSelection(mSearchHistories.get(position).getContent().length()); + binding.tgHistoryBooks.setOnTagClickListener((tag, pos) -> { + binding.etSearchKey.setText(tag); + binding.etSearchKey.setSelection(tag.length()); search(); }); //清空历史记录 - binding.llClearHistory.setOnClickListener(v -> { - mSearchHistoryService.clearHistory(); - initHistoryList(); + binding.tvClearHistory.setOnClickListener(v -> { + DialogCreator.createCommonDialog(this, "清除搜索记录", "确定要清除全部搜索记录吗?", + true, (dialog, which) -> { + mSearchHistoryService.clearHistory(); + initHistoryList(); + }, null); }); //清除单个历史记录 - binding.lvHistoryList.setOnItemLongClickListener((parent, view, position, id) -> { - if (mSearchHistories.get(position) != null) { - mSearchHistoryService.deleteHistory(mSearchHistories.get(position)); + binding.tgHistoryBooks.setLongClickDelete(true); + binding.tgHistoryBooks.setOnTagChangeListener(new TagGroup.OnTagChangeListener() { + @Override + public void onAppend(TagGroup tagGroup, String tag) { + + } + + @Override + public void onDelete(TagGroup tagGroup, String tag, int pos) { + if (mCurHistories.get(pos) != null) { + mSearchHistoryService.deleteHistory(mCurHistories.get(pos)); + } initHistoryList(); } - return true; }); binding.fabSearchStop.setOnClickListener(v -> { @@ -445,7 +491,6 @@ public class SearchBookActivity extends BaseActivity { initSuggestionList(); } }); - ; } } @@ -460,11 +505,10 @@ public class SearchBookActivity extends BaseActivity { mSuggestions.clear(); if (StringHelper.isEmpty(searchKey)) { if (mHotKeys.isEmpty()) { - binding.llSuggestBooksView.setVisibility(View.GONE); + binding.llSuggestBook.setVisibility(View.GONE); } else { - binding.llSuggestBooksView.setVisibility(View.VISIBLE); - binding.llRefreshSuggestBooks.setVisibility(View.VISIBLE); - binding.tgSuggestBook.setTags2(mHotKeys.subList(0, mHotKeys.size() / 2)); + binding.llSuggestBook.setVisibility(View.VISIBLE); + binding.tgSuggestBook.setTags2(mHotKeys); } } else { String url = "https://newzxautocmp.reader.qq.com/BookSuggAll?key=" + searchKey; @@ -480,13 +524,18 @@ public class SearchBookActivity extends BaseActivity { @Override public void onSuccess(@NotNull String s) { parseSuggListByKey(s); - binding.llRefreshSuggestBooks.setVisibility(View.GONE); + if (mSuggestions.isEmpty()) { + binding.llSuggestBook.setVisibility(View.GONE); + return; + } else { + binding.llSuggestBook.setVisibility(View.VISIBLE); + } binding.tgSuggestBook.setTags2(mSuggestions); } @Override public void onError(Throwable e) { - binding.llSuggestBooksView.setVisibility(View.GONE); + binding.llSuggestBook.setVisibility(View.GONE); } }); } @@ -527,32 +576,65 @@ public class SearchBookActivity extends BaseActivity { } } - private class RenewSuggestionBook implements View.OnClickListener { - @Override - public void onClick(View v) { - if (mHotKeys.size() > 0) { - String[] s = binding.tgSuggestBook.getTags(); - if (s[0].equals(mHotKeys.get(0))) { - binding.tgSuggestBook.setTags2(mHotKeys.subList(mHotKeys.size() / 2, mHotKeys.size())); - } else { - binding.tgSuggestBook.setTags2(mHotKeys.subList(0, mHotKeys.size() / 2)); - } - } - } - } - /** * 初始化历史列表 */ private void initHistoryList() { - mSearchHistories = mSearchHistoryService.findAllSearchHistory(); - if (mSearchHistories == null || mSearchHistories.size() == 0) { - binding.llHistoryView.setVisibility(View.GONE); - } else { - mSearchHistoryAdapter = new SearchHistoryAdapter(this, R.layout.listview_search_history_item, mSearchHistories); - binding.lvHistoryList.setAdapter(mSearchHistoryAdapter); - binding.llHistoryView.setVisibility(View.VISIBLE); + if (hisDis != null) { + hisDis.dispose(); } + Single.create((SingleOnSubscribe) emitter -> { + mSearchHistories = mSearchHistoryService.findAllSearchHistory(); + mHistoryNames.clear(); + mCurHistories.clear(); + if (mSearchHistories == null || mSearchHistories.size() == 0) { + emitter.onSuccess(false); + } else { + if (StringHelper.isEmpty(searchKey)) { + mCurHistories.addAll(mSearchHistories); + for (SearchHistory history : mSearchHistories) { + mHistoryNames.add(history.getContent()); + } + } else { + for (SearchHistory history : mSearchHistories) { + String title = history.getContent(); + int start = title.indexOf(searchKey); + if (start != -1) { + SpannableString spannableString = new SpannableString(title); + spannableString.setSpan(new ForegroundColorSpan(Color.RED), + start, start + searchKey.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + mHistoryNames.add(spannableString); + mCurHistories.add(history); + } + } + } + emitter.onSuccess(!mHistoryNames.isEmpty()); + } + }).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + hisDis = d; + } + + @Override + public void onSuccess(@NonNull Boolean aBoolean) { + if (aBoolean) { + binding.llHistoryBooks.setVisibility(View.VISIBLE); + binding.tgHistoryBooks.setTags2(mHistoryNames); + } else { + binding.llHistoryBooks.setVisibility(View.GONE); + } + } + + @Override + public void onError(Throwable e) { + e.printStackTrace(); + binding.llHistoryBooks.setVisibility(View.GONE); + } + }); + } /** @@ -561,9 +643,67 @@ public class SearchBookActivity extends BaseActivity { private void initSearchList() { //initmBooksBean(); binding.rvSearchBooksList.setVisibility(View.VISIBLE); - binding.llSuggestBooksView.setVisibility(View.GONE); + binding.llPreKeys.setVisibility(View.GONE); } + /** + * 搜索书架 + */ + private void searchBookcase() { + if (caseDis != null) { + caseDis.dispose(); + } + if (StringHelper.isEmpty(searchKey)) { + binding.llBookcase.setVisibility(View.GONE); + } else { + Single.create((SingleOnSubscribe) emitter -> { + mBookcase.clear(); + mBookcaseNames.clear(); + for (Book book : mBooks) { + String title = book.getName() + "-" + book.getAuthor(); + if ("本地书籍".equals(book.getType())) { + title += "[本地]"; + } + int start = title.indexOf(searchKey); + if (start != -1) { + SpannableString spannableString = new SpannableString(title); + spannableString.setSpan(new ForegroundColorSpan(Color.RED), + start, start + searchKey.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + mBookcaseNames.add(spannableString); + mBookcase.add(book); + } + } + emitter.onSuccess(!mBookcase.isEmpty()); + }).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + caseDis = d; + } + + @Override + public void onSuccess(@NonNull Boolean aBoolean) { + if (aBoolean) { + binding.llBookcase.setVisibility(View.VISIBLE); + binding.tgBookcase.setTags2(mBookcaseNames); + binding.tgBookcase.setOnTagClickListener((tag, pos) -> { + Intent intent = new Intent(SearchBookActivity.this, BookDetailedActivity.class); + BitIntentDataManager.getInstance().putData(intent, mBookcase.get(pos)); + startActivity(intent); + }); + } else { + binding.llBookcase.setVisibility(View.GONE); + } + } + + @Override + public void onError(Throwable e) { + e.printStackTrace(); + binding.llBookcase.setVisibility(View.GONE); + } + }); + } + } /** * 获取搜索数据 @@ -595,7 +735,7 @@ public class SearchBookActivity extends BaseActivity { stopSearch(); binding.rpb.setIsAutoLoading(false); binding.rvSearchBooksList.setVisibility(View.GONE); - binding.llSuggestBooksView.setVisibility(View.VISIBLE); + binding.llPreKeys.setVisibility(View.VISIBLE); binding.fabSearchStop.setVisibility(View.GONE); initHistoryList(); binding.rvSearchBooksList.setAdapter(null); @@ -606,8 +746,7 @@ public class SearchBookActivity extends BaseActivity { binding.rvSearchBooksList.setAdapter(mSearchBookAdapter); binding.srlSearchBookList.setEnableRefresh(true); binding.rvSearchBooksList.setVisibility(View.VISIBLE); - binding.llSuggestBooksView.setVisibility(View.GONE); - binding.llHistoryView.setVisibility(View.GONE); + binding.llPreKeys.setVisibility(View.GONE); binding.fabSearchStop.setVisibility(View.VISIBLE); getData(); mSearchHistoryService.addOrUpadteHistory(searchKey); diff --git a/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java b/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java index 472d708..6a27148 100644 --- a/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java +++ b/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java @@ -70,6 +70,9 @@ public class TagGroup extends ViewGroup { private final float default_horizontal_padding; private final float default_vertical_padding; + /** Indicate whether the tags are deleted by holding down. Default is false. */ + private boolean isLongClickDelete; + /** Indicates whether this TagGroup is set up to APPEND mode or DISPLAY mode. Default is false. */ private boolean isAppendMode; @@ -156,6 +159,7 @@ public class TagGroup extends ViewGroup { // Load styled attributes. final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TagGroup, defStyleAttr, R.style.TagGroup); try { + isLongClickDelete = a.getBoolean(R.styleable.TagGroup_atg_isLongClickDelete, false); isAppendMode = a.getBoolean(R.styleable.TagGroup_atg_isAppendMode, false); inputHint = a.getText(R.styleable.TagGroup_atg_inputHint); borderColor = a.getColor(R.styleable.TagGroup_atg_borderColor, default_border_color); @@ -492,8 +496,15 @@ public class TagGroup extends ViewGroup { throw new IllegalStateException("Already has a INPUT tag in group."); } - final TagView newInputTag = new TagView(getContext(), TagView.STATE_INPUT, tag); + final TagView newInputTag = new TagView(getContext(), TagView.STATE_INPUT, tag, getChildCount()); newInputTag.setOnClickListener(mInternalTagClickListener); + newInputTag.setOnLongClickListener(v -> { + if (isLongClickDelete) { + deleteTag(newInputTag); + return true; + } + return false; + }); addView(newInputTag); } @@ -503,8 +514,15 @@ public class TagGroup extends ViewGroup { * @param tag the tag to append. */ protected void appendTag(CharSequence tag) { - final TagView newTag = new TagView(getContext(), TagView.STATE_NORMAL, tag); + final TagView newTag = new TagView(getContext(), TagView.STATE_NORMAL, tag, getChildCount()); newTag.setOnClickListener(mInternalTagClickListener); + newTag.setOnLongClickListener(v -> { + if (isLongClickDelete) { + deleteTag(newTag); + return true; + } + return false; + }); addView(newTag); } @@ -532,10 +550,18 @@ public class TagGroup extends ViewGroup { mOnTagClickListener = l; } + /** + * Set up whether the tags are deleted by holding down. + * @param longClickDelete + */ + public void setLongClickDelete(boolean longClickDelete) { + isLongClickDelete = longClickDelete; + } + protected void deleteTag(TagView tagView) { removeView(tagView); if (mOnTagChangeListener != null) { - mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString()); + mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString(), tagView.pos); } } @@ -555,7 +581,7 @@ public class TagGroup extends ViewGroup { * * @param tag the deleted tag. */ - void onDelete(TagGroup tagGroup, String tag); + void onDelete(TagGroup tagGroup, String tag, int pos); } /** @@ -567,7 +593,7 @@ public class TagGroup extends ViewGroup { * * @param tag The tag text of the tag that was clicked. */ - void onTagClick(String tag); + void onTagClick(String tag, int pos); } /** @@ -630,6 +656,7 @@ public class TagGroup extends ViewGroup { * The tag view click listener for internal use. */ class InternalTagClickListener implements OnClickListener { + @Override public void onClick(View v) { final TagView tag = (TagView) v; @@ -656,7 +683,7 @@ public class TagGroup extends ViewGroup { } } else { if (mOnTagClickListener != null) { - mOnTagClickListener.onTagClick(tag.getText().toString()); + mOnTagClickListener.onTagClick(tag.getText().toString(), tag.pos); } } } @@ -669,6 +696,9 @@ public class TagGroup extends ViewGroup { public static final int STATE_NORMAL = 1; public static final int STATE_INPUT = 2; + /** The position in the group. */ + private int pos = -1; + /** The offset to the text. */ private static final int CHECKED_MARKER_OFFSET = 3; @@ -724,8 +754,9 @@ public class TagGroup extends ViewGroup { } - public TagView(Context context, final int state, CharSequence text) { + public TagView(Context context, final int state, CharSequence text, int pos) { super(context); + this.pos = pos; setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); setLayoutParams(new LayoutParams( LayoutParams.WRAP_CONTENT, @@ -788,7 +819,7 @@ public class TagGroup extends ViewGroup { if (lastNormalTagView.isChecked) { removeView(lastNormalTagView); if (mOnTagChangeListener != null) { - mOnTagChangeListener.onDelete(TagGroup.this, lastNormalTagView.getText().toString()); + mOnTagChangeListener.onDelete(TagGroup.this, lastNormalTagView.getText().toString(), pos); } } else { final TagView checkedTagView = getCheckedTag(); diff --git a/app/src/main/res/layout/activity_search_book.xml b/app/src/main/res/layout/activity_search_book.xml index 41a1334..56bf83e 100644 --- a/app/src/main/res/layout/activity_search_book.xml +++ b/app/src/main/res/layout/activity_search_book.xml @@ -87,102 +87,168 @@ android:layout_height="3dp" android:visibility="visible" /> - - - + android:layout_height="wrap_content"> + android:orientation="vertical" + android:padding="5dp"> - + android:orientation="vertical" + android:paddingHorizontal="5dp" + android:visibility="gone"> - + + + + + + + + + + + - - - - - - - - - - - + android:orientation="vertical" + android:paddingHorizontal="5dp" + android:visibility="visible"> - - - - - + + + + + + + + + + + + android:orientation="vertical" + android:paddingHorizontal="5dp" + android:visibility="visible"> + + + + + + + + + + + + + + - - + + app:layout_anchorGravity="right|bottom" /> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index b22bd86..781aed0 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,6 @@ - #FF2196F3 + @color/blue_bar #3F51B5 #90cbf6 @@ -102,6 +102,7 @@ #18188a + #FF2196F3 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4f10c34..b06e871 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -518,6 +518,11 @@ 清除搜索结果 发送验证码 重新发送%s + 推荐 + 搜索记录(长按删除) + 清除搜索记录 + 收起 + 展开 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ae8d236..25f2e4e 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -273,6 +273,7 @@ + From 525b59acdaa1f0f02f534cb2be3be2219e127224 Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Mon, 17 Jan 2022 15:52:23 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E5=88=B0=E7=AB=A0=E8=8A=82=E6=9C=80=E5=90=8E=E4=B8=80=E9=A1=B5?= =?UTF-8?q?=E6=97=B6=E5=81=9C=E6=AD=A2=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/xyz/fycz/myreader/ui/activity/ReadActivity.java | 6 ++++-- .../xyz/fycz/myreader/ui/activity/SearchBookActivity.java | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java index 7064b1e..f2e1ad5 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java @@ -419,8 +419,10 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe pagePos = pos; saveLastChapterReadPosition(); } - screenOffTimerStart(); - initMenu(); + mHandler.post(()->{ + screenOffTimerStart(); + initMenu(); + }); recordReadTime(); if (ReadAloudService.running) { if (mPageLoader.hasChapterData(mChapters.get(mPageLoader.getChapterPos()))) { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java index 6dccc43..9baa6d9 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java @@ -114,6 +114,7 @@ public class SearchBookActivity extends BaseActivity { private boolean foldBookcase; private boolean foldSuggest; private boolean foldHistory; + private boolean needReGetHistory; @Override protected void bindView() { @@ -150,6 +151,7 @@ public class SearchBookActivity extends BaseActivity { foldBookcase = SharedPreUtils.getInstance().getBoolean("foldBookcase"); foldSuggest = SharedPreUtils.getInstance().getBoolean("foldSuggest"); foldHistory = SharedPreUtils.getInstance().getBoolean("foldHistory"); + needReGetHistory = true; searchEngine = new SearchEngine(); searchEngine.setOnSearchListener(new SearchEngine.OnSearchListener() { @Override @@ -317,6 +319,7 @@ public class SearchBookActivity extends BaseActivity { if (mCurHistories.get(pos) != null) { mSearchHistoryService.deleteHistory(mCurHistories.get(pos)); } + needReGetHistory = true; initHistoryList(); } }); @@ -584,7 +587,8 @@ public class SearchBookActivity extends BaseActivity { hisDis.dispose(); } Single.create((SingleOnSubscribe) emitter -> { - mSearchHistories = mSearchHistoryService.findAllSearchHistory(); + if (needReGetHistory) + mSearchHistories = mSearchHistoryService.findAllSearchHistory(); mHistoryNames.clear(); mCurHistories.clear(); if (mSearchHistories == null || mSearchHistories.size() == 0) { @@ -750,6 +754,7 @@ public class SearchBookActivity extends BaseActivity { binding.fabSearchStop.setVisibility(View.VISIBLE); getData(); mSearchHistoryService.addOrUpadteHistory(searchKey); + needReGetHistory = true; //收起软键盘 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(binding.etSearchKey.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); From 8171e64a30ef8ec4d6d72eda2b47a6032adff23f Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Mon, 17 Jan 2022 16:37:50 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E5=88=A0=E9=99=A4=E7=B2=92=E5=AD=90=E7=88=86?= =?UTF-8?q?=E7=82=B8=E5=8A=A8=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updatelog.fy | 1 + .../ui/activity/SearchBookActivity.java | 6 +- .../xyz/fycz/myreader/widget/TagGroup.java | 18 ++ .../explosion_field/ExplosionAnimator.java | 150 +++++++++++++ .../explosion_field/ExplosionField.java | 200 ++++++++++++++++++ .../explosion_field/OnAnimatorListener.java | 8 + .../widget/explosion_field/Utils.java | 72 +++++++ 7 files changed, 451 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionAnimator.java create mode 100644 app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionField.java create mode 100644 app/src/main/java/xyz/fycz/myreader/widget/explosion_field/OnAnimatorListener.java create mode 100644 app/src/main/java/xyz/fycz/myreader/widget/explosion_field/Utils.java diff --git a/app/src/main/assets/updatelog.fy b/app/src/main/assets/updatelog.fy index 528d152..31ff725 100644 --- a/app/src/main/assets/updatelog.fy +++ b/app/src/main/assets/updatelog.fy @@ -2,6 +2,7 @@ 风月读书v2.3.2 更新内容: 1、修复MIUI13阅读界面切换日夜间闪退的问题 +2、 2021.12.11 风月读书v2.2.8 diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java index 9baa6d9..bbd443a 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java @@ -318,9 +318,8 @@ public class SearchBookActivity extends BaseActivity { public void onDelete(TagGroup tagGroup, String tag, int pos) { if (mCurHistories.get(pos) != null) { mSearchHistoryService.deleteHistory(mCurHistories.get(pos)); + mSearchHistories.remove(mCurHistories.get(pos)); } - needReGetHistory = true; - initHistoryList(); } }); @@ -587,8 +586,7 @@ public class SearchBookActivity extends BaseActivity { hisDis.dispose(); } Single.create((SingleOnSubscribe) emitter -> { - if (needReGetHistory) - mSearchHistories = mSearchHistoryService.findAllSearchHistory(); + mSearchHistories = mSearchHistoryService.findAllSearchHistory(); mHistoryNames.clear(); mCurHistories.clear(); if (mSearchHistories == null || mSearchHistories.size() == 0) { diff --git a/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java b/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java index 6a27148..638ec6c 100644 --- a/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java +++ b/app/src/main/java/xyz/fycz/myreader/widget/TagGroup.java @@ -1,5 +1,6 @@ package xyz.fycz.myreader.widget; +import android.app.Activity; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; @@ -32,6 +33,7 @@ import java.util.ArrayList; import java.util.List; import xyz.fycz.myreader.R; +import xyz.fycz.myreader.widget.explosion_field.ExplosionField; /** * A TagGroup is a special layout with a set of tags. @@ -139,6 +141,8 @@ public class TagGroup extends ViewGroup { /** Listener used to handle tag click event. */ private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener(); + private ExplosionField mExplosionField; + public TagGroup(Context context) { this(context, null); } @@ -197,6 +201,18 @@ public class TagGroup extends ViewGroup { } } + @Override + protected void onAttachedToWindow() { + mExplosionField = ExplosionField.attach2Window((Activity) getContext()); + super.onAttachedToWindow(); + } + + @Override + protected void onDetachedFromWindow() { + mExplosionField.clear(); + super.onDetachedFromWindow(); + } + /** * Call this to submit the INPUT tag. */ @@ -559,6 +575,7 @@ public class TagGroup extends ViewGroup { } protected void deleteTag(TagView tagView) { + mExplosionField.explode(tagView); removeView(tagView); if (mOnTagChangeListener != null) { mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString(), tagView.pos); @@ -1034,6 +1051,7 @@ public class TagGroup extends ViewGroup { } break; } + case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: { isPressed = false; invalidatePaint(); diff --git a/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionAnimator.java b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionAnimator.java new file mode 100644 index 0000000..91da4d2 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionAnimator.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 tyrantgit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.fycz.myreader.widget.explosion_field; + +import android.animation.ValueAnimator; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.view.View; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.Interpolator; + +import java.util.Random; + +public class ExplosionAnimator extends ValueAnimator { + + static long DEFAULT_DURATION = 0x400; + private static final Interpolator DEFAULT_INTERPOLATOR = new AccelerateInterpolator(0.6f); + private static final float END_VALUE = 1.4f; + private static final float X = Utils.dp2Px(5); + private static final float Y = Utils.dp2Px(20); + private static final float V = Utils.dp2Px(2); + private static final float W = Utils.dp2Px(1); + private Paint mPaint; + private Particle[] mParticles; + private Rect mBound; + private View mContainer; + + public ExplosionAnimator(View container, Bitmap bitmap, Rect bound) { + mPaint = new Paint(); + mBound = new Rect(bound); + int partLen = 15; + mParticles = new Particle[partLen * partLen]; + Random random = new Random(System.currentTimeMillis()); + int w = bitmap.getWidth() / (partLen + 2); + int h = bitmap.getHeight() / (partLen + 2); + for (int i = 0; i < partLen; i++) { + for (int j = 0; j < partLen; j++) { + mParticles[(i * partLen) + j] = generateParticle(bitmap.getPixel((j + 1) * w, (i + 1) * h), random); + } + } + mContainer = container; + setFloatValues(0f, END_VALUE); + setInterpolator(DEFAULT_INTERPOLATOR); + setDuration(DEFAULT_DURATION); + } + + private Particle generateParticle(int color, Random random) { + Particle particle = new Particle(); + particle.color = color; + particle.radius = V; + if (random.nextFloat() < 0.2f) { + particle.baseRadius = V + ((X - V) * random.nextFloat()); + } else { + particle.baseRadius = W + ((V - W) * random.nextFloat()); + } + float nextFloat = random.nextFloat(); + particle.top = mBound.height() * ((0.18f * random.nextFloat()) + 0.2f); + particle.top = nextFloat < 0.2f ? particle.top : particle.top + ((particle.top * 0.2f) * random.nextFloat()); + particle.bottom = (mBound.height() * (random.nextFloat() - 0.5f)) * 1.8f; + float f = nextFloat < 0.2f ? particle.bottom : nextFloat < 0.8f ? particle.bottom * 0.6f : particle.bottom * 0.3f; + particle.bottom = f; + particle.mag = 4.0f * particle.top / particle.bottom; + particle.neg = (-particle.mag) / particle.bottom; + f = mBound.centerX() + (Y * (random.nextFloat() - 0.5f)); + particle.baseCx = f; + particle.cx = f; + f = mBound.centerY() + (Y * (random.nextFloat() - 0.5f)); + particle.baseCy = f; + particle.cy = f; + particle.life = END_VALUE / 10 * random.nextFloat(); + particle.overflow = 0.4f * random.nextFloat(); + particle.alpha = 1f; + return particle; + } + + public boolean draw(Canvas canvas) { + if (!isStarted()) { + return false; + } + for (Particle particle : mParticles) { + particle.advance((float) getAnimatedValue()); + if (particle.alpha > 0f) { + mPaint.setColor(particle.color); + mPaint.setAlpha((int) (Color.alpha(particle.color) * particle.alpha)); + canvas.drawCircle(particle.cx, particle.cy, particle.radius, mPaint); + } + } + mContainer.invalidate(); + return true; + } + + @Override + public void start() { + super.start(); + mContainer.invalidate(mBound); + } + + private class Particle { + float alpha; + int color; + float cx; + float cy; + float radius; + float baseCx; + float baseCy; + float baseRadius; + float top; + float bottom; + float mag; + float neg; + float life; + float overflow; + + + public void advance(float factor) { + float f = 0f; + float normalization = factor / END_VALUE; + if (normalization < life || normalization > 1f - overflow) { + alpha = 0f; + return; + } + normalization = (normalization - life) / (1f - life - overflow); + float f2 = normalization * END_VALUE; + if (normalization >= 0.7f) { + f = (normalization - 0.7f) / 0.3f; + } + alpha = 1f - f; + f = bottom * f2; + cx = baseCx + f; + cy = (float) (baseCy - this.neg * Math.pow(f, 2.0)) - f * mag; + radius = V + (baseRadius - V) * f2; + } + } +} diff --git a/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionField.java b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionField.java new file mode 100644 index 0000000..9597026 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/ExplosionField.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2015 tyrantgit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.fycz.myreader.widget.explosion_field; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.media.MediaPlayer; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + + +public class ExplosionField extends View { + + private long customDuration = ExplosionAnimator.DEFAULT_DURATION; + private int idPlayAnimationEffect = 0; + private OnAnimatorListener mZAnimatorListener; + private OnClickListener mOnClickListener; + + private List mExplosions = new ArrayList<>(); + private int[] mExpandInset = new int[2]; + + public ExplosionField(Context context) { + super(context); + init(); + } + + public ExplosionField(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public ExplosionField(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + + Arrays.fill(mExpandInset, Utils.dp2Px(32)); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + for (ExplosionAnimator explosion : mExplosions) { + explosion.draw(canvas); + } + } + + public void playSoundAnimationEffect(int id) { + this.idPlayAnimationEffect = id; + } + + public void setCustomDuration(long customDuration) { + this.customDuration = customDuration; + } + + public void addActionEvent(OnAnimatorListener ievents) { + this.mZAnimatorListener = ievents; + } + + + public void expandExplosionBound(int dx, int dy) { + mExpandInset[0] = dx; + mExpandInset[1] = dy; + } + + public void explode(Bitmap bitmap, Rect bound, long startDelay) { + explode(bitmap, bound, startDelay, null); + } + + public void explode(Bitmap bitmap, Rect bound, long startDelay, final View view) { + long currentDuration = customDuration; + final ExplosionAnimator explosion = new ExplosionAnimator(this, bitmap, bound); + explosion.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mExplosions.remove(animation); + if (view != null) { + view.setScaleX(1); + view.setScaleY(1); + view.setAlpha(1); + view.setOnClickListener(mOnClickListener);//set event + + } + } + }); + explosion.setStartDelay(startDelay); + explosion.setDuration(currentDuration); + mExplosions.add(explosion); + explosion.start(); + } + + public void explode(View view) { + explode(view, false); + } + + public void explode(final View view, Boolean restartState) { + + Rect r = new Rect(); + view.getGlobalVisibleRect(r); + int[] location = new int[2]; + getLocationOnScreen(location); +// getLocationInWindow(location); +// view.getLocationInWindow(location); + r.offset(-location[0], -location[1]); + r.inset(-mExpandInset[0], -mExpandInset[1]); + int startDelay = 100; + ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(150); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + + Random random = new Random(); + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + view.setTranslationX((random.nextFloat() - 0.5f) * view.getWidth() * 0.05f); + view.setTranslationY((random.nextFloat() - 0.5f) * view.getHeight() * 0.05f); + } + }); + + animator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animator) { + if (idPlayAnimationEffect != 0) + MediaPlayer.create(getContext(), idPlayAnimationEffect).start(); + } + + @Override + public void onAnimationEnd(Animator animator) { + if (mZAnimatorListener != null) { + mZAnimatorListener.onAnimationEnd(animator, ExplosionField.this); + } + } + + @Override + public void onAnimationCancel(Animator animator) { + Log.i("PRUEBA", "CANCEL"); + } + + @Override + public void onAnimationRepeat(Animator animator) { + Log.i("PRUEBA", "REPEAT"); + } + }); + + animator.start(); + view.animate().setDuration(150).setStartDelay(startDelay).scaleX(0f).scaleY(0f).alpha(0f).start(); + if (restartState) + explode(Utils.createBitmapFromView(view), r, startDelay, view); + else + explode(Utils.createBitmapFromView(view), r, startDelay); + + } + + public void clear() { + mExplosions.clear(); + invalidate(); + } + + public static ExplosionField attach2Window(Activity activity) { + ViewGroup rootView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); + ExplosionField explosionField = new ExplosionField(activity); + rootView.addView(explosionField, new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + return explosionField; + } + + public void setOnClickListener(OnClickListener mOnClickListener) { + this.mOnClickListener = mOnClickListener; + } + + +} diff --git a/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/OnAnimatorListener.java b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/OnAnimatorListener.java new file mode 100644 index 0000000..571c2c9 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/OnAnimatorListener.java @@ -0,0 +1,8 @@ +package xyz.fycz.myreader.widget.explosion_field; + +import android.animation.Animator; +import android.view.View; + +public interface OnAnimatorListener { + void onAnimationEnd(Animator animator, View view); +} diff --git a/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/Utils.java b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/Utils.java new file mode 100644 index 0000000..f41bbb6 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/widget/explosion_field/Utils.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 tyrantgit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.fycz.myreader.widget.explosion_field; + + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; + +public class Utils { + + private Utils() { + } + + private static final float DENSITY = Resources.getSystem().getDisplayMetrics().density; + private static final Canvas sCanvas = new Canvas(); + + public static int dp2Px(int dp) { + return Math.round(dp * DENSITY); + } + + public static Bitmap createBitmapFromView(View view) { + if (view instanceof ImageView) { + Drawable drawable = ((ImageView) view).getDrawable(); + if (drawable != null && drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + } + view.clearFocus(); + Bitmap bitmap = createBitmapSafely(view.getWidth(), + view.getHeight(), Bitmap.Config.ARGB_8888, 1); + if (bitmap != null) { + synchronized (sCanvas) { + Canvas canvas = sCanvas; + canvas.setBitmap(bitmap); + view.draw(canvas); + canvas.setBitmap(null); + } + } + return bitmap; + } + + public static Bitmap createBitmapSafely(int width, int height, Bitmap.Config config, int retryCount) { + try { + return Bitmap.createBitmap(width, height, config); + } catch (OutOfMemoryError e) { + e.printStackTrace(); + if (retryCount > 0) { + System.gc(); + return createBitmapSafely(width, height, config, retryCount - 1); + } + return null; + } + } +} From cdcc11b08363c825db896064797225aa0f162d5b Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Mon, 17 Jan 2022 16:43:46 +0800 Subject: [PATCH 4/6] v2.3.2 --- app/release.md | 7 ++++--- app/src/main/assets/updatelog.fy | 8 +++++--- .../xyz/fycz/myreader/ui/presenter/BookcasePresenter.java | 3 +++ app/version_code.properties | 4 ++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/app/release.md b/app/release.md index e0f4764..d568252 100644 --- a/app/release.md +++ b/app/release.md @@ -1,3 +1,4 @@ -* 1、开放用户登录\注册入口及同步书架(在v1.9.3版本关闭),感谢[@黑白人生]提供的服务器 -* 2、新增邮箱验证(用于找回密码),之前注册的帐号登录时需要绑定邮箱 -* 3、webdav同步书架改为从webdav恢复 \ No newline at end of file +* 1、修复部分机型阅读界面切换日夜间闪退的问题 +* 2、优化搜索界面 +* 3、搜索界面新增书架书籍搜索 +* 4、修复朗读到章节最后一页停止的问题 \ No newline at end of file diff --git a/app/src/main/assets/updatelog.fy b/app/src/main/assets/updatelog.fy index 31ff725..921f22f 100644 --- a/app/src/main/assets/updatelog.fy +++ b/app/src/main/assets/updatelog.fy @@ -1,8 +1,10 @@ -2022.01.07 +2022.01.17 风月读书v2.3.2 更新内容: -1、修复MIUI13阅读界面切换日夜间闪退的问题 -2、 +1、修复部分机型阅读界面切换日夜间闪退的问题 +2、优化搜索界面 +3、搜索界面新增书架书籍搜索 +4、修复朗读到章节最后一页停止的问题 2021.12.11 风月读书v2.2.8 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 70d6079..1a7c4ed 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 @@ -999,12 +999,15 @@ public class BookcasePresenter implements BasePresenter { if (!isAutoSyn) { DialogCreator.createTipDialog(mMainActivity, "成功将书架同步至网络!"); } + } else if (result.getCode() == 216) { + ToastUtils.showWarring("当前应用版本过旧,同步书架失败,请更新应用后重试"); } else { if (!isAutoSyn) { DialogCreator.createTipDialog(mMainActivity, "同步失败,请重试!"); } } } + @Override public void onError(Throwable e) { if (!isAutoSyn) { diff --git a/app/version_code.properties b/app/version_code.properties index e314e56..a628e66 100644 --- a/app/version_code.properties +++ b/app/version_code.properties @@ -1,3 +1,3 @@ #Fri Jun 18 21:45:31 CST 2021 -VERSION_CODE=231 -NEED_CREATE_RELEASE=false +VERSION_CODE=232 +NEED_CREATE_RELEASE=true From 23f8336d8e5cc430f3807e2e3f6e527ea52a2a11 Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Mon, 17 Jan 2022 17:50:18 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E6=96=B0=E5=A2=9EQQ=E9=A2=91=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 2 +- README.md | 4 +- app/release.md | 3 +- app/src/main/assets/updatelog.fy | 1 + .../myreader/ui/activity/AboutActivity.java | 6 +++ .../myreader/ui/fragment/MineFragment.java | 6 ++- .../main/res/layout/layout_about_content.xml | 37 ++++++++++++++++--- app/src/main/res/values/strings.xml | 3 +- 8 files changed, 49 insertions(+), 13 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 74eac7a..a92f8ed 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -41,7 +41,7 @@ - + diff --git a/README.md b/README.md index 3ca9dd4..1e7f73b 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ * 官网:[https://reader.fycz.tk](https://reader.fycz.tk) -* 反馈交流群: +* 反馈交流: * QQ群:[1085028304](https://jq.qq.com/?_wv=1027&k=6pcq8YBk) - * Telegram:[https://t.me/FYReader](https://t.me/FYReader) + * QQ频道:[点击加入](https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=2aP6ZQ&from=246610&biz=ka) * [更新日志](./app/src/main/assets/updatelog.fy) * [免责声明](./app/src/main/assets/disclaimer.fy) diff --git a/app/release.md b/app/release.md index d568252..e2efcf4 100644 --- a/app/release.md +++ b/app/release.md @@ -1,4 +1,5 @@ * 1、修复部分机型阅读界面切换日夜间闪退的问题 * 2、优化搜索界面 * 3、搜索界面新增书架书籍搜索 -* 4、修复朗读到章节最后一页停止的问题 \ No newline at end of file +* 4、修复朗读到章节最后一页停止的问题 +* 5、新增QQ频道,建议反馈请到QQ频道进行 \ No newline at end of file diff --git a/app/src/main/assets/updatelog.fy b/app/src/main/assets/updatelog.fy index 921f22f..33539ec 100644 --- a/app/src/main/assets/updatelog.fy +++ b/app/src/main/assets/updatelog.fy @@ -5,6 +5,7 @@ 2、优化搜索界面 3、搜索界面新增书架书籍搜索 4、修复朗读到章节最后一页停止的问题 +5、新增QQ频道,建议反馈请到QQ频道进行 2021.12.11 风月读书v2.2.8 diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java index 60c44fe..7cc3fc7 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java @@ -96,6 +96,12 @@ public class AboutActivity extends BaseActivity { mClipboardManager.setPrimaryClip(mClipData); ToastUtils.showSuccess("邮箱\"fengyuecanzhu@gmail.com\"已复制到剪切板"); }); + binding.il.rlJoinQqChannel.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=2aP6ZQ&from=246610&biz=ka")); + startActivity(intent); + }); + binding.il.rlShareLog.setOnClickListener(v -> DialogCreator.createCommonDialog(this, "分享崩溃日志", "你是希望将日志上传到服务器,还是直接分享给他人?", true, "上传服务器", "直接分享", (dialog, which) -> uploadCrashLog(), (dialog, which) -> shareCrashLog())); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java b/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java index ca4e67a..8989968 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java @@ -4,6 +4,7 @@ import static android.app.Activity.RESULT_OK; import android.annotation.SuppressLint; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -389,8 +390,9 @@ public class MineFragment extends BaseFragment { }); binding.mineRlFeedback.setOnClickListener(v -> { - Intent intent = new Intent(getContext(), FeedbackActivity.class); - getActivity().startActivity(intent); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=2aP6ZQ&from=246610&biz=ka")); + startActivity(intent); }); binding.mineRlDonate.setOnClickListener(v -> startActivity(new Intent(getActivity(), DonateActivity.class))); diff --git a/app/src/main/res/layout/layout_about_content.xml b/app/src/main/res/layout/layout_about_content.xml index f33a1f2..bdaa5ed 100644 --- a/app/src/main/res/layout/layout_about_content.xml +++ b/app/src/main/res/layout/layout_about_content.xml @@ -15,8 +15,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorForeground" - android:orientation="vertical" - > + android:orientation="vertical"> + + + + + + + + + - - https://github.com/fengyuecanzhu/FYReader 检查更新 致谢名单 + 加入QQ频道 @@ -150,7 +151,7 @@ 搜索 主题模式 加入QQ群 - 建议反馈 + 建议反馈(QQ频道) 分组切换 分组管理 设置分组 From 96f6323d54f90314e4b7994a2b9fc7876ac8cb11 Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Tue, 18 Jan 2022 09:04:58 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E6=96=B0=E5=A2=9EQQ=E9=A2=91=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 1 + .../myreader/model/sourceAnalyzer/BookSourceManager.java | 4 ++++ .../fycz/myreader/ui/activity/SourceEditActivity.java | 9 +++++++++ app/src/main/res/layout/activity_search_book.xml | 2 +- app/src/main/res/menu/menu_source_edit.xml | 5 +++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index a92f8ed..6f853a3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -52,6 +52,7 @@ + diff --git a/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java b/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java index 2985c0c..606ecc6 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java +++ b/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java @@ -189,6 +189,10 @@ public class BookSourceManager { DbManager.getDaoSession().getBookSourceDao().deleteInTx(sources); } + public static boolean isBookSourceExist(BookSource source){ + if (source == null) return false; + return DbManager.getDaoSession().getBookSourceDao().load(source.getSourceUrl()) != null; + } public static String getBookSourceSort() { switch (SharedPreUtils.getInstance().getInt("SourceSort", 0)) { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceEditActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceEditActivity.java index 7dcd369..41efdee 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceEditActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceEditActivity.java @@ -182,6 +182,15 @@ public class SourceEditActivity extends BaseActivity { } else if (item.getItemId() == R.id.action_clear_cookie) { DbManager.getDaoSession().getCookieBeanDao().deleteByKey(getSource().getSourceUrl()); ToastUtils.showSuccess("Cookie清除成功"); + } else if (item.getItemId() == R.id.action_delete) { + if (BookSourceManager.isBookSourceExist(source)) { + BookSourceManager.removeBookSource(source); + setResult(Activity.RESULT_OK); + ToastUtils.showSuccess("书源删除成功"); + finish(); + } else { + ToastUtils.showWarring("当前书源暂未保存,无法删除"); + } } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/res/layout/activity_search_book.xml b/app/src/main/res/layout/activity_search_book.xml index 56bf83e..d9f2477 100644 --- a/app/src/main/res/layout/activity_search_book.xml +++ b/app/src/main/res/layout/activity_search_book.xml @@ -151,7 +151,7 @@ android:layout_height="wrap_content" android:orientation="vertical" android:paddingHorizontal="5dp" - android:visibility="visible"> + android:visibility="gone"> + + \ No newline at end of file