add pull refresh

fix bugs
This commit is contained in:
mwang 2019-04-16 23:11:00 +08:00
parent 5fcb00da5e
commit bcd0d91ffb
26 changed files with 624 additions and 193 deletions

View File

@ -39,6 +39,9 @@ public abstract class Activity_base extends AppCompatActivity {
protected Gson gson = new Gson(); protected Gson gson = new Gson();
@Nullable @Nullable
@BindView(R.id.toolbar)
Toolbar toolbar;
@Nullable
@BindView(R.id.recycleViewBookList) @BindView(R.id.recycleViewBookList)
RecyclerView rvshudan; RecyclerView rvshudan;
void showBook(String bookName) { //show paihangbang activity void showBook(String bookName) { //show paihangbang activity
@ -66,8 +69,7 @@ public abstract class Activity_base extends AppCompatActivity {
initData(); initData();
initViews(); initViews();
} }
@BindView(R.id.toolbar)
Toolbar toolbar;
protected void setupToolbar(){ protected void setupToolbar(){
// Toolbar toolbar = findViewById(R.id.toolbar); // Toolbar toolbar = findViewById(R.id.toolbar);
// setSupportActionBar(toolbar); // setSupportActionBar(toolbar);

View File

@ -1,9 +1,13 @@
package com.novelbook.android; package com.novelbook.android;
import android.content.Intent;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import com.novelbook.android.Fragments.Fragment_booklist; import com.novelbook.android.Fragments.Fragment_booklist;
@ -34,6 +38,7 @@ public class Activity_cate_books extends Activity_base {
@Override @Override
protected void initViews() { protected void initViews() {
creatToolbar();
initTabs(); initTabs();
} }
@ -90,5 +95,29 @@ public class Activity_cate_books extends Activity_base {
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.booksearch, menu);
return true;
}
private void creatToolbar() {
setSupportActionBar(toolbar);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int menuItemId = item.getItemId();
if(menuItemId==R.id.menuSearch){
Intent intent = new Intent(Activity_cate_books.this, Activity_Search.class);
startActivity(intent);
}
return true;
}
});
}
} }

View File

@ -2,11 +2,13 @@ package com.novelbook.android;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
@ -69,7 +71,7 @@ public static String TAG ="com.novelbook.android.paihangbang";
@Override @Override
protected void initData() { protected void initData() {
creatToolbar();
} }
@ -115,8 +117,31 @@ public static String TAG ="com.novelbook.android.paihangbang";
// tabLayout.setViewPager(mViewpager, mTitle, activity, mFragments); // tabLayout.setViewPager(mViewpager, mTitle, activity, mFragments);
mViewpager.setCurrentItem(0); mViewpager.setCurrentItem(0);
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.booksearch, menu);
return true;
}
private void creatToolbar() {
setSupportActionBar(toolbar);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int menuItemId = item.getItemId();
if(menuItemId==R.id.menuSearch){
Intent intent = new Intent(Activity_paihangbang.this, Activity_Search.class);
startActivity(intent);
}
return true;
}
});
}
} }

View File

@ -132,6 +132,11 @@ public class BookActivity extends Activity_base {
TextView tvTonglei; TextView tvTonglei;
@BindView(R.id.txtLatestUpdate) @BindView(R.id.txtLatestUpdate)
TextView tvLastUpdate; TextView tvLastUpdate;
@BindView(R.id.progress)
TextView tvProgress;
@BindView(R.id.smallCate)
TextView tvSmallcate;
public Intent getSvrIntent(){ public Intent getSvrIntent(){
@ -216,6 +221,7 @@ public class BookActivity extends Activity_base {
} }
rvBooklistAuthor.setVisibility(View.VISIBLE); rvBooklistAuthor.setVisibility(View.VISIBLE);
mAdapterAuthor = getBookListAdapter(mDataAuthor,R.layout.recycle_list_item_horizon); mAdapterAuthor = getBookListAdapter(mDataAuthor,R.layout.recycle_list_item_horizon);
rvBooklistAuthor.setLayoutManager(new LinearLayoutManager(this)); rvBooklistAuthor.setLayoutManager(new LinearLayoutManager(this));
rvBooklistAuthor.setAdapter(mAdapterAuthor); rvBooklistAuthor.setAdapter(mAdapterAuthor);
@ -231,6 +237,7 @@ public class BookActivity extends Activity_base {
} }
rvBooklistRelated.setVisibility(View.VISIBLE); rvBooklistRelated.setVisibility(View.VISIBLE);
mAdapterRelated = getBookListAdapter(mDataRelated,R.layout.recycle_list_item); mAdapterRelated = getBookListAdapter(mDataRelated,R.layout.recycle_list_item);
rvBooklistRelated.setLayoutManager(new GridLayoutManager(this, Constants.NOVEL_SPAN_CNT)); rvBooklistRelated.setLayoutManager(new GridLayoutManager(this, Constants.NOVEL_SPAN_CNT));
rvBooklistRelated.setAdapter(mAdapterRelated); rvBooklistRelated.setAdapter(mAdapterRelated);
@ -243,9 +250,11 @@ public class BookActivity extends Activity_base {
//this.setTitle(mNovel.getName());//why not apply //this.setTitle(mNovel.getName());//why not apply
this.txtAuth.setText(mNovel.getAuthor()); this.txtAuth.setText(mNovel.getAuthor());
this.txtCategory.setText(mNovel.getNovelType()); this.txtCategory.setText(mNovel.getNovelType());
this.txtDesc.setText(mNovel.getDesc ()); // this.txtDesc.setText(mNovel.getDesc ());
this.txtTitle.setText(mNovel.getName()); this.txtTitle.setText(mNovel.getName());
this.txtDesc2.setFullString(mNovel.getDesc ()); this.txtDesc2.setFullString(mNovel.getDesc ());
this.tvSmallcate.setText(mNovel.getSmallNovelType());
this.tvProgress.setText(mNovel.getProgress());
// txtDesc2.setCollapsedLines(2); // txtDesc2.setCollapsedLines(2);
// txtDesc2.setSuffixColor(R.color.colorPrimary); // txtDesc2.setSuffixColor(R.color.colorPrimary);

View File

@ -17,6 +17,7 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -72,7 +73,7 @@ import butterknife.ButterKnife;
public abstract class BasicFragment extends Fragment { public abstract class BasicFragment extends Fragment {
public static String TAG = "need to be replaced"; public static String TAG = "need to be replaced";
private View rootView; protected View rootView;
protected abstract int getLayoutRes(); protected abstract int getLayoutRes();
protected abstract void initData(); protected abstract void initData();
protected abstract void fillData(); protected abstract void fillData();
@ -82,7 +83,9 @@ public abstract class BasicFragment extends Fragment {
// protected MyImageLoader imgloader = new MyImageLoader(); // protected MyImageLoader imgloader = new MyImageLoader();
// Main2Activity activity; // Main2Activity activity;
FragmentActivity activity; FragmentActivity activity;
@Nullable
@BindView(R.id.swipeLayout)
SwipeRefreshLayout mSwipeRefresh;
public BasicFragment() { public BasicFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -114,6 +117,7 @@ public abstract class BasicFragment extends Fragment {
initListener(); initListener();
initData(); initData();
initViews(); initViews();
initSwipeRefreshLayout();
return view; return view;
// Inflate the layout for this fragment // Inflate the layout for this fragment
@ -202,7 +206,8 @@ public abstract class BasicFragment extends Fragment {
}else { }else {
nv.save(); nv.save();
} }
Log.d(TAG, String.format("prepare book %s 开始prepare.",nv.getName()) );
Log.d(TAG, String.format("prepare book %s ,lastchapt %s, last pos %s ,开始prepare.",nv.getName(),nv.getLastReadChapt(),nv.getLastReadPos()) );
// final Novel novel = nv; // final Novel novel = nv;
/* new Thread(){ /* new Thread(){
@Override @Override
@ -230,11 +235,37 @@ public abstract class BasicFragment extends Fragment {
} }
void showProgressDialog(boolean flag,String msg){ void showProgressDialog(boolean flag,String msg){
((Activity_base) getActivity()).showProgressDialog(flag,msg); if(mSwipeRefresh!=null && !mSwipeRefresh.isRefreshing()) {
((Activity_base) getActivity()).showProgressDialog(flag,msg);
}
} }
void hideProgress(){ void hideProgress(){
if(mSwipeRefresh!=null && mSwipeRefresh.isRefreshing()) {
mSwipeRefresh.setRefreshing(false);
}
((Activity_base) getActivity()).hideProgress(); ((Activity_base) getActivity()).hideProgress();
} }
void initSwipeRefreshLayout(){
if(mSwipeRefresh==null){return;}
mSwipeRefresh.setColorSchemeResources(R.color.colorPrimary,R.color.colorPrimaryDark);
mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// 开始刷新设置当前为刷新状态
//swipeRefreshLayout.setRefreshing(true);
// 这里是主线程
// 一些比较耗时的操作比如联网获取数据需要放到子线程去执行
initData();
// TODO 获取数据
}
});
}
void openBook(Novel book, BookListAdapter mAdapter) { void openBook(Novel book, BookListAdapter mAdapter) {
//从新从数据库抓取该书的最新阅读进度 //从新从数据库抓取该书的最新阅读进度

View File

@ -1,10 +1,13 @@
package com.novelbook.android.Fragments; package com.novelbook.android.Fragments;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@ -12,7 +15,10 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.novelbook.android.Activity_Search;
import com.novelbook.android.Main2Activity;
import com.novelbook.android.R; import com.novelbook.android.R;
import com.novelbook.android.activity_cates;
import com.novelbook.android.bean.NovelBlock; import com.novelbook.android.bean.NovelBlock;
import com.novelbook.android.db.Novel; import com.novelbook.android.db.Novel;
import com.novelbook.android.netsubscribe.BookSubscribe; import com.novelbook.android.netsubscribe.BookSubscribe;
@ -42,6 +48,7 @@ public class Fragment_booklist extends BasicFragment {
private BookListAdapter mAdapter; private BookListAdapter mAdapter;
// private BookListAdapter mAdapter; // private BookListAdapter mAdapter;
private List<Novel> mData;; private List<Novel> mData;;
private List<Novel> mMoreData;
private String cate; private String cate;
private int progress; private int progress;
private String keyWord; private String keyWord;
@ -52,7 +59,7 @@ public class Fragment_booklist extends BasicFragment {
private int totalCount; private int totalCount;
private int pageCount; private int pageCount;
@BindView(R.id.rvBooklist) @BindView(R.id.rvBooklist)
RecyclerView rvBooklist; RecyclerView mRecyclerView;
public Fragment_booklist() { public Fragment_booklist() {
// Required empty public constructor // Required empty public constructor
@ -101,30 +108,40 @@ public class Fragment_booklist extends BasicFragment {
@Override @Override
protected void fillData() { protected void fillData() {
if(mData==null){ if(mData==null) {
return; 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();
}
});
mRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mRecyclerView.setAdapter(mAdapter);
} }
mAdapter = new BookListAdapter(activity, mData, R.layout.recycle_list_item_horizon, new OnItemClickListener() { if(mMoreData!=null) {
if(mMoreData.size()>0) {
@Override pageNo++;
public void onItemClick(View view, int position) {
showBookDetail(mData.get(position) );
// openBook(mData.get(position),mAdapter);
} }
int status = pageCount > pageNo ? BookListAdapter.PULLUP_LOAD_MORE : BookListAdapter.NO_LOAD_MORE;
@Override mAdapter.AddFooterItem(mMoreData);
public void onItemLongClick(View view, int position) { mAdapter.changeMoreStatus(status);
// 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();
}
});
initialBookList();
} }
@Override @Override
@ -137,14 +154,21 @@ public class Fragment_booklist extends BasicFragment {
@Override @Override
public void initData() { public void initData() {
/* if(mAdapter!=null){
mAdapter.changeMoreStatus(BookListAdapter.LOADING_MORE);
}*/
mMoreData =null;
OnSuccessAndFaultListener successAndFaultListener = new OnSuccessAndFaultListener() { OnSuccessAndFaultListener successAndFaultListener = new OnSuccessAndFaultListener() {
@Override @Override
public void onSuccess(String result) { public void onSuccess(String result) {
// mFirstPage= gson.fromJson(result, FirstPage.class); // mFirstPage= gson.fromJson(result, FirstPage.class);
try { try {
JSONObject jsonObject = new JSONObject(result);
pageCount = jsonObject.getInt("pageCount");
mMoreData = GsonUtil. parserJsonArray(jsonObject,Constants.BLOCK_TITLE_NOVELS);
mData = GsonUtil. parserJsonArray(result,Constants.BLOCK_TITLE_NOVELS);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -173,8 +197,9 @@ public class Fragment_booklist extends BasicFragment {
try { try {
JSONObject jsonObject = new JSONObject(result); JSONObject jsonObject = new JSONObject(result);
String resultstr = jsonObject.getString("rank") ; String resultstr = jsonObject.getString("rank") ;
pageCount = jsonObject.getJSONObject("rank").getInt("pageCount");
mMoreData = GsonUtil. parserJsonArray(resultstr,Constants.BLOCK_TITLE_NOVELS);
mData = GsonUtil. parserJsonArray(resultstr,Constants.BLOCK_TITLE_NOVELS);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -209,22 +234,51 @@ public class Fragment_booklist extends BasicFragment {
} }
@Override @Override
public void initViews(){ public void initViews(){
initLoadMoreListener();
} }
//----------------绑定列表 //----------------绑定列表
void initialBookList() { void initialBookList() {
rvBooklist.setLayoutManager(new LinearLayoutManager(activity));
rvBooklist.setAdapter(mAdapter);
} }
@Override @Override
public void setFTag() { public void setFTag() {
} }
private void initLoadMoreListener() {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
int lastVisibleItem ;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//判断RecyclerView的状态 是空闲时同时是最后一个可见的ITEM时才加载
if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==mAdapter.getItemCount()){
//设置正在加载更多
mAdapter.changeMoreStatus(mAdapter.LOADING_MORE);
//改为网络请求
initData();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//最后一个可见的ITEM
lastVisibleItem=layoutManager.findLastVisibleItemPosition();
}
});
}
} }

View File

@ -6,6 +6,7 @@ import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -104,6 +105,8 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
@BindView(R.id.llBlock4) @BindView(R.id.llBlock4)
LinearLayout ll4; LinearLayout ll4;
private List<Fragment> mFragments; private List<Fragment> mFragments;
private ArrayList<View> mList; private ArrayList<View> mList;
// String[] mTitle; // String[] mTitle;
@ -144,7 +147,9 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
@Override @Override
public void initData() { public void initData() {
showProgressDialog(true, "正在加载"); showProgressDialog(true, "正在加载");
BookSubscribe.getFirstPage(Constants.SEX,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { BookSubscribe.getFirstPage(Constants.SEX,new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() {
@Override @Override
public void onSuccess(String result) { public void onSuccess(String result) {
@ -165,6 +170,7 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
//失败 //失败
Log.d(TAG, "error on get firstpage: " + errorMsg); Log.d(TAG, "error on get firstpage: " + errorMsg);
handler.sendEmptyMessage(1); handler.sendEmptyMessage(1);
} }
}, getActivity())); }, getActivity()));
@ -268,11 +274,11 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
@Override @Override
public void initViews() { public void initViews() {
} }
@Override @Override
public void setFTag() { public void setFTag() {
TAG = "com.novelbook.android.Fragments.Fragment_jingxuan"; TAG = "com.novelbook.android.Fragments.Fragment_jingxuan";
@ -382,7 +388,8 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
void initTuijianPagers() { void initTuijianPagers() {
if (mFragments == null || mFragments.size() == 0) { // mViewpagerTuijian =( MyViewPager) rootView.findViewById(R.id.viewpager_tuijian);
// if (mFragments == null || mFragments.size() == 0) {
// mTitle = new String[]{"精选", "榜单", "书单"}; // mTitle = new String[]{"精选", "榜单", "书单"};
mFragments = new ArrayList<>(); mFragments = new ArrayList<>();
NovelBlock block = mBlocks.get(1); NovelBlock block = mBlocks.get(1);
@ -399,7 +406,7 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
} }
Log.d(TAG, "initial fragments in tabs "); Log.d(TAG, "initial fragments in tabs ");
} // }
Log.d(TAG, "set viewPager adapter "); Log.d(TAG, "set viewPager adapter ");
// FragmentPagerAdapter mAdapter = new FragmentPagerAdapter(activity.getSupportFragmentManager()) { 第一次进入没问题再次进入ViewPager的fragment时里面内容就没了,数据丢失 https://blog.csdn.net/allan_bst/article/details/64920076 // FragmentPagerAdapter mAdapter = new FragmentPagerAdapter(activity.getSupportFragmentManager()) { 第一次进入没问题再次进入ViewPager的fragment时里面内容就没了,数据丢失 https://blog.csdn.net/allan_bst/article/details/64920076
@ -420,7 +427,10 @@ public class Fragment_jingxuan extends BasicFragment implements OnBannerListener
// return mTitle[position]; // return mTitle[position];
// } // }
}; };
cyclell.removeAllViews();
mViewpagerTuijian.setAdapter(mAdapter); mViewpagerTuijian.setAdapter(mAdapter);
mViewpagerTuijian.clearOnPageChangeListeners();
// mViewpagerTuijian.setOnPageChangeListener(new CyclePageIndicator(getContext(), cyclell, mFragments.size()));
mViewpagerTuijian.addOnPageChangeListener(new CyclePageIndicator(getContext(), cyclell, mFragments.size())); mViewpagerTuijian.addOnPageChangeListener(new CyclePageIndicator(getContext(), cyclell, mFragments.size()));
} }

View File

@ -45,8 +45,7 @@ public class Main2Activity extends Activity_base
implements NavigationView.OnNavigationItemSelectedListener{//} , BasicFragment.OnFragmentInteractionListener { implements NavigationView.OnNavigationItemSelectedListener{//} , BasicFragment.OnFragmentInteractionListener {
public MyApp app ; public MyApp app ;
public static String TAG ="com.novelbook.android.Main2Activity"; public static String TAG ="com.novelbook.android.Main2Activity";
@BindView(R.id.toolbar)
Toolbar toolbar;
// @BindView(R.id.fab) // @BindView(R.id.fab)
// FloatingActionButton fab ; // FloatingActionButton fab ;
@BindView(R.id.nav_view ) @BindView(R.id.nav_view )
@ -145,7 +144,7 @@ public class Main2Activity extends Activity_base
// toolbar.setTitle("Title");//设置主标题 // toolbar.setTitle("Title");//设置主标题
// setTitle("titleaa"); // setTitle("titleaa");
// toolbar.setSubtitle("Subtitle");//设置子标题 // toolbar.setSubtitle("Subtitle");//设置子标题
toolbar.inflateMenu(R.menu.main);//设置右上角的填充菜单
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
@ -170,7 +169,13 @@ public class Main2Activity extends Activity_base
} }
}); });
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void udateShelfZhengli() { private void udateShelfZhengli() {
switchShelfZhengli(true); switchShelfZhengli(true);
} }
@ -215,16 +220,7 @@ public class Main2Activity extends Activity_base
} }
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
// SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
// SearchView searchView = (SearchView) menu.findItem(R.id.menuSearch).getActionView();
// Assumes current activity is the searchable activity
// searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return true;
}
/* @Override /* @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {

View File

@ -216,12 +216,12 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
// mChapter = ( Chapter ) intent.getSerializableExtra(EXTRA_CHAPTER); // mChapter = ( Chapter ) intent.getSerializableExtra(EXTRA_CHAPTER);
bookpage.setPageMode(config.getPageMode()); bookpage.setPageMode(config.getPageMode());
pageFactory.setPageWidget(bookpage); pageFactory.setPageWidget(bookpage);
Log.d(TAG, String .format("prepare Book: set pagewidget %s" , book.getName()));
try { try {
hideSystemUI();
pageFactory.openBook(book,this); pageFactory.openBook(book,this);
hideSystemUI();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -594,7 +594,7 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
/** /**
* 隐藏菜单沉浸式阅读 * 隐藏菜单沉浸式阅读
*/ */
private void hideSystemUI() { public void hideSystemUI() {
// Set the IMMERSIVE flag. // Set the IMMERSIVE flag.
// Set the content to appear under the system bars so that the content // Set the content to appear under the system bars so that the content
// doesn't resize when the system bars hide and show. // doesn't resize when the system bars hide and show.
@ -933,4 +933,8 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis
llTopAd.setVisibility(View.VISIBLE); llTopAd.setVisibility(View.VISIBLE);
} }
} }
} }

View File

@ -12,6 +12,8 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
@ -56,7 +58,7 @@ public class activity_cates extends Activity_base {
private List<Cataloge> mCataloges; private List<Cataloge> mCataloges;
@Override @Override
protected void initViews() { protected void initViews() {
creatToolbar();
} }
@ -184,10 +186,32 @@ public class activity_cates extends Activity_base {
}, this)); }, this));
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.booksearch, menu);
return true;
}
private void creatToolbar() {
setSupportActionBar(toolbar);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int menuItemId = item.getItemId();
if(menuItemId==R.id.menuSearch){
Intent intent = new Intent(activity_cates.this, Activity_Search.class);
startActivity(intent);
}
return true;
}
});
}
void initReceyleView() { void initReceyleView() {

View File

@ -1,13 +1,18 @@
package com.novelbook.android.adapter; package com.novelbook.android.adapter;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.novelbook.android.BookActivity; import com.novelbook.android.BookActivity;
import com.novelbook.android.R;
import com.novelbook.android.db.Novel; import com.novelbook.android.db.Novel;
import com.novelbook.android.netutils.NetUtil; import com.novelbook.android.netutils.NetUtil;
@ -18,23 +23,46 @@ import com.novelbook.android.utils.OnItemClickListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class BookListAdapter extends RecyclerView.Adapter< MyViewHolder> { import butterknife.BindView;
import butterknife.ButterKnife;
public class BookListAdapter extends RecyclerView.Adapter< RecyclerView.ViewHolder> {
private final int EMPTY_VIEW = 1; private final int EMPTY_VIEW = 1;
private final int PROGRESS_VIEW = 2; private final int PROGRESS_VIEW = 2;
private final int IMAGE_VIEW = 3; private final int IMAGE_VIEW = 3;
private static final int TYPE_ITEM = 4;
private static final int TYPE_FOOTER = 5;
// private MyImageLoader loader = new MyImageLoader(); // private MyImageLoader loader = new MyImageLoader();
private Context context; private Context context;
private List<Novel> mDatas ; private List<Novel> mDatas ;
private OnItemClickListener mOnItemClickListener; private OnItemClickListener mOnItemClickListener;
private int listItemID; private int listItemID;
//private List<Novel> mBooks;
private LayoutInflater mInflater;
private List<Novel> mBooks; //上拉加载更多
public static final int PULLUP_LOAD_MORE = 0;
//正在加载中
public static final int LOADING_MORE = 1;
//没有加载更多 隐藏
public static final int NO_LOAD_MORE = 2;
//上拉加载更多状态-默认为0
private int mLoadMoreStatus = 0;
public BookListAdapter(Context context, List<Novel> datas) {
context = context;
mInflater = LayoutInflater.from(context);
mDatas = datas;
}
public BookListAdapter(Context context, List<Novel> mBooks, int listItemID, OnItemClickListener clickLitener) { public BookListAdapter(Context context, List<Novel> mBooks, int listItemID, OnItemClickListener clickLitener) {
this.context = context; this.context = context;
this.mDatas = mBooks; this.mDatas = mBooks;
this.mOnItemClickListener = clickLitener; this.mOnItemClickListener = clickLitener;
this.listItemID = listItemID; this.listItemID = listItemID;
mInflater = LayoutInflater.from(context);
} }
@ -57,19 +85,40 @@ public class BookListAdapter extends RecyclerView.Adapter< MyViewHolder> {
return EMPTY_VIEW; return EMPTY_VIEW;
} else if (mDatas.get(position) == null) { } else if (mDatas.get(position) == null) {
return PROGRESS_VIEW; return PROGRESS_VIEW;
} else if ( position + 1 == getItemCount()) {
//最后一个item设置为footerView
return TYPE_FOOTER;
} else { } else {
return super.getItemViewType(position); return TYPE_ITEM;
} }
// return super.getItemViewType(position);
} }
@Override @Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder holder = new MyViewHolder(LayoutInflater.from( if (viewType == TYPE_FOOTER) {
context).inflate(listItemID, parent, View itemView = mInflater.inflate(R.layout.load_more_footview_layout, parent, false);
false));
return holder; return new FooterViewHolder(itemView);
}else if(viewType == EMPTY_VIEW){
EmptyViewHolder holder = new EmptyViewHolder (LayoutInflater.from(context).inflate(R.layout.recycle_list_empty_item, parent, false));
return holder;
}
View itemView = mInflater.inflate(listItemID, parent, false);
return new MyViewHolder(itemView);
} }
public void setBookList(List<Novel> bookLists){ public void setBookList(List<Novel> bookLists){
this.mDatas = bookLists; this.mDatas = bookLists;
notifyDataSetChanged(); notifyDataSetChanged();
@ -84,33 +133,58 @@ public class BookListAdapter extends RecyclerView.Adapter< MyViewHolder> {
} }
@Override @Override
public void onBindViewHolder(MyViewHolder holder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder hd, int position) {
holder.tvTitle.setText(mDatas.get(position).getName());
if (holder.tvAuthor != null) holder.tvAuthor.setText(mDatas.get(position).getAuthor());
if (holder.tvCate != null) holder.tvCate.setText(mDatas.get(position).getNovelType());
if (holder.tvDesc != null) holder.tvDesc.setText(mDatas.get(position).getDesc());
if (holder.imageView != null && !TextUtils.isEmpty(mDatas.get(position).getCover())) {
ImageUtil.loadImage( context, mDatas.get(position).getCover() ,holder. imageView);
}
if(holder.tvNum!=null)holder.tvNum.setText("999");
// 如果设置了回调则设置点击事件
if (mOnItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onItemClick(holder.itemView, pos);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override if (hd instanceof FooterViewHolder) {
public boolean onLongClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onItemLongClick(holder.itemView, pos); FooterViewHolder footerViewHolder = (FooterViewHolder) hd;
return false;
}
}); switch (mLoadMoreStatus) {
case PULLUP_LOAD_MORE:
footerViewHolder.mTvLoadText.setText("上拉加载更多...");
break;
case LOADING_MORE:
footerViewHolder.mTvLoadText.setText("正加载更多...");
break;
case NO_LOAD_MORE:
//隐藏加载更多
footerViewHolder.mLoadLayout.setVisibility(View.GONE);
break;
}
}else if (hd instanceof MyViewHolder) {
MyViewHolder holder = (MyViewHolder)hd;
holder.tvTitle.setText(mDatas.get(position).getName());
if (holder.tvAuthor != null) holder.tvAuthor.setText(mDatas.get(position).getAuthor());
if (holder.tvCate != null) holder.tvCate.setText(mDatas.get(position).getNovelType());
if (holder.tvDesc != null) holder.tvDesc.setText(mDatas.get(position).getDesc());
if (holder.imageView != null && !TextUtils.isEmpty(mDatas.get(position).getCover())) {
ImageUtil.loadImage(context, mDatas.get(position).getCover(), holder.imageView);
}
if (holder.tvNum != null) holder.tvNum.setText("999");
// 如果设置了回调则设置点击事件
if (mOnItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onItemClick(holder.itemView, pos);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onItemLongClick(holder.itemView, pos);
return false;
}
});
}
} }
} }
@ -129,5 +203,40 @@ public class BookListAdapter extends RecyclerView.Adapter< MyViewHolder> {
notifyItemRemoved(position); notifyItemRemoved(position);
} }
public class FooterViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.pbLoad)
ProgressBar mPbLoad;
@BindView(R.id.tvLoadText)
TextView mTvLoadText;
@BindView(R.id.loadLayout)
LinearLayout mLoadLayout;
public FooterViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
public EmptyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
public void AddHeaderItem(List<Novel> items) {
mDatas.addAll(0, items);
notifyDataSetChanged();
}
public void AddFooterItem(List<Novel> items) {
mDatas.addAll(items);
notifyDataSetChanged();
}
/**
* 更新加载更多状态
* @param status
*/
public void changeMoreStatus(int status){
mLoadMoreStatus=status;
notifyDataSetChanged();
}
} }

View File

@ -65,7 +65,7 @@ public class CatalogueAdapter extends BaseAdapter {
if (currentCharter == position){ if (currentCharter == position){
viewHolder.catalogue_tv.setTextColor(mContext.getResources().getColor(R.color.colorPrimaryDark)); viewHolder.catalogue_tv.setTextColor(mContext.getResources().getColor(R.color.colorPrimaryDark));
}else{ }else{
viewHolder.catalogue_tv.setTextColor(mContext.getResources().getColor(R.color.colorPrimaryDark)); viewHolder.catalogue_tv.setTextColor(mContext.getResources().getColor(R.color.dark_gray));
} }
viewHolder.catalogue_tv.setText(bookCatalogueList.get(position).getChapterName()); viewHolder.catalogue_tv.setText(bookCatalogueList.get(position).getChapterName());
//Log.d("catalogue",bookCatalogueList.get(position).getBookCatalogue()); //Log.d("catalogue",bookCatalogueList.get(position).getBookCatalogue());

View File

@ -142,14 +142,12 @@ public class Novel extends LitePalSupport implements Serializable{
} }
public int getLastReadChapt() { public int getLastReadChapt() {
if(lastReadChapt<=0){ // if(lastReadChapt<=0){lastReadChapt=1;}
lastReadChapt=1;
}
return lastReadChapt; return lastReadChapt;
} }
public void setLastReadChapt(int lastReadChapt) { public void setLastReadChapt(int lastReadChapt) {
lastReadChapt = lastReadChapt >0 ? lastReadChapt :1; // lastReadChapt = lastReadChapt >0 ? lastReadChapt :1;
this.lastReadChapt = lastReadChapt; this.lastReadChapt = lastReadChapt;
} }

View File

@ -245,7 +245,7 @@ public class HttpMethods {
public Response intercept(Chain chain) throws IOException { public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request()); Response originalResponse = chain.proceed(chain.request());
String cacheControl = originalResponse.header("Cache-Control"); String cacheControl = originalResponse.header("Cache-Control");
int maxAge =60*60; //一小时 int maxAge =0;//60*60; //一小时
if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") || if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") ||
cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) { //目标网站禁用cache则设置为1小时 cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) { //目标网站禁用cache则设置为1小时
return originalResponse.newBuilder() return originalResponse.newBuilder()
@ -253,6 +253,10 @@ public class HttpMethods {
.header("Cache-Control", "public, max-age=" + maxAge) .header("Cache-Control", "public, max-age=" + maxAge)
.build(); .build();
} else { } else {
/* return originalResponse.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();*/
return originalResponse; return originalResponse;
} }
} }

View File

@ -7,4 +7,5 @@ public interface AdInterface {
* @param adY * @param adY
*/ */
public void showAd(boolean showAd,int height,int adY); public void showAd(boolean showAd,int height,int adY);
public void hideSystemUI();
} }

View File

@ -114,11 +114,60 @@ public class BookUtil {
//当前目录网站 //当前目录网站
private Site mSite; private Site mSite;
private SiteRule mSiteRule; private SiteRule mSiteRule;
public synchronized void openBook(Novel novel) throws IOException, InterruptedException {
this.mNovel = novel;
//如果当前缓存不是要打开的书本就缓存书本同时删除缓存
//TODO 构建新的缓存策略几个选项1每本书一个缓存 2控制缓存总大小超过限制删除旧缓存 3网络小说的缓存
boolean isLocalImport = novel.isLocalBook();
boolean isOnShelf = isLocalImport || novel.isOnShelf();
boolean isLoadChaptsFromRemote = !isLocalImport ;// && !novel.isFinished() ; //是否从目标网站下载目录
// showProgressDialog();
if(isLocalImport) {
mChapters = LitePal.where("novelId=?", mNovel.getId() + "").find(Chapter.class);
for (Chapter c : mChapters) {
Log.d(TAG, String.format("bookchapter :%s,fileName :%s, chapter Size %s", c.getChapterName(), c.getChapterPath(), c.getLength()));
}
chaptCache = new HashMap<Integer, Cache>();
if (mChapters.isEmpty()) { //1. 首次打开 本地导入的书
if (bookPath == null || !bookPath.equals(mNovel.getNovelPath())) {
cleanCacheFile();
this.bookPath = mNovel.getNovelPath();
bookName = FileUtils.getFileName(bookPath);
cacheBook();
}
}
}else{ //读取目录列表
MuluStatus m = mMuluStatus;
// Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
Log.d(TAG, String.format("prepare book %s open book in background.... mMuluStatus %smSiteRule %s,thread %s",mNovel.getName(),mMuluStatus,mSiteRule,Thread.currentThread().getName()) );
while( mSiteRule ==null || mMuluStatus==null || mMuluStatus == MuluStatus.isDownloading){
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){
dismissProgressDialog();
throw new RuntimeException("读取资源失败,请检查网络");
}
}
}
// dismissProgressDialog();
}
public void setNovelSites(NovelSites nvs) { public void setNovelSites(NovelSites nvs) {
this.mNovelSites = nvs; this.mNovelSites = nvs;
Log.d(TAG, String.format("prepare book %s get novel sites count .",nvs.getSites().length) ); Log.d(TAG, String.format("prepare book %s get novel sites count %s .",mNovel.getName(), nvs.getSites().length) );
if(nvs.getSites().length ==0){ if(nvs.getSites().length ==0){
throw new RuntimeException("书本错误 code 001"); //无目标网站 throw new RuntimeException("书本错误 code 001"); //无目标网站
// return; // return;
@ -151,7 +200,7 @@ public class BookUtil {
public void onSuccess(String result) { public void onSuccess(String result) {
//成功 //成功
try { try {
Log.d(TAG, String.format("prepare book %s get target sites done.",mNovel.getName()) ); Log.d(TAG, String.format("prepare book %s get target sites done.thread %s",mNovel.getName(),Thread.currentThread().getName()) );
NovelSites nvs = (NovelSites) gson.fromJson(result,NovelSites.class); NovelSites nvs = (NovelSites) gson.fromJson(result,NovelSites.class);
//pageFactory.prepareBook(mNovel,nvs, BookActivity.this); //pageFactory.prepareBook(mNovel,nvs, BookActivity.this);
@ -159,6 +208,8 @@ public class BookUtil {
} catch ( Exception e) { } catch ( Exception e) {
Log.d(TAG, String.format("prepare book %s get target sites fail.thread %s ,msg %s",mNovel.getName(),Thread.currentThread().getName(),e.getMessage()) );
Log.e(TAG, "prepare book fail", e);
e.printStackTrace(); e.printStackTrace();
} }
@ -191,7 +242,7 @@ public class BookUtil {
} }
mSiteRule =sr; mSiteRule =sr;
setSiteInfo(); setSiteInfo();
Log.d(TAG, String.format("prepare book %s 目录正则表达式下载完成,开始读章节信息.",mNovel.getName()) ); Log.d(TAG, String.format("prepare book %s 目录正则表达式下载完成,开始读章节信息. thread %s ",mNovel.getName(),Thread.currentThread().getName()) );
Log.d(TAG, String.format("目录正则表达式下载完成,开始读取章节信息") ); Log.d(TAG, String.format("目录正则表达式下载完成,开始读取章节信息") );
@ -282,50 +333,7 @@ public class BookUtil {
} }
} }
public synchronized void openBook(Novel novel) throws IOException, InterruptedException {
this.mNovel = novel;
//如果当前缓存不是要打开的书本就缓存书本同时删除缓存
//TODO 构建新的缓存策略几个选项1每本书一个缓存 2控制缓存总大小超过限制删除旧缓存 3网络小说的缓存
boolean isLocalImport = novel.isLocalBook();
boolean isOnShelf = isLocalImport || novel.isOnShelf();
boolean isLoadChaptsFromRemote = !isLocalImport ;// && !novel.isFinished() ; //是否从目标网站下载目录
// showProgressDialog();
if(isLocalImport) {
mChapters = LitePal.where("novelId=?", mNovel.getId() + "").find(Chapter.class);
for (Chapter c : mChapters) {
Log.d(TAG, String.format("bookchapter :%s,fileName :%s, chapter Size %s", c.getChapterName(), c.getChapterPath(), c.getLength()));
}
chaptCache = new HashMap<Integer, Cache>();
if (mChapters.isEmpty()) { //1. 首次打开 本地导入的书
if (bookPath == null || !bookPath.equals(mNovel.getNovelPath())) {
cleanCacheFile();
this.bookPath = mNovel.getNovelPath();
bookName = FileUtils.getFileName(bookPath);
cacheBook();
}
}
}else{ //读取目录列表
MuluStatus m = mMuluStatus;
// Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
Log.d(TAG, String.format("prepare book %s open book in background.... mMuluStatus %smSiteRule %s",mNovel.getName(),mMuluStatus,mSiteRule) );
while(mSiteRule ==null || mMuluStatus == MuluStatus.isDownloading){
Thread.sleep(50);
Log.d(TAG,String.format("prepare book waiting for mulu downloading ,mMuluStatus %s,msiteRule %s" ,mMuluStatus,mSiteRule));
if(mMuluStatus == MuluStatus.failed){
dismissProgressDialog();
throw new RuntimeException("读取资源失败,请检查网络");
}
}
}
// dismissProgressDialog();
}
// String getMuluUrl() { // String getMuluUrl() {
// return "https://www.qu.la/book/390/"; // return "https://www.qu.la/book/390/";
@ -371,9 +379,12 @@ public class BookUtil {
HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { HttpMethods.getOkClient().newCall(request).enqueue(new Callback() {
@Override @Override
public void onFailure(Call call, IOException e) { public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: " + e.getMessage()); // 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,String.format("loadChapts---- failed %s 目录 from %s", mNovel.getName() ,url ));
//TODO 如果是取消了访问则返回
if( mNovelSites.getSites().length ==1){ //仅有一个rule,且失败了 if( mNovelSites.getSites().length ==1){ //仅有一个rule,且失败了
mMuluStatus = MuluStatus.failed; mMuluStatus = MuluStatus.failed;
return; return;
@ -400,7 +411,7 @@ public class BookUtil {
return; return;
} }
if (body != null) { if (body != null) {
Log.d(TAG, String.format("prepare book %s 章节信息读取成功.",mNovel.getName()) ); Log.d(TAG, String.format("prepare book %s 章节信息读取成功.thread %s",mNovel.getName(),Thread.currentThread().getName()) );
try { try {
String bodyStr = body.string(); String bodyStr = body.string();
// Log.d(TAG, "onResponse: " +bodyStr); // Log.d(TAG, "onResponse: " +bodyStr);
@ -535,7 +546,7 @@ public class BookUtil {
return line.toCharArray(); return line.toCharArray();
} }
public char chaptCurrent(){ public char chaptCurrent(){
chapterNo = mChapters.size() <= chapterNo ? 1 : chapterNo; chapterNo = mChapters.size() < chapterNo ? 1 : chapterNo;
char[] charArray = chaptChars(chapterNo); char[] charArray = chaptChars(chapterNo);
@ -890,8 +901,8 @@ public class BookUtil {
if(!file.exists()) { if(!file.exists()) {
if(mMuluStatus ==null){ if(mMuluStatus ==null){
Log.d(TAG,String.format("prepare book loadChapts---- 还未有目录信息,出错了 %s 目录, 目录数量 %s, MuluStatus %s", mNovel.getName() , mChapters.size(), mMuluStatus )); Log.d(TAG,String.format("prepare book loadChapts---- 还未有目录信息,出错了 %s 目录, 目录数量 %s, MuluStatus %s ,thread %s", mNovel.getName() , mChapters.size(), mMuluStatus,Thread.currentThread().getName() ));
getTargetSites(); // getTargetSites();
} }
int slept = 0; int slept = 0;
while(slept <100 && mMuluStatus ==MuluStatus.isDownloading){ while(slept <100 && mMuluStatus ==MuluStatus.isDownloading){
@ -906,8 +917,8 @@ public class BookUtil {
} }
if( mChapters ==null || mChapters.size() ==0){ if( mChapters ==null || mChapters.size() ==0){
Log.d(TAG,String.format("loadChapts----超时。。。或出错了 %s 目录, 目录数量 %s, slept %s, MuluStatus %s", mNovel.getName() , mChapters.size(),slept ,mMuluStatus )); 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 = "获取目录失败,网络错误,请重试. " +mMuluStatus; String error = " ";
return error.toCharArray(); return error.toCharArray();
} }
@ -932,7 +943,7 @@ public class BookUtil {
while( !getDownloadStatus() && chaptDownStatus.get(Integer.valueOf(index)) == DownloadStatus.downloading && slepttime <maxSleep){ while( !getDownloadStatus() && chaptDownStatus.get(Integer.valueOf(index)) == DownloadStatus.downloading && slepttime <maxSleep){
Thread.sleep(50); Thread.sleep(50);
slepttime+=50; slepttime+=50;
Log.d(TAG,String.format(" prepare book loadChaptContent slept %s for downloading,isDownload %s ",slepttime,getDownloadStatus() ) ); 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("loadChaptContent slept %s for downloading ",slepttime ) );
Log.d( "loadChaptContent",String.format("dismissing dialog " )); Log.d( "loadChaptContent",String.format("dismissing dialog " ));
@ -996,7 +1007,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
2. 查询主服务器若有地址更新则更新本地信息并重复1若没有更新地址则地址无效返回章节内容正待手打 2. 查询主服务器若有地址更新则更新本地信息并重复1若没有更新地址则地址无效返回章节内容正待手打
*/ */
// //
final int index = mChapters.size() <= chapterIndex ? 1 : chapterIndex; final int index = mChapters.size() < chapterIndex ? 1 : chapterIndex;
if(mChapters.size() <chapterIndex){ if(mChapters.size() <chapterIndex){
Log.d(TAG,String.format("loadChaptContent----wrong index, chapter size %s,load index %s,bookname %s", mChapters.size(),index,mNovel.getName() )); Log.d(TAG,String.format("loadChaptContent----wrong index, chapter size %s,load index %s,bookname %s", mChapters.size(),index,mNovel.getName() ));
@ -1042,6 +1053,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
} }
try { try {
String bodyStr = body.string(); String bodyStr = body.string();
String title = chapter.getChapterName(); String title = chapter.getChapterName();
String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson);
@ -1052,7 +1064,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), charachterType);//"UTF-16LE"); // UTF-16LE utf-8 文件小 final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), charachterType);//"UTF-16LE"); // UTF-16LE utf-8 文件小
writer.write(buf); writer.write(buf);
writer.close(); writer.close();
Log.d( "loadChaptContent",String.format("loadChaptContent file created: %s", file.getPath())); Log.d( "loadChaptContent",String.format("prepare book loadChaptContent file created: %s, thread %s", file.getPath(), Thread.currentThread().getName()));
handler.sendEmptyMessage(123); handler.sendEmptyMessage(123);
setDownloadFlag(true); setDownloadFlag(true);
} catch (IOException | JSONException e) { } catch (IOException | JSONException e) {
@ -1070,7 +1082,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
chapter.save(); chapter.save();
setDownloadFlag(true); setDownloadFlag(true);
chaptDownStatus.put(index,DownloadStatus.success); chaptDownStatus.put(index,DownloadStatus.success);
Log.d(TAG,String.format("loadChaptContent---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() )); Log.d(TAG,String.format(" prepare book loadChaptContent---- finished download %s, cost time %s ,content path %s ,thread %s", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() , Thread.currentThread().getName() ));
} }
} }

View File

@ -74,6 +74,10 @@ public class GsonUtil {
public static List<Novel> parserJsonArray(String restult,String blockName ) throws JSONException { public static List<Novel> parserJsonArray(String restult,String blockName ) throws JSONException {
JSONObject jsonObject = new JSONObject(restult); JSONObject jsonObject = new JSONObject(restult);
return parserJsonArray(jsonObject,blockName);
}
public static List<Novel> parserJsonArray( JSONObject jsonObject,String blockName ) throws JSONException {
String resultstr = jsonObject.getString(blockName); String resultstr = jsonObject.getString(blockName);
List<Novel> list = new ArrayList<Novel>(); List<Novel> list = new ArrayList<Novel>();

View File

@ -15,6 +15,7 @@ import android.graphics.Typeface;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast; import android.widget.Toast;
@ -25,6 +26,8 @@ import com.novelbook.android.db.Novel;
import com.novelbook.android.netutils.NetUtil; import com.novelbook.android.netutils.NetUtil;
import com.novelbook.android.view.PageWidget; import com.novelbook.android.view.PageWidget;
import org.litepal.LitePal;
import java.io.IOException; import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -168,9 +171,10 @@ public class PageFactory {
chaptId = mChapters!=null && mChapters.size() <= chaptId ? 1 : chaptId; chaptId = mChapters!=null && mChapters.size() <= chaptId ? 1 : chaptId;
Log.d(TAG, String.format("prepare book to open chapter %s ",chaptId ) ); // Log.d(TAG, String.format("prepare book to open chapter %s ",chaptId ) );
char[] chars = mBookUtil.chaptChars(chaptId); char[] chars = mBookUtil.chaptChars(chaptId);
String s = new String(chars);
// Log.d(TAG, String.format("prepare book to open chapter %s,chars %s ",chaptId ,s ) );
mBookUtil.setBookLen(chars.length); mBookUtil.setBookLen(chars.length);
mBookUtil.setChapterNo(chaptId); mBookUtil.setChapterNo(chaptId);
// TRPage page = new TRPage(); // TRPage page = new TRPage();
@ -179,7 +183,7 @@ public class PageFactory {
while(length <chars.length ) { while(length <chars.length ) {
pageNo++; pageNo++;
TRPage page = getNextChapterPage(length); TRPage page = getNextChapterPage(length);
Log.d(TAG,"page.getBegin :" + page.getBegin()+ ",chapter length "+ mBookUtil.getBookLen()); // Log.d(TAG,"prepare book page.getBegin :" + page.getBegin()+ ",chapter length "+ mBookUtil.getBookLen());
// if(page.getBegin() == mBookUtil.getBookLen() ){ //最后一页空白的情况 // if(page.getBegin() == mBookUtil.getBookLen() ){ //最后一页空白的情况
@ -328,6 +332,7 @@ public class PageFactory {
Log.d(TAG,"line count is " + mLineCount +" paragrapheight is " +paragrapheight); Log.d(TAG,"line count is " + mLineCount +" paragrapheight is " +paragrapheight);
} }
private void drawStatus(Bitmap bitmap){ private void drawStatus(Bitmap bitmap){
mAd.hideSystemUI();
String status = ""; String status = "";
switch (mStatus){ switch (mStatus){
case OPENING: case OPENING:
@ -353,6 +358,7 @@ public class PageFactory {
c.drawText(status, targetRect.centerX(), baseline, waitPaint); c.drawText(status, targetRect.centerX(), baseline, waitPaint);
// c.drawText("正在打开书本...", mHeight / 2, 0, waitPaint); // c.drawText("正在打开书本...", mHeight / 2, 0, waitPaint);
mBookPageWidget.postInvalidate(); mBookPageWidget.postInvalidate();
mAd.hideSystemUI();
} }
public void onDraw(Bitmap bitmap,List<String> m_lines,Boolean updateChapter) { public void onDraw(Bitmap bitmap,List<String> m_lines,Boolean updateChapter) {
@ -366,9 +372,25 @@ public class PageFactory {
public void run() { public void run() {
super.run(); super.run();
if(mBook.getLastReadChapt() !=currentChapter || mBook.getLastReadPos()!=currentPage.getBegin()) { if(mBook.getLastReadChapt() !=currentChapter || mBook.getLastReadPos()!=currentPage.getBegin()) {
mBook.setLastReadChapt(currentChapter); if(currentChapter >1) {
mBook.setLastReadChapt(currentChapter);
}else{
mBook.setToDefault("lastReadChapt");
}
mBook.setLastReadPos(currentPage.getBegin()); mBook.setLastReadPos(currentPage.getBegin());
mBook.update(mBook.getId()); mBook.update(mBook.getId()); //If you set a default value to a field, the corresponding
// * column won't be updated.
// mBook.save();
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()));
} }
/* /*
values.put("lastReadPos",currentPage.getBegin()); values.put("lastReadPos",currentPage.getBegin());
@ -477,7 +499,7 @@ public class PageFactory {
c.drawText(chapterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom + mBatterryFontSize, mBatterryPaint); c.drawText(chapterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom + mBatterryFontSize, mBatterryPaint);
} }
mBookPageWidget.postInvalidate(); mBookPageWidget.postInvalidate();
} }
private void showAd(int adHeight,int adY) { private void showAd(int adHeight,int adY) {
@ -606,6 +628,7 @@ public class PageFactory {
mStatus = Status.OPENING; mStatus = Status.OPENING;
drawStatus(mBookPageWidget.getCurPage()); drawStatus(mBookPageWidget.getCurPage());
drawStatus(mBookPageWidget.getNextPage()); drawStatus(mBookPageWidget.getNextPage());
if (bookTask != null && bookTask.getStatus() != AsyncTask.Status.FINISHED){ if (bookTask != null && bookTask.getStatus() != AsyncTask.Status.FINISHED){
bookTask.cancel(true); bookTask.cancel(true);
} }
@ -635,7 +658,7 @@ public class PageFactory {
if (mBookPageWidget != null) { if (mBookPageWidget != null) {
currentPage(true); currentPage(true);
} }
Log.d(TAG, String.format("prepare book set PageFactory.mStatus %s .",PageFactory.Status.FINISH ) );
PageFactory.mStatus = PageFactory.Status.FINISH; PageFactory.mStatus = PageFactory.Status.FINISH;
}else{ }else{
PageFactory.mStatus = PageFactory.Status.FAIL; PageFactory.mStatus = PageFactory.Status.FAIL;
@ -743,7 +766,8 @@ public class PageFactory {
return page; return page;
} }
} }
return new TRPage(); //return new TRPage();// currentChaptPages.get(currentChaptPages.size()-1);
return currentChaptPages.get(currentChaptPages.size()-1);
} }
boolean showChapTitleOnTopWhenNextPage =false; boolean showChapTitleOnTopWhenNextPage =false;
@ -1110,7 +1134,7 @@ public class PageFactory {
} }
public void clear(){ public void clear(){
Log.d(TAG, String .format("prepareBook: clearing book info %s" , getNovle().getName())); Log.d(TAG, String .format("prepare Book: clearing book info %s" , getNovle().getName()));
//mBookUtil=null; //mBookUtil=null;
currentChapter = 0; currentChapter = 0;
bookPath = ""; bookPath = "";

View File

@ -94,6 +94,13 @@
android:id="@+id/desc" android:id="@+id/desc"
style="@style/TextViewNovelDesc.head" style="@style/TextViewNovelDesc.head"
android:text=" " android:text=" "
android:visibility="gone"
/>
<TextView
android:id="@+id/author"
style="@style/TextViewNovelAuthor"
android:text=""
/> />
<LinearLayout <LinearLayout
@ -107,14 +114,19 @@
android:text="" android:text=""
/> />
<TextView <TextView
android:id="@+id/author" android:id="@+id/smallCate"
style="@style/TextViewNovelAuthor" style="@style/TextViewNovelType"
android:text="" android:text=""
/> />
</LinearLayout> </LinearLayout>
<TextView
android:id="@+id/progress"
style="@style/TextViewNovelAuthor"
android:text=""
/>
</LinearLayout> </LinearLayout>

View File

@ -3,14 +3,19 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".Fragments.Fragment_booklist"> tools:context=".Fragments.Fragment_booklist">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:id="@+id/rvBooklist" android:id="@+id/rvBooklist"
android:divider="#ffff0000"
android:dividerHeight="10dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:nestedScrollingEnabled="false" android:nestedScrollingEnabled="false"
android:paddingTop="10dp" android:paddingTop="10dp"
/> />
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout> </FrameLayout>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loadLayout"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_marginTop="5dip"
android:gravity="center">
<ProgressBar
android:id="@+id/pbLoad"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:indeterminate="false"/>
<TextView
android:id="@+id/tvLoadText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:layout_marginLeft="4dip"
android:layout_toRightOf="@id/pbLoad"
android:clickable="true"
android:text="魂牵梦萦 魂牵梦萦 "
android:textColor="#000000"
android:textSize="16sp"/>
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loadLayout"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_marginTop="5dip"
android:gravity="center">
<ProgressBar
android:id="@+id/pbLoad"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:indeterminate="false"/>
<TextView
android:id="@+id/tvLoadText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:layout_marginLeft="4dip"
android:layout_toRightOf="@id/pbLoad"
android:clickable="true"
android:text="没有数据 "
android:textColor="#000000"
android:textSize="16sp"/>
</RelativeLayout>
</LinearLayout>

View File

@ -10,6 +10,6 @@
android:singleLine="true" android:singleLine="true"
android:gravity="center_vertical" android:gravity="center_vertical"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:textColor="@color/colorAccent"/> />
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,15 @@
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menuSearch"
android:orderInCategory="100"
android:title=""
android:icon="@drawable/ic_search_white_24dp"
app:showAsAction="ifRoom" />
</menu>

View File

@ -13,22 +13,7 @@
android:icon="@drawable/ic_search_white_24dp" android:icon="@drawable/ic_search_white_24dp"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<!--item app:actionViewClass="android.support.v7.widget.SearchView"
android:id="@+id/menu_2"
android:orderInCategory="100"
android:title="@string/fenlei"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
app:showAsAction="never" / -->
<!--<item-->
<!--android:id="@+id/action_settings"-->
<!--android:orderInCategory="100"-->
<!--android:showAsAction="never"-->
<!--android:title="@string/action_settings"/>-->
<!--<item-->
<!--android:id="@+id/action_login"-->
<!--android:orderInCategory="100"-->
<!--android:showAsAction="never"-->
<!--android:title="@string/action_login"/>-->
<item <item
android:id="@+id/menuMore" android:id="@+id/menuMore"

View File

@ -190,7 +190,7 @@
<color name="full_transparent">#00000000</color> <color name="full_transparent">#00000000</color>
<color name="half_transparent">#aa000000</color> <color name="half_transparent">#aa000000</color>
<color name="background_color">#eeeeee</color> <color name="background_color">#eeeeee</color>
<color name="list_item_divider">#cccccc</color> <color name="list_item_divider">#F5F5F5</color>
<color name="divider">#9c9c9c</color> <color name="divider">#9c9c9c</color>
<color name="text_color">#000000</color> <color name="text_color">#000000</color>
<color name="text_color_pressed">#ffffff</color> <color name="text_color_pressed">#ffffff</color>