@ -1,204 +1,26 @@ |
|||||||
# FYReader-master |
# FYReader-master |
||||||
风月读书,一款开源、无广告的小说阅读软件。 |
风月读书,一款开源、无广告的小说阅读软件。 |
||||||
|
|
||||||
demo下载:https://fycz.lanzoui.com/iaVu6i6ywlg |
11个网络小说书源:天籁小说、笔趣阁44、品书网、笔趣阁、 |
||||||
|
|
||||||
#### 一、关于书源 |
|
||||||
|
|
||||||
* 软件内置了15个书源如下: |
|
||||||
* 11个网络小说书源:天籁小说、笔趣阁44、品书网、笔趣阁、 |
|
||||||
全本小说、米趣小说、九桃小说、云中书库、 |
全本小说、米趣小说、九桃小说、云中书库、 |
||||||
搜小说网、全小说网、奇奇小说 |
搜小说网、全小说网、奇奇小说 |
||||||
* 4个实体书书源:超星图书·实体、作品集·实体、99藏书·实体、100本·实体 |
4个实体书书源:超星图书·实体、作品集·实体、99藏书·实体、100本·实体 |
||||||
|
|
||||||
* 如何自行制作并添加书源. |
|
||||||
|
|
||||||
* 基于面向接口开发的思想,对于书源我设计了如下接口: |
|
||||||
|
|
||||||
* ```java |
|
||||||
// 这个接口位于xyz.fycz.myreader.webapi.crawler.base包下 |
|
||||||
public interface ReadCrawler { |
|
||||||
String getSearchLink(); // 书源的搜索url |
|
||||||
String getCharset(); // 书源的字符编码 |
|
||||||
String getSearchCharset(); // 书源搜索关键字的字符编码,和书源的字符编码就行 |
|
||||||
String getNameSpace(); // 书源主页地址 |
|
||||||
Boolean isPost(); // 是否以post请求搜索 |
|
||||||
String getContentFormHtml(String html); // 获取书籍内容规则 |
|
||||||
ArrayList<Chapter> getChaptersFromHtml(String html); // 获取书籍章节列表规则 |
|
||||||
ConcurrentMultiValueMap<SearchBookBean, Book> getBooksFromSearchHtml(String html); // 搜索书籍规则 |
|
||||||
} |
|
||||||
``` |
|
||||||
|
|
||||||
* 了解上述接口的方法,我们就可以开始创建书源了 |
|
||||||
|
|
||||||
* 第一步:创建一个书源类实现上述接口,下面以笔趣阁44为例进行说明 |
|
||||||
|
|
||||||
* ```java |
|
||||||
// 注意:如果搜索书籍页没有图片、最新章节、书籍简介等信息,可以通过实现BookInfoCrawler接口,从书籍详情页获取 |
|
||||||
public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { |
|
||||||
//网站主页地址 |
|
||||||
public static final String NAME_SPACE = "https://www.wqge.cc"; |
|
||||||
/* |
|
||||||
搜索url,搜索关键词以{key}进行占位 |
|
||||||
如果是post请求,以“,”分隔url,“,”前是搜索地址,“,”后是请求体,搜索关键词同样以{key}占位 |
|
||||||
例如:"https://www.9txs.com/search.html,searchkey={key}" |
|
||||||
*/ |
|
||||||
public static final String NOVEL_SEARCH = "https://www.wqge.cc/modules/article/search.php?searchkey={key}"; |
|
||||||
// 书源字符编码 |
|
||||||
public static final String CHARSET = "GBK"; |
|
||||||
// 书源搜索关键词编码 |
|
||||||
public static final String SEARCH_CHARSET = "utf-8"; |
|
||||||
@Override |
|
||||||
public String getSearchLink() { |
|
||||||
return NOVEL_SEARCH; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getCharset() { |
|
||||||
return CHARSET; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getNameSpace() { |
|
||||||
return NAME_SPACE; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public Boolean isPost() { |
|
||||||
return false; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public String getSearchCharset() { |
|
||||||
return SEARCH_CHARSET; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 从html中获取章节正文 |
|
||||||
* @param html |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
public String getContentFormHtml(String html) { |
|
||||||
Document doc = Jsoup.parse(html); |
|
||||||
Element divContent = doc.getElementById("content"); |
|
||||||
if (divContent != null) { |
|
||||||
String content = Html.fromHtml(divContent.html()).toString(); |
|
||||||
char c = 160; |
|
||||||
String spaec = "" + c; |
|
||||||
content = content.replace(spaec, " "); |
|
||||||
return content; |
|
||||||
} else { |
|
||||||
return ""; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 从html中获取章节列表 |
|
||||||
* |
|
||||||
* @param html |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
public ArrayList<Chapter> getChaptersFromHtml(String html) { |
|
||||||
ArrayList<Chapter> chapters = new ArrayList<>(); |
|
||||||
Document doc = Jsoup.parse(html); |
|
||||||
String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); |
|
||||||
Element divList = doc.getElementById("list"); |
|
||||||
String lastTile = null; |
|
||||||
int i = 0; |
|
||||||
Elements elementsByTag = divList.getElementsByTag("dd"); |
|
||||||
for (int j = 9; j < elementsByTag.size(); j++) { |
|
||||||
Element dd = elementsByTag.get(j); |
|
||||||
Elements as = dd.getElementsByTag("a"); |
|
||||||
if (as.size() > 0) { |
|
||||||
Element a = as.get(0); |
|
||||||
String title = a.text() ; |
|
||||||
if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
Chapter chapter = new Chapter(); |
|
||||||
chapter.setNumber(i++); |
|
||||||
chapter.setTitle(title); |
|
||||||
String url = readUrl + a.attr("href"); |
|
||||||
chapter.setUrl(url); |
|
||||||
chapters.add(chapter); |
|
||||||
lastTile = title; |
|
||||||
} |
|
||||||
} |
|
||||||
return chapters; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 从搜索html中得到书列表 |
|
||||||
* @param html |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
public ConcurrentMultiValueMap<SearchBookBean, Book> getBooksFromSearchHtml(String html) { |
|
||||||
ConcurrentMultiValueMap<SearchBookBean, Book> books = new ConcurrentMultiValueMap<>(); |
|
||||||
Document doc = Jsoup.parse(html); |
|
||||||
Elements divs = doc.getElementsByTag("table"); |
|
||||||
Element div = divs.get(0); |
|
||||||
Elements elementsByTag = div.getElementsByTag("tr"); |
|
||||||
for (int i = 1; i < elementsByTag.size(); i++) { |
|
||||||
Element element = elementsByTag.get(i); |
|
||||||
Book book = new Book(); |
|
||||||
Elements info = element.getElementsByTag("td"); |
|
||||||
book.setName(info.get(0).text()); |
|
||||||
book.setChapterUrl(NAME_SPACE + info.get(0).getElementsByTag("a").attr("href")); |
|
||||||
book.setAuthor(info.get(2).text()); |
|
||||||
book.setNewestChapterTitle(info.get(1).text()); |
|
||||||
book.setSource(BookSource.biquge44.toString()); |
|
||||||
// SearchBookBean用于合并相同书籍 |
|
||||||
SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); |
|
||||||
books.add(sbb, book); |
|
||||||
} |
|
||||||
return books; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取书籍详细信息 |
|
||||||
* @param book |
|
||||||
*/ |
|
||||||
public Book getBookInfo(String html, Book book){ |
|
||||||
Document doc = Jsoup.parse(html); |
|
||||||
Element img = doc.getElementById("fmimg"); |
|
||||||
book.setImgUrl(img.getElementsByTag("img").get(0).attr("src")); |
|
||||||
Element desc = doc.getElementById("intro"); |
|
||||||
book.setDesc(desc.getElementsByTag("p").get(0).text()); |
|
||||||
Element type = doc.getElementsByClass("con_top").get(0); |
|
||||||
book.setType(type.getElementsByTag("a").get(2).text()); |
|
||||||
return book; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
``` |
|
||||||
|
|
||||||
* 第二步:注册书源信息。有两个地方需要注册: |
|
||||||
|
|
||||||
* 1)在xyz.fycz.myreader.enums.BookSource类(这是个枚举类型)中添加你的书源的命名以及书源名称,例如: |
|
||||||
|
|
||||||
* ```java |
|
||||||
biquge44("笔趣阁44") // biquge44是书源的命名,笔趣阁44是书源名称 |
|
||||||
``` |
|
||||||
|
|
||||||
* 2)在app/src/main/resources/crawler.properties配置文件中添加书源类信息,例如: |
|
||||||
|
|
||||||
* ```java |
发现界面:排行榜、分类、书城 |
||||||
// biquge44书源的命名,与BookSource中的命名一致,xyz.fycz.myreader.webapi.crawler.read.BiQuGe44ReadCrawler是书源类的完整路径 |
|
||||||
biquge44=xyz.fycz.myreader.webapi.crawler.read.BiQuGe44ReadCrawler |
|
||||||
``` |
|
||||||
|
|
||||||
* 第三步:启用书源(新增的书源默认禁用)。只需在软件内-我的-设置-禁用书源中取消该书源的禁用即可。 |
详细功能可查看图片或下载自行体验或自行编译 |
||||||
|
|
||||||
#### 二、关于发现界面 |
demo下载:https://fycz.lanzoui.com/iBofFh42pxg |
||||||
|
|
||||||
* 软件内置的两个发现源: |
如有问题请加QQ群:1085028304 |
||||||
* 某点的排行榜、分类,全本小说网 |
|
||||||
* 制作发现源方法与书源类似,在此不再赘述 |
|
||||||
|
|
||||||
![Image](./img/1.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/1.png) |
||||||
![Image](./img/2.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/2.png) |
||||||
![Image](./img/3.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/3.png) |
||||||
![Image](./img/4.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/4.png) |
||||||
![Image](./img/5.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/5.png) |
||||||
![Image](./img/6.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/6.png) |
||||||
![Image](./img/7.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/7.png) |
||||||
![Image](./img/8.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/8.png) |
||||||
![Image](./img/9.png) |
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/9.png) |
||||||
|
![Image](https://github.com/fengyuecanzhu/FYReader/tree/master/img/10.png) |
@ -1,30 +0,0 @@ |
|||||||
package xyz.fycz.myreader.util; |
|
||||||
|
|
||||||
import android.content.Context; |
|
||||||
import android.provider.Settings; |
|
||||||
import android.util.DisplayMetrics; |
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity; |
|
||||||
|
|
||||||
/** |
|
||||||
*/ |
|
||||||
|
|
||||||
public class ScreenHelper { |
|
||||||
|
|
||||||
public static double getScreenPhysicalSize(AppCompatActivity ctx) { |
|
||||||
DisplayMetrics dm = new DisplayMetrics(); |
|
||||||
ctx.getWindowManager().getDefaultDisplay().getMetrics(dm); |
|
||||||
double diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2)); |
|
||||||
return diagonalPixels / (160 * dm.density); |
|
||||||
} |
|
||||||
public static int getScreenOffTime(Context context) { |
|
||||||
int screenOffTime = 0; |
|
||||||
try { |
|
||||||
screenOffTime = Settings.System.getInt(context.getContentResolver(), |
|
||||||
Settings.System.SCREEN_OFF_TIMEOUT); |
|
||||||
} catch (Exception e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
return screenOffTime; |
|
||||||
} |
|
||||||
} |
|
@ -1,59 +1,99 @@ |
|||||||
package xyz.fycz.myreader.widget.page; |
package xyz.fycz.myreader.widget.page; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
/** |
/** |
||||||
* Created by newbiechen on 17-7-1. |
* Created by zhouas666 on 18-1-23. |
||||||
|
* 书籍chapter |
||||||
*/ |
*/ |
||||||
|
|
||||||
public class TxtChapter { |
public class TxtChapter{ |
||||||
|
|
||||||
//章节所属的小说(网络)
|
private int position; |
||||||
String bookId; |
private List<TxtPage> txtPageList = new ArrayList<>(); |
||||||
//章节名
|
private List<Integer> txtPageLengthList = new ArrayList<>(); |
||||||
String title; |
private List<Integer> paragraphLengthList = new ArrayList<>(); |
||||||
|
private Status status = Status.LOADING; |
||||||
|
private String msg; |
||||||
|
|
||||||
//章节内容在文章中的起始位置(本地)
|
TxtChapter(int position) { |
||||||
long start; |
this.position = position; |
||||||
//章节内容在文章中的终止位置(本地)
|
} |
||||||
long end; |
|
||||||
|
|
||||||
public String getBookId() { |
public int getPosition() { |
||||||
return bookId; |
return position; |
||||||
} |
} |
||||||
|
|
||||||
public void setBookId(String id) { |
List<TxtPage> getTxtPageList() { |
||||||
this.bookId = id; |
return txtPageList; |
||||||
} |
} |
||||||
|
|
||||||
public String getTitle() { |
void addPage(TxtPage txtPage) { |
||||||
return title; |
txtPageList.add(txtPage); |
||||||
} |
} |
||||||
|
|
||||||
public void setTitle(String title) { |
int getPageSize() { |
||||||
this.title = title; |
return txtPageList.size(); |
||||||
} |
} |
||||||
|
|
||||||
public long getStart() { |
TxtPage getPage(int page) { |
||||||
return start; |
if (!txtPageList.isEmpty()) { |
||||||
|
return txtPageList.get(Math.max(0, Math.min(page, txtPageList.size() - 1))); |
||||||
|
} |
||||||
|
return null; |
||||||
} |
} |
||||||
|
|
||||||
public void setStart(long start) { |
Status getStatus() { |
||||||
this.start = start; |
return status; |
||||||
} |
} |
||||||
|
|
||||||
public long getEnd() { |
void setStatus(Status mStatus) { |
||||||
return end; |
this.status = mStatus; |
||||||
} |
} |
||||||
|
|
||||||
public void setEnd(long end) { |
public String getMsg() { |
||||||
this.end = end; |
return msg; |
||||||
} |
} |
||||||
|
|
||||||
@Override |
public void setMsg(String msg) { |
||||||
public String toString() { |
this.msg = msg; |
||||||
return "TxtChapter{" + |
|
||||||
"title='" + title + '\'' + |
|
||||||
", start=" + start + |
|
||||||
", end=" + end + |
|
||||||
'}'; |
|
||||||
} |
} |
||||||
|
|
||||||
|
int getPageLength(int position) { |
||||||
|
if (txtPageLengthList != null && position >= 0 && position < txtPageLengthList.size()) { |
||||||
|
return txtPageLengthList.get(position); |
||||||
|
} |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
void addTxtPageLength(int length) { |
||||||
|
txtPageLengthList.add(length); |
||||||
|
} |
||||||
|
|
||||||
|
List<Integer> getTxtPageLengthList() { |
||||||
|
return txtPageLengthList; |
||||||
|
} |
||||||
|
|
||||||
|
List<Integer> getParagraphLengthList() { |
||||||
|
return paragraphLengthList; |
||||||
|
} |
||||||
|
|
||||||
|
void addParagraphLength(int length) { |
||||||
|
paragraphLengthList.add(length); |
||||||
|
} |
||||||
|
|
||||||
|
int getParagraphIndex(int length) { |
||||||
|
for (int i = 0; i < paragraphLengthList.size(); i++) { |
||||||
|
if ((i == 0 || paragraphLengthList.get(i - 1) < length) && length <= paragraphLengthList.get(i)) { |
||||||
|
return i; |
||||||
|
} |
||||||
|
} |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
public enum Status { |
||||||
|
LOADING, FINISH, ERROR, EMPTY, CATEGORY_EMPTY, CHANGE_SOURCE, |
||||||
|
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,199 +1,239 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
xmlns:tools="http://schemas.android.com/tools" |
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
android:layout_width="match_parent" |
xmlns:tools="http://schemas.android.com/tools" |
||||||
android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> |
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent"> |
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout |
<com.google.android.material.appbar.AppBarLayout |
||||||
android:id="@+id/read_abl_top_menu" |
android:id="@+id/read_abl_top_menu" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:background="@color/read_menu_bg" |
||||||
|
android:visibility="gone" |
||||||
|
tools:visibility="visible"> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:background="@color/read_menu_bg" |
android:orientation="vertical"> |
||||||
android:visibility="gone" |
|
||||||
tools:visibility="visible"> |
|
||||||
|
|
||||||
<LinearLayout |
<androidx.appcompat.widget.Toolbar |
||||||
|
android:id="@+id/toolbar" |
||||||
|
style="@style/NoPaddingToolbar" |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="wrap_content" |
android:layout_height="45dp" |
||||||
android:orientation="vertical"> |
android:gravity="center_vertical" |
||||||
|
android:minHeight="?attr/actionBarSize" |
||||||
|
android:theme="?attr/actionBarStyle" |
||||||
|
android:transitionName="sharedView" |
||||||
|
app:layout_scrollFlags="scroll|enterAlways" |
||||||
|
app:popupTheme="@style/AppTheme.PopupOverlay" |
||||||
|
app:title="大主宰" /> |
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar |
|
||||||
android:id="@+id/toolbar" |
|
||||||
style="@style/NoPaddingToolbar" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="45dp" |
|
||||||
android:minHeight="?attr/actionBarSize" |
|
||||||
android:gravity="center_vertical" |
|
||||||
android:theme="?attr/actionBarStyle" |
|
||||||
android:transitionName="sharedView" |
|
||||||
app:title="大主宰" |
|
||||||
app:layout_scrollFlags="scroll|enterAlways" |
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay"> |
|
||||||
</androidx.appcompat.widget.Toolbar> |
|
||||||
<View |
<View |
||||||
android:layout_width="fill_parent" |
android:layout_width="fill_parent" |
||||||
android:layout_height="0.5dp" |
android:layout_height="0.5dp" |
||||||
android:background="@color/sys_dialog_setting_line" /> |
android:background="@color/sys_dialog_setting_line" /> |
||||||
|
|
||||||
<LinearLayout |
<LinearLayout |
||||||
android:id="@+id/ll_chapter_view" |
android:id="@+id/ll_chapter_view" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="40dp" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/tv_chapter_title_top" |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="40dp" |
android:layout_height="wrap_content" |
||||||
android:orientation="vertical"> |
android:layout_marginStart="14dp" |
||||||
<TextView android:id="@+id/tv_chapter_title_top" |
android:layout_marginEnd="14dp" |
||||||
android:layout_width="match_parent" |
android:ellipsize="end" |
||||||
android:layout_height="wrap_content" |
android:maxLines="1" |
||||||
android:layout_marginStart="14dp" |
android:text="章节名称" |
||||||
android:layout_marginEnd="14dp" |
android:textColor="@color/read_menu_text" |
||||||
android:textSize="15sp" |
android:textSize="15sp" /> |
||||||
android:text="章节名称" |
|
||||||
android:ellipsize="end" |
<TextView |
||||||
android:maxLines="1" |
android:id="@+id/tv_chapter_url" |
||||||
android:textColor="@color/read_menu_text"> |
android:layout_width="match_parent" |
||||||
</TextView> |
android:layout_height="wrap_content" |
||||||
<TextView android:id="@+id/tv_chapter_url" |
android:layout_marginStart="14dp" |
||||||
android:layout_width="match_parent" |
android:layout_marginEnd="14dp" |
||||||
android:layout_height="wrap_content" |
android:ellipsize="end" |
||||||
android:layout_marginStart="14dp" |
android:maxLines="1" |
||||||
android:layout_marginEnd="14dp" |
android:text="章节链接" |
||||||
android:ellipsize="end" |
android:textColor="@color/read_menu_text" |
||||||
android:textSize="13sp" |
android:textSize="13sp" /> |
||||||
android:text="章节链接" |
|
||||||
android:maxLines="1" |
|
||||||
android:textColor="@color/read_menu_text"> |
|
||||||
</TextView> |
|
||||||
</LinearLayout> |
</LinearLayout> |
||||||
</LinearLayout> |
</LinearLayout> |
||||||
</com.google.android.material.appbar.AppBarLayout> |
</com.google.android.material.appbar.AppBarLayout> |
||||||
|
|
||||||
<!--阅读页面--> |
<!--阅读页面--> |
||||||
<xyz.fycz.myreader.widget.page.PageView |
<xyz.fycz.myreader.widget.page.PageView |
||||||
android:id="@+id/read_pv_content" |
android:id="@+id/read_pv_content" |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="match_parent" |
android:layout_height="match_parent" |
||||||
android:clickable="true" |
android:clickable="true" |
||||||
tools:visibility="gone"/> |
tools:visibility="gone" /> |
||||||
|
|
||||||
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper |
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_marginTop="20dp" |
||||||
|
android:layout_marginBottom="20dp"> |
||||||
|
|
||||||
|
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBar |
||||||
|
android:id="@+id/pb_nextPage" |
||||||
android:layout_width="wrap_content" |
android:layout_width="wrap_content" |
||||||
android:layout_height="match_parent" |
android:layout_height="match_parent" |
||||||
android:layout_marginTop="20dp" |
android:splitTrack="false" |
||||||
android:layout_marginBottom="20dp"> |
android:visibility="invisible" |
||||||
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBar |
app:seekBarRotation="CW270" |
||||||
android:id="@+id/pb_nextPage" |
tools:visibility="visible" /> |
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="match_parent" |
|
||||||
android:splitTrack="false" |
|
||||||
app:seekBarRotation="CW270" |
|
||||||
android:visibility="invisible" |
|
||||||
tools:visibility="visible"/> |
|
||||||
</com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper> |
</com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper> |
||||||
|
|
||||||
<ProgressBar |
<ProgressBar |
||||||
android:id="@+id/pb_loading" |
android:id="@+id/pb_loading" |
||||||
android:layout_width="wrap_content" |
android:layout_width="wrap_content" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:layout_centerInParent="true" |
android:layout_centerInParent="true" |
||||||
android:visibility="gone" |
android:visibility="gone" |
||||||
tools:visibility="visible"/> |
tools:visibility="visible" /> |
||||||
|
|
||||||
|
|
||||||
<!--切换页面提示--> |
|
||||||
<TextView |
|
||||||
android:id="@+id/read_tv_page_tip" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_above="@+id/read_ll_bottom_menu" |
|
||||||
android:layout_centerHorizontal="true" |
|
||||||
android:layout_marginBottom="10dp" |
|
||||||
android:background="@color/read_menu_bg" |
|
||||||
android:gravity="center" |
|
||||||
android:paddingLeft="12dp" |
|
||||||
android:paddingTop="8dp" |
|
||||||
android:paddingRight="12dp" |
|
||||||
android:paddingBottom="8dp" |
|
||||||
android:text="1/12" |
|
||||||
android:textColor="@color/md_white_1000" |
|
||||||
android:visibility="gone"/> |
|
||||||
|
|
||||||
<!--底部页面--> |
<!--底部页面--> |
||||||
<LinearLayout |
<LinearLayout |
||||||
android:id="@+id/read_ll_bottom_menu" |
android:id="@+id/read_ll_bottom_menu" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_alignParentBottom="true" |
||||||
|
android:clickable="true" |
||||||
|
android:orientation="vertical" |
||||||
|
android:visibility="gone" |
||||||
|
tools:visibility="visible"> |
||||||
|
<RelativeLayout |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content"> |
||||||
android:layout_alignParentBottom="true" |
<!--切换页面提示--> |
||||||
android:background="@color/read_menu_bg" |
<TextView |
||||||
android:clickable="true" |
android:id="@+id/read_tv_page_tip" |
||||||
android:orientation="vertical" |
android:layout_width="wrap_content" |
||||||
android:visibility="gone" |
android:layout_height="wrap_content" |
||||||
tools:visibility="visible"> |
android:layout_centerHorizontal="true" |
||||||
|
android:layout_marginBottom="10dp" |
||||||
|
android:background="@color/read_menu_bg" |
||||||
|
android:gravity="center" |
||||||
|
android:layout_marginTop="4dp" |
||||||
|
android:paddingLeft="12dp" |
||||||
|
android:paddingTop="8dp" |
||||||
|
android:paddingRight="12dp" |
||||||
|
android:paddingBottom="8dp" |
||||||
|
android:text="1/12" |
||||||
|
android:textColor="@color/md_white_1000" /> |
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton |
||||||
|
android:id="@+id/iv_listen_book" |
||||||
|
app:backgroundTint="@color/read_menu_bg" |
||||||
|
android:layout_marginEnd="15dp" |
||||||
|
android:layout_marginBottom="12dp" |
||||||
|
android:layout_width="40dp" |
||||||
|
android:layout_height="40dp" |
||||||
|
android:layout_alignParentEnd="true" |
||||||
|
android:tint="@color/read_menu_text" |
||||||
|
android:src="@drawable/ic_listen_book" |
||||||
|
app:elevation="2dp" |
||||||
|
app:fabCustomSize="40dp" |
||||||
|
app:pressedTranslationZ="2dp" |
||||||
|
/> |
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
<!--页面进度栏--> |
<!--页面进度栏--> |
||||||
<LinearLayout |
<LinearLayout |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="60dp" |
android:layout_height="60dp" |
||||||
android:gravity="center_vertical" |
android:background="@color/read_menu_bg" |
||||||
android:orientation="horizontal"> |
android:gravity="center_vertical" |
||||||
|
android:orientation="horizontal"> |
||||||
|
|
||||||
<TextView |
<TextView |
||||||
android:id="@+id/read_tv_pre_chapter" |
android:id="@+id/read_tv_pre_chapter" |
||||||
style="@style/MAppTheme.TextAppearance.Read.BottomMenu" |
style="@style/MAppTheme.TextAppearance.Read.BottomMenu" |
||||||
android:layout_width="80dp" |
android:layout_width="80dp" |
||||||
android:layout_height="match_parent" |
android:layout_height="match_parent" |
||||||
android:gravity="center" |
android:gravity="center" |
||||||
android:text="上一章"/> |
android:clickable="true" |
||||||
|
android:focusable="true" |
||||||
|
android:text="上一章" /> |
||||||
|
|
||||||
<SeekBar |
<SeekBar |
||||||
android:id="@+id/read_sb_chapter_progress" |
android:id="@+id/read_sb_chapter_progress" |
||||||
android:layout_width="0dp" |
android:layout_width="0dp" |
||||||
android:layout_height="wrap_content" |
android:layout_height="wrap_content" |
||||||
android:layout_weight="1" |
android:layout_weight="1" |
||||||
android:max="100" |
android:max="100" |
||||||
android:maxHeight="3dp" |
android:maxHeight="3dp" |
||||||
android:minHeight="3dp" |
android:minHeight="3dp" |
||||||
android:progressDrawable="@drawable/seekbar_bg" |
android:progressDrawable="@drawable/seekbar_bg" |
||||||
android:thumb="@mipmap/thumb" |
android:thumb="@mipmap/thumb" |
||||||
android:thumbOffset="10dp"/> |
android:thumbOffset="10dp" /> |
||||||
|
|
||||||
<TextView |
<TextView |
||||||
android:id="@+id/read_tv_next_chapter" |
android:id="@+id/read_tv_next_chapter" |
||||||
style="@style/MAppTheme.TextAppearance.Read.BottomMenu" |
style="@style/MAppTheme.TextAppearance.Read.BottomMenu" |
||||||
android:layout_width="80dp" |
android:layout_width="80dp" |
||||||
android:layout_height="match_parent" |
android:layout_height="match_parent" |
||||||
android:gravity="center" |
android:gravity="center" |
||||||
android:text="下一章"/> |
android:clickable="true" |
||||||
|
android:focusable="true" |
||||||
|
android:text="下一章" /> |
||||||
</LinearLayout> |
</LinearLayout> |
||||||
|
|
||||||
<View |
<View |
||||||
android:layout_width="fill_parent" |
android:layout_width="fill_parent" |
||||||
android:layout_height="0.5dp" |
android:layout_height="0.5dp" |
||||||
android:background="@color/sys_dialog_setting_line" /> |
android:background="@color/sys_dialog_setting_line" /> |
||||||
<!--菜单栏--> |
<!--菜单栏--> |
||||||
<LinearLayout |
<LinearLayout |
||||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||||
android:layout_height="72dp" |
android:layout_height="72dp" |
||||||
android:orientation="horizontal" |
android:background="@color/read_menu_bg" |
||||||
android:paddingTop="12dp" |
android:orientation="horizontal" |
||||||
android:paddingBottom="12dp"> |
android:paddingTop="12dp" |
||||||
|
android:paddingBottom="12dp"> |
||||||
|
|
||||||
<TextView |
<TextView |
||||||
android:id="@+id/read_tv_category" |
android:id="@+id/read_tv_category" |
||||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||||
android:drawableTop="@mipmap/t3" |
android:text="目录" |
||||||
android:text="目录"/> |
android:clickable="true" |
||||||
|
android:focusable="true" |
||||||
|
app:drawableTopCompat="@mipmap/t3" /> |
||||||
|
|
||||||
<TextView |
<TextView |
||||||
android:id="@+id/read_tv_download" |
android:id="@+id/read_tv_download" |
||||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||||
android:drawableTop="@mipmap/download" |
android:text="下载" |
||||||
android:text="下载"/> |
android:clickable="true" |
||||||
|
android:focusable="true" |
||||||
|
app:drawableTopCompat="@mipmap/download" /> |
||||||
|
|
||||||
<TextView |
<TextView |
||||||
android:id="@+id/read_tv_night_mode" |
android:id="@+id/read_tv_night_mode" |
||||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||||
android:drawableTop="@mipmap/ao" |
android:text="夜间" |
||||||
android:text="夜间"/> |
android:clickable="true" |
||||||
|
android:focusable="true" |
||||||
|
app:drawableTopCompat="@mipmap/ao" /> |
||||||
|
|
||||||
<TextView |
<TextView |
||||||
android:id="@+id/read_tv_setting" |
android:id="@+id/read_tv_setting" |
||||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||||
android:drawableTop="@mipmap/t6" |
android:text="设置" |
||||||
android:text="设置"/> |
android:clickable="true" |
||||||
|
android:focusable="true" |
||||||
|
app:drawableTopCompat="@mipmap/t6" /> |
||||||
</LinearLayout> |
</LinearLayout> |
||||||
</LinearLayout> |
</LinearLayout> |
||||||
</RelativeLayout> |
</RelativeLayout> |
||||||
|
@ -1,6 +1,9 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<androidx.constraintlayout.widget.ConstraintLayout |
<androidx.appcompat.widget.AppCompatImageView |
||||||
xmlns:android="http://schemas.android.com/apk/res/android" |
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
android:layout_width="match_parent" |
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
android:layout_height="match_parent" |
android:id="@+id/iv_splash" |
||||||
android:background="@drawable/start"/> |
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:scaleType="fitXY" |
||||||
|
app:srcCompat="@drawable/start"/> |
@ -1,2 +1,2 @@ |
|||||||
#Mon Nov 09 21:09:26 CST 2020 |
#Wed Nov 11 20:37:05 CST 2020 |
||||||
VERSION_CODE=155 |
VERSION_CODE=154 |
||||||
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 122 KiB |