This commit is contained in:
mwang 2019-04-23 22:45:08 +08:00
parent 7e813c9c6c
commit 9f964f1e31
39 changed files with 1221 additions and 478 deletions

View File

@ -83,5 +83,5 @@ dependencies {
// implementation 'com.ms-square:expandableTextView:0.1.4'
// implementation 'com.github.tangguna:SearchBox:1.0.1'
implementation 'com.github.chengzipi:Searchbox:v1.0.0'
implementation 'com.github.ixiaow:multilayout:1.0.0'
}

View File

@ -2,7 +2,7 @@
<litepal>
<dbname value="book" ></dbname>
<version value="2" ></version>
<version value="3" ></version>
<list>
<mapping class="com.novelbook.android.db.Chapter"></mapping>

View File

@ -7,6 +7,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
@ -320,7 +321,7 @@ public class BookActivity extends Activity_base {
break;
case R.id.llCate:
Log.d(TAG, String .format("prepareBook: current book %s, start to open book cate of %s" , mNovel.getName() , pageFactory.getNovle().getName()));
// Log.d(TAG, String .format("prepareBook: current book %s, start to open book cate of %s" , mNovel.getName() , pageFactory.getNovle().getName()));
intent = new Intent(BookActivity.this, MarkActivity.class);
startActivity(intent);;
@ -684,7 +685,10 @@ void onResponseProcess( String content ,String url){
registerReceiver(receiver,filter);
if(mNovel!=null && mNovel.getId()>0) {
mNovel = LitePal.find(Novel.class, mNovel.getId()); //更新最新进度
if((pageFactory.getNovle()==null || mNovel.getId() !=pageFactory.getNovle().getId())){
if(pageFactory==null){
pageFactory = PageFactory.getInstance();
}
if(( pageFactory.getNovle()==null || mNovel.getId() !=pageFactory.getNovle().getId())){
pageFactory.prepareBook(mNovel);
}
}

View File

@ -8,6 +8,7 @@ import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import com.novelbook.android.MarkActivity;
import com.novelbook.android.R;
import com.novelbook.android.adapter.MarkAdapter;
import com.novelbook.android.db.BookMarks;
@ -23,7 +24,7 @@ import butterknife.BindView;
/**
* Created by Administrator on 2016/8/31 0031.
*/
public class BookMarkFragment extends BasicFragment {
public class BookMarkFragment extends BasicFragment implements MarkActivity.Sortmark{
public static final String ARGUMENT = "argument";
@BindView(R.id.lv_bookmark)
@ -42,14 +43,17 @@ public class BookMarkFragment extends BasicFragment {
@Override
protected void initData() {
pageFactory = PageFactory.getInstance();
Bundle bundle = getArguments();
if (bundle != null) {
novelId = bundle.getInt(ARGUMENT);
}
bookMarksList = new ArrayList<>();
bookMarksList = LitePal.where("novelId = ?", novelId+"").find(BookMarks.class);
bookMarksList = LitePal.where("novelId = ?", novelId+"").order(String.format("id %s",isAsc ?"asc" :"desc")). find(BookMarks.class);
Log.d(TAG, "initData: bookmark size " +bookMarksList.size());
markAdapter = new MarkAdapter(getActivity(), bookMarksList);
lv_bookmark.setAdapter(markAdapter);
}
@Override
protected void fillData() {
@ -66,6 +70,7 @@ public class BookMarkFragment extends BasicFragment {
@Override
protected void initListener() {
pageFactory = PageFactory.getInstance();
lv_bookmark.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@ -101,8 +106,8 @@ public class BookMarkFragment extends BasicFragment {
@Override
protected void initViews() {
markAdapter = new MarkAdapter(getActivity(), bookMarksList);
lv_bookmark.setAdapter(markAdapter);
((MarkActivity) getActivity()).setSortmark(this);
}
@Override
@ -124,4 +129,10 @@ public class BookMarkFragment extends BasicFragment {
return bookMarkFragment;
}
boolean isAsc = true;
@Override
public void sortList() {
isAsc =!isAsc;
initData();
}
}

View File

@ -2,13 +2,18 @@ package com.novelbook.android.Fragments;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import com.novelbook.android.MarkActivity;
import com.novelbook.android.R;
import com.novelbook.android.ReadActivity;
import com.novelbook.android.adapter.CatalogueAdapter;
@ -19,25 +24,36 @@ import com.novelbook.android.netutils.NetUtil;
import com.novelbook.android.utils.PageFactory;
import org.litepal.LitePal;
import java.io.File;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Created by Administrator on 2016/8/31 0031.
*/
public class CatalogFragment extends BasicFragment {
public class CatalogFragment extends BasicFragment implements MarkActivity.Sortcat {
public static final String TAG=CatalogFragment.class.getSimpleName();
public static final String ARGUMENT = "argument";
private PageFactory pageFactory;
ArrayList<Chapter> catalogueList = new ArrayList<>();
ArrayList<Integer> catalogCached = new ArrayList<>();
@BindView(R.id.lv_catalogue)
ListView lv_catalogue;
/* @BindView(R.id.tvTitle)
TextView tvTitle;
@BindView(R.id.tvChapts)
TextView tvChapters;
@BindView(R.id.btnSort)
ImageButton ibSort;*/
CatalogueAdapter catalogueAdapter;
protected void processArguments(){
if (getArguments() != null) {
Bundle bundle = getArguments() ;
@ -46,18 +62,60 @@ public class CatalogFragment extends BasicFragment {
}
}
boolean isAsc = true;
@Override
protected void fillData() {
catalogueList.clear();
catalogueList.addAll(pageFactory.getChapters());
CatalogueAdapter catalogueAdapter = new CatalogueAdapter(getContext(), catalogueList);
catalogueAdapter.setCharter(pageFactory.getCurrentChapter());
// int currentChp =pageFactory.getCurrentChapter()-1;
int currentChp =pageFactory.getNovle().getLastReadChapt()-1;
if(!isAsc){
catalogueList =revertArray();
currentChp = catalogueList.size() -currentChp-1;
}
catalogueAdapter = new CatalogueAdapter(getContext(), catalogueList);
catalogueAdapter.setCharter(currentChp+1);
lv_catalogue.setAdapter(catalogueAdapter);
catalogueAdapter.setCahedChapters(catalogCached);
catalogueAdapter.notifyDataSetChanged();
int count= lv_catalogue.getCount();
if(count >=pageFactory.getCurrentChapter() ){
lv_catalogue.setSelection(currentChp);
}
/* tvTitle.setText(pageFactory.getBookName());
tvChapters.setText(String.format("共%s章",catalogueList.size()));*/
}
ArrayList<Chapter> revertArray(){
ArrayList<Chapter> tmp = new ArrayList<>();
for(int i = catalogueList.size()-1;i>=0;i--){
tmp.add(catalogueList.get(i));
}
return tmp;
}
/* @OnClick(R.id.btnSort)
void Onclick(View view){
if(view.getId() == R.id.btnSort){
Log.d(TAG, "Onclick: sorted");
catalogueList = getArray();
catalogueAdapter.notifyDataSetChanged();
}
}*/
@Override
protected int getLayoutRes() {
return R.layout.fragment_catalog;
@ -66,6 +124,8 @@ public class CatalogFragment extends BasicFragment {
@Override
protected void initData() {
((MarkActivity) getActivity()).setSortcat(this);
showProgressDialog(false,"请稍等");
pageFactory = PageFactory.getInstance();
@ -75,6 +135,20 @@ public class CatalogFragment extends BasicFragment {
new Thread() {
@Override
public void run() {
ArrayList<Chapter> list =(ArrayList<Chapter>) LitePal.where("novelId=?" ,pageFactory.getNovle().getId()+"").find(Chapter.class);
File file;
for(Chapter cp : list){
if(!TextUtils.isEmpty(cp.getChapterPath())) {
String filename =pageFactory.getChapterFileName(cp.getIndex());
file = new File(filename);
if(file.exists()) {
Log.d(TAG, String .format("prepare book: load cats,chapter %s ,id %s,file %s is exist" ,cp.getChapterName(),cp.getIndex() , filename));
catalogCached.add(cp.getIndex());
}
}
}
int slepttime = 0;
while (NetUtil.isNetworkConnected() &&( slepttime < 1000 && ( pageFactory.isReadingCatalogs() || pageFactory.getChapters().size() == 0))) {
try {
@ -113,61 +187,16 @@ public class CatalogFragment extends BasicFragment {
// if(pageFactory.getPageWidget()==null){
Novel novel = pageFactory.getNovle();
Chapter cp = catalogueList.get(position);
Log.d(TAG, String .format("prepare book: catalog list postion %s, cp.index %s ,cp.name %s ",position,cp.getIndex(),cp.getChapterName()));
if(novel!=null){
novel.setLastReadChapt(position+1);
novel.setLastReadChapt(cp.getIndex());
novel.setLastReadPos(1);
ReadActivity.openBook(novel, getActivity());
/* new Thread() {
@Override
public void run() {
try {
sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
ReadActivity.openBook(novel, getActivity());
}}.start();*/
}
// }else {
// pageFactory.changeChapter(position+1);
// }
/*new Thread() {
@Override
public void run() {
super.run();
int slepttime =0;
int chapid = position+1;
File f = new File(pageFactory.getChapterFileName(chapid)) ;
while( pageFactory.getChapters().size() ==0 || !f.exists()){
try {
sleep(50);
slepttime+=1;
if(pageFactory.getChapters().size()>0){
//Log.d(TAG, String .format("prepare book: slept %s for loading chapter content %s,chapter.getid %s " , slepttime*50, chapid,pageFactory.getChapters().get(chapid-1).getId()));
}else{
// Log.d(TAG, String .format("prepare book: slept %s for loading pageFactory.getChapters().size() %s " , slepttime*50, pageFactory.getChapters().size()));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if(slepttime>100)
{
break;
}
}
Log.d(TAG, String .format("prepare book: total slept %s for loading chapter content %s,chapter.getid %s " , slepttime*50, chapid,pageFactory.getChapters().get(chapid-1).getId()));
handler.sendEmptyMessage(2);
*//* if(getActivity()!=null) {
getActivity().finish();
}*//*
}
}.start();*/
getActivity().finish();
@ -200,4 +229,12 @@ public class CatalogFragment extends BasicFragment {
}
@Override
public void sortList() {
isAsc =!isAsc;
fillData();
}
}

View File

@ -198,8 +198,15 @@ public class Fragment_Shelf extends BasicFragment {
.setBackgroundColor(getResources().getColor(android.R.color.transparent));
TextView tv =(TextView) bottomSheetDialog.findViewById(R.id.bdTitle);
tv.setText(bookLists.get(position).getName());
LinearLayout lldetail=(LinearLayout) bottomSheetDialog.findViewById(R.id.llBookdetail);
lldetail.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showBookDetail(bookLists.get(position));
}
});
bottomSheetDialog.show();
}

View File

@ -6,6 +6,7 @@ import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import com.ixiaow.multilayout.MultiLayout;
import com.novelbook.android.R;
import com.novelbook.android.adapter.BandanAdapterNew;
import com.novelbook.android.adapter.BookListAdapter;
@ -20,6 +21,7 @@ import com.novelbook.android.utils.GsonUtil;
import com.novelbook.android.utils.OnItemClickListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
@ -36,7 +38,16 @@ public class Fragment_bangdan extends BasicFragment {
// private List<Novel> mData;
@BindView(R.id.rvBangdan)
RecyclerView rvBandan;
// @BindView(R.id.topic_layout)
// MultiLayout topic_layout;
private static final String[] TAB_NAMES = {
"全部", "赛事", "原创", "少年", "少女", "日漫",
"杂志", "热血", "搞笑", "治愈", "惊秫", "古风",
"全部全部", "赛事2", "原创1", "少年2", "少女1", "日漫2",
"杂志eeee3", "热血2", "搞笑1", "治愈2", "惊秫2", "古风2",
"全部1", "赛事1", "原创2", "少年1", "少女", "日漫2",
"杂志1", "热血1", "搞笑2", "治愈1", "惊秫1", "古风1"
};
public static Fragment_bangdan newInstance(String param1, String param2) {
Fragment_bangdan fragment = new Fragment_bangdan();
Bundle args = new Bundle();
@ -139,7 +150,7 @@ public class Fragment_bangdan extends BasicFragment {
public void initViews(){
//topic_layout.initTabNames(Arrays.asList(TAB_NAMES));
}
void initialBookList() {

View File

@ -284,7 +284,8 @@ public class Fragment_booklist extends BasicFragment {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.d(TAG, String.format("onScrollStateChanged , state %s ,lastVisibleitem %s ,getItemCount %s,pageno %s ,pageCount %s",
newState==RecyclerView.SCROLL_STATE_IDLE,lastVisibleItem,mAdapter.getItemCount(),pageNo,pageCount));
//判断RecyclerView的状态 是空闲时同时是最后一个可见的ITEM时才加载
if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==mAdapter.getItemCount()){

View File

@ -1,29 +1,51 @@
package com.novelbook.android.Fragments;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.ixiaow.multilayout.MultiLayout;
import com.novelbook.android.R;
import com.novelbook.android.adapter.JudgeNestedScrollView;
import com.novelbook.android.bean.Progress;
import com.novelbook.android.db.Novel;
import com.novelbook.android.netsubscribe.BookSubscribe;
import com.novelbook.android.netutils.NetUtil;
import com.novelbook.android.netutils.OnSuccessAndFaultListener;
import com.novelbook.android.netutils.OnSuccessAndFaultSub;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.GsonUtil;
import com.novelbook.android.utils.OnItemClickListener;
import com.novelbook.android.adapter.BookListAdapter;
import com.flyco.tablayout.CommonTabLayout;
import com.flyco.tablayout.listener.CustomTabEntity;
import com.flyco.tablayout.listener.OnTabSelectListener;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
public class Fragment_paihang extends BasicFragment {
import static com.novelbook.android.utils.Constants.lstNt;
import static com.novelbook.android.utils.Constants.lstProgress;
import static com.novelbook.android.utils.Constants.lstSex;
public class Fragment_paihang extends BasicFragment {
final String TAG = Fragment_paihang.class.getSimpleName();
public static String getFTag() {
return "com.novelbook.android.Fragments.Fragment_paihang";
@ -34,15 +56,26 @@ public class Fragment_paihang extends BasicFragment {
private BookListAdapter mAdapter;
// private BookListAdapter mAdapter;
private List<Novel> mData;;
private List<Novel> mMoreData;
@BindView(R.id.rvPaihang)
RecyclerView rvPaihang;
@BindView(R.id.tab_layout1)
/* @BindView(R.id.tab_layout1)
CommonTabLayout tabLayout1;
@BindView(R.id.tab_layout2)
CommonTabLayout tabLayout2;
@BindView(R.id.tab_layout3)
@BindView(R.id.tab_layout3)*/
CommonTabLayout tabLayout3;
@BindView(R.id.topic_layout)
MultiLayout topic_layout;
@BindView(R.id.topic_layout1)
MultiLayout topic_layout1;
@BindView(R.id.topic_layout2)
MultiLayout topic_layout2;
public Fragment_paihang() {
// Required empty public constructor
@ -50,13 +83,28 @@ public class Fragment_paihang extends BasicFragment {
protected void processArguments(){
if (getArguments() != null) {
Bundle bundle = getArguments() ;
}
}
@Override
protected void fillData() {
if(rvPaihang.getAdapter()==null) {
rvPaihang.setLayoutManager(new LinearLayoutManager(activity));
rvPaihang.setAdapter(mAdapter);
}
if(mMoreData!=null) {
if(mMoreData.size()>0) {
pageNo++;
}
int status = pageCount >= pageNo ? BookListAdapter.LOADING_MORE : BookListAdapter.NO_LOAD_MORE;
// mAdapter.setPercent(pageNo/pageCount);
mAdapter.AddFooterItem(mMoreData);
mAdapter.changeMoreStatus(status);
}
mAdapter.notifyDataSetChanged();
}
public static Fragment_paihang newInstance(String param1, String param2) {
@ -73,9 +121,8 @@ public class Fragment_paihang extends BasicFragment {
if (getArguments() != null) {
}
initData();
}
}
@Override
protected int getLayoutRes() {
@ -84,155 +131,262 @@ public class Fragment_paihang extends BasicFragment {
@Override
public void initData() {
tmp=0;
loadSearchData();
}
private void loadSearchData(){
int pn = pageNo;
String sex = lstSex.get(tab1Pos);
String cate = lstNt.get(tab2Pos);
if(pageNo==1) {
mData =initData(mData,'Z');
mData1= new ArrayList<>();
mData2 = new ArrayList<>();
mData3 = new ArrayList<>();
mData1.add(new TabEntry("男A",0,0) );
mData1.add(new TabEntry("女A",0,0));
for (int i = 'A'; i < 'F'; i++)
{
mData2.add(new TabEntry("" + (char) i,0,0) );
if(i<'D')
mData3.add(new TabEntry("" + (char) i,0,0) );
if (mData != null) { //下拉刷新
mData = new ArrayList<Novel>();
mAdapter.setData(mData);
} else {
mData = new ArrayList<Novel>();
mAdapter = new BookListAdapter(activity, mData, R.layout.recycle_list_item_horizon, new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
showBookDetail(mData.get(position));
// openBook(mData.get(position),mAdapter);
}
@Override
public void onItemLongClick(View view, int position) {
// initDialog(position);
// mAdapter.removeData(position);
}
@Override
public void onLinearOutClick(View view, int position, int llId) {
Toast.makeText(activity, "book " + position + " clicked",
Toast.LENGTH_SHORT).show();
}
});
mAdapter.setShowFootView(true);
rvPaihang.setLayoutManager(new LinearLayoutManager(activity));
rvPaihang.setAdapter(mAdapter);
}
}
mAdapter = new BookListAdapter(activity, mData, R.layout.recycle_list_item_shudan, new OnItemClickListener() {
mMoreData =null;
OnSuccessAndFaultListener successAndFaultListener = new OnSuccessAndFaultListener() {
@Override
public void onItemClick(View view, int position) {
showBookDetail(mData.get(position) );
//openBook(mData.get(position),mAdapter);
public void onSuccess(String result) {
// mFirstPage= gson.fromJson(result, FirstPage.class);
try {
JSONObject jsonObject = new JSONObject(result);
pageCount = jsonObject.getInt("pageCount");
mMoreData = GsonUtil. parserJsonArray(jsonObject,Constants.BLOCK_TITLE_NOVELS);
} catch (Exception e) {
e.printStackTrace();
}
handler.sendEmptyMessage(1);
}
@Override
public void onItemLongClick(View view, int position) {
// initDialog(position);
// mAdapter.removeData(position);
public void onFault(String errorMsg) {
//失败
Log.d(TAG, "error on get firstpage: " + errorMsg);
handler.sendEmptyMessage(1);
}
};
BookSubscribe.getCateNovelList(cate, pageNo, tab1Pos+1, tab3Pos+1, new OnSuccessAndFaultSub(successAndFaultListener, getActivity()));
@Override
public void onLinearOutClick(View view, int position ,int llId) {
Toast.makeText(activity, "book " + position + " clicked",
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void initViews(){
/*
showProgressDialog(false,"加载。。。。");
new Thread(){
@Override
public void run() {
Log.d(TAG, "changing Source: to get site rule" );
while(lstNt==null){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
handler.sendEmptyMessage(2);
}
}.start();*/
//setScrollListner();
initLoadMoreListener();
initTabs();
initialBookList();
setScrollListner();
}
class TabEntry implements CustomTabEntity{
public String title;
public int selectedIcon;
public int unSelectedIcon;
public TabEntry(String title, int selectedIcon, int unSelectedIcon) {
this.title = title;
this.selectedIcon = selectedIcon;
this.unSelectedIcon = unSelectedIcon;
}
@Override
public String getTabTitle() {
return title;
}
@Override
public int getTabSelectedIcon() {
return selectedIcon;
}
@Override
public int getTabUnselectedIcon() {
return unSelectedIcon;
}
}
private void initTabs() {
tabLayout1.setTabData(mData1);
tabLayout1.setOnTabSelectListener(new OnTabSelectListener() {
/*
while(lstNt==null){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/
topic_layout.initTabNames(lstNt) ;
topic_layout1.initTabNames( lstSex) ;
topic_layout2.initTabNames(Arrays.asList(lstProgress)) ;
// topic_layout.initTabNames(lstNt);
topic_layout.setOnTabSelectListener(new MultiLayout.OnTabSelectListener() {
@Override
public void onTabSelect(int position) {
tab1Pos = position;
public void select(TextView textView, int i, int i1) {
Log.d(TAG, String.format("select: text %si %s i1 %s ",textView.getText(),i,i1));
tab2Pos = i1;
tabChanged();
}
});
topic_layout1.setOnTabSelectListener(new MultiLayout.OnTabSelectListener() {
@Override
public void select(TextView textView, int i, int i1) {
Log.d(TAG, String.format("select: text %si %s i1 %s ",textView.getText(),i,i1));
tab1Pos = i1;
tabChanged();
}
@Override
public void onTabReselect(int position) {
//TODO 重选
}
});
tabLayout2.setTabData(mData2);
tabLayout2.setOnTabSelectListener(new OnTabSelectListener() {
topic_layout2.setOnTabSelectListener(new MultiLayout.OnTabSelectListener() {
@Override
public void onTabSelect(int position) {
tab2Pos = position;
public void select(TextView textView, int i, int i1) {
Log.d(TAG, String.format("select: text %si %s i1 %s ",textView.getText(),i,i1));
tab3Pos = i1;
tabChanged();
}
@Override
public void onTabReselect(int position) {
//TODO 重选
}
});
tabLayout3.setTabData(mData3);
tabLayout3.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelect(int position) {
tab3Pos = position;
tabChanged();
}
// tabChanged();
@Override
public void onTabReselect(int position) {
//TODO 重选
}
});
tabChanged();
}
int tmp=0;
void tabChanged() {
Log.d(TAG, String.format("tabChanged: to load data tmp %s" , tmp ));
tmp++;
/* Toast.makeText(activity, String.format( "TAB1 :{0}, TAB2 :{1}, TAB3 :{3}",
mData1.get(tab1Pos).getTabTitle(),
mData2.get(tab2Pos).getTabTitle(),
mData3.get(tab3Pos).getTabTitle()),
Toast.LENGTH_SHORT).show();
*/
String selectedKey = mData1.get(tab1Pos).getTabTitle() +" " +
String selectedKey = mData1.get(tab1Pos).getTabTitle() +" " +
mData2.get(tab2Pos).getTabTitle() +" " +
mData3.get(tab3Pos).getTabTitle() ;
initialBookList();
*/
if(lstSex==null) return;
pageNo=1;
String sex = lstSex.get(tab1Pos);
String cate = lstNt.get(tab2Pos);
String selectedKey = lstSex.get(tab1Pos) +" " +
cate +" " +
lstProgress[tab3Pos] ;
Toast.makeText(activity, selectedKey,
Toast.LENGTH_SHORT).show();
tvHint.setText(selectedKey);
Log.d(TAG, String.format("tabChanged: to load data %s,pageno %s" , selectedKey,pageNo ));
if( tmp<4) return;
loadSearchData();
}
private void initLoadMoreListener() {
rvPaihang.addOnScrollListener(new RecyclerView.OnScrollListener() {
int lastVisibleItem ,visibleItemCount,totalItemCount,pastVisiblesItems;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//判断RecyclerView的状态 是空闲时同时是最后一个可见的ITEM时才加载
Log.d(TAG, String.format("onScrollStateChanged , state %s ,lastVisibleitem %s ,getItemCount %s,pageno %s ,pageCount %s",
newState==RecyclerView.SCROLL_STATE_IDLE,lastVisibleItem,mAdapter.getItemCount(),pageNo,pageCount));
if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==mAdapter.getItemCount()){
if(pageNo <= pageCount) {
//设置正在加载更多
mAdapter.changeMoreStatus(mAdapter.LOADING_MORE);
//改为网络请求
loadSearchData();
}else{
mAdapter.changeMoreStatus(mAdapter.NO_LOAD_MORE);
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
// if (dy > 0) {
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
// }
Log.d(TAG, String.format("onScrolled:dy %s,visibleItemCount %s,totalItemCount %s,pastVisiblesItems %s ",
dy, visibleItemCount,totalItemCount,pastVisiblesItems));
//最后一个可见的ITEM
lastVisibleItem=layoutManager.findLastVisibleItemPosition();
lastVisibleItem=layoutManager.findLastCompletelyVisibleItemPosition();
}
});
}
//----------------绑定列表
void initialBookList() {
rvPaihang.setLayoutManager(new LinearLayoutManager(activity));
rvPaihang.setAdapter(mAdapter);
// rvPaihang.setLayoutManager(new LinearLayoutManager(activity));
// rvPaihang.setAdapter(mAdapter);
}
@BindView(R.id.tvHint)
TextView tvHint;
//------------滑动监听
@BindView(R.id.n_scroll_view)
NestedScrollView mNestedScrollView;
/* @BindView(R.id.n_scroll_view)
JudgeNestedScrollView mNestedScrollView;
@BindView(R.id.llTabs)
LinearLayout llTabs;
@BindView(R.id.tvHint)
@ -259,6 +413,7 @@ public class Fragment_paihang extends BasicFragment {
// 随着滑动距离改变透明度
// Log.e("al=","="+alpha);
// re.setBackgroundColor(Color.argb(alpha, 255, 0, 0));
mNestedScrollView.setNeedScroll(true);
} else {
tvHint.setVisibility(View.VISIBLE);
// if (alpha < 255) {
@ -267,19 +422,54 @@ public class Fragment_paihang extends BasicFragment {
// alpha = 255;
// re.setBackgroundColor(Color.argb(alpha, 255, 0, 0));
// }
mNestedScrollView.setNeedScroll(false);
}
*//* LinearLayoutManager layoutManager = (LinearLayoutManager) NestedScrollView.getLayoutManager();
int lastVisibleItemPosition = 0;
int totalItemCount = layoutManager.getItemCount();
if(v.getChildAt(v.getChildCount() - 1) != null) {
if (scrollY >= (v.getChildAt(v.getChildCount()-1).getMeasuredHeight() - v.getMeasuredHeight())
&& scrollY > oldScrollY) {
if (layoutManager instanceof LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
}
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
}
if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
currentPage++;
onLoadMore();
loading = true;
}
}
}*//*
}
});
}
*/
@Override
public void onResume() {
super.onResume();
//mNestedScrollView.smoothScrollBy(1,1);
tvHint.setVisibility(isShowHint? View.VISIBLE:View.GONE);
// tvHint.setVisibility(isShowHint? View.VISIBLE:View.GONE);
}

View File

@ -32,6 +32,7 @@ import com.novelbook.android.netutils.OnSuccessAndFaultListener;
import com.novelbook.android.netutils.OnSuccessAndFaultSub;
import com.novelbook.android.utils.Config;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.GsonUtil;
import com.novelbook.android.utils.PageFactory;
@ -74,7 +75,7 @@ public class Main2Activity extends Activity_base
// ButterKnife.bind(this);
initialSexOption();
getSearchTabTtitle();
}
@ -523,5 +524,33 @@ private int bottomSelectedIndex;
}
}, this));
}
void getSearchTabTtitle(){
BookSubscribe.getSearchTitles(new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() {
@Override
public void onSuccess(String result) {
// mFirstPage= gson.fromJson(result, FirstPage.class);
try {
Constants.lstSex = GsonUtil.parserStringBlocks(result,"sex");
Constants.lstNt =GsonUtil.parserStringBlocks(result,"nt");
// Constants.lstProgress =GsonUtil.parserProgressBlocks(result,"progress");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFault(String errorMsg) {
//失败
Log.d(TAG, "error on get firstpage: " + errorMsg);
}
},this));
}
}

View File

@ -7,6 +7,7 @@ import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import com.flyco.tablayout.SlidingTabLayout;
import com.novelbook.android.adapter.MyPagerAdapter;
@ -17,6 +18,7 @@ import com.novelbook.android.utils.PageFactory;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.OnClick;
public class MarkActivity extends Activity_base {
@ -34,11 +36,13 @@ public class MarkActivity extends Activity_base {
SlidingTabLayout tabLayout;
// @Bind(R.id.lv_catalogue)
// ListView lv_catalogue;
@BindView(R.id.btnSort)
ImageButton ibSort;
private PageFactory pageFactory;
private Config config;
private PageFactory pageFactory;
/* private Config config;
private Typeface typeface;
private ArrayList<Chapter> catalogueList = new ArrayList<>();
private ArrayList<Chapter> catalogueList = new ArrayList<>();*/
private DisplayMetrics dm;
private String EXTR_BOOK ="book";
@ -62,9 +66,9 @@ public class MarkActivity extends Activity_base {
pageFactory = PageFactory.getInstance();
Log.d(TAG, "prepareBook: pagefactory.mbook is ?" + (pageFactory.getNovle() .getName()) );
config = Config.getInstance();
dm = getResources().getDisplayMetrics();
typeface = config.getTypeface();
//config = Config.getInstance();
// dm = getResources().getDisplayMetrics();
// typeface = config.getTypeface();
setSupportActionBar(toolbar);
//设置导航图标
@ -93,5 +97,35 @@ public class MarkActivity extends Activity_base {
protected void initListener() {
}
@OnClick(R.id.btnSort)
void Onclick(View view){
if(view.getId() == R.id.btnSort){
Log.d(TAG, "Onclick: sorted");
if(sortcat!=null){
sortcat.sortList();
}
if(sortmark!=null){
sortmark.sortList();
}
}
}
private Sortcat sortcat=null;
private Sortmark sortmark=null;
public void setSortcat(Sortcat sort) {
this.sortcat = sort;
}
public void setSortmark(Sortmark sort) {
this.sortmark = sort;
}
public interface Sortmark {
public void sortList();
}
public interface Sortcat {
public void sortList();
}
}

View File

@ -739,7 +739,7 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
private void showReadSetting(){
isShow = true;
rl_progress.setVisibility(View.GONE);
// rl_progress.setVisibility(View.GONE);
if (isSpeaking){
Animation topAnim = AnimationUtils.loadAnimation(this, R.anim.dialog_top_enter);
@ -831,7 +831,7 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
R.id.tv_dayornight,R.id.tv_pagemode, R.id.tv_setting, R.id.bookpop_bottom, /*R.id.rl_bottom,*/R.id.tv_stop_read
,R.id.llTopAd})
public void onClick(View view) {
if( pageFactory.isReady())
// if( pageFactory.isReady())
switch (view.getId()) {
// case R.id.btn_return:
// finish();

View File

@ -19,15 +19,17 @@ import java.util.List;
public class CatalogueAdapter extends BaseAdapter {
private Context mContext;
private List<Chapter> bookCatalogueList;
private List<Integer> bookCatalogueListCached;
private Typeface typeface;
private Config config;
private int currentCharter = 0;
public CatalogueAdapter(Context context, List<Chapter> bookCatalogueList) {
public CatalogueAdapter(Context context, List<Chapter> bookCatalogueList ) {
mContext = context;
this.bookCatalogueList = bookCatalogueList;
config = config.getInstance();
typeface = config.getTypeface();
}
@Override
@ -49,6 +51,11 @@ public class CatalogueAdapter extends BaseAdapter {
currentCharter = charter;
}
public void setCahedChapters(List<Integer> listCached ){
bookCatalogueListCached =listCached;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(mContext);
@ -58,6 +65,10 @@ public class CatalogueAdapter extends BaseAdapter {
convertView = inflater.inflate(R.layout.zcataloguelistview_item,null);
viewHolder.catalogue_tv = (TextView)convertView.findViewById(R.id.catalogue_tv);
viewHolder.catalogue_tv.setTypeface(typeface);
viewHolder.getCatalogue_cache =(TextView)convertView.findViewById(R.id.catalogue_cache);
viewHolder.getCatalogue_cache.setTypeface(typeface);
// viewHolder.getCatalogue_cache.setTextSize( viewHolder.catalogue_tv.getTextSize()-2);
viewHolder.getCatalogue_cache.setTextColor( mContext.getResources().getColor(R.color.light_gray));
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder)convertView.getTag();
@ -67,12 +78,20 @@ public class CatalogueAdapter extends BaseAdapter {
}else{
viewHolder.catalogue_tv.setTextColor(mContext.getResources().getColor(R.color.dark_gray));
}
viewHolder.catalogue_tv.setText(bookCatalogueList.get(position).getChapterName());
Chapter chapter = bookCatalogueList.get(position);
viewHolder.catalogue_tv.setText(chapter.getChapterName());
viewHolder.getCatalogue_cache.setVisibility(View.GONE);
if(bookCatalogueListCached.contains(chapter.getIndex())) {
viewHolder.getCatalogue_cache.setVisibility(View.VISIBLE);
}
//Log.d("catalogue",bookCatalogueList.get(position).getBookCatalogue());
return convertView;
}
class ViewHolder {
TextView catalogue_tv;
TextView getCatalogue_cache;
}
}

View File

@ -0,0 +1,38 @@
package com.novelbook.android.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class JudgeNestedScrollView extends NestedScrollView {
private boolean isNeedScroll = true;
public JudgeNestedScrollView(@NonNull Context context) {
super(context);
}
public JudgeNestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public JudgeNestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/* switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
return isNeedScroll;
}*/ //will cause tab no response
return super.onInterceptTouchEvent(ev);
}
/*
改方法用来处理NestedScrollView是否拦截滑动事件
*/
public void setNeedScroll(boolean isNeedScroll) {
this.isNeedScroll = isNeedScroll;
}
}

View File

@ -0,0 +1,22 @@
package com.novelbook.android.bean;
public class Progress {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -31,7 +31,7 @@ public class Novel extends LitePalSupport implements Serializable{
private String chapterName;
private String desc;
private String progress;
private long lastUpateTime;
private long lastUpdateTime;
private boolean isOnShelf; //是否入书架
private boolean isFinished; //是否完本
@ -187,11 +187,11 @@ public class Novel extends LitePalSupport implements Serializable{
public long getLastUpateTime() {
return lastUpateTime;
return lastUpdateTime;
}
public void setLastUpateTime(long lastUpateTime) {
this.lastUpateTime = lastUpateTime;
this.lastUpdateTime = lastUpateTime;
}
public boolean isOnShelf() {

View File

@ -81,7 +81,8 @@ public interface HttpApi {
Observable<ResponseBody> getSiteRankDetail(@Query("fn")String fn,@Query("pn")int pageNo,@Query("sex") int Sex);
@GET( "search/{keyword}/{pageno}")
Observable<ResponseBody> getSeachNolvelist(@Path("keyword")String keyWord,@Path("pageno")int pageNo,@Query("sex") int Sex);
// 搜索分类 http://xiaoshuofenxiang.com/api/page/topdata
@GET("page/topdata")
Observable<ResponseBody> getSearchTitles();
}

View File

@ -75,5 +75,9 @@ public class BookSubscribe {
Observable<ResponseBody> observable = HttpMethods.getInstance().getHttpApi().getSeachNolvelist(keyWord,pageNo,sex);
HttpMethods.getInstance().toSubscribe(observable, subscriber);
}
public static void getSearchTitles(DisposableObserver<ResponseBody> subscriber){
Observable<ResponseBody> observable = HttpMethods.getInstance().getHttpApi().getSearchTitles();
HttpMethods.getInstance().toSubscribe(observable, subscriber);
}
}

View File

@ -174,7 +174,7 @@ public class OnSuccessAndFaultSub extends DisposableObserver<ResponseBody>
try {
// final String result = CompressUtils.decompress(body.byteStream());
final String result =body.string();
Log.e("body", result);
// Log.e("body", result);
JSONObject jsonObject = new JSONObject(result);
int resultCode = jsonObject.getInt("code");
if (resultCode == 0) {
@ -182,7 +182,7 @@ public class OnSuccessAndFaultSub extends DisposableObserver<ResponseBody>
} else {
String errorMsg = jsonObject.getString("message");
mOnSuccessAndFaultListener.onFault(errorMsg);
Log.e("OnSuccessAndFaultSub", "errorMsg: " + errorMsg);
Log.e("OnSuccessAndFaultSub", "errorMsg: " + errorMsg);
}
} catch (Exception e) {
Toast.makeText(context,"出错了" + e.getMessage(),Toast.LENGTH_LONG);

View File

@ -121,7 +121,7 @@ public class BookUtil {
return mNovelSites;
}
public synchronized void openBook(Novel novel) throws IOException, InterruptedException {
public synchronized void openBook(Novel novel, long chapter) throws IOException, InterruptedException {
this.mNovel = novel;
//如果当前缓存不是要打开的书本就缓存书本同时删除缓存
@ -150,6 +150,15 @@ public class BookUtil {
}
}
}else{ //读取目录列表
Log.d(TAG, String.format("prepare book %s open chapter %s in background.... mMuluStatus %smSiteRule %s,thread %s",mNovel.getName(),chapter,mMuluStatus,mSiteRule,Thread.currentThread().getName()) );
File file =new File(fileChapterName((int)chapter));
if( file.exists()){
Log.d(TAG, String.format("prepare book open chapter file %s, exist,not waiting more...to open file...",fileChapterName((int)chapter) ));
return;
}
MuluStatus m = mMuluStatus;
// Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
@ -159,16 +168,17 @@ public class BookUtil {
while( mSiteRule ==null || mMuluStatus==null || mMuluStatus == MuluStatus.isDownloading){
sleptTime++;
if(sleptTime >100 || !NetUtil.isNetworkConnected()){
if(sleptTime >400 || sleptTime >30 && !NetUtil.isNetworkConnected()){
break;
}
Thread.sleep(50);
Log.d(TAG,String.format("prepare book %s waiting for mulu downloading ,mMuluStatus %s,msiteRule %s" ,mNovel.getName(),mMuluStatus,mSiteRule));
if(mMuluStatus == MuluStatus.failed){
throw new RuntimeException("读取资源失败,请检查网络");
Thread.sleep(50);
if(mMuluStatus == MuluStatus.failed){
Log.d(TAG,String.format("prepare book %s failed ,mMuluStatus %s,msiteRule %s,slept %s" ,mNovel.getName(),mMuluStatus,mSiteRule,sleptTime*50));
// throw new RuntimeException("读取资源失败,请检查网络");
}
}
Log.d(TAG,String.format("prepare book %s waiting for mulu downloading ,mMuluStatus %s,msiteRule %s,slept %s" ,mNovel.getName(),mMuluStatus,mSiteRule,sleptTime*50));
}
// dismissProgressDialog();
@ -522,7 +532,7 @@ public class BookUtil {
int muluRetryCount =0;
void readChaptersAsync( ) {
String url = mSite.getMuluUrl();
@ -531,47 +541,84 @@ public class BookUtil {
long startTime= new Date().getTime();
Log.d(TAG,String.format("loadChapts----start download %s 目录 from %s", mNovel.getName() ,url ));
/* if(muluRetryCount<3){
muluRetryCount++;
return;
}
if(muluRetryCount>=3) {
return;
}*/
HttpMethods.getOkClient().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// Log.d(TAG, "onFailure: " + e.getMessage());
Log.e(TAG, "loadChapts---- failed: ",e );
Log.d(TAG,String.format("loadChapts---- failed %s 目录 from %s", mNovel.getName() ,url ));
// Log.d(TAG, "onFailure: " + e.getMessage());
Log.e(TAG, "prepare book loadChapts---- failed: ", e);
Log.d(TAG, String.format("prepare book loadChapts---- failed %s 目录 from %s", mNovel.getName(), url));
handler.sendEmptyMessage(3);
//TODO 如果是取消了访问则返回
if(e.toString().contains("closed") ||e.getMessage().contains("Canceled"))
{
if (e.toString().contains("closed") || e.getMessage().contains("Canceled")) {
Log.d(TAG, String.format("prepare book loadChapts---- canceled %s 目录 from %s", mNovel.getName(), url));
return;
}
mMuluStatus = MuluStatus.failed;
if (muluRetryCount < 3) {
try {
Thread.sleep(50);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
muluRetryCount++;
Log.d(TAG,String.format("prepare book loadChapts----failed, retrying count %s",muluRetryCount ));
readChaptersAsync();
}
if (mNovelSites.getSites().length == 1) { //仅有一个rule,且失败了
// mMuluStatus = MuluStatus.failed;
if( mNovelSites.getSites().length ==1){ //仅有一个rule,且失败了
mMuluStatus = MuluStatus.failed;
return;
}
//try next site
for(Site st : mNovelSites.getSites() ){
if(!st.getDomain().equals(mSite.getDomain())){
mSite =st;
break;
}
}
// readChaptersAsync();
getSiteRule();
}
for (Site st : mNovelSites.getSites()) {
if (!st.getDomain().equals(mSite.getDomain())) {
mSite = st;
break;
}
}
muluRetryCount=0;
// readChaptersAsync();
getSiteRule();
}
@Override
public void onResponse(Call call, Response response){
ResponseBody body = response.body();
if(response.code()!=200){
Log.d(TAG,String.format("loadChapts----failed, %s 目录 from %s,return code %s", mNovel.getName() ,url,response.code() ));
Log.d(TAG,String.format("prepare book loadChapts----failed, %s 目录 from %s,return code %s", mNovel.getName() ,url,response.code() ));
handler.sendEmptyMessage(3);
mMuluStatus = MuluStatus.failed;
if(muluRetryCount <3){
Log.d(TAG,String.format("prepare book loadChapts----failed, response code %s retrying count %s",response.code(), muluRetryCount ));
muluRetryCount++;
readChaptersAsync();
}
return;
}
muluRetryCount =0;
if (body != null) {
Log.d(TAG, String.format("prepare book %s 章节信息读取成功.thread %s",mNovel.getName(),Thread.currentThread().getName()) );
try {
@ -580,7 +627,7 @@ public class BookUtil {
// Log.d(TAG,String.format("loadChaptContent----end download %s 目录, 目录数量 %s, cost %s", mNovel.getName() , mChapters.size(), new Date().getTime() -startTime ));
// long startTime2= new Date().getTime();
buildChapters(bodyStr,url);
Log.d(TAG,String.format("loadChapts----end download %s 目录, 目录数量 %s, cost %s", mNovel.getName() , mChapters.size(), new Date().getTime() -startTime ));
Log.d(TAG,String.format("prepare book loadChapts----end download %s 目录, 目录数量 %s, cost %s", mNovel.getName() , mChapters.size(), new Date().getTime() -startTime ));
mMuluStatus = MuluStatus.isDone;
Log.d(TAG, String.format("prepare book %s 章节信息完成.",mNovel.getName()) );
@ -623,7 +670,7 @@ public class BookUtil {
}*/
} catch (JSONException e) {
// } catch (JSONException | IOException e) {
Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
Log.d(TAG,String.format("prepare book, mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
e.printStackTrace();
} finally {
// result.close();
@ -1139,109 +1186,121 @@ public class BookUtil {
try {
File file = new File(fileChapterName(index));
if(!file.exists()) {
if (!file.exists()) {
if(mMuluStatus ==null){
Log.d(TAG,String.format("prepare book loadChapts---- 还未有目录信息,出错了 %s 目录, 目录数量 %s, MuluStatus %s ,thread %s", mNovel.getName() , mChapters.size(), mMuluStatus,Thread.currentThread().getName() ));
// getTargetSites();
if (mMuluStatus == null) {
Log.d(TAG, String.format("prepare book loadChapts---- 还未有目录信息,出错了 %s 目录, 目录数量 %s, MuluStatus %s ,thread %s", mNovel.getName(), mChapters.size(), mMuluStatus, Thread.currentThread().getName()));
// getTargetSites();
}
int slept = 0;
while(NetUtil.isNetworkConnected() && slept <100 && mMuluStatus ==MuluStatus.isDownloading){
while (NetUtil.isNetworkConnected() && slept < 100 && mMuluStatus == MuluStatus.isDownloading) {
try {
Thread.sleep(50);
slept++;
Log.d(TAG,String.format("prepare book loadChapts----等待中 %s 目录, 目录数量 %s, slept %s, MuluStatus %s", mNovel.getName() , mChapters.size(),slept ,mMuluStatus ));
Log.d(TAG, String.format("prepare book loadChapts----等待中 %s 目录, 目录数量 %s, slept %s, MuluStatus %s", mNovel.getName(), mChapters.size(), slept, mMuluStatus));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if( !NetUtil.isNetworkConnected() || mChapters ==null || mChapters.size() ==0){
Log.d(TAG,String.format("loadChapts----超时。。。或出错了 %s 目录, 目录数量 %s, slept %s, MuluStatus %s,thread %s", mNovel.getName() , mChapters.size(),slept ,mMuluStatus,Thread.currentThread().getName() ));
if (!NetUtil.isNetworkConnected() || muluRetryCount >= 3 && (mChapters == null || mChapters.size() == 0)) {
Log.d(TAG, String.format("loadChapts----超时。。。或出错了 %s 目录, 目录数量 %s, slept %s, MuluStatus %s,thread %s", mNovel.getName(), mChapters.size(), slept, mMuluStatus, Thread.currentThread().getName()));
String error = "网络不给力";
return error.toCharArray();
return error.toCharArray();
}
Log.d(TAG,String.format("loadChaptContent----start %s" ,new Date().toString() ));
Log.d(TAG, String.format("loadChaptContent----start %s", new Date().toString()));
Log.d("loadChaptContent", String.format("begin to load content for chapter %s", index));
Log.d("loadChaptContent", String.format("isDownloadChapt: %s", isDownloadChapt));
Log.d( "loadChaptContent",String.format("begin to load content for chapter %s",index));
Log.d( "loadChaptContent",String.format("isDownloadChapt: %s",isDownloadChapt));
if(!chaptDownStatus.containsKey(Integer.valueOf(index))){
chaptDownStatus.put(index,DownloadStatus.downloading);
if (!chaptDownStatus.containsKey(Integer.valueOf(index))) {
chaptDownStatus.put(index, DownloadStatus.downloading);
loadChaptContent(index);
}
Log.d( "loadChaptContent",String.format("showing dialog " ));
Log.d("loadChaptContent", String.format("showing dialog "));
// Log.d(TAG,String.format("showing progress diaglog......"));
int maxSleep =6000;
int slepttime =0;
// while(!file.exists() && !getDownloadStatus()){//&& slepttime <maxSleep){
// while( !getDownloadStatus() && slepttime <maxSleep){
while( NetUtil.isNetworkConnected() && !getDownloadStatus() && chaptDownStatus.get(Integer.valueOf(index)) == DownloadStatus.downloading && slepttime <maxSleep){
int maxSleep = 4500;
int slepttime = 0;
// while(!file.exists() && !getDownloadStatus()){//&& slepttime <maxSleep){
// while( !getDownloadStatus() && slepttime <maxSleep){
while (NetUtil.isNetworkConnected() && !getDownloadStatus() && chaptDownStatus.get(Integer.valueOf(index)) == DownloadStatus.downloading && slepttime < maxSleep) {
Thread.sleep(50);
slepttime+=50;
Log.d(TAG,String.format(" prepare book loadChaptContent slept %s for downloading,isDownload %s thread %s ",slepttime,getDownloadStatus(),Thread.currentThread().getName() ) );
slepttime += 50;
Log.d(TAG, String.format(" prepare book loadChaptContent slept %s for downloading,isDownload %s thread %s ", slepttime, getDownloadStatus(), Thread.currentThread().getName()));
}
Log.d("loadChaptContent",String.format("loadChaptContent slept %s for downloading ",slepttime ) );
Log.d( "loadChaptContent",String.format("dismissing dialog " ));
Log.d("loadChaptContent", String.format("loadChaptContent slept %s for downloading ", slepttime));
Log.d(TAG,String.format("loadChaptContent slept %s for downloading chaptercontent ",slepttime ));
}
Log.d( "loadChaptContent",String.format(" %s, file.exists()? %s", file.getPath(),file.exists()));
if(!file.exists() || !NetUtil.isNetworkConnected()) {
Log.d("loadChaptContent", String.format(" %s, file.exists()? %s", file.getPath(), file.exists()));
if (!file.exists() && !NetUtil.isNetworkConnected()) {
String error = "网络不给力";
return error.toCharArray();
return error.toCharArray();
}
if(mChapters.size() > index ) {
if (mChapters.size() > index && NetUtil.isNetworkConnected()) {
File file2 = new File(fileChapterName(index+1));
if (!chaptDownStatus.containsKey(index + 1) || chaptDownStatus.get(index + 1).equals(DownloadStatus.failure)) {
if(!file2.exists()) {
Log.d(TAG,String.format(" prepare book to load next chapt %s",index+1));
loadChaptContent(index + 1);
File file2 = new File(fileChapterName(index + 1));
if (!file2.exists()) {
Log.d(TAG, String.format(" prepare book to load next chapt %s,down status %s ", index + 1, chaptDownStatus.get(index + 1)));
chaptDownStatus.put(index + 1, DownloadStatus.downloading);
loadChaptContent(index + 1);
}
}
}
if( index >1 && index -1 < mChapters.size() ) {
if (index > 1 && index - 1 < mChapters.size() && NetUtil.isNetworkConnected()) {
File file2 = new File(fileChapterName(index-1));
if (!chaptDownStatus.containsKey(index - 1) || chaptDownStatus.get(index - 1).equals(DownloadStatus.failure)) {
File file2 = new File(fileChapterName(index - 1));
if (!file2.exists()) {
Log.d(TAG, String.format(" prepare book to load pre chapt %s,down status %s ", index - 1, chaptDownStatus.get(index - 1)));
chaptDownStatus.put(index - 1, DownloadStatus.downloading);
loadChaptContent(index - 1);
}
if(!file2.exists()) {
Log.d(TAG,String.format(" prepare book to load pre chapt %s",index-1));
loadChaptContent(index - 1);
}
}
int size = (int)file.length();
int size = (int) file.length();
if (size < 0) {
throw new RuntimeException("Error during reading " + fileChapterName(index));
Log.e(TAG, "prepare book chaptChars: Error during reading"+ fileChapterName(index) );
// throw new RuntimeException("Error during reading " + fileChapterName(index));
}
block = new char[size / 2];
InputStreamReader reader =
new InputStreamReader(
new FileInputStream(file),
charachterType
);
long l = reader.read(block);
if (reader.read(block) != block.length) {
// throw new RuntimeException("Error during reading " + fileChapterName(index));
InputStreamReader reader = null;
try {
reader =
new InputStreamReader(
new FileInputStream(file),
charachterType
);
long l = reader.read(block);
if (reader.read(block) != block.length) {
// throw new RuntimeException("Error during reading " + fileChapterName(index));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Error during reading " + fileChapterName(index));
} catch (JSONException e) {
} catch (JSONException | IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
}
Cache cache = new Cache();
cache.setSize(block.length);

View File

@ -18,9 +18,12 @@ import android.view.TextureView;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@ -30,12 +33,12 @@ public class CommonUtil {
private static final String TAG= CommonUtil.class.getSimpleName();
public static int getScreenHeight(Context context){
if(checkDeviceHasNavigationBar(context)){
return getDpi(context);
int diff = checkDeviceHasNavigationBar(context);
if(diff >0){
return getDpi(context) -diff; // return height for no navigation bar
}
return getScreenHeightWithOutBottomBar(context);
return getScreenHeightWithOutBottomBar(context); //return for with navigationbar
}
/**
@ -43,14 +46,17 @@ public class CommonUtil {
* @param context
* @return
*/
public static boolean checkDeviceHasNavigationBar(Context context) {
public static int checkDeviceHasNavigationBar(Context context) {
Point appUsableSize = getAppUsableScreenSize(context);
Point realScreenSize = getRealScreenSize(context);
Log.d(TAG, String.format("getNavigationBarSize: usablesize.y %s,realScreenSize.y %s,realScreenSize.y -usablesize.y =%s, statusbar height %s"
Log.d(TAG, String.format("getNavigationBarSize: usablesize.y %s,realScreenSize.y %s" +
",realScreenSize.y -usablesize.y =%s, statusbar height %s"
,appUsableSize.y ,realScreenSize.y, realScreenSize.y-appUsableSize.y ,getStatusBarHeight(context) ));
Point p = getNavigationBarSize(context);
return realScreenSize.y-appUsableSize.y - getStatusBarHeight(context)>0;
// Toast.makeText(context,String.format("getNavigationBarSize: usablesize.y %s,realScreenSize.y %s,diff %s",
// appUsableSize.y ,realScreenSize.y,realScreenSize.y-appUsableSize.y - getStatusBarHeight(context)),Toast.LENGTH_LONG).show();
return realScreenSize.y-appUsableSize.y - getStatusBarHeight(context);
}
public static Point getNavigationBarSize(Context context) {
@ -415,9 +421,31 @@ public class CommonUtil {
public static String getDateString(long time,String format){
String f = TextUtils.isEmpty(format) ?"yyyy年MM月dd日 HH:mm:ss":format;
Date dt = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String rt =sdf.format(dt);
Log.d(TAG, String.format("getDateString:timestamp %s, formated time %s",time,rt));
long time2 =System.currentTimeMillis();
dt = new Date(time2);
rt =sdf.format(dt);
Log.d(TAG, String.format("getDateString:timestamp %s, formated time %s",time2,rt));
return sdf.format(dt);
/* Timestamp ts = new Timestamp(time);
String tsStr = "";
DateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
try {
//方法一
tsStr = sdf2.format(ts);
System.out.println(tsStr);
//方法二
tsStr = ts.toString();
System.out.println(tsStr);
} catch (Exception e) {
e.printStackTrace();
}*/
}
public static String getDateString(long time){

View File

@ -1,9 +1,18 @@
package com.novelbook.android.utils;
import com.novelbook.android.bean.Progress;
import java.util.List;
public class Constants {
public static final String BLOCK_TITLE_NOVELS = "ns";
public static final int NOVEL_SPAN_CNT =3 ; //grid columns
public static final boolean SHOWAD =false ;
public static int SEX=1;
public static int SEX=1; //1 2女
public static String A_Regex = "<a[^>]+href[\\s]*=[\\s]*['\"]?([^'\"]+)['\"\\s]?[^>]*>([^<]+)<"; //TODO: 从服务器更新
public static List<String> lstProperties =null;
public static List<String> lstSex =null;
public static List<String> lstNt=null;
//public static List<Progress> lstProgress=null;
public static String[] lstProgress={"连载中","已完本","新书"};
}

View File

@ -6,8 +6,10 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.novelbook.android.bean.NovelBlock;
import com.novelbook.android.bean.Progress;
import com.novelbook.android.db.Novel;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -38,6 +40,48 @@ public class GsonUtil {
}
return nv;
}
public static List<String> parserStringBlocks(String result,String blockName ) throws JSONException {
JSONObject jsonObject = new JSONObject(result);
JSONArray array = jsonObject.getJSONArray(blockName);
List<String> lst = new ArrayList<String>();
for( int i=0;i< array.length();i++){
lst .add(array.getString(i));
}
return lst;
}
public static List<Progress> parserProgressBlocks(String restult, String blockName ) throws JSONException {
JSONObject jsonObject = new JSONObject(restult);
String strJson = jsonObject.getString(blockName);
List<Progress> list = new ArrayList<Progress>();
//创建一个Gson对象
// Gson gson = new Gson();
//创建一个JsonParser
JsonParser parser = new JsonParser();
//通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
JsonElement el = parser.parse(strJson);
//把JsonElement对象转换成JsonObject
JsonObject jsonObj = null;
if (el.isJsonObject()) {
jsonObj = el.getAsJsonObject();
}
//把JsonElement对象转换成JsonArray
JsonArray jsonArray = null;
if (el.isJsonArray()) {
jsonArray = el.getAsJsonArray();
}
//遍历JsonArray对象
Iterator it = jsonArray.iterator();
while (it.hasNext()) {
JsonElement e = (JsonElement) it.next();
//JsonElement转换为JavaBean对象
list.add((Progress) gson.fromJson(e, Progress.class));
}
return list;
}
public static List<NovelBlock> parserNovleBlocks(String restult,String blockName ) throws JSONException {
JSONObject jsonObject = new JSONObject(restult);
String strJson = jsonObject.getString(blockName);

View File

@ -192,13 +192,19 @@ public class PageFactory implements ChangeSource{
}
}
private List<TRPage> loadCurrentChapt(int chaptId){
Log.d(TAG, String.format("prepare book, loadCurrentChapt chaptId %s, getChapters().size() %s ",chaptId,getChapters().size() ) );
chaptId = chaptId >getChapters().size()?getChapters().size():chaptId;
final File file = new File(getChapterFileName(chaptId));
chaptId = chaptId >0?chaptId:1;
if (!file.exists()) { //待下载
chaptId = chaptId > getChapters().size() ? getChapters().size() : chaptId;
chaptId = chaptId > 0 ? chaptId : 1;
}
List<TRPage> chaptPages = new ArrayList<TRPage>();
chaptPages.add(new TRPage());
List<TRPage> chaptPages = new ArrayList<TRPage>();
chaptPages.add(new TRPage());
@ -208,9 +214,12 @@ public class PageFactory implements ChangeSource{
drawStatus(mBookPageWidget.getCurPage());
drawStatus(mBookPageWidget.getNextPage());
final File file = new File(getChapterFileName(chaptId));
// final File file = new File(getChapterFileName(chaptId));
Log.d(TAG, String.format("prepare book to open chapter %s ,file is exist ? %s",chaptId,file.exists() ) );
if (!file.exists()) {
Log.d(TAG, String.format("prepare book to open chapter %s ,file is not download",chaptId ) );
mStatus = Status.OPENING;
if( !NetUtil.isNetworkConnected()){ //TODO: 500错误处理
mStatus = Status.NETWORKFAILE;
@ -218,7 +227,14 @@ public class PageFactory implements ChangeSource{
drawStatus(mBookPageWidget.getNextPage());
return chaptPages;
}
if(getChapters().size()==0 && mBookUtil.muluRetryCount>=3) {
Log.d(TAG, String.format("prepare book download mulu 失败,重试次数: %s ,thread.name %s",mBookUtil.muluRetryCount,Thread.currentThread().getName() ) );
mBookUtil.muluRetryCount=0;
mStatus = Status.FAIL;
drawStatus(mBookPageWidget.getCurPage());
drawStatus(mBookPageWidget.getNextPage());
return chaptPages;
}
// showProgressDialog();
final int chid = chaptId;
new Thread() {
@ -234,7 +250,7 @@ public class PageFactory implements ChangeSource{
@Override
public void run() {
int slepttime =0;
while( !file.exists() && slepttime <100){
while( !file.exists() && slepttime <100 && mBookUtil.muluRetryCount<3){
try {
sleep(50);
slepttime++;
@ -243,7 +259,12 @@ public class PageFactory implements ChangeSource{
}
}
Log.d(TAG, String.format("prepare book to download chapter %s ,slepted %s ,thread.name %s",chid,slepttime*50 ,Thread.currentThread().getName() ) );
mStatus = Status.FINISH;
if( mBookUtil.muluRetryCount>=3){
mStatus = Status.FAIL;
}
//notice file done
handler.sendEmptyMessage(1);
@ -261,17 +282,17 @@ public class PageFactory implements ChangeSource{
}
}else if(getChapters().size()==0) {
}/*else if(getChapters().size()==0) {
mStatus = Status.FAIL;
drawStatus(mBookPageWidget.getCurPage());
drawStatus(mBookPageWidget.getNextPage());
return chaptPages;
}
}*/
chaptPages.clear();
chaptId = mChapters!=null && mChapters.size() <= chaptId ? 1 : chaptId;
// chaptId = mChapters!=null && mChapters.size() <= chaptId ? 1 : chaptId;
Log.d(TAG, String.format("changing Source prepare book to open chapter %s ",chaptId ) );
char[] chars = mBookUtil.chaptChars(chaptId);
@ -408,6 +429,9 @@ public static boolean busy(){
marginWidth = mContext.getResources().getDimension(R.dimen.readingMarginWidth);
marginHeight = mContext.getResources().getDimension(R.dimen.readingMarginHeight);
// Log.d(TAG, "PageFactory: marginHeight +" +marginHeight);
// marginHeight = CommonUtil. getStatusBarHeight(mContext);
Log.d(TAG, "PageFactory: marginHeight " +marginHeight);
statusMarginBottom = mContext.getResources().getDimension(R.dimen.reading_status_margin_bottom);
lineSpace = context.getResources().getDimension(R.dimen.reading_line_spacing);
paragraphSpace = context.getResources().getDimension(R.dimen.reading_paragraph_spacing);
@ -496,7 +520,7 @@ public static boolean busy(){
status = "正在拼命加载...";
break;
case FAIL:
status = "打开书本失败!";
status = "读取错误,请稍后重试";
break;
case NETWORKFAILE:
status = "请开启网络";
@ -525,6 +549,7 @@ public static boolean busy(){
}
public void onDraw(Bitmap bitmap,List<String> m_lines,Boolean updateChapter) {
mAd.hideSystemUI();
if(m_lines.size()==0){
return;
}
@ -550,11 +575,11 @@ public static boolean busy(){
// * column won't be updated.
// mBook.save();
/* Novel nv = LitePal.find(Novel.class,mBook.getId());
/*Novel nv = LitePal.find(Novel.class,mBook.getId());
Log.d(TAG,String.format("prepare book saved lastchapt %s,lastpos %s, db lastchapt %s last pos %s",
currentChapter,currentPage.getBegin(),nv.getLastReadChapt(),nv.getLastReadPos()));*/
currentChapter,currentPage.getBegin(),nv.getLastReadChapt(),nv.getLastReadPos()));
*/
}
/*
@ -582,25 +607,30 @@ public static boolean busy(){
if (m_lines.size() > 0) {
float y = marginHeight;
String lastLine ="";
for (String strLine : m_lines) {
// if(strLine.endsWith("\n")) {
// if(strLine.charAt(strLine.length()-1) == ('\n' )) {
// Log.d("TAG", strLine);
// Log.d("TAG","最后字符 。。。" +strLine.charAt(strLine.length()-1) + "");
// Log.d(TAG, strLine);
// Log.d(TAG,"最后字符 。。。" +strLine.charAt(strLine.length()-1) + "");
lastLine =strLine;
if(( strLine.charAt(strLine.length()-1) + "" ).equals("\n")){
strLine =strLine.replace("\n","");
y += space;
space =m_fontSize + paragraphSpace;
Log.d("TAG",String.format("开始新段落 %s, y plus is %s" ,strLine, m_fontSize + paragraphSpace));
Log.d( TAG ,String.format("开始新段落 %s, y plus is %s" ,strLine, m_fontSize + paragraphSpace));
}else{
y += space;
space =m_fontSize + lineSpace;
Log.d("TAG",String.format("%s,y plus is %s" ,strLine, m_fontSize + lineSpace));
Log.d(TAG,String.format("%s,y plus is %s" ,strLine, m_fontSize + lineSpace));
}
c.drawText(strLine, measureMarginWidth, y, mPaint);
// word.append(strLine);
}
Log.d(TAG,String.format("getNavigationBarSize mHeight is %s ,last line height %s, power %s, %s",
mHeight,y,mHeight - CommonUtil.convertDpToPixel(mContext,10) + mBorderWidth - statusMarginBottom, lastLine));
float adHeight = mHeight -y - space -marginHeight-statusMarginBottom;
float adY =y +space;
showAd((int)adHeight,(int)adY);
@ -698,6 +728,7 @@ public static boolean busy(){
}
}
Log.d(TAG, "prepare book prePage: to open prepage: ");
cancelPage = currentPage;
onDraw(mBookPageWidget.getCurPage(),currentPage.getLines(),true);
currentPage = getPrePage();
@ -728,7 +759,7 @@ public static boolean busy(){
}
}
Log.d(TAG, "prepare book nextPage: to open next page: ");
cancelPage = currentPage;
onDraw(mBookPageWidget.getCurPage(),currentPage.getLines(),true);
prePage = currentPage;
@ -758,12 +789,12 @@ public static boolean busy(){
NetUtil.cancelRequest(mBook.getNovelId() );
}catch (Exception e)
{
Log.e(TAG, "prepare Book: error on canceling request "+e.getMessage());
Log.e(TAG, "prepare book: error on canceling request "+e.getMessage());
e.printStackTrace();
}
}
// Log.d(TAG, "prepareBook: .start prepare book " + book.getName());
Log.d(TAG, "prepare book: .start prepare book " + book.getName());
this.mBook = book ;
mBookUtil = new BookUtil();
//this.mBookUtil.setContext(context);
@ -820,9 +851,10 @@ public static boolean busy(){
return;
}
if (result) {
Log.d(TAG, String.format("prepare book ready, to open chapter %s ",chapter ) );
// m_mbBufLen = mBookUtil.getBookLen();
mBookUtil.setChapterNo((int)chapter);
Log.d(TAG, String.format("prepare book ready, to open chapter, loadCurrentChapt %s ",chapter ) );
currentChaptPages = loadCurrentChapt((int)chapter);
currentPage = getPageForBegin(begin) ;// currentChaptPages.get(0);
// currentPage = getPageForBegin(begin);
@ -856,7 +888,7 @@ public static boolean busy(){
begin = params[1];
currentChapter = (int) chapter;
try {
mBookUtil.openBook(mBook);
mBookUtil.openBook(mBook,chapter);
} catch (Exception e) {
e.printStackTrace();
return false;
@ -1152,12 +1184,14 @@ public static boolean busy(){
//绘制当前页面
public void currentPage(Boolean updateChapter){
Log.d(TAG, "prepare book currentPage: to open current Page : ");
onDraw(mBookPageWidget.getCurPage(),currentPage.getLines(),updateChapter);
onDraw(mBookPageWidget.getNextPage(),currentPage.getLines(),updateChapter);
}
//更新电量
public void updateBattery(int mLevel){
mAd.hideSystemUI();
if (currentPage != null && mBookPageWidget != null && !mBookPageWidget.isRunning()) {
if (level != mLevel) {
level = mLevel;
@ -1167,6 +1201,7 @@ public static boolean busy(){
}
public void updateTime(){
mAd.hideSystemUI();
if (currentPage != null && mBookPageWidget != null && !mBookPageWidget.isRunning()) {
String mDate = sdf.format(new java.util.Date());
if (date != mDate) {
@ -1368,6 +1403,10 @@ public static boolean busy(){
//是否可以翻页
public boolean isReady() {
return mStatus==Status.FINISH;
}
//设置页面背景
public void setBgBitmap(Bitmap BG) {

View File

@ -158,7 +158,8 @@ public class PageWidget extends View {
if (!isMove) {
isMove = Math.abs(downX - x) > slop || Math.abs(downY - y) > slop;
}
Log.d(TAG, String.format("onTouchEvent:ACTION_MOVE isMove %s, isbusy %s",isMove,PageFactory.busy()));
if(!PageFactory.busy())
if (isMove){
isMove = true;
if (moveX == 0 && moveY ==0) {
@ -218,10 +219,11 @@ public class PageWidget extends View {
}
}else if (event.getAction() == MotionEvent.ACTION_UP){
Log.e(TAG,"ACTION_UP");
if (!isMove){
Log.d(TAG, String.format("onTouchEvent:ACTION_UP isMove %s, isbusy %s",isMove,PageFactory.busy()));
if (!isMove || PageFactory.busy()){
cancelPage = false;
//是否点击了中间
if (downX > mScreenWidth / 3 && downX < mScreenWidth * 2 / 3 && downY > mScreenHeight / 3 && downY < mScreenHeight * 2 / 3){
if (downX > mScreenWidth / 3 && downX < mScreenWidth * 2 / 3 && downY > mScreenHeight / 3 && downY < mScreenHeight * 2 / 3 ){
if (mTouchListener != null){
mTouchListener.center();
}
@ -231,7 +233,9 @@ public class PageWidget extends View {
// mTouch.x = 0.1f;
// mTouch.y = 0.1f;
return true;
}else if (x < mScreenWidth / 2){
}
else if (x < mScreenWidth / 2){
isNext = false;
}else{
isNext = true;
@ -252,18 +256,21 @@ public class PageWidget extends View {
}
}
if (cancelPage && mTouchListener != null){
mTouchListener.cancel();
}
if(!PageFactory.busy()) {
if (cancelPage && mTouchListener != null) {
mTouchListener.cancel();
}
Log.e(TAG,"isNext:" + isNext);
if (!noNext) {
isRuning = true;
mAnimationProvider.startAnimation(mScroller);
this.postInvalidate();
Log.e(TAG, "isNext:" + isNext);
if (!noNext) {
isRuning = true;
mAnimationProvider.startAnimation(mScroller);
this.postInvalidate();
}
}
}
return true;
}

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M6,7h2.5L5,3.5 1.5,7L4,7v10L1.5,17L5,20.5 8.5,17L6,17L6,7zM10,5v2h12L22,5L10,5zM10,19h12v-2L10,17v2zM10,13h12v-2L10,11v2z"/>
</vector>

View File

@ -1,23 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BookActivity"
>
<android.support.design.widget.CoordinatorLayout
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:clipToPadding="false"
android:fitsSystemWindows="true"
android:layout_weight="1"
>
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
@ -31,11 +30,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:collapsedTitleGravity="center"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom"
app:expandedTitleTextAppearance="@style/TitleText"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
@ -51,29 +50,27 @@
android:id="@+id/imageViewHead"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
/>
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_gravity="center"
android:layout_marginLeft="30dp"
android:layout_marginRight="20dp"
android:gravity="bottom"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
style="@style/NovelImage"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_weight="0"
android:gravity="left"
android:scaleType="fitXY"
android:layout_height="100dp"
android:layout_width="80dp"
/>
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="match_parent"
@ -88,48 +85,46 @@
style="@style/TextViewNovelTitle.horizon.bold"
android:text=" "
/>
/>
<TextView
android:id="@+id/desc"
style="@style/TextViewNovelDesc.head"
android:text=" "
android:visibility="gone"
/>
android:visibility="gone" />
<TextView
android:id="@+id/author"
style="@style/TextViewNovelAuthor"
android:layout_marginTop="3dp"
android:layout_marginBottom="1dp"
android:text=""
/>
android:text="" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:orientation="horizontal">
<TextView
android:id="@+id/category"
style="@style/TextViewNovelType"
android:text=""
/>
android:text="" />
<TextView
android:id="@+id/smallCate"
style="@style/TextViewNovelType"
android:text=""
/>
android:text="" />
</LinearLayout>
<TextView
android:layout_marginTop="2dp"
android:id="@+id/progress"
style="@style/TextViewNovelAuthor"
android:textColor="@color/common_google_signin_btn_text_light"
android:layout_marginTop="2dp"
android:text=""
/>
android:textColor="@color/common_google_signin_btn_text_light" />
</LinearLayout>
@ -144,64 +139,65 @@
android:layout_width="match_parent"
android:layout_height="40dp"
android:minHeight="40dp"
app:layout_collapseMode="pin"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin"
app:popupTheme="@style/ToolBarTheme.PopupOverlay" >
app:popupTheme="@style/ToolBarTheme.PopupOverlay">
<Button android:id="@+id/btnFistPage"
style="@style/buttonCates"
<Button
android:id="@+id/btnFistPage"
style="@style/buttonCates"
android:layout_width="wrap_content"
android:textColor="@color/white"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="10dp"
android:text="首页" />
android:text="首页"
android:textColor="@color/white" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_book" />
</android.support.design.widget.CoordinatorLayout>
<include layout="@layout/content_book" />
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/botoomNavi"
android:orientation="horizontal"
android:layout_weight="0"
android:layout_gravity="bottom"
>
android:layout_weight="0"
android:orientation="horizontal">
<Button
android:id="@+id/btnShelf"
android:text="加入书架"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableTop="@drawable/ic_mood_black_24dp"
android:layout_weight="1"
android:background="@drawable/item_selector"
/>
android:drawableTop="@drawable/ic_mood_black_24dp"
android:text="加入书架" />
<Button
android:id="@+id/btnRead"
android:text="立即阅读"
android:textColor="@color/white"
android:textSize="15sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:background="@drawable/item_selector_red"
/>
android:text="立即阅读"
android:textColor="@color/white"
android:textSize="15sp" />
<Button
android:id="@+id/btnCacheBook"
android:text="全本缓存"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableTop="@drawable/ic_mood_black_24dp"
android:layout_weight="1"
android:background="@drawable/item_selector"
/>
android:drawableTop="@drawable/ic_mood_black_24dp"
android:text="全本缓存" />
</LinearLayout>

View File

@ -66,7 +66,7 @@
</LinearLayout>
<LinearLayout style="@style/llGraySplit" />
<LinearLayout style="@style/llGraySplit.2dp" />
<LinearLayout
@ -123,7 +123,7 @@
<LinearLayout style="@style/llGraySplit" />
<LinearLayout style="@style/llGraySplit.2dp" />
<LinearLayout
android:layout_width="match_parent"
@ -162,8 +162,8 @@
android:orientation="horizontal">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center"
android:layout_weight="0"
android:layout_marginRight="5dp"
@ -181,7 +181,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
android:orientation="vertical"
android:layout_marginLeft="5dp"
>
<TextView
android:id="@+id/txtLatestUpdate"
style="@style/TextViewDesc.small"
@ -191,6 +193,7 @@
/>
<TextView
android:layout_marginTop="2dp"
android:id="@+id/txtLatestCate"
style="@style/TextViewDesc"
android:layout_width="wrap_content"
@ -203,7 +206,7 @@
</LinearLayout>
</LinearLayout>
<LinearLayout style="@style/llGraySplit" />
<LinearLayout style="@style/llGraySplit.2dp" />
<!--
<LinearLayout

View File

@ -4,6 +4,31 @@
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<!--
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tvTitle"
style="@style/TitleText"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageButton
android:id="@+id/btnSort"
android:layout_weight="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_format_line_spacing_black_24dp"
style="@style/buttonCates"/>
</LinearLayout>-->
<TextView
android:id="@+id/tvChapts"
style="@style/TextViewNovelTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/lv_catalogue"

View File

@ -1,11 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
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"
android:orientation="vertical"
android:layout_marginBottom="-2dp"
android:id="@+id/swipeLayout" >
<!--
<com.novelbook.android.adapter.JudgeNestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.ixiaow.multilayout.MultiLayout
android:id="@+id/topic_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tab_indicator_color="@color/colorAccent"
app:tab_indicator_height="1dp"
app:tab_indicator_radius="1dp"
app:tab_text_size="14sp"
app:tl_indicator_style="BLOCK"
app:tl_textUnselectColor="@color/darkgray" />
</com.novelbook.android.adapter.JudgeNestedScrollView>
-->
<!-- TODO: Update blank fragment layout -->
<android.support.v7.widget.RecyclerView
android:id="@+id/rvBangdan"

View File

@ -8,12 +8,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvBooklist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:nestedScrollingEnabled="true"
android:paddingTop="5dp"
/>

View File

@ -1,128 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragments.Fragment_paihang">
android:clipToPadding="false"
android:fitsSystemWindows="true">
<!-- TODO: Update blank fragment layout -->
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/swipeLayout" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.widget.NestedScrollView
android:id="@+id/n_scroll_view"
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:layout_height="@dimen/app_bar_height_250"
android:fitsSystemWindows="true"
<LinearLayout
android:theme="@style/ToolBarTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
android:fitsSystemWindows="true"
app:collapsedTitleGravity="center"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom"
app:expandedTitleTextAppearance="@style/TitleText"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<LinearLayout
android:id="@+id/llTabs"
<LinearLayout
android:id="@+id/llTabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white"
android:paddingBottom="16dp"
android:layout_marginTop="40dp"
app:layout_collapseMode="pin"
app:layout_collapseParallaxMultiplier="0.7">
<LinearLayout style="@style/llGraySplit.2dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.ixiaow.multilayout.MultiLayout
android:id="@+id/topic_layout1"
android:layout_width="90dp"
android:layout_height="wrap_content"
app:tab_indicator_color="@color/colorAccent"
app:tab_indicator_height="0dp"
app:tab_indicator_radius="0dp"
app:tab_text_size="15sp"
app:tab_text_width="40dp"
android:layout_weight="0"
app:tl_textUnselectColor="@color/darkgray" />
<TextView
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout style="@style/llGraySplit.2dp" />
<com.ixiaow.multilayout.MultiLayout
android:id="@+id/topic_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
app:tab_indicator_color="@color/colorAccent"
app:tab_indicator_height="0dp"
app:tab_indicator_radius="0dp"
app:tab_text_size="14sp"
app:tl_indicator_style="BLOCK"
>
app:tl_textUnselectColor="@color/darkgray" />
<com.flyco.tablayout.CommonTabLayout
android:id="@+id/tab_layout1"
<LinearLayout style="@style/llGraySplit.2dp" />
<com.ixiaow.multilayout.MultiLayout
android:id="@+id/topic_layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tab_indicator_color="@color/colorAccent"
app:tab_indicator_height="0dp"
app:tab_indicator_radius="0dp"
app:tab_text_size="15sp"
app:tab_text_width="60dp"
app:tl_textUnselectColor="@color/darkgray" />
<LinearLayout style="@style/llGraySplit.2dp" />
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:minHeight="5dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin"
app:popupTheme="@style/ToolBarTheme.PopupOverlay">
<TextView
android:id="@+id/tvHint"
android:layout_width="match_parent"
android:layout_height="40dp"
app:tl_iconVisible="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:tl_indicator_margin_left="2dp"
app:tl_indicator_margin_right="2dp"
app:tl_indicator_style="BLOCK"
app:tl_textSelectColor="@color/white"
app:tl_textUnselectColor="@color/darkgray"
app:tl_textsize="14sp"
app:tl_indicator_color="@color/red"
app:tl_tab_space_equal ="false"
app:tl_indicator_width="@dimen/tabBlock_width"
android:background="@color/white"
android:gravity="center"
android:text="selected texts"
android:textColor="@color/red"
android:textSize="15sp"
/>
<com.flyco.tablayout.CommonTabLayout
android:id="@+id/tab_layout2"
android:layout_width="match_parent"
android:layout_height="40dp"
app:tl_iconVisible="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:tl_indicator_margin_left="2dp"
app:tl_indicator_margin_right="2dp"
app:tl_indicator_style="BLOCK"
app:tl_textSelectColor="@color/white"
app:tl_textUnselectColor="@color/darkgray"
app:tl_textsize="14sp"
app:tl_indicator_color="@color/red"
app:tl_tab_space_equal ="true"
app:tl_indicator_width="@dimen/tabBlock_width"
</android.support.v7.widget.Toolbar>
/>
<com.flyco.tablayout.CommonTabLayout
android:id="@+id/tab_layout3"
android:layout_width="match_parent"
android:layout_height="40dp"
app:tl_iconVisible="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:tl_indicator_margin_left="2dp"
app:tl_indicator_margin_right="2dp"
app:tl_indicator_style="BLOCK"
app:tl_textSelectColor="@color/white"
app:tl_textUnselectColor="@color/darkgray"
app:tl_textsize="14sp"
app:tl_indicator_color="@color/red"
app:tl_tab_space_equal ="false"
app:tl_indicator_width="@dimen/tabBlock_width"/>
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!-- data begin -->
<android.support.v7.widget.RecyclerView
android:id="@+id/rvPaihang"
android:divider="#ffff0000"
android:dividerHeight="10dp"
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:paddingBottom="50dp"
/>
android:layout_weight="1"
android:layout_below ="@+id/app_bar"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:orientation="vertical">
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<TextView
android:id="@+id/tvHint"
android:gravity="center"
android:text="selected texts"
android:textColor="@color/red"
<android.support.v7.widget.RecyclerView
android:id="@+id/rvPaihang"
android:layout_width="match_parent"
android:textSize="15sp"
android:visibility="gone"
android:background="@color/white"
android:layout_height="40dp" />
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
android:layout_height="match_parent"
android:divider="#ffff0000"
android:dividerHeight="10dp"
android:nestedScrollingEnabled="true"
android:paddingBottom="50dp" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="1300dp"
/>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>

View File

@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/llout"
>
@ -105,7 +106,7 @@
android:orientation="vertical"
android:layout_width="60dp"
android:layout_height="70dp"
android:id="@+id/llBookdetail"
android:gravity="center"
android:background="@drawable/item_selector"
android:clickable="true"
@ -119,6 +120,7 @@
android:src="@drawable/googleg_standard_color_18" />
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_below ="@+id/app_bar"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvPaihang"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#ffff0000"
android:dividerHeight="10dp"
android:nestedScrollingEnabled="true"
android:paddingBottom="50dp" />
<TextView
android:id="@+id/tvHint"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/white"
android:gravity="center"
android:text="selected texts"
android:textColor="@color/red"
android:textSize="15sp"
android:visibility="gone" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>

View File

@ -16,7 +16,18 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
app:popupTheme="@style/AppTheme.PopupOverlay">
<ImageButton
android:id="@+id/btnSort"
android:layout_weight="0"
android:layout_gravity ="right|center_vertical"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_format_line_spacing_black_24dp"
style="@style/buttonCates"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<!--<ListView-->

View File

@ -10,6 +10,19 @@
android:singleLine="true"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_weight="1"
/>
<TextView
android:id="@+id/catalogue_cache"
style="@style/TextViewNovelDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="0"
android:gravity="right|center_vertical"
android:text="@string/cached"
android:layout_marginLeft="10dp"
/>
</LinearLayout>

View File

@ -47,6 +47,7 @@
<dimen name="botoomNavi">42dp</dimen>
<dimen name="_10dp">10dp</dimen>
<dimen name="toolbarHeight">40dp</dimen>
<dimen name="app_bar_height_250">240dp</dimen>
<!-- Default screen margins, per the Android Design guidelines. -->

View File

@ -187,6 +187,7 @@
<string name="noRecord">没有数据</string>
<string name="title_Activity_ChgSource">换源</string>
<string name="_00_00">00.00%</string>
<string name="cached">已缓存</string>
<string-array name="voicer_cloud_entries">
<item>小燕—女青、中英、普通话</item>

View File

@ -205,6 +205,7 @@
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.3@jar" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:viewpager:28.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.google.android.gms:play-services-basement:16.0.1@aar" level="project" />
<orderEntry type="library" name="Gradle: com.github.ixiaow:multilayout:1.0.0@aar" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-integration:1.3@jar" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-library:1.3@jar" level="project" />
<orderEntry type="library" name="Gradle: android.arch.lifecycle:common:1.1.1@jar" level="project" />