parent
5c9d92b4dd
commit
27040c5e2f
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<litepal> |
||||||
|
<dbname value="readDb" /> |
||||||
|
|
||||||
|
<version value="6" /> |
||||||
|
|
||||||
|
<list> |
||||||
|
<!--搜索记录表--> |
||||||
|
<mapping class="com.novel.read.model.db.SearchListTable"/> |
||||||
|
<!--收藏书籍表--> |
||||||
|
<mapping class="com.novel.read.model.db.CollBookBean"/> |
||||||
|
<!--章节表--> |
||||||
|
<mapping class="com.novel.read.model.db.BookChapterBean"/> |
||||||
|
<!--阅读记录表--> |
||||||
|
<mapping class="com.novel.read.model.db.BookRecordBean"/> |
||||||
|
<!--章节详情表--> |
||||||
|
<mapping class="com.novel.read.model.db.ChapterInfoBean" /> |
||||||
|
<!--章节详情表--> |
||||||
|
<mapping class="com.novel.read.model.db.DownloadTaskBean" /> |
||||||
|
</list> |
||||||
|
</litepal> |
||||||
@ -1,12 +0,0 @@ |
|||||||
package com.novel.read |
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity |
|
||||||
import android.os.Bundle |
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() { |
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) { |
|
||||||
super.onCreate(savedInstanceState) |
|
||||||
setContentView(R.layout.activity_main) |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,286 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.app.ProgressDialog; |
||||||
|
import android.content.Intent; |
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.common_lib.base.utils.ToastUtils; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.LoveLyAdapter; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.BookArticleEvent; |
||||||
|
import com.novel.read.event.GetBookDetailEvent; |
||||||
|
import com.novel.read.event.GetRecommendBookEvent; |
||||||
|
import com.novel.read.event.UpdateBookEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.db.BookChapterBean; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
import com.novel.read.model.db.dbManage.BookRepository; |
||||||
|
import com.novel.read.model.protocol.BookDetailResp; |
||||||
|
import com.novel.read.model.protocol.RecommendBookResp; |
||||||
|
import com.novel.read.utlis.DateUtli; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
import com.novel.read.widget.RefreshLayout; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import org.litepal.LitePal; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
|
||||||
|
import static com.novel.read.constants.Constant.RequestCode.REQUEST_READ; |
||||||
|
import static com.novel.read.constants.Constant.ResultCode.RESULT_IS_COLLECTED; |
||||||
|
|
||||||
|
public class NovelBookDetailActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.iv_book) |
||||||
|
ImageView mIvBook; |
||||||
|
@BindView(R.id.tv_book_name) |
||||||
|
TextView mTvBookName; |
||||||
|
@BindView(R.id.tv_book_author) |
||||||
|
TextView mTvBookAuthor; |
||||||
|
@BindView(R.id.tv_book_length) |
||||||
|
TextView mTvBookLength; |
||||||
|
@BindView(R.id.tv_new_title) |
||||||
|
TextView mTvNewTitle; |
||||||
|
@BindView(R.id.tv_update_time) |
||||||
|
TextView mTvUpdateTime; |
||||||
|
@BindView(R.id.tv_human_num) |
||||||
|
TextView mTvHumanNum; |
||||||
|
@BindView(R.id.tv_love_look_num) |
||||||
|
TextView mTvLoveLookNum; |
||||||
|
@BindView(R.id.tv_Intro) |
||||||
|
TextView mTvIntro; |
||||||
|
@BindView(R.id.rlv_lovely) |
||||||
|
RecyclerView mRlvLovely; |
||||||
|
@BindView(R.id.tv_add_book) |
||||||
|
TextView mTvAddBook; |
||||||
|
@BindView(R.id.tv_start_read) |
||||||
|
TextView mTvStartRead; |
||||||
|
@BindView(R.id.refresh) |
||||||
|
RefreshLayout refreshLayout; |
||||||
|
|
||||||
|
private LoveLyAdapter mAdapter; |
||||||
|
private List<RecommendBookResp.BookBean> mList = new ArrayList<>(); |
||||||
|
|
||||||
|
private int mBookId; |
||||||
|
|
||||||
|
private boolean isCollected = false; |
||||||
|
private CollBookBean mCollBookBean; |
||||||
|
|
||||||
|
private ProgressDialog mProgressDialog; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_book_detail; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
mBookId = getIntent().getIntExtra(Constant.Bundle.BookId,0); |
||||||
|
mRlvLovely.setLayoutManager(new LinearLayoutManager(this)); |
||||||
|
mAdapter = new LoveLyAdapter(mList); |
||||||
|
mRlvLovely.setAdapter(mAdapter); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
refreshLayout.showLoading(); |
||||||
|
refreshLayout.setOnReloadingListener(new RefreshLayout.OnReloadingListener() { |
||||||
|
@Override |
||||||
|
public void onReload() { |
||||||
|
getData(); |
||||||
|
} |
||||||
|
}); |
||||||
|
getData(); |
||||||
|
toolbar.setNavigationOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
finish(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData(){ |
||||||
|
AccountManager.getInstance().getRecommendBook(String.valueOf(mBookId), "10"); |
||||||
|
AccountManager.getInstance().getBookDetail(String.valueOf(mBookId)); |
||||||
|
} |
||||||
|
|
||||||
|
@OnClick({R.id.tv_add_book, R.id.tv_start_read}) |
||||||
|
public void onViewClicked(View view) { |
||||||
|
switch (view.getId()) { |
||||||
|
case R.id.tv_add_book: |
||||||
|
//点击存储
|
||||||
|
if (isCollected) { |
||||||
|
//放弃点击
|
||||||
|
BookRepository.getInstance().deleteCollBookInRx(mCollBookBean); |
||||||
|
mTvAddBook.setText(getResources().getString(R.string.add_book)); |
||||||
|
isCollected = false; |
||||||
|
} else { |
||||||
|
if (mProgressDialog == null) { |
||||||
|
mProgressDialog = new ProgressDialog(this); |
||||||
|
mProgressDialog.setTitle("正在添加到书架中"); |
||||||
|
} |
||||||
|
mProgressDialog.show(); |
||||||
|
AccountManager.getInstance().getBookArticle(String.valueOf(mBookId),"2","1","100000"); |
||||||
|
|
||||||
|
} |
||||||
|
break; |
||||||
|
case R.id.tv_start_read: |
||||||
|
// if (mCollBookBean.getInclude_image()==Constant.HasImage.has){
|
||||||
|
// startActivityForResult(new Intent(this, NovelWebReadActivity.class)
|
||||||
|
// .putExtra(NovelReadActivity.EXTRA_IS_COLLECTED, isCollected)
|
||||||
|
// .putExtra(NovelReadActivity.EXTRA_COLL_BOOK, mCollBookBean), REQUEST_READ);
|
||||||
|
// }else {
|
||||||
|
startActivityForResult(new Intent(this, NovelReadActivity.class) |
||||||
|
.putExtra(NovelReadActivity.EXTRA_IS_COLLECTED, isCollected) |
||||||
|
.putExtra(NovelReadActivity.EXTRA_COLL_BOOK, mCollBookBean), REQUEST_READ); |
||||||
|
// }
|
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n") |
||||||
|
@Subscribe |
||||||
|
public void getBookDetail(GetBookDetailEvent event) { |
||||||
|
refreshLayout.showFinish(); |
||||||
|
if (event.isFail()) { |
||||||
|
refreshLayout.showError(); |
||||||
|
} else { |
||||||
|
BookDetailResp.BookBean bookBean = event.getResult().getBook(); |
||||||
|
GlideImageLoader.displayCornerImage(this, bookBean.getCover(), mIvBook); |
||||||
|
mTvBookName.setText(bookBean.getTitle()); |
||||||
|
|
||||||
|
mTvBookAuthor.setText(bookBean.getAuthor() + " | "); |
||||||
|
mTvBookLength.setText(getString(R.string.book_word, bookBean.getWords() / 10000)); |
||||||
|
|
||||||
|
if (event.getResult().getLast_article()!=null){ |
||||||
|
mTvNewTitle.setText(getString(R.string.new_chapter,event.getResult().getLast_article().getTitle())); |
||||||
|
mTvUpdateTime.setText(DateUtli.dateConvert(event.getResult().getLast_article().getCreate_time(),0)); |
||||||
|
} |
||||||
|
|
||||||
|
mTvHumanNum.setText(bookBean.getHot() + ""); |
||||||
|
mTvLoveLookNum.setText(bookBean.getLike()); |
||||||
|
mTvIntro.setText(bookBean.getDescription()); |
||||||
|
mCollBookBean = BookRepository.getInstance().getCollBook(String.valueOf(bookBean.getId())); |
||||||
|
//判断是否收藏
|
||||||
|
if (mCollBookBean != null) { |
||||||
|
isCollected = true; |
||||||
|
mTvAddBook.setText(getResources().getString(R.string.already_add)); |
||||||
|
mTvStartRead.setText("继续阅读"); |
||||||
|
} else { |
||||||
|
mCollBookBean = event.getResult().getCollBookBean(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getRecommendBook(GetRecommendBookEvent event) { |
||||||
|
if (event.isFail()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(event.getResult().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onResume() { |
||||||
|
super.onResume(); |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onPause() { |
||||||
|
super.onPause(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getArticle(BookArticleEvent event){ |
||||||
|
|
||||||
|
if (event.isFail()){ |
||||||
|
dismiss(); |
||||||
|
ToastUtils.showNormalToast(this,getString(R.string.net_error)); |
||||||
|
}else { |
||||||
|
//存储收藏
|
||||||
|
boolean success = false; |
||||||
|
if (mCollBookBean!=null){ |
||||||
|
success = mCollBookBean.saveOrUpdate("bookId=?",mCollBookBean.getId()); |
||||||
|
} |
||||||
|
if (success){ |
||||||
|
List<BookChapterBean> bookChapterBean = event.getResult().getChapterBean(); |
||||||
|
for (int i = 0; i <bookChapterBean.size() ; i++) { |
||||||
|
bookChapterBean.get(i).setCollBookBean(mCollBookBean); |
||||||
|
} |
||||||
|
LitePal.saveAllAsync(bookChapterBean).listen(success1 -> { |
||||||
|
if (success1) { |
||||||
|
if (mTvAddBook!=null) { |
||||||
|
mTvAddBook.setText(getResources().getString(R.string.already_add)); |
||||||
|
} |
||||||
|
isCollected = true; |
||||||
|
}else { |
||||||
|
LitePal.deleteAll(CollBookBean.class,"bookId =?",mCollBookBean.getId()); |
||||||
|
ToastUtils.showNormalToast(this,getString(R.string.net_error)); |
||||||
|
} |
||||||
|
dismiss(); |
||||||
|
}); |
||||||
|
}else { |
||||||
|
ToastUtils.showNormalToast(this,getString(R.string.net_error)); |
||||||
|
dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void dismiss(){ |
||||||
|
if (mProgressDialog != null) { |
||||||
|
mProgressDialog.dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
||||||
|
super.onActivityResult(requestCode, resultCode, data); |
||||||
|
//如果进入阅读页面收藏了,页面结束的时候,就需要返回改变收藏按钮
|
||||||
|
if (requestCode == REQUEST_READ) { |
||||||
|
if (data == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
isCollected = data.getBooleanExtra(RESULT_IS_COLLECTED, false); |
||||||
|
|
||||||
|
if (isCollected) { |
||||||
|
mTvAddBook.setText(getResources().getString(R.string.already_add)); |
||||||
|
mTvStartRead.setText("继续阅读"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().postEvent(new UpdateBookEvent()); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,120 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.BookListAdapter; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.SearchListEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.SearchResp; |
||||||
|
import com.novel.read.widget.RefreshLayout; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
|
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
public class NovelBookTypeListActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.rlv_type_list) |
||||||
|
RecyclerView mRlvTypeList; |
||||||
|
@BindView(R.id.refresh) |
||||||
|
RefreshLayout refreshLayout; |
||||||
|
private List<SearchResp.BookBean> mList; |
||||||
|
private BookListAdapter mAdapter; |
||||||
|
private String mCategoryId; |
||||||
|
private String mTitle; |
||||||
|
private int page = 1; |
||||||
|
private int loadSize; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_book_type_list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
|
||||||
|
mCategoryId = getIntent().getStringExtra(Constant.Bundle.CategoryId); |
||||||
|
mTitle = getIntent().getStringExtra(Constant.Bundle.mTitle); |
||||||
|
|
||||||
|
mRlvTypeList.setLayoutManager(new LinearLayoutManager(this)); |
||||||
|
mList = new ArrayList<>(); |
||||||
|
|
||||||
|
mAdapter = new BookListAdapter(mList, mRlvTypeList); |
||||||
|
mRlvTypeList.setAdapter(mAdapter); |
||||||
|
|
||||||
|
mAdapter.setOnLoadMoreListener(() -> { |
||||||
|
if (mAdapter.isLoadingMore()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
if (loadSize >= COMMENT_SIZE) { |
||||||
|
mAdapter.setLoadingMore(true); |
||||||
|
mList.add(null); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
page++; |
||||||
|
getData(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
refreshLayout.showLoading(); |
||||||
|
refreshLayout.setOnReloadingListener(this::getData); |
||||||
|
getData(); |
||||||
|
toolbar.setTitle(mTitle); |
||||||
|
toolbar.setNavigationOnClickListener(view -> finish()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void getData() { |
||||||
|
AccountManager.getInstance().getSearchBookList(mCategoryId, "", page); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getSearchList(SearchListEvent event) { |
||||||
|
refreshLayout.showFinish(); |
||||||
|
if (event.isFail()) { |
||||||
|
refreshLayout.showError(); |
||||||
|
} else { |
||||||
|
loadSize = event.getResult().getBook().size(); |
||||||
|
if (mAdapter.isLoadingMore()){ |
||||||
|
mList.remove(mList.size() - 1); |
||||||
|
mList.addAll(event.getResult().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
mAdapter.setLoadingMore(false); |
||||||
|
}else { |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(event.getResult().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,258 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.content.ActivityNotFoundException; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.net.Uri; |
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.KeyEvent; |
||||||
|
import android.view.MenuItem; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.fragment.app.Fragment; |
||||||
|
import androidx.fragment.app.FragmentTransaction; |
||||||
|
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.HideBottomBarEvent; |
||||||
|
import com.novel.read.event.LoginEvent; |
||||||
|
import com.novel.read.event.SwitchFragmentEvent; |
||||||
|
import com.novel.read.event.UpdateBookEvent; |
||||||
|
import com.novel.read.event.VersionEvent; |
||||||
|
import com.novel.read.fragment.BookFragment; |
||||||
|
import com.novel.read.fragment.MoreFragment; |
||||||
|
import com.novel.read.fragment.RecommendFragment; |
||||||
|
import com.novel.read.fragment.StackFragment; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.db.dbManage.BookRepository; |
||||||
|
import com.novel.read.utlis.DateUtli; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.novel.read.utlis.ToastUtil; |
||||||
|
import com.novel.read.utlis.VersionUtil; |
||||||
|
import com.novel.read.widget.dialog.AppraiseDialog; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
|
||||||
|
public class NovelMainActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.fl_content) |
||||||
|
FrameLayout flContent; |
||||||
|
|
||||||
|
BottomNavigationView bottomBar; |
||||||
|
|
||||||
|
private List<Fragment> mFragmentList; |
||||||
|
private Fragment mCurrentFrag; |
||||||
|
private BookFragment mMainFragment; |
||||||
|
private RecommendFragment mRecommendFragment; |
||||||
|
private StackFragment mStackFragment; |
||||||
|
private MoreFragment mMoreFragment; |
||||||
|
|
||||||
|
@SuppressLint("MissingSuperCall") |
||||||
|
@Override |
||||||
|
protected void onSaveInstanceState(Bundle outState) { |
||||||
|
super.onSaveInstanceState(outState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_main; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
bottomBar = findViewById(R.id.bottom_bar); |
||||||
|
mCurrentFrag = new Fragment(); |
||||||
|
mMainFragment = BookFragment.newInstance(); |
||||||
|
mRecommendFragment = RecommendFragment.newInstance(); |
||||||
|
mStackFragment = StackFragment.newInstance(); |
||||||
|
mMoreFragment = MoreFragment.newInstance(); |
||||||
|
|
||||||
|
|
||||||
|
//计算apk的启动次数
|
||||||
|
int count = SpUtil.getIntValue(Constant.InstallCount, 0); |
||||||
|
SpUtil.setIntValue(Constant.InstallCount, count + 1); |
||||||
|
Log.e("count", "count: " + count); |
||||||
|
AccountManager.getInstance().login(this); |
||||||
|
AccountManager.getInstance().checkVersion(VersionUtil.getPackageCode(this)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
bottomBar.setOnNavigationItemSelectedListener(menuItem -> { |
||||||
|
switch (menuItem.getItemId()) { |
||||||
|
case R.id.tab_one: |
||||||
|
switchFragment(mMainFragment); |
||||||
|
return true; |
||||||
|
case R.id.tab_two: |
||||||
|
switchFragment(mRecommendFragment); |
||||||
|
return true; |
||||||
|
case R.id.tab_three: |
||||||
|
switchFragment(mStackFragment); |
||||||
|
return true; |
||||||
|
case R.id.tab_four: |
||||||
|
switchFragment(mMoreFragment); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
}); |
||||||
|
|
||||||
|
if (BookRepository.getInstance().getCollBooks().size() > 0) { |
||||||
|
switchFragment(mMainFragment); |
||||||
|
} else { |
||||||
|
bottomBar.setSelectedItemId(R.id.tab_two); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void switchFragment(Fragment targetFragment) { |
||||||
|
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); |
||||||
|
if (!targetFragment.isAdded()) { |
||||||
|
//第一次使用switchFragment()时currentFragment为null,所以要判断一下
|
||||||
|
if (mCurrentFrag != null) { |
||||||
|
transaction.hide(mCurrentFrag); |
||||||
|
|
||||||
|
} |
||||||
|
transaction.add(R.id.fl_content, targetFragment, targetFragment.getClass().getName()); |
||||||
|
} else { |
||||||
|
transaction.hide(mCurrentFrag).show(targetFragment); |
||||||
|
|
||||||
|
} |
||||||
|
mCurrentFrag = targetFragment; |
||||||
|
transaction.commit(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onResume() { |
||||||
|
super.onResume(); |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
if (SpUtil.getLongValue(Constant.InstallTime) == 0) { |
||||||
|
SpUtil.setLongValue(Constant.InstallTime, System.currentTimeMillis()); |
||||||
|
} else { |
||||||
|
if (DateUtli.checkInstallTime()&&!SpUtil.getBooleanValue(Constant.AppraiseShow)) { |
||||||
|
SpUtil.setBooleanValue(Constant.AppraiseShow, true); |
||||||
|
final AppraiseDialog dialog = new AppraiseDialog(this); |
||||||
|
dialog.AppraiseDialog(view -> { |
||||||
|
goToMarket(this, VersionUtil.getPackage(this)); |
||||||
|
dialog.dismiss(); |
||||||
|
}); |
||||||
|
dialog.show(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onPause() { |
||||||
|
super.onPause(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
|
||||||
|
public static void goToMarket(Context context, String packageName) { |
||||||
|
Uri uri = Uri.parse("market://details?id=" + packageName); |
||||||
|
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); |
||||||
|
final String GOOGLE_PLAY = "com.android.vending";//这里对应的是谷歌商店,跳转别的商店改成对应的即可
|
||||||
|
|
||||||
|
goToMarket.setPackage(GOOGLE_PLAY);//这里对应的是谷歌商店,跳转别的商店改成对应的即可
|
||||||
|
|
||||||
|
try { |
||||||
|
context.startActivity(goToMarket); |
||||||
|
} catch (ActivityNotFoundException e) { |
||||||
|
if (goToMarket.resolveActivity(context.getPackageManager()) != null) { //有浏览器
|
||||||
|
context.startActivity(goToMarket); |
||||||
|
}else { |
||||||
|
ToastUtil.show(context,"未检测到Google应用商店"); |
||||||
|
} |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void checkVersion(VersionEvent event) { |
||||||
|
if (event.isFail()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
if (TextUtils.isEmpty(event.getResult().getVersion().getSize())) { |
||||||
|
return; |
||||||
|
} |
||||||
|
//版本大小不为空 去更新。
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void login(LoginEvent event) { |
||||||
|
if (event.isFail()) { |
||||||
|
Log.e("NovelMainActivity", "login: " + event.getEr().getMsg()); |
||||||
|
} else { |
||||||
|
SpUtil.setStringValue(Constant.Uid, String.valueOf(event.getResult().getUid())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//记录用户首次点击返回键的时间
|
||||||
|
private long firstTime = 0; |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event) { |
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { |
||||||
|
if (!isVisible(bottomBar)) { |
||||||
|
bottomBar.setVisibility(View.VISIBLE); |
||||||
|
mMainFragment.updateBook(new UpdateBookEvent()); |
||||||
|
} else { |
||||||
|
long secondTime = System.currentTimeMillis(); |
||||||
|
if (secondTime - firstTime > 1000) { |
||||||
|
firstTime = secondTime; |
||||||
|
ToastUtil.show(NovelMainActivity.this, "再次点击退出界面"); |
||||||
|
} else { |
||||||
|
finish(); |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return super.onKeyUp(keyCode, event); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void setBottomBar(HideBottomBarEvent event) { |
||||||
|
if (event.getResult()) { |
||||||
|
bottomBar.setVisibility(View.GONE); |
||||||
|
} else { |
||||||
|
bottomBar.setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void reStart(Context context) { |
||||||
|
Intent intent = new Intent(context, NovelMainActivity.class); |
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); |
||||||
|
context.startActivity(intent); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void toRecommendFragment(SwitchFragmentEvent event) { |
||||||
|
// switchFragment(mRecommendFragment);
|
||||||
|
bottomBar.setSelectedItemId(R.id.tab_two); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,131 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.RankListAdapter; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.RankByUpadateResp; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import retrofit2.Call; |
||||||
|
import retrofit2.Callback; |
||||||
|
import retrofit2.Response; |
||||||
|
|
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
/** |
||||||
|
* 推荐fragment中点击更多跳转来的。 |
||||||
|
*/ |
||||||
|
public class NovelRankListActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.rlv_book_list) |
||||||
|
RecyclerView mRlvBookList; |
||||||
|
private RankListAdapter mAdapter; |
||||||
|
private List<RankByUpadateResp.BookBean> mList; |
||||||
|
private int page = 1; |
||||||
|
private int loadSize; |
||||||
|
private String type; |
||||||
|
private String sex; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_rank_list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
mList = new ArrayList<>(); |
||||||
|
|
||||||
|
mRlvBookList.setLayoutManager(new LinearLayoutManager(this)); |
||||||
|
mAdapter = new RankListAdapter(mList, mRlvBookList); |
||||||
|
mRlvBookList.setAdapter(mAdapter); |
||||||
|
sex = getIntent().getStringExtra(Constant.Sex); |
||||||
|
type = getIntent().getStringExtra(Constant.Type); |
||||||
|
switch (type) { |
||||||
|
case Constant.ListType.Human: |
||||||
|
toolbar.setTitle(getString(R.string.popular_selection)); |
||||||
|
break; |
||||||
|
case Constant.ListType.EditRecommend: |
||||||
|
toolbar.setTitle(getString(R.string.edit_recommend)); |
||||||
|
break; |
||||||
|
case Constant.ListType.HotSearch: |
||||||
|
toolbar.setTitle(getString(R.string.hot_search)); |
||||||
|
break; |
||||||
|
} |
||||||
|
getData(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
toolbar.setNavigationOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
finish(); |
||||||
|
} |
||||||
|
}); |
||||||
|
mAdapter.setOnLoadMoreListener(() -> { |
||||||
|
if (mAdapter.isLoadingMore()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
if (loadSize >= COMMENT_SIZE) { |
||||||
|
mAdapter.setLoadingMore(true); |
||||||
|
mList.add(null); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
page++; |
||||||
|
getData(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData() { |
||||||
|
AccountManager.getInstance().getRankList(type, sex, Constant.DateTyp.Week, String.valueOf(page), new RankCallBack()); |
||||||
|
} |
||||||
|
|
||||||
|
private class RankCallBack implements Callback<RankByUpadateResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RankByUpadateResp> call, @NonNull Response<RankByUpadateResp> response) { |
||||||
|
if (response.isSuccessful()) { |
||||||
|
if (response.body() != null) { |
||||||
|
loadSize = response.body().getBook().size(); |
||||||
|
if (mAdapter.isLoadingMore()) { |
||||||
|
mList.remove(mList.size() - 1); |
||||||
|
mList.addAll(response.body().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
mAdapter.setLoadingMore(false); |
||||||
|
} else { |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(response.body().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(@NonNull Call<RankByUpadateResp> call, @NonNull Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,813 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.app.Activity; |
||||||
|
import android.app.Service; |
||||||
|
import android.content.BroadcastReceiver; |
||||||
|
import android.content.ComponentName; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.content.IntentFilter; |
||||||
|
import android.content.ServiceConnection; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.os.Build; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.IBinder; |
||||||
|
import android.os.Message; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.Gravity; |
||||||
|
import android.view.KeyEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.WindowManager; |
||||||
|
import android.view.animation.Animation; |
||||||
|
import android.view.animation.AnimationUtils; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
import android.widget.ListView; |
||||||
|
import android.widget.SeekBar; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog; |
||||||
|
import androidx.appcompat.widget.LinearLayoutCompat; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout; |
||||||
|
import androidx.core.content.ContextCompat; |
||||||
|
import androidx.core.view.GravityCompat; |
||||||
|
import androidx.core.widget.ContentLoadingProgressBar; |
||||||
|
import androidx.drawerlayout.widget.DrawerLayout; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.common_lib.base.utils.ToastUtils; |
||||||
|
import com.google.android.material.appbar.AppBarLayout; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.BuildConfig; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.CategoryAdapter; |
||||||
|
import com.novel.read.adapter.MarkAdapter; |
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.AddBookSignEvent; |
||||||
|
import com.novel.read.event.BookArticleEvent; |
||||||
|
import com.novel.read.event.DeleteBookSignEvent; |
||||||
|
import com.novel.read.event.ErrorChapterEvent; |
||||||
|
import com.novel.read.event.FinishChapterEvent; |
||||||
|
import com.novel.read.event.GetBookSignEvent; |
||||||
|
import com.novel.read.event.RxBus; |
||||||
|
import com.novel.read.event.SetAdsBgEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.db.BookChapterBean; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
import com.novel.read.model.db.DownloadTaskBean; |
||||||
|
import com.novel.read.model.db.dbManage.BookRepository; |
||||||
|
import com.novel.read.model.protocol.MarkResp; |
||||||
|
import com.novel.read.service.DownloadMessage; |
||||||
|
import com.novel.read.service.DownloadService; |
||||||
|
import com.novel.read.utlis.BrightnessUtils; |
||||||
|
import com.novel.read.utlis.ScreenUtils; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.novel.read.utlis.SystemBarUtils; |
||||||
|
import com.novel.read.widget.dialog.ReadSettingDialog; |
||||||
|
import com.novel.read.widget.page.PageLoader; |
||||||
|
import com.novel.read.widget.page.PageView; |
||||||
|
import com.novel.read.widget.page.ReadSettingManager; |
||||||
|
import com.novel.read.widget.page.TxtChapter; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
|
||||||
|
import static android.view.View.GONE; |
||||||
|
import static android.view.View.LAYER_TYPE_SOFTWARE; |
||||||
|
import static android.view.View.VISIBLE; |
||||||
|
import static com.novel.read.constants.Constant.ResultCode.RESULT_IS_COLLECTED; |
||||||
|
|
||||||
|
public class NovelReadActivity extends NovelBaseActivity implements DownloadService.OnDownloadListener { |
||||||
|
|
||||||
|
@BindView(R.id.read_pv_page) |
||||||
|
PageView mPvPage; |
||||||
|
@BindView(R.id.read_abl_top_menu) |
||||||
|
AppBarLayout mAblTopMenu; |
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.read_ll_bottom_menu) |
||||||
|
LinearLayoutCompat mLlBottomMenu; |
||||||
|
|
||||||
|
@BindView(R.id.read_dl_slide) |
||||||
|
DrawerLayout mDlSlide; |
||||||
|
@BindView(R.id.read_tv_category) |
||||||
|
TextView mTvCategory; |
||||||
|
@BindView(R.id.tv_light) |
||||||
|
TextView mTvLight; |
||||||
|
@BindView(R.id.read_setting_sb_brightness) |
||||||
|
SeekBar mSbBrightness; |
||||||
|
@BindView(R.id.tvBookReadMode) |
||||||
|
TextView mTvNightMode; |
||||||
|
@BindView(R.id.ll_light) |
||||||
|
LinearLayoutCompat mLLight; |
||||||
|
@BindView(R.id.tv_cache) |
||||||
|
TextView mTvCache; |
||||||
|
@BindView(R.id.tv_setting) |
||||||
|
TextView mTvSetting; |
||||||
|
@BindView(R.id.rlv_list) |
||||||
|
ListView mLvCategory; |
||||||
|
@BindView(R.id.tv_book_name) |
||||||
|
TextView mTvBookName; |
||||||
|
@BindView(R.id.read_tv_brief) |
||||||
|
TextView mTvBrief; |
||||||
|
@BindView(R.id.read_tv_community) |
||||||
|
TextView mTvMark; |
||||||
|
@BindView(R.id.rlReadMark) |
||||||
|
ConstraintLayout rlReadMark; |
||||||
|
@BindView(R.id.tvAddMark) |
||||||
|
TextView mTvAddMark; |
||||||
|
@BindView(R.id.tvClear) |
||||||
|
TextView mTvClear; |
||||||
|
@BindView(R.id.rlv_mark) |
||||||
|
RecyclerView mRlvMark; |
||||||
|
@BindView(R.id.ll_download) |
||||||
|
LinearLayoutCompat mLlDownLoad; |
||||||
|
@BindView(R.id.pb_loading) |
||||||
|
ContentLoadingProgressBar loadingProgressBar; |
||||||
|
@BindView(R.id.tv_progress) |
||||||
|
TextView mTvProgress; |
||||||
|
@BindView(R.id.cl_layout) |
||||||
|
ConstraintLayout mClLayout; |
||||||
|
@BindView(R.id.iv_guide) |
||||||
|
ImageView mIvGuide; |
||||||
|
private CategoryAdapter mCategoryAdapter; |
||||||
|
private List<TxtChapter> mChapters = new ArrayList<>(); |
||||||
|
private TxtChapter mCurrentChapter; //当前章节
|
||||||
|
private int currentChapter = 0; |
||||||
|
private MarkAdapter mMarkAdapter; |
||||||
|
private List<MarkResp.SignBean> mMarks = new ArrayList<>(); |
||||||
|
private PageLoader mPageLoader; |
||||||
|
private Animation mTopInAnim; |
||||||
|
private Animation mTopOutAnim; |
||||||
|
private Animation mBottomInAnim; |
||||||
|
private Animation mBottomOutAnim; |
||||||
|
|
||||||
|
private ReadSettingDialog mSettingDialog; |
||||||
|
private boolean isCollected = false; // isFromSDCard
|
||||||
|
private boolean isNightMode = false; |
||||||
|
private boolean isFullScreen = false; |
||||||
|
private boolean isRegistered = false; |
||||||
|
|
||||||
|
private CollBookBean mCollBook; |
||||||
|
private String mBookId; |
||||||
|
|
||||||
|
private static final String TAG = "NovelReadActivity"; |
||||||
|
public static final String EXTRA_COLL_BOOK = "extra_coll_book"; |
||||||
|
public static final String EXTRA_IS_COLLECTED = "extra_is_collected"; |
||||||
|
private static final int WHAT_CATEGORY = 1; |
||||||
|
private static final int WHAT_CHAPTER = 2; |
||||||
|
|
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
private Handler mHandler = new Handler() { |
||||||
|
@Override |
||||||
|
public void handleMessage(Message msg) { |
||||||
|
super.handleMessage(msg); |
||||||
|
switch (msg.what) { |
||||||
|
case WHAT_CATEGORY: |
||||||
|
mLvCategory.setSelection(mPageLoader.getChapterPos()); |
||||||
|
break; |
||||||
|
case WHAT_CHAPTER: |
||||||
|
mPageLoader.openChapter(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_read; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
mCollBook = (CollBookBean) getIntent().getSerializableExtra(EXTRA_COLL_BOOK); |
||||||
|
isCollected = getIntent().getBooleanExtra(EXTRA_IS_COLLECTED, false); |
||||||
|
mBookId = mCollBook.getId(); |
||||||
|
initService(); |
||||||
|
// 如果 API < 18 取消硬件加速
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { |
||||||
|
mPvPage.setLayerType(LAYER_TYPE_SOFTWARE, null); |
||||||
|
} |
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
||||||
|
|
||||||
|
//获取页面加载器
|
||||||
|
mPageLoader = mPvPage.getPageLoader(mCollBook); |
||||||
|
|
||||||
|
mSettingDialog = new ReadSettingDialog(this, mPageLoader); |
||||||
|
//禁止滑动展示DrawerLayout
|
||||||
|
mDlSlide.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); |
||||||
|
//侧边打开后,返回键能够起作用
|
||||||
|
mDlSlide.setFocusableInTouchMode(false); |
||||||
|
//半透明化StatusBar
|
||||||
|
SystemBarUtils.transparentStatusBar(this); |
||||||
|
//隐藏StatusBar
|
||||||
|
mPvPage.post( |
||||||
|
this::hideSystemBar |
||||||
|
); |
||||||
|
mAblTopMenu.setPadding(0, ScreenUtils.getStatusBarHeight(), 0, 0); |
||||||
|
mLlDownLoad.setPadding(0, ScreenUtils.getStatusBarHeight(), 0, ScreenUtils.dpToPx(15)); |
||||||
|
|
||||||
|
WindowManager.LayoutParams lp = getWindow().getAttributes(); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { |
||||||
|
lp.layoutInDisplayCutoutMode = 1; |
||||||
|
} |
||||||
|
getWindow().setAttributes(lp); |
||||||
|
|
||||||
|
//设置当前Activity的Brightness
|
||||||
|
if (ReadSettingManager.getInstance().isBrightnessAuto()) { |
||||||
|
BrightnessUtils.setDefaultBrightness(this); |
||||||
|
} else { |
||||||
|
BrightnessUtils.setBrightness(this, ReadSettingManager.getInstance().getBrightness()); |
||||||
|
} |
||||||
|
|
||||||
|
//注册广播
|
||||||
|
IntentFilter intentFilter = new IntentFilter(); |
||||||
|
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); |
||||||
|
intentFilter.addAction(Intent.ACTION_TIME_TICK); |
||||||
|
registerReceiver(mReceiver, intentFilter); |
||||||
|
|
||||||
|
if (!SpUtil.getBooleanValue(Constant.BookGuide,false)){ |
||||||
|
mIvGuide.setVisibility(VISIBLE); |
||||||
|
toggleMenu(false); |
||||||
|
} |
||||||
|
|
||||||
|
Log.e(TAG, "mBookId: " + mBookId); |
||||||
|
if (isCollected) { |
||||||
|
mPageLoader.getCollBook().setBookChapters(BookRepository.getInstance().getBookChaptersInRx(mBookId)); |
||||||
|
// 刷新章节列表
|
||||||
|
mPageLoader.refreshChapterList(); |
||||||
|
// 如果是网络小说并被标记更新的,则从网络下载目录
|
||||||
|
if (mCollBook.isUpdate() && !mCollBook.isLocal()) { |
||||||
|
AccountManager.getInstance().getBookArticle(mBookId, "2", "1", "10000"); |
||||||
|
} |
||||||
|
} else { |
||||||
|
AccountManager.getInstance().getBookArticle(mBookId, "2", "1", "10000"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setAdsBg(new SetAdsBgEvent()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
mTvBookName.setText(mCollBook.getTitle()); |
||||||
|
mCategoryAdapter = new CategoryAdapter(); |
||||||
|
mLvCategory.setAdapter(mCategoryAdapter); |
||||||
|
mLvCategory.setFastScrollEnabled(true); |
||||||
|
mRlvMark.setLayoutManager(new LinearLayoutManager(this)); |
||||||
|
mMarkAdapter = new MarkAdapter(mMarks); |
||||||
|
mRlvMark.setAdapter(mMarkAdapter); |
||||||
|
isNightMode = ReadSettingManager.getInstance().isNightMode(); |
||||||
|
//夜间模式按钮的状态
|
||||||
|
toggleNightMode(); |
||||||
|
isFullScreen = ReadSettingManager.getInstance().isFullScreen(); |
||||||
|
toolbar.setNavigationOnClickListener(view -> finish()); |
||||||
|
mSbBrightness.setProgress(ReadSettingManager.getInstance().getBrightness()); |
||||||
|
mPageLoader.setOnPageChangeListener( |
||||||
|
new PageLoader.OnPageChangeListener() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onChapterChange(int pos) { |
||||||
|
mCategoryAdapter.setChapter(pos); |
||||||
|
mCurrentChapter = mChapters.get(pos); |
||||||
|
currentChapter = pos; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void requestChapters(List<TxtChapter> requestChapters) { |
||||||
|
AccountManager.getInstance().getBookArticleDetail(mBookId, requestChapters); |
||||||
|
mHandler.sendEmptyMessage(WHAT_CATEGORY); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onCategoryFinish(List<TxtChapter> chapters) { |
||||||
|
mChapters.clear(); |
||||||
|
mChapters.addAll(chapters); |
||||||
|
mCategoryAdapter.refreshItems(mChapters); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPageCountChange(int count) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPageChange(int pos) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
mPvPage.setTouchListener(new PageView.TouchListener() { |
||||||
|
@Override |
||||||
|
public boolean onTouch() { |
||||||
|
return !hideReadMenu(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void center() { |
||||||
|
toggleMenu(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void prePage() { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void nextPage() { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void cancel() { |
||||||
|
} |
||||||
|
}); |
||||||
|
mTvCategory.setOnClickListener( |
||||||
|
(v) -> { |
||||||
|
//移动到指定位置
|
||||||
|
if (mCategoryAdapter.getCount() > 0) { |
||||||
|
mLvCategory.setSelection(mPageLoader.getChapterPos()); |
||||||
|
} |
||||||
|
//切换菜单
|
||||||
|
toggleMenu(true); |
||||||
|
//打开侧滑动栏
|
||||||
|
mDlSlide.openDrawer(GravityCompat.START); |
||||||
|
} |
||||||
|
); |
||||||
|
mTvLight.setOnClickListener(view -> { |
||||||
|
mLLight.setVisibility(GONE); |
||||||
|
rlReadMark.setVisibility(GONE); |
||||||
|
if (isVisible(mLLight)) { |
||||||
|
mLLight.setVisibility(GONE); |
||||||
|
} else { |
||||||
|
mLLight.setVisibility(VISIBLE); |
||||||
|
} |
||||||
|
}); |
||||||
|
mTvSetting.setOnClickListener(view -> { |
||||||
|
mLLight.setVisibility(GONE); |
||||||
|
rlReadMark.setVisibility(GONE); |
||||||
|
toggleMenu(false); |
||||||
|
mSettingDialog.show(); |
||||||
|
}); |
||||||
|
|
||||||
|
mSbBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { |
||||||
|
@Override |
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) { |
||||||
|
int progress = seekBar.getProgress(); |
||||||
|
//设置当前 Activity 的亮度
|
||||||
|
BrightnessUtils.setBrightness(NovelReadActivity.this, progress); |
||||||
|
//存储亮度的进度条
|
||||||
|
ReadSettingManager.getInstance().setBrightness(progress); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
mTvNightMode.setOnClickListener( |
||||||
|
(v) -> { |
||||||
|
isNightMode = !isNightMode; |
||||||
|
mPageLoader.setNightMode(isNightMode); |
||||||
|
toggleNightMode(); |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
mTvBrief.setOnClickListener(view -> { |
||||||
|
Intent intent = new Intent(this, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, Integer.valueOf(mBookId)); |
||||||
|
startActivity(intent); |
||||||
|
}); |
||||||
|
|
||||||
|
mTvMark.setOnClickListener(view -> { |
||||||
|
if (isVisible(mLlBottomMenu)) { |
||||||
|
if (isVisible(rlReadMark)) { |
||||||
|
gone(rlReadMark); |
||||||
|
} else { |
||||||
|
gone(mLLight); |
||||||
|
updateMark(); |
||||||
|
visible(rlReadMark); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
mTvAddMark.setOnClickListener(view -> { |
||||||
|
if (mCurrentChapter != null) { |
||||||
|
mMarkAdapter.setEdit(false); |
||||||
|
AccountManager.getInstance().addSign(mBookId, mCurrentChapter.getChapterId(), mCurrentChapter.getTitle()); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
mTvClear.setOnClickListener(view -> { |
||||||
|
if (mMarkAdapter.getEdit()) { |
||||||
|
String sign = mMarkAdapter.getSelectList(); |
||||||
|
if (!sign.equals("")) { |
||||||
|
AccountManager.getInstance().deleteSign(sign); |
||||||
|
} |
||||||
|
mMarkAdapter.setEdit(false); |
||||||
|
} else { |
||||||
|
mMarkAdapter.setEdit(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
mTvCache.setOnClickListener(view -> { |
||||||
|
if (!isCollected) { //没有收藏 先收藏 然后弹框
|
||||||
|
//设置为已收藏
|
||||||
|
isCollected = true; |
||||||
|
//设置阅读时间
|
||||||
|
mCollBook.setLastRead(String.valueOf(System.currentTimeMillis())); |
||||||
|
BookRepository.getInstance().saveCollBookWithAsync(mCollBook); |
||||||
|
} |
||||||
|
showDownLoadDialog(); |
||||||
|
|
||||||
|
}); |
||||||
|
mLvCategory.setOnItemClickListener((parent, view, position, id) -> { |
||||||
|
mDlSlide.closeDrawer(GravityCompat.START); |
||||||
|
mPageLoader.skipToChapter(position); |
||||||
|
}); |
||||||
|
mIvGuide.setOnClickListener(view -> { |
||||||
|
mIvGuide.setVisibility(GONE); |
||||||
|
SpUtil.setBooleanValue(Constant.BookGuide, true); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void showDownLoadDialog() { |
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this); |
||||||
|
builder.setTitle(getString(R.string.d_cache_num)) |
||||||
|
.setItems(new String[]{getString(R.string.d_cache_last_50), getString(R.string.d_cache_last_all), getString(R.string.d_cache_all)}, (dialog, which) -> { |
||||||
|
switch (which) { |
||||||
|
case 0: //50章
|
||||||
|
int last = currentChapter + 50; |
||||||
|
if (last > mCollBook.getBookChapters().size()) { |
||||||
|
downLoadCache(mCollBook.getBookChapters(), mCollBook.getBookChapters().size()); |
||||||
|
} else { |
||||||
|
downLoadCache(mCollBook.getBookChapters(), last); |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
case 1: //后面所有
|
||||||
|
List<BookChapterBean> lastBeans = new ArrayList<>(); |
||||||
|
for (int i = currentChapter; i < mCollBook.getBookChapters().size(); i++) { |
||||||
|
lastBeans.add(mCollBook.getBookChapters().get(i)); |
||||||
|
} |
||||||
|
downLoadCache(lastBeans, mCollBook.getBookChapters().size() - currentChapter); |
||||||
|
break; |
||||||
|
case 2: //所有
|
||||||
|
downLoadCache(mCollBook.getBookChapters(), mCollBook.getBookChapters().size()); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
toggleMenu(true); |
||||||
|
}); |
||||||
|
builder.show(); |
||||||
|
} |
||||||
|
|
||||||
|
private void downLoadCache(List<BookChapterBean> beans, int size) { |
||||||
|
DownloadTaskBean task = new DownloadTaskBean(); |
||||||
|
task.setTaskName(mCollBook.getTitle()); |
||||||
|
task.setBookId(mCollBook.getId()); |
||||||
|
task.setBookChapters(beans); //计算要缓存的章节
|
||||||
|
task.setCurrentChapter(currentChapter); |
||||||
|
task.setLastChapter(size); |
||||||
|
|
||||||
|
RxBus.getInstance().post(task); |
||||||
|
startService(new Intent(this, DownloadService.class)); |
||||||
|
} |
||||||
|
|
||||||
|
private void toggleNightMode() { |
||||||
|
if (isNightMode) { |
||||||
|
mTvNightMode.setText(getResources().getString(R.string.book_read_mode_day)); |
||||||
|
Drawable drawable = ContextCompat.getDrawable(this, R.drawable.ic_read_menu_moring); |
||||||
|
mTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null); |
||||||
|
mClLayout.setBackgroundColor(getResources().getColor(R.color.nb_read_bg_night)); |
||||||
|
} else { |
||||||
|
mTvNightMode.setText(getResources().getString(R.string.book_read_mode_day)); |
||||||
|
Drawable drawable = ContextCompat.getDrawable(this, R.drawable.ic_read_menu_night); |
||||||
|
mTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null); |
||||||
|
mClLayout.setBackgroundColor(getResources().getColor(ReadSettingManager.getInstance().getPageStyle().getBgColor())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 隐藏阅读界面的菜单显示 |
||||||
|
* |
||||||
|
* @return 是否隐藏成功 |
||||||
|
*/ |
||||||
|
private boolean hideReadMenu() { |
||||||
|
hideSystemBar(); |
||||||
|
if (mAblTopMenu.getVisibility() == VISIBLE) { |
||||||
|
toggleMenu(true); |
||||||
|
return true; |
||||||
|
} else if (mSettingDialog.isShowing()) { |
||||||
|
mSettingDialog.dismiss(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private void showSystemBar() { |
||||||
|
//显示
|
||||||
|
SystemBarUtils.showUnStableStatusBar(this); |
||||||
|
if (isFullScreen) { |
||||||
|
SystemBarUtils.showUnStableNavBar(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void hideSystemBar() { |
||||||
|
//隐藏
|
||||||
|
SystemBarUtils.hideStableStatusBar(this); |
||||||
|
if (isFullScreen) { |
||||||
|
SystemBarUtils.hideStableNavBar(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换菜单栏的可视状态 |
||||||
|
* 默认是隐藏的 |
||||||
|
*/ |
||||||
|
private void toggleMenu(boolean hideStatusBar) { |
||||||
|
initMenuAnim(); |
||||||
|
gone(mLLight, rlReadMark); |
||||||
|
if (mAblTopMenu.getVisibility() == View.VISIBLE) { |
||||||
|
//关闭
|
||||||
|
mAblTopMenu.startAnimation(mTopOutAnim); |
||||||
|
mLlBottomMenu.startAnimation(mBottomOutAnim); |
||||||
|
mAblTopMenu.setVisibility(GONE); |
||||||
|
mLlBottomMenu.setVisibility(GONE); |
||||||
|
|
||||||
|
if (hideStatusBar) { |
||||||
|
hideSystemBar(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
mAblTopMenu.setVisibility(View.VISIBLE); |
||||||
|
mLlBottomMenu.setVisibility(View.VISIBLE); |
||||||
|
mAblTopMenu.startAnimation(mTopInAnim); |
||||||
|
mLlBottomMenu.startAnimation(mBottomInAnim); |
||||||
|
|
||||||
|
showSystemBar(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//初始化菜单动画
|
||||||
|
private void initMenuAnim() { |
||||||
|
if (mTopInAnim != null) return; |
||||||
|
mTopInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_in); |
||||||
|
mTopOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_out); |
||||||
|
mBottomInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_in); |
||||||
|
mBottomOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_out); |
||||||
|
//退出的速度要快
|
||||||
|
mTopOutAnim.setDuration(200); |
||||||
|
mBottomOutAnim.setDuration(200); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getBookArticle(BookArticleEvent event) { |
||||||
|
Log.e(TAG, "getBookArticle: "); |
||||||
|
if (event.isFail()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
List<BookChapterBean> chapterBeans = event.getResult().getChapterBean(); |
||||||
|
mPageLoader.getCollBook().setBookChapters(chapterBeans); |
||||||
|
mPageLoader.refreshChapterList(); |
||||||
|
|
||||||
|
// 如果是目录更新的情况,那么就需要存储更新数据
|
||||||
|
if (mCollBook.isUpdate() && isCollected) { |
||||||
|
BookRepository.getInstance().saveBookChaptersWithAsync(event.getResult().getChapterBean(), mCollBook); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void finishChapter(FinishChapterEvent event) { |
||||||
|
if (mPageLoader.getPageStatus() == PageLoader.STATUS_LOADING) { |
||||||
|
mHandler.sendEmptyMessage(WHAT_CHAPTER); |
||||||
|
} |
||||||
|
// 当完成章节的时候,刷新列表
|
||||||
|
mCategoryAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void errorChapter(ErrorChapterEvent event) { |
||||||
|
if (mPageLoader.getPageStatus() == PageLoader.STATUS_LOADING) { |
||||||
|
mPageLoader.chapterError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void updateMark() { |
||||||
|
AccountManager.getInstance().getSignList(mBookId); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void addSign(AddBookSignEvent event) { |
||||||
|
if (event.isFail()) { |
||||||
|
ToastUtils.showNormalToast(this, "添加书签失败,请检查网络设置"); |
||||||
|
} else { |
||||||
|
ToastUtils.showNormalToast(this, "添加书签成功"); |
||||||
|
updateMark(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void deleteSigin(DeleteBookSignEvent event) { |
||||||
|
if (event.isFail()) { |
||||||
|
ToastUtils.showNormalToast(this, event.getEr().getMsg()); |
||||||
|
} else { |
||||||
|
ToastUtils.showNormalToast(this, event.getResult().getMsg()); |
||||||
|
updateMark(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getSignList(GetBookSignEvent event) { |
||||||
|
if (event.isFail()) { |
||||||
|
ToastUtils.showNormalToast(this, "获取书签失败,请检查网络设置"); |
||||||
|
} else { |
||||||
|
mMarks.clear(); |
||||||
|
mMarks.addAll(event.getResult().getSign()); |
||||||
|
mMarkAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 接收电池信息和时间更新的广播
|
||||||
|
private BroadcastReceiver mReceiver = new BroadcastReceiver() { |
||||||
|
@Override |
||||||
|
public void onReceive(Context context, Intent intent) { |
||||||
|
if (Objects.requireNonNull(intent.getAction()).equals(Intent.ACTION_BATTERY_CHANGED)) { |
||||||
|
int level = intent.getIntExtra("level", 0); |
||||||
|
mPageLoader.updateBattery(level); |
||||||
|
} |
||||||
|
// 监听分钟的变化
|
||||||
|
else if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { |
||||||
|
mPageLoader.updateTime(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void setAdsBg(SetAdsBgEvent event) { |
||||||
|
mClLayout.setBackgroundColor(getResources().getColor(ReadSettingManager.getInstance().getPageStyle().getBgColor())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) { |
||||||
|
switch (keyCode) { |
||||||
|
case KeyEvent.KEYCODE_VOLUME_UP: |
||||||
|
return mPageLoader.skipToPrePage(); |
||||||
|
|
||||||
|
case KeyEvent.KEYCODE_VOLUME_DOWN: |
||||||
|
return mPageLoader.skipToNextPage(); |
||||||
|
} |
||||||
|
return super.onKeyDown(keyCode, event); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBackPressed() { |
||||||
|
if (mAblTopMenu.getVisibility() == View.VISIBLE) { |
||||||
|
// 非全屏下才收缩,全屏下直接退出
|
||||||
|
if (!ReadSettingManager.getInstance().isFullScreen()) { |
||||||
|
toggleMenu(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
} else if (mSettingDialog.isShowing()) { |
||||||
|
mSettingDialog.dismiss(); |
||||||
|
return; |
||||||
|
}else if (mDlSlide.isDrawerOpen(GravityCompat.START)) { |
||||||
|
mDlSlide.closeDrawer(GravityCompat.START); |
||||||
|
return; |
||||||
|
} |
||||||
|
Log.e(TAG, "onBackPressed: " + mCollBook.getBookChapters().isEmpty()); |
||||||
|
|
||||||
|
if (!mCollBook.isLocal() && !isCollected && !mCollBook.getBookChapters().isEmpty()) { |
||||||
|
AlertDialog alertDialog = new AlertDialog.Builder(this) |
||||||
|
.setTitle(getString(R.string.add_book)) |
||||||
|
.setMessage(getString(R.string.like_book)) |
||||||
|
.setPositiveButton(getString(R.string.sure), (dialog, which) -> { |
||||||
|
//设置为已收藏
|
||||||
|
isCollected = true; |
||||||
|
//设置阅读时间
|
||||||
|
mCollBook.setLastRead(String.valueOf(System.currentTimeMillis())); |
||||||
|
|
||||||
|
BookRepository.getInstance().saveCollBookWithAsync(mCollBook); |
||||||
|
|
||||||
|
exit(); |
||||||
|
}) |
||||||
|
.setNegativeButton(getString(R.string.cancel), (dialog, which) -> exit()).create(); |
||||||
|
alertDialog.show(); |
||||||
|
} else { |
||||||
|
exit(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 退出
|
||||||
|
private void exit() { |
||||||
|
// 返回给BookDetail。
|
||||||
|
Intent result = new Intent(); |
||||||
|
result.putExtra(RESULT_IS_COLLECTED, isCollected); |
||||||
|
setResult(Activity.RESULT_OK, result); |
||||||
|
// 退出
|
||||||
|
super.onBackPressed(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onPause() { |
||||||
|
super.onPause(); |
||||||
|
if (isCollected) { |
||||||
|
mPageLoader.saveRecord(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
mPageLoader.closeBook(); |
||||||
|
mPageLoader = null; |
||||||
|
unbindService(mConn); |
||||||
|
unregisterReceiver(mReceiver); |
||||||
|
} |
||||||
|
|
||||||
|
private DownloadService.IDownloadManager mService; |
||||||
|
private ServiceConnection mConn; |
||||||
|
|
||||||
|
private void initService() { |
||||||
|
|
||||||
|
mConn = new ServiceConnection() { |
||||||
|
@Override |
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) { |
||||||
|
mService = (DownloadService.IDownloadManager) service; |
||||||
|
mService.setOnDownloadListener(NovelReadActivity.this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onServiceDisconnected(ComponentName name) { |
||||||
|
} |
||||||
|
}; |
||||||
|
//绑定
|
||||||
|
bindService(new Intent(this, DownloadService.class), mConn, Service.BIND_AUTO_CREATE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDownloadChange(int pos, int status, String msg) { |
||||||
|
// DownloadTaskBean bean = mDownloadAdapter.getItem(pos);
|
||||||
|
// bean.setStatus(status);
|
||||||
|
// if (DownloadTaskBean.STATUS_LOADING == status){
|
||||||
|
// bean.setCurrentChapter(Integer.valueOf(msg));
|
||||||
|
// }
|
||||||
|
// mDownloadAdapter.notifyItemChanged(pos);
|
||||||
|
Log.e(TAG, "onDownloadChange: " + pos + " " + status + " " + msg); |
||||||
|
|
||||||
|
if (msg.equals(getString(R.string.download_success)) || msg.equals(getString(R.string.download_error))) { |
||||||
|
//下载成功或失败后隐藏下载视图
|
||||||
|
if (mLlDownLoad != null) { |
||||||
|
mLlDownLoad.setVisibility(GONE); |
||||||
|
ToastUtils.showNormalToast(this, msg); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (mLlDownLoad != null) { |
||||||
|
mLlDownLoad.setVisibility(VISIBLE); |
||||||
|
mTvProgress.setText(getString(R.string.download_loading, |
||||||
|
mService.getDownloadTaskList().get(pos).getCurrentChapter(), |
||||||
|
mService.getDownloadTaskList().get(pos).getLastChapter())); |
||||||
|
loadingProgressBar.setMax(mService.getDownloadTaskList().get(pos).getLastChapter()); |
||||||
|
loadingProgressBar.setProgress(mService.getDownloadTaskList().get(pos).getCurrentChapter()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDownloadResponse(int pos, int status) { |
||||||
|
// DownloadTaskBean bean = mDownloadAdapter.getItem(pos);
|
||||||
|
// bean.setStatus(status);
|
||||||
|
// mDownloadAdapter.notifyItemChanged(pos);
|
||||||
|
Log.e(TAG, "onDownloadResponse: " + pos + " " + status); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void onDownLoadEvent(DownloadMessage message) { |
||||||
|
ToastUtils.showNormalToast(this, message.message); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,105 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.fragment.app.Fragment; |
||||||
|
import androidx.viewpager.widget.ViewPager; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.ViewPageAdapter; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.fragment.BookListFragment; |
||||||
|
import com.novel.read.widget.VpTabLayout; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
|
||||||
|
public class NovelRecommendBookListActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.vp_tab) |
||||||
|
VpTabLayout mVpTab; |
||||||
|
@BindView(R.id.vp_recommend_type) |
||||||
|
ViewPager mVpRecommendType; |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_recommend_book_list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
List<Fragment> fragmentList = new ArrayList<>(); |
||||||
|
String sex = getIntent().getStringExtra(Constant.Sex); |
||||||
|
String type = getIntent().getStringExtra(Constant.Type); |
||||||
|
if (type.equals(Constant.ListType.Human)){ |
||||||
|
toolbar.setTitle(getString(R.string.popular_selection)); |
||||||
|
}else if (type.equals(Constant.ListType.EditRecommend)){ |
||||||
|
toolbar.setTitle(getString(R.string.edit_recommend)); |
||||||
|
}else if (type.equals(Constant.ListType.HotSearch)){ |
||||||
|
toolbar.setTitle(getString(R.string.hot_search)); |
||||||
|
} |
||||||
|
|
||||||
|
BookListFragment generalFragment = BookListFragment.newInstance(type, Constant.DateTyp.General, sex); |
||||||
|
BookListFragment monthFragment = BookListFragment.newInstance(type, Constant.DateTyp.Month, sex); |
||||||
|
BookListFragment weekFragment = BookListFragment.newInstance(type, Constant.DateTyp.Week, sex); |
||||||
|
fragmentList.add(generalFragment); |
||||||
|
fragmentList.add(monthFragment); |
||||||
|
fragmentList.add(weekFragment); |
||||||
|
ViewPageAdapter pageAdapter = new ViewPageAdapter(getSupportFragmentManager(), fragmentList); |
||||||
|
mVpRecommendType.setAdapter(pageAdapter); |
||||||
|
mVpRecommendType.setOffscreenPageLimit(2); |
||||||
|
mVpRecommendType.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { |
||||||
|
@Override |
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPageSelected(int position) { |
||||||
|
mVpTab.setAnim(position, mVpRecommendType); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPageScrollStateChanged(int state) { |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
toolbar.setNavigationOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
finish(); |
||||||
|
} |
||||||
|
}); |
||||||
|
mVpTab.setOnTabBtnClickListener(new VpTabLayout.OnTabClickListener() { |
||||||
|
@Override |
||||||
|
public void onTabBtnClick(VpTabLayout.CommonTabBtn var1, View var2) { |
||||||
|
switch (var1) { |
||||||
|
case ONE: |
||||||
|
mVpTab.setAnim(0, mVpRecommendType); |
||||||
|
break; |
||||||
|
case TWO: |
||||||
|
mVpTab.setAnim(1, mVpRecommendType); |
||||||
|
break; |
||||||
|
case THREE: |
||||||
|
mVpTab.setAnim(2, mVpRecommendType); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,295 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
import android.text.Editable; |
||||||
|
import android.text.TextUtils; |
||||||
|
import android.text.TextWatcher; |
||||||
|
import android.view.KeyEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.EditText; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.google.android.flexbox.AlignItems; |
||||||
|
import com.google.android.flexbox.FlexDirection; |
||||||
|
import com.google.android.flexbox.FlexWrap; |
||||||
|
import com.google.android.flexbox.FlexboxLayoutManager; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.HistoryAdapter; |
||||||
|
import com.novel.read.adapter.HotAdapter; |
||||||
|
import com.novel.read.adapter.SearchAdapter; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.event.HotSearchEvent; |
||||||
|
import com.novel.read.event.SearchListEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.db.SearchListTable; |
||||||
|
import com.novel.read.model.protocol.SearchResp; |
||||||
|
import com.novel.read.utlis.DialogUtils; |
||||||
|
import com.novel.read.widget.HeadLayout; |
||||||
|
import com.novel.read.widget.RefreshLayout; |
||||||
|
import com.spreada.utils.chinese.ZHConverter; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import org.litepal.LitePal; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
|
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
public class NovelSearchActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.tv_search) |
||||||
|
EditText mTvSearch; |
||||||
|
@BindView(R.id.tv_cancel) |
||||||
|
TextView tvCancel; |
||||||
|
@BindView(R.id.head_hot) |
||||||
|
HeadLayout headHot; |
||||||
|
@BindView(R.id.rlv_hot) |
||||||
|
RecyclerView mRlvHot; |
||||||
|
@BindView(R.id.head_history) |
||||||
|
HeadLayout headHistory; |
||||||
|
@BindView(R.id.rlv_history) |
||||||
|
RecyclerView mRlvHistory; |
||||||
|
@BindView(R.id.rlv_search) |
||||||
|
RecyclerView mRlvSearch; |
||||||
|
@BindView(R.id.refresh) |
||||||
|
RefreshLayout refreshLayout; |
||||||
|
|
||||||
|
private List<String> mHotList = new ArrayList<>(); |
||||||
|
private HotAdapter mHotAdapter; |
||||||
|
|
||||||
|
private List<SearchListTable> mHisList = new ArrayList<>(); |
||||||
|
private HistoryAdapter mHisAdapter; |
||||||
|
|
||||||
|
private List<SearchResp.BookBean> mSearchList = new ArrayList<>(); |
||||||
|
private SearchAdapter mSearchAdapter; |
||||||
|
|
||||||
|
private int page = 1; |
||||||
|
private int loadSize; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_search; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
|
||||||
|
FlexboxLayoutManager manager = new FlexboxLayoutManager(this); |
||||||
|
//设置主轴排列方式
|
||||||
|
manager.setFlexDirection(FlexDirection.ROW); |
||||||
|
//设置是否换行
|
||||||
|
manager.setFlexWrap(FlexWrap.WRAP); |
||||||
|
manager.setAlignItems(AlignItems.STRETCH); |
||||||
|
mRlvHot.setLayoutManager(manager); |
||||||
|
mHotAdapter = new HotAdapter(mHotList); |
||||||
|
mRlvHot.setAdapter(mHotAdapter); |
||||||
|
|
||||||
|
mHisList = LitePal.order("saveTime desc").limit(5).find(SearchListTable.class); |
||||||
|
FlexboxLayoutManager manager2 = new FlexboxLayoutManager(this); |
||||||
|
//设置主轴排列方式
|
||||||
|
manager2.setFlexDirection(FlexDirection.ROW); |
||||||
|
//设置是否换行
|
||||||
|
manager2.setFlexWrap(FlexWrap.WRAP); |
||||||
|
manager2.setAlignItems(AlignItems.STRETCH); |
||||||
|
mHisAdapter = new HistoryAdapter(mHisList); |
||||||
|
mRlvHistory.setLayoutManager(manager2); |
||||||
|
mRlvHistory.setAdapter(mHisAdapter); |
||||||
|
|
||||||
|
mRlvSearch.setLayoutManager(new LinearLayoutManager(this)); |
||||||
|
mSearchAdapter = new SearchAdapter(mSearchList, mRlvSearch); |
||||||
|
mRlvSearch.setAdapter(mSearchAdapter); |
||||||
|
mSearchAdapter.setOnLoadMoreListener(() -> { |
||||||
|
if (mSearchAdapter.isLoadingMore()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
if (loadSize >= COMMENT_SIZE) { |
||||||
|
mSearchAdapter.setLoadingMore(true); |
||||||
|
mSearchList.add(null); |
||||||
|
mSearchAdapter.notifyDataSetChanged(); |
||||||
|
page++; |
||||||
|
getData(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
AccountManager.getInstance().getHotSearch(); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData() { |
||||||
|
String str = convertCC(mTvSearch.getText().toString().trim()); |
||||||
|
AccountManager.getInstance().getSearchBookList("", str, page); |
||||||
|
} |
||||||
|
|
||||||
|
//繁簡轉換
|
||||||
|
public String convertCC(String input) { |
||||||
|
if (TextUtils.isEmpty(input) || input.length() == 0) |
||||||
|
return ""; |
||||||
|
return ZHConverter.getInstance(ZHConverter.SIMPLIFIED).convert(input); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
//输入框
|
||||||
|
mTvSearch.addTextChangedListener(new TextWatcher() { |
||||||
|
@Override |
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||||
|
if (s.toString().trim().equals("")) { |
||||||
|
refreshLayout.setVisibility(View.GONE); |
||||||
|
headHot.setVisibility(View.VISIBLE); |
||||||
|
headHistory.setVisibility(View.VISIBLE); |
||||||
|
mRlvHot.setVisibility(View.VISIBLE); |
||||||
|
mRlvHistory.setVisibility(View.VISIBLE); |
||||||
|
} else { |
||||||
|
refreshLayout.setVisibility(View.VISIBLE); |
||||||
|
headHot.setVisibility(View.GONE); |
||||||
|
headHistory.setVisibility(View.GONE); |
||||||
|
mRlvHot.setVisibility(View.GONE); |
||||||
|
mRlvHistory.setVisibility(View.GONE); |
||||||
|
refreshLayout.showLoading(); |
||||||
|
page = 1; |
||||||
|
getData(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterTextChanged(Editable s) { |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
//键盘的搜索
|
||||||
|
mTvSearch.setOnKeyListener((v, keyCode, event) -> { |
||||||
|
//修改回车键功能
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_ENTER) { |
||||||
|
mSearchAdapter.setHolderType(true); |
||||||
|
saveKey(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
}); |
||||||
|
|
||||||
|
mHotAdapter.setOnItemClickListener((view, pos) -> { |
||||||
|
mSearchAdapter.setHolderType(true); |
||||||
|
refreshLayout.setVisibility(View.VISIBLE); |
||||||
|
mTvSearch.setText(mHotList.get(pos)); |
||||||
|
saveKey(); |
||||||
|
}); |
||||||
|
|
||||||
|
mHisAdapter.setOnItemClickListener((view, pos) -> { |
||||||
|
mSearchAdapter.setHolderType(true); |
||||||
|
refreshLayout.setVisibility(View.VISIBLE); |
||||||
|
mTvSearch.setText(mHisList.get(pos).getKey()); |
||||||
|
saveKey(); |
||||||
|
}); |
||||||
|
|
||||||
|
mSearchAdapter.setOnItemClickListener((view, pos) -> { |
||||||
|
mSearchAdapter.setHolderType(true); |
||||||
|
mTvSearch.setText(mSearchList.get(pos).getTitle()); |
||||||
|
saveKey(); |
||||||
|
}); |
||||||
|
headHistory.setOnClickListener(view -> DialogUtils.getInstance() |
||||||
|
.showAlertDialog(NovelSearchActivity.this, |
||||||
|
getString(R.string.clear_search), (dialogInterface, i) -> { |
||||||
|
LitePal.deleteAll(SearchListTable.class); |
||||||
|
mHisList.clear(); |
||||||
|
mHisList.addAll(LitePal.order("saveTime desc").limit(5).find(SearchListTable.class)); |
||||||
|
mHisAdapter.notifyDataSetChanged(); |
||||||
|
})); |
||||||
|
|
||||||
|
refreshLayout.setOnReloadingListener(new RefreshLayout.OnReloadingListener() { |
||||||
|
@Override |
||||||
|
public void onReload() { |
||||||
|
getData(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void saveKey() { |
||||||
|
if (mTvSearch.getText().toString().trim().equals("")) { |
||||||
|
return; |
||||||
|
} |
||||||
|
SearchListTable searchListTable = new SearchListTable(); |
||||||
|
searchListTable.setKey(mTvSearch.getText().toString().trim()); |
||||||
|
searchListTable.setSaveTime(System.currentTimeMillis()); |
||||||
|
searchListTable.saveOrUpdate("key=?", mTvSearch.getText().toString().trim()); |
||||||
|
mHisList.clear(); |
||||||
|
mHisList.addAll(LitePal.order("saveTime desc").limit(5).find(SearchListTable.class)); |
||||||
|
mHisAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBackPressed() { |
||||||
|
if (refreshLayout.getVisibility() == View.VISIBLE) { |
||||||
|
mTvSearch.setText(""); |
||||||
|
mSearchAdapter.setHolderType(false); |
||||||
|
page = 1; |
||||||
|
} else { |
||||||
|
super.onBackPressed(); |
||||||
|
overridePendingTransition(R.anim.message_fade_in, R.anim.message_fade_out); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@OnClick(R.id.tv_cancel) |
||||||
|
public void onViewClicked() { |
||||||
|
onBackPressed(); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getHotSearch(HotSearchEvent event) { |
||||||
|
|
||||||
|
if (event.isFail()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
mHotList.clear(); |
||||||
|
mHotList.addAll(event.getResult().getKey()); |
||||||
|
mHotAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getSearchList(SearchListEvent event) { |
||||||
|
refreshLayout.showFinish(); |
||||||
|
if (event.isFail()) { |
||||||
|
refreshLayout.showError(); |
||||||
|
} else { |
||||||
|
loadSize = event.getResult().getBook().size(); |
||||||
|
if (mSearchAdapter.isLoadingMore()){ |
||||||
|
mSearchList.remove(mSearchList.size() - 1); |
||||||
|
mSearchList.addAll(event.getResult().getBook()); |
||||||
|
mSearchAdapter.notifyDataSetChanged(); |
||||||
|
mSearchAdapter.setLoadingMore(false); |
||||||
|
}else { |
||||||
|
mSearchList.clear(); |
||||||
|
mSearchList.addAll(event.getResult().getBook()); |
||||||
|
mSearchAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,174 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.app.AlertDialog; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.text.TextUtils; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
|
||||||
|
import com.allenliu.versionchecklib.v2.AllenVersionChecker; |
||||||
|
import com.allenliu.versionchecklib.v2.builder.DownloadBuilder; |
||||||
|
import com.allenliu.versionchecklib.v2.builder.UIData; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.base.NovelBaseActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.UpdateBookEvent; |
||||||
|
import com.novel.read.event.VersionEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.VersionResp; |
||||||
|
import com.novel.read.utlis.CleanCacheUtils; |
||||||
|
import com.novel.read.utlis.LocalManageUtil; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.novel.read.utlis.VersionUtil; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
|
||||||
|
public class NovelSettingActivity extends NovelBaseActivity { |
||||||
|
|
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.tv_language) |
||||||
|
TextView mTvLanguage; |
||||||
|
@BindView(R.id.tv_cache_num) |
||||||
|
TextView mTvCacheNum; |
||||||
|
@BindView(R.id.tv_version) |
||||||
|
TextView mTvVersion; |
||||||
|
@BindView(R.id.tv_check) |
||||||
|
TextView mTvCheck; |
||||||
|
private VersionResp resp; |
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.activity_setting; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n") |
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
mTvLanguage.setText(getResources().getStringArray(R.array.setting_dialog_language_choice)[SpUtil.getIntValue(Constant.Language, 1)]); |
||||||
|
mTvVersion.setText("V" + VersionUtil.getPackageName(this)); |
||||||
|
try { |
||||||
|
final String cacheSize = CleanCacheUtils.getInstance().getTotalCacheSize(NovelSettingActivity.this); |
||||||
|
mTvCacheNum.setText(cacheSize); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
toolbar.setNavigationOnClickListener(view -> finish()); |
||||||
|
|
||||||
|
AccountManager.getInstance().checkVersion(VersionUtil.getPackageCode(this)); |
||||||
|
} |
||||||
|
|
||||||
|
@OnClick({R.id.ll_choose_language, R.id.ll_clear_cache, R.id.tv_check}) |
||||||
|
public void onViewClicked(View view) { |
||||||
|
switch (view.getId()) { |
||||||
|
case R.id.ll_choose_language: |
||||||
|
showLanguageDialog(); |
||||||
|
break; |
||||||
|
case R.id.ll_clear_cache: |
||||||
|
//默认不勾选清空书架列表,防手抖!!
|
||||||
|
final boolean[] selected = {true, false}; |
||||||
|
new AlertDialog.Builder(this) |
||||||
|
.setTitle(getString(R.string.clear_cache)) |
||||||
|
.setCancelable(true) |
||||||
|
.setMultiChoiceItems(new String[]{getString(R.string.clear_cache), getString(R.string.clear_book)}, selected, (dialog, which, isChecked) -> selected[which] = isChecked) |
||||||
|
.setPositiveButton(getString(R.string.sure), (dialog, which) -> { |
||||||
|
new Thread(() -> { |
||||||
|
CleanCacheUtils.getInstance().clearCache(selected[0], selected[1], NovelSettingActivity.this); |
||||||
|
String cacheSize = ""; |
||||||
|
try { |
||||||
|
cacheSize = CleanCacheUtils.getInstance().getTotalCacheSize(NovelSettingActivity.this); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
String finalCacheSize = cacheSize; |
||||||
|
runOnUiThread(() -> { |
||||||
|
EventManager.Companion.getInstance().postEvent(new UpdateBookEvent()); |
||||||
|
mTvCacheNum.setText(finalCacheSize); |
||||||
|
}); |
||||||
|
}).start(); |
||||||
|
dialog.dismiss(); |
||||||
|
}) |
||||||
|
.setNegativeButton(getString(R.string.cancel), (dialog, which) -> dialog.dismiss()) |
||||||
|
.create().show(); |
||||||
|
break; |
||||||
|
case R.id.tv_check: |
||||||
|
//版本大小不为空 去更新。
|
||||||
|
updateApk(resp); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void showLanguageDialog() { |
||||||
|
new AlertDialog.Builder(this) |
||||||
|
.setTitle(getString(R.string.choose_language)) |
||||||
|
.setSingleChoiceItems(getResources().getStringArray(R.array.setting_dialog_language_choice), |
||||||
|
SpUtil.getIntValue(Constant.Language, 1), |
||||||
|
(dialog, which) -> { |
||||||
|
String language = getResources().getStringArray(R.array.setting_dialog_language_choice)[which]; |
||||||
|
mTvLanguage.setText(language); |
||||||
|
SpUtil.setIntValue(Constant.Language, which); |
||||||
|
dialog.dismiss(); |
||||||
|
|
||||||
|
if (which == 0) { |
||||||
|
selectLanguage(0); |
||||||
|
} else { |
||||||
|
selectLanguage(1); |
||||||
|
} |
||||||
|
}) |
||||||
|
.create().show(); |
||||||
|
} |
||||||
|
|
||||||
|
private void selectLanguage(int select) { |
||||||
|
LocalManageUtil.saveSelectLanguage(this, select); |
||||||
|
NovelMainActivity.reStart(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void checkVersion(VersionEvent event){ |
||||||
|
if (event.isFail()){ |
||||||
|
|
||||||
|
}else { |
||||||
|
if (TextUtils.isEmpty(event.getResult().getVersion().getSize())){ |
||||||
|
return; |
||||||
|
} |
||||||
|
resp = event.getResult(); |
||||||
|
mTvCheck.setVisibility(View.VISIBLE); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void updateApk(VersionResp resp){ |
||||||
|
VersionResp.VersionBean versionBean = resp.getVersion(); |
||||||
|
DownloadBuilder builder = AllenVersionChecker |
||||||
|
.getInstance() |
||||||
|
.downloadOnly(UIData.create() |
||||||
|
.setTitle(getString(R.string.new_version,versionBean.getVersion())) |
||||||
|
.setContent(versionBean.getContent()) |
||||||
|
.setDownloadUrl(versionBean.getDownload()) |
||||||
|
); |
||||||
|
builder.executeMission(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,102 @@ |
|||||||
|
package com.novel.read.activity; |
||||||
|
|
||||||
|
import android.content.Intent; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.appcompat.app.AppCompatActivity; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.utlis.PermissionUtil; |
||||||
|
import com.novel.read.utlis.StatusBarUtil; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.ButterKnife; |
||||||
|
import butterknife.Unbinder; |
||||||
|
|
||||||
|
public class NovelSplashActivity extends AppCompatActivity implements PermissionUtil.PermissionCallBack { |
||||||
|
@BindView(R.id.tvSkip) |
||||||
|
TextView tvSkip; |
||||||
|
|
||||||
|
private boolean flag = false; |
||||||
|
private Runnable runnable; |
||||||
|
|
||||||
|
protected PermissionUtil mPermissionUtil; |
||||||
|
private static final int PERMISSION_CODE = 999; |
||||||
|
private Unbinder unbinder; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
StatusBarUtil.setBarsStyle(this, R.color.colorPrimary, true); |
||||||
|
setContentView(R.layout.activity_splash); |
||||||
|
unbinder = ButterKnife.bind(this); |
||||||
|
|
||||||
|
mPermissionUtil = PermissionUtil.getInstance(); |
||||||
|
mPermissionUtil.requestPermissions(this, PERMISSION_CODE, this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { |
||||||
|
mPermissionUtil.requestResult(this, permissions, grantResults, this); |
||||||
|
} |
||||||
|
|
||||||
|
private void init() { |
||||||
|
runnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
goHome(); |
||||||
|
} |
||||||
|
}; |
||||||
|
tvSkip.postDelayed(runnable, 2000); |
||||||
|
tvSkip.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
goHome(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private synchronized void goHome() { |
||||||
|
if (!flag) { |
||||||
|
flag = true; |
||||||
|
startActivity(new Intent(this, NovelMainActivity.class)); |
||||||
|
finish(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
flag = true; |
||||||
|
tvSkip.removeCallbacks(runnable); |
||||||
|
unbinder.unbind(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onResume() { |
||||||
|
super.onResume(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onPause() { |
||||||
|
super.onPause(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPermissionSuccess() { |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPermissionReject(String strMessage) { |
||||||
|
finish(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPermissionFail() { |
||||||
|
mPermissionUtil.requestPermissions(this, PERMISSION_CODE,this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,188 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.Button; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelReadActivity; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class BookAdapter extends RecyclerView.Adapter { |
||||||
|
|
||||||
|
private List<CollBookBean> mList; |
||||||
|
private Context mContext; |
||||||
|
private final int VALUE_ITEM = 100; //正常item
|
||||||
|
private final int EMPTY_ITEM = 101; //空白item
|
||||||
|
protected OnItemClickListener mClickListener; |
||||||
|
private boolean mEdit; |
||||||
|
|
||||||
|
public BookAdapter(List<CollBookBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext == null) { |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
if (i == VALUE_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} else if (i == EMPTY_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_add_book, viewGroup, false); |
||||||
|
return new EmptyHolder(view); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { |
||||||
|
if (viewHolder instanceof ViewHolder) { |
||||||
|
if (mEdit) { //编辑模式
|
||||||
|
((ViewHolder) viewHolder).mIvCheck.setSelected(mList.get(i).isSelect()); |
||||||
|
((ViewHolder) viewHolder).mIvCheck.setVisibility(View.VISIBLE); |
||||||
|
((ViewHolder) viewHolder).mTvBookName.setText(mList.get(i).getTitle()); |
||||||
|
((ViewHolder) viewHolder).mTvBookAuthor.setText(mList.get(i).getAuthor()); |
||||||
|
if (mList.get(i).isUpdate()) { |
||||||
|
((ViewHolder) viewHolder).mIvGeng.setVisibility(View.VISIBLE); |
||||||
|
} else { |
||||||
|
((ViewHolder) viewHolder).mIvGeng.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
GlideImageLoader.displayCornerImage(mContext, mList.get(i).getCover(), ((ViewHolder) viewHolder).mIvBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
((ViewHolder) viewHolder).mIvCheck.setSelected(!mList.get(i).isSelect()); |
||||||
|
mList.get(i).setSelect(!mList.get(i).isSelect()); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { //正常模式
|
||||||
|
((ViewHolder) viewHolder).mIvCheck.setVisibility(View.GONE); |
||||||
|
if (mList.size() == i) { //最后的条目
|
||||||
|
((ViewHolder) viewHolder).mTvBookName.setText(""); |
||||||
|
((ViewHolder) viewHolder).mTvBookAuthor.setText(""); |
||||||
|
((ViewHolder) viewHolder).mIvBook.setImageResource(R.drawable.ic_book_add); |
||||||
|
((ViewHolder) viewHolder).mIvGeng.setVisibility(View.GONE); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
mClickListener.onItemClick(view, i); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
((ViewHolder) viewHolder).mTvBookName.setText(mList.get(i).getTitle()); |
||||||
|
((ViewHolder) viewHolder).mTvBookAuthor.setText(mList.get(i).getAuthor()); |
||||||
|
if (mList.get(i).isUpdate()) { |
||||||
|
((ViewHolder) viewHolder).mIvGeng.setVisibility(View.VISIBLE); |
||||||
|
} else { |
||||||
|
((ViewHolder) viewHolder).mIvGeng.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
GlideImageLoader.displayCornerImage(mContext, mList.get(i).getCover(), ((ViewHolder) viewHolder).mIvBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent = new Intent(mContext, NovelReadActivity.class); |
||||||
|
intent.putExtra(NovelReadActivity.EXTRA_IS_COLLECTED, true); |
||||||
|
intent.putExtra(NovelReadActivity.EXTRA_COLL_BOOK, mList.get(i)); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (viewHolder instanceof EmptyHolder) { //空条目
|
||||||
|
((EmptyHolder) viewHolder).mBtnAdd.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
mClickListener.onItemClick(view, i); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
if (mList.size() == 0) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
if (mEdit) { |
||||||
|
return mList.size(); |
||||||
|
} else { |
||||||
|
return mList.size() + 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemViewType(int position) { |
||||||
|
if (mList == null || mList.size() == 0) { |
||||||
|
return EMPTY_ITEM; |
||||||
|
} else { |
||||||
|
return VALUE_ITEM; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder { |
||||||
|
ImageView mIvBook; |
||||||
|
TextView mTvBookName, mTvBookAuthor; |
||||||
|
ImageView mIvCheck; |
||||||
|
ImageView mIvGeng; |
||||||
|
|
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mIvBook = itemView.findViewById(R.id.iv_book); |
||||||
|
mTvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
mTvBookAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
mIvCheck = itemView.findViewById(R.id.iv_check); |
||||||
|
mIvGeng = itemView.findViewById(R.id.iv_geng); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class EmptyHolder extends RecyclerView.ViewHolder { |
||||||
|
Button mBtnAdd; |
||||||
|
|
||||||
|
public EmptyHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mBtnAdd = itemView.findViewById(R.id.btn_add); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setOnItemClickListener(OnItemClickListener mListener) { |
||||||
|
this.mClickListener = mListener; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public interface OnItemClickListener { |
||||||
|
void onItemClick(View view, int pos); |
||||||
|
} |
||||||
|
|
||||||
|
public void setEdit(boolean edit) { //开启编辑模式
|
||||||
|
mEdit = edit; |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public List<CollBookBean> getSelectList() { |
||||||
|
List<CollBookBean> collBookBeans = new ArrayList<>(); |
||||||
|
for (int i = 0; i < mList.size(); i++) { |
||||||
|
if (mList.get(i).isSelect()) { |
||||||
|
collBookBeans.add(mList.get(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
return collBookBeans; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,146 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.adapter.holder.EmptyHolder; |
||||||
|
import com.novel.read.adapter.holder.MoreHolder; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.inter.OnLoadMoreListener; |
||||||
|
import com.novel.read.model.protocol.SearchResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
public class BookListAdapter extends RecyclerView.Adapter { |
||||||
|
|
||||||
|
|
||||||
|
private List<SearchResp.BookBean> mList; |
||||||
|
private Context mContext; |
||||||
|
private final int VALUE_ITEM = 100; //正常item
|
||||||
|
private final int EMPTY_ITEM = 101; //空白item
|
||||||
|
private final int PROCESS_ITEM = 102; |
||||||
|
private boolean loadingMore; |
||||||
|
private int lastVisibleItem, totalItemCount; |
||||||
|
private int visibleThreshold = 1; |
||||||
|
private OnLoadMoreListener mOnLoadMoreListener; |
||||||
|
|
||||||
|
public BookListAdapter(List<SearchResp.BookBean> mList, RecyclerView recyclerView) { |
||||||
|
this.mList = mList; |
||||||
|
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { |
||||||
|
final LinearLayoutManager llMangager = (LinearLayoutManager) recyclerView.getLayoutManager(); |
||||||
|
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { |
||||||
|
@Override |
||||||
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { |
||||||
|
super.onScrolled(recyclerView, dx, dy); |
||||||
|
totalItemCount = llMangager.getItemCount(); |
||||||
|
lastVisibleItem = llMangager.findLastVisibleItemPosition(); |
||||||
|
if (!loadingMore && totalItemCount == (lastVisibleItem + visibleThreshold) && totalItemCount >= (COMMENT_SIZE)) { |
||||||
|
if (mOnLoadMoreListener != null) { |
||||||
|
mOnLoadMoreListener.onLoadMore(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoadingMore(boolean loadingMore) { |
||||||
|
this.loadingMore = loadingMore; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isLoadingMore() { |
||||||
|
return loadingMore; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOnLoadMoreListener(OnLoadMoreListener listener) { |
||||||
|
this.mOnLoadMoreListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { |
||||||
|
if (mContext == null) { |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
if (viewType == VALUE_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_list, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} else if (viewType == EMPTY_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_view, viewGroup, false); |
||||||
|
return new EmptyHolder(view); |
||||||
|
}else if (viewType==PROCESS_ITEM){ |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.load_more_layout, viewGroup, false); |
||||||
|
return new MoreHolder(view); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int i) { |
||||||
|
if (viewHolder instanceof ViewHolder){ |
||||||
|
SearchResp.BookBean bookBean = mList.get(i); |
||||||
|
((ViewHolder) viewHolder).tvBookName.setText(bookBean.getTitle()); |
||||||
|
((ViewHolder) viewHolder).tvBookAuthor.setText(bookBean.getAuthor()); |
||||||
|
((ViewHolder) viewHolder).tvBookDescription.setText(bookBean.getDescription()); |
||||||
|
GlideImageLoader.displayCornerImage(mContext,bookBean.getCover(),((ViewHolder) viewHolder).ivBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent=new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, bookBean.getId()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
if (mList.size() == 0) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemViewType(int position) { |
||||||
|
if (mList == null || mList.size() == 0) { |
||||||
|
return EMPTY_ITEM; |
||||||
|
} else if (mList.get(position) == null) { |
||||||
|
return PROCESS_ITEM; |
||||||
|
} else { |
||||||
|
return VALUE_ITEM; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder { |
||||||
|
ImageView ivBook; |
||||||
|
TextView tvBookName; |
||||||
|
TextView tvBookAuthor; |
||||||
|
TextView tvBookDescription; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
ivBook = itemView.findViewById(R.id.iv_book); |
||||||
|
tvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
tvBookAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
tvBookDescription = itemView.findViewById(R.id.tv_book_description); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
|
||||||
|
import com.novel.read.adapter.holder.CategoryHolder; |
||||||
|
import com.novel.read.widget.page.TxtChapter; |
||||||
|
|
||||||
|
public class CategoryAdapter extends EasyAdapter<TxtChapter> { |
||||||
|
private int currentSelected = 0; |
||||||
|
|
||||||
|
@Override |
||||||
|
public View getView(int position, View convertView, ViewGroup parent) { |
||||||
|
View view = super.getView(position, convertView, parent); |
||||||
|
CategoryHolder holder = (CategoryHolder) view.getTag(); |
||||||
|
|
||||||
|
if (position == currentSelected){ |
||||||
|
holder.setSelectedChapter(); |
||||||
|
} |
||||||
|
|
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected IViewHolder<TxtChapter> onCreateViewHolder(int viewType) { |
||||||
|
return new CategoryHolder(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setChapter(int pos){ |
||||||
|
currentSelected = pos; |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,87 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.BaseAdapter; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public abstract class EasyAdapter<T> extends BaseAdapter { |
||||||
|
|
||||||
|
private List<T> mList = new ArrayList<T>(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public T getItem(int position) { |
||||||
|
return mList.get(position); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getItemId(int position) { |
||||||
|
return position; |
||||||
|
} |
||||||
|
|
||||||
|
public void addItem(T value){ |
||||||
|
mList.add(value); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public void addItem(int index,T value){ |
||||||
|
mList.add(index, value); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public void addItems(List<T> values){ |
||||||
|
mList.addAll(values); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public void removeItem(T value){ |
||||||
|
mList.remove(value); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public List<T> getItems(){ |
||||||
|
return Collections.unmodifiableList(mList); |
||||||
|
} |
||||||
|
|
||||||
|
public int getItemSize(){ |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshItems(List<T> list){ |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(list); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public void clear(){ |
||||||
|
mList.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public View getView(int position, View convertView, ViewGroup parent) { |
||||||
|
IViewHolder holder; |
||||||
|
if (convertView == null){ |
||||||
|
holder = onCreateViewHolder(getItemViewType(position)); |
||||||
|
convertView = holder.createItemView(parent); |
||||||
|
convertView.setTag(holder); |
||||||
|
//初始化
|
||||||
|
holder.initView(); |
||||||
|
} |
||||||
|
else { |
||||||
|
holder = (IViewHolder)convertView.getTag(); |
||||||
|
} |
||||||
|
//执行绑定
|
||||||
|
holder.onBind(getItem(position),position); |
||||||
|
return convertView; |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract IViewHolder<T> onCreateViewHolder(int viewType); |
||||||
|
} |
||||||
@ -0,0 +1,85 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/19 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class EditRecommendAdapter extends RecyclerView.Adapter<EditRecommendAdapter.ViewHolder> { |
||||||
|
|
||||||
|
private List<RecommendListResp.ListBean> mList; |
||||||
|
private Context mContext; |
||||||
|
public EditRecommendAdapter(List<RecommendListResp.ListBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view = LayoutInflater.from(mContext).inflate(R.layout.rlv_edit_recommend_item, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { |
||||||
|
RecommendListResp.ListBean listBean = mList.get(i); |
||||||
|
viewHolder.mTvBookName.setText(listBean.getBook_title()); |
||||||
|
viewHolder.mTvAuthor.setText(listBean.getAuthor()); |
||||||
|
viewHolder.mTvDescription.setText(listBean.getDescription()); |
||||||
|
viewHolder.mTvHumanNum.setText(listBean.getHot()); |
||||||
|
viewHolder.mTvLoveNum.setText(listBean.getLike()); |
||||||
|
GlideImageLoader.displayCornerImage(mContext,listBean.getBook_cover(),viewHolder.mIvBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent=new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, listBean.getBook_id()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
ImageView mIvBook; |
||||||
|
TextView mTvBookName; |
||||||
|
TextView mTvAuthor; |
||||||
|
TextView mTvDescription; |
||||||
|
TextView mTvHumanNum; |
||||||
|
TextView mTvLoveNum; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mIvBook = itemView.findViewById(R.id.iv_book); |
||||||
|
mTvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
mTvAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
mTvDescription = itemView.findViewById(R.id.tv_book_description); |
||||||
|
mTvHumanNum = itemView.findViewById(R.id.tv_human_num); |
||||||
|
mTvLoveNum = itemView.findViewById(R.id.tv_love_look_num); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.model.db.SearchListTable; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/17 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> { |
||||||
|
|
||||||
|
private List<SearchListTable> mList; |
||||||
|
private Context mContext; |
||||||
|
protected OnItemClickListener mClickListener; |
||||||
|
|
||||||
|
public HistoryAdapter(List<SearchListTable> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
|
||||||
|
TextView mTvLabel; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mTvLabel = itemView.findViewById(R.id.tv_label); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext == null) { |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view = LayoutInflater.from(mContext).inflate(R.layout.item_label, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { |
||||||
|
viewHolder.mTvLabel.setText(mList.get(i).getKey()); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
mClickListener.onItemClick(view,i); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setOnItemClickListener(OnItemClickListener mListener) { |
||||||
|
this.mClickListener = mListener; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public interface OnItemClickListener{ |
||||||
|
void onItemClick(View view, int pos); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/17 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class HotAdapter extends RecyclerView.Adapter<HotAdapter.ViewHolder> { |
||||||
|
|
||||||
|
private List<String> mList; |
||||||
|
private Context mContext; |
||||||
|
protected OnItemClickListener mClickListener; |
||||||
|
|
||||||
|
public HotAdapter(List<String> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view = LayoutInflater.from(mContext).inflate(R.layout.item_label, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) { |
||||||
|
viewHolder.mTvLabel.setText(mList.get(i)); |
||||||
|
viewHolder.mTvLabel.setBackgroundColor(Constant.tagColors[i]); |
||||||
|
viewHolder.itemView.setOnClickListener(view -> mClickListener.onItemClick(view,i)); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
if (mList.size()>8){ |
||||||
|
return 8; |
||||||
|
} |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
TextView mTvLabel; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mTvLabel = itemView.findViewById(R.id.tv_label); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setOnItemClickListener(OnItemClickListener mListener) { |
||||||
|
this.mClickListener = mListener; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public interface OnItemClickListener{ |
||||||
|
void onItemClick(View view, int pos); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
|
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/19 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class HumanAdapter extends RecyclerView.Adapter<HumanAdapter.ViewHolder> { |
||||||
|
|
||||||
|
private List<RecommendListResp.ListBean> mList; |
||||||
|
private Context mContext; |
||||||
|
public HumanAdapter(List<RecommendListResp.ListBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view = LayoutInflater.from(mContext).inflate(R.layout.rlv_human_item, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { |
||||||
|
viewHolder.mTvBookName.setText(mList.get(i).getBook_title()); |
||||||
|
viewHolder.mTvAuthor.setText(mList.get(i).getAuthor()); |
||||||
|
GlideImageLoader.displayCornerImage(mContext,mList.get(i).getBook_cover(),viewHolder.mIvBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent=new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, mList.get(i).getBook_id()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
ImageView mIvBook; |
||||||
|
TextView mTvBookName; |
||||||
|
TextView mTvAuthor; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mIvBook = itemView.findViewById(R.id.iv_book); |
||||||
|
mTvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
mTvAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-17. |
||||||
|
*/ |
||||||
|
|
||||||
|
public interface IViewHolder<T> { |
||||||
|
View createItemView(ViewGroup parent); |
||||||
|
void initView(); |
||||||
|
void onBind(T data, int pos); |
||||||
|
void onClick(); |
||||||
|
} |
||||||
@ -0,0 +1,81 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.model.protocol.RecommendBookResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 猜你喜欢adapter |
||||||
|
*/ |
||||||
|
public class LoveLyAdapter extends RecyclerView.Adapter { |
||||||
|
|
||||||
|
private List<RecommendBookResp.BookBean> mList; |
||||||
|
private Context mContext; |
||||||
|
|
||||||
|
public LoveLyAdapter(List<RecommendBookResp.BookBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_lovely, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { |
||||||
|
if (viewHolder instanceof ViewHolder) { |
||||||
|
RecommendBookResp.BookBean bookBean = mList.get(i); |
||||||
|
GlideImageLoader.displayCornerImage(mContext, bookBean.getCover(), ((ViewHolder) viewHolder).mIvBook); |
||||||
|
((ViewHolder) viewHolder).mTvBookName.setText(bookBean.getTitle()); |
||||||
|
((ViewHolder) viewHolder).mTvBookAuthor.setText(mContext.getString(R.string.author_zhu,bookBean.getAuthor())); |
||||||
|
((ViewHolder) viewHolder).mTvDescription.setText(bookBean.getDescription()); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent=new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, bookBean.getId()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
ImageView mIvBook; |
||||||
|
TextView mTvBookName; |
||||||
|
TextView mTvBookAuthor; |
||||||
|
TextView mTvDescription; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mIvBook = itemView.findViewById(R.id.iv_book); |
||||||
|
mTvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
mTvBookAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
mTvDescription = itemView.findViewById(R.id.tv_book_description); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,97 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.CheckBox; |
||||||
|
import android.widget.CompoundButton; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.model.protocol.MarkResp; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class MarkAdapter extends RecyclerView.Adapter{ |
||||||
|
|
||||||
|
private Context mContext; |
||||||
|
private List<MarkResp.SignBean> mList; |
||||||
|
private boolean edit; |
||||||
|
|
||||||
|
public MarkAdapter(List<MarkResp.SignBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_mark, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { |
||||||
|
if (viewHolder instanceof ViewHolder){ |
||||||
|
if (edit){ |
||||||
|
((ViewHolder) viewHolder).mCheck.setVisibility(View.VISIBLE); |
||||||
|
((ViewHolder) viewHolder).mCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { |
||||||
|
@Override |
||||||
|
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { |
||||||
|
mList.get(i).setEdit(b); |
||||||
|
} |
||||||
|
}); |
||||||
|
}else { |
||||||
|
((ViewHolder) viewHolder).mCheck.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
((ViewHolder) viewHolder).mTvMark.setText(mList.get(i).getContent()); |
||||||
|
((ViewHolder) viewHolder).mCheck.setChecked(mList.get(i).isEdit()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
TextView mTvMark; |
||||||
|
CheckBox mCheck; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mTvMark = itemView.findViewById(R.id.tvMarkItem); |
||||||
|
mCheck = itemView.findViewById(R.id.checkbox); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setEdit(boolean edit){ |
||||||
|
this.edit = edit; |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean getEdit(){ |
||||||
|
return edit; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public String getSelectList() { |
||||||
|
StringBuilder signs = new StringBuilder(); |
||||||
|
for (int i = 0; i < mList.size(); i++) { |
||||||
|
if (mList.get(i).isEdit()) { |
||||||
|
if (signs.equals("")){ |
||||||
|
signs.append(mList.get(i).getId()); |
||||||
|
}else { |
||||||
|
signs.append(",").append(mList.get(i).getId()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return String.valueOf(signs); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,74 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.event.SetAdsBgEvent; |
||||||
|
import com.novel.read.widget.page.PageLoader; |
||||||
|
import com.novel.read.widget.page.PageStyle; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class PageStyleAdapter extends RecyclerView.Adapter<PageStyleAdapter.PageHolder> { |
||||||
|
|
||||||
|
private List<Drawable> mList; |
||||||
|
private Context mContext; |
||||||
|
private int currentChecked; |
||||||
|
private PageLoader mPageLoader; |
||||||
|
public PageStyleAdapter(List<Drawable> mList, PageLoader mPageLoader) { |
||||||
|
this.mList = mList; |
||||||
|
this.mPageLoader = mPageLoader; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public PageHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view = LayoutInflater.from(mContext).inflate(R.layout.item_read_bg, viewGroup, false); |
||||||
|
return new PageHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull PageHolder pageHolder, int i) { |
||||||
|
pageHolder.mReadBg.setBackground(mList.get(i)); |
||||||
|
pageHolder.mIvChecked.setVisibility(View.GONE); |
||||||
|
if (currentChecked == i){ |
||||||
|
pageHolder.mIvChecked.setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
pageHolder.itemView.setOnClickListener(view -> { |
||||||
|
currentChecked = i; |
||||||
|
notifyDataSetChanged(); |
||||||
|
mPageLoader.setPageStyle(PageStyle.values()[i]); |
||||||
|
EventManager.Companion.getInstance().postEvent(new SetAdsBgEvent()); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void setPageStyleChecked(PageStyle pageStyle){ |
||||||
|
currentChecked = pageStyle.ordinal(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class PageHolder extends RecyclerView.ViewHolder{ |
||||||
|
private View mReadBg; |
||||||
|
private ImageView mIvChecked; |
||||||
|
public PageHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mReadBg = itemView.findViewById(R.id.read_bg_view); |
||||||
|
mIvChecked = itemView.findViewById(R.id.read_bg_iv_checked); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,77 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
|
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/20 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class RankAdapter extends RecyclerView.Adapter<RankAdapter.ViewHolder>{ |
||||||
|
|
||||||
|
private List<RecommendListResp.ListBean> mList; |
||||||
|
private Context mContext; |
||||||
|
public RankAdapter(List<RecommendListResp.ListBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext==null){ |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view = LayoutInflater.from(mContext).inflate(R.layout.rlv_human_item, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { |
||||||
|
viewHolder.mTvBookName.setText(mList.get(i).getBook_title()); |
||||||
|
viewHolder.mTvAuthor.setText(mList.get(i).getAuthor()); |
||||||
|
GlideImageLoader.displayCornerImage(mContext,mList.get(i).getBook_cover(),viewHolder.mIvBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent=new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, mList.get(i).getBook_id()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder{ |
||||||
|
ImageView mIvBook; |
||||||
|
TextView mTvBookName; |
||||||
|
TextView mTvAuthor; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mIvBook = itemView.findViewById(R.id.iv_book); |
||||||
|
mTvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
mTvAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,146 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.adapter.holder.EmptyHolder; |
||||||
|
import com.novel.read.adapter.holder.MoreHolder; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.inter.OnLoadMoreListener; |
||||||
|
import com.novel.read.model.protocol.RankByUpadateResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
public class RankListAdapter extends RecyclerView.Adapter { |
||||||
|
|
||||||
|
|
||||||
|
private List<RankByUpadateResp.BookBean> mList; |
||||||
|
private Context mContext; |
||||||
|
private final int VALUE_ITEM = 100; //正常item
|
||||||
|
private final int EMPTY_ITEM = 101; //空白item
|
||||||
|
|
||||||
|
private final int PROCESS_ITEM = 102; |
||||||
|
private boolean loadingMore; |
||||||
|
private int lastVisibleItem, totalItemCount; |
||||||
|
private int visibleThreshold = 1; |
||||||
|
private OnLoadMoreListener mOnLoadMoreListener; |
||||||
|
|
||||||
|
public RankListAdapter(List<RankByUpadateResp.BookBean> mList,RecyclerView recyclerView) { |
||||||
|
this.mList = mList; |
||||||
|
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { |
||||||
|
final LinearLayoutManager llMangager = (LinearLayoutManager) recyclerView.getLayoutManager(); |
||||||
|
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { |
||||||
|
@Override |
||||||
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { |
||||||
|
super.onScrolled(recyclerView, dx, dy); |
||||||
|
totalItemCount = llMangager.getItemCount(); |
||||||
|
lastVisibleItem = llMangager.findLastVisibleItemPosition(); |
||||||
|
if (!loadingMore && totalItemCount == (lastVisibleItem + visibleThreshold) && totalItemCount >= (COMMENT_SIZE)) { |
||||||
|
if (mOnLoadMoreListener != null) { |
||||||
|
mOnLoadMoreListener.onLoadMore(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoadingMore(boolean loadingMore) { |
||||||
|
this.loadingMore = loadingMore; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isLoadingMore() { |
||||||
|
return loadingMore; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOnLoadMoreListener(OnLoadMoreListener listener) { |
||||||
|
this.mOnLoadMoreListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { |
||||||
|
if (mContext == null) { |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
if (viewType == VALUE_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_list, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} else if (viewType == EMPTY_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_view, viewGroup, false); |
||||||
|
return new EmptyHolder(view); |
||||||
|
}else if (viewType==PROCESS_ITEM){ |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.load_more_layout, viewGroup, false); |
||||||
|
return new MoreHolder(view); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int i) { |
||||||
|
if (viewHolder instanceof ViewHolder){ |
||||||
|
RankByUpadateResp.BookBean bookBean = mList.get(i); |
||||||
|
((ViewHolder) viewHolder).tvBookName.setText(bookBean.getTitle()); |
||||||
|
((ViewHolder) viewHolder).tvBookAuthor.setText(bookBean.getAuthor()); |
||||||
|
((ViewHolder) viewHolder).tvBookDescription.setText(bookBean.getDescription()); |
||||||
|
GlideImageLoader.displayCornerImage(mContext,bookBean.getCover(),((ViewHolder) viewHolder).ivBook); |
||||||
|
viewHolder.itemView.setOnClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
Intent intent=new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, bookBean.getId()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
if (mList.size() == 0) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemViewType(int position) { |
||||||
|
if (mList == null || mList.size() == 0) { |
||||||
|
return EMPTY_ITEM; |
||||||
|
} else if (mList.get(position) == null) { |
||||||
|
return PROCESS_ITEM; |
||||||
|
} else { |
||||||
|
return VALUE_ITEM; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder { |
||||||
|
ImageView ivBook; |
||||||
|
TextView tvBookName; |
||||||
|
TextView tvBookAuthor; |
||||||
|
TextView tvBookDescription; |
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
ivBook = itemView.findViewById(R.id.iv_book); |
||||||
|
tvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
tvBookAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
tvBookDescription = itemView.findViewById(R.id.tv_book_description); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,183 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookDetailActivity; |
||||||
|
import com.novel.read.adapter.holder.EmptyHolder; |
||||||
|
import com.novel.read.adapter.holder.MoreHolder; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.inter.OnLoadMoreListener; |
||||||
|
import com.novel.read.model.protocol.SearchResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
public class SearchAdapter extends RecyclerView.Adapter { |
||||||
|
|
||||||
|
private List<SearchResp.BookBean> mList; |
||||||
|
private Context mContext; |
||||||
|
private final int VALUE_ITEM = 100; //正常item
|
||||||
|
private final int BOOK_ITEM = 102; //书本item
|
||||||
|
private final int EMPTY_ITEM = 101; //空白item
|
||||||
|
private boolean book = false; |
||||||
|
protected OnItemClickListener mClickListener; |
||||||
|
|
||||||
|
private final int PROCESS_ITEM = 103; //加载更多
|
||||||
|
private boolean loadingMore; |
||||||
|
private int lastVisibleItem, totalItemCount; |
||||||
|
private int visibleThreshold = 1; |
||||||
|
private OnLoadMoreListener mOnLoadMoreListener; |
||||||
|
|
||||||
|
public SearchAdapter(List<SearchResp.BookBean> mList, RecyclerView recyclerView) { |
||||||
|
this.mList = mList; |
||||||
|
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { |
||||||
|
final LinearLayoutManager llMangager = (LinearLayoutManager) recyclerView.getLayoutManager(); |
||||||
|
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { |
||||||
|
@Override |
||||||
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { |
||||||
|
super.onScrolled(recyclerView, dx, dy); |
||||||
|
totalItemCount = llMangager.getItemCount(); |
||||||
|
lastVisibleItem = llMangager.findLastVisibleItemPosition(); |
||||||
|
if (!loadingMore && totalItemCount == (lastVisibleItem + visibleThreshold) && totalItemCount >= (COMMENT_SIZE)) { |
||||||
|
if (mOnLoadMoreListener != null) { |
||||||
|
mOnLoadMoreListener.onLoadMore(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setLoadingMore(boolean loadingMore) { |
||||||
|
this.loadingMore = loadingMore; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isLoadingMore() { |
||||||
|
return loadingMore; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOnLoadMoreListener(OnLoadMoreListener listener) { |
||||||
|
this.mOnLoadMoreListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext == null) { |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
if (i == VALUE_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_search, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} else if (i == BOOK_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_list_search, viewGroup, false); |
||||||
|
return new BookHolder(view); |
||||||
|
} else if (i == EMPTY_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_view, viewGroup, false); |
||||||
|
return new EmptyHolder(view); |
||||||
|
} else if (i == PROCESS_ITEM) { |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.load_more_layout, viewGroup, false); |
||||||
|
return new MoreHolder(view); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { |
||||||
|
if (viewHolder instanceof ViewHolder) { |
||||||
|
SearchResp.BookBean bookBean = mList.get(i); |
||||||
|
((ViewHolder) viewHolder).mTvBookName.setText(bookBean.getTitle()); |
||||||
|
viewHolder.itemView.setOnClickListener(view -> mClickListener.onItemClick(view, i)); |
||||||
|
} else if (viewHolder instanceof BookHolder) { |
||||||
|
SearchResp.BookBean bookBean = mList.get(i); |
||||||
|
((BookHolder) viewHolder).tvBookName.setText(bookBean.getTitle()); |
||||||
|
((BookHolder) viewHolder).tvBookAuthor.setText(bookBean.getAuthor()); |
||||||
|
((BookHolder) viewHolder).tvBookDescription.setText(bookBean.getDescription()); |
||||||
|
GlideImageLoader.displayCornerImage(mContext, bookBean.getCover(), ((BookHolder) viewHolder).ivBook); |
||||||
|
viewHolder.itemView.setOnClickListener(view -> { |
||||||
|
Intent intent = new Intent(mContext, NovelBookDetailActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.BookId, bookBean.getId()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
if (mList.size() == 0) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemViewType(int position) { |
||||||
|
if (mList == null || mList.size() == 0) { |
||||||
|
return EMPTY_ITEM; |
||||||
|
} else { |
||||||
|
if (mList.get(position) == null) { |
||||||
|
return PROCESS_ITEM; |
||||||
|
} |
||||||
|
if (book) { |
||||||
|
return BOOK_ITEM; |
||||||
|
|
||||||
|
} else { |
||||||
|
return VALUE_ITEM; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setHolderType(boolean book) { |
||||||
|
this.book = book; |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder { |
||||||
|
TextView mTvBookName; |
||||||
|
|
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mTvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class BookHolder extends RecyclerView.ViewHolder { |
||||||
|
ImageView ivBook; |
||||||
|
TextView tvBookName; |
||||||
|
TextView tvBookAuthor; |
||||||
|
TextView tvBookDescription; |
||||||
|
|
||||||
|
public BookHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
ivBook = itemView.findViewById(R.id.iv_book); |
||||||
|
tvBookName = itemView.findViewById(R.id.tv_book_name); |
||||||
|
tvBookAuthor = itemView.findViewById(R.id.tv_book_author); |
||||||
|
tvBookDescription = itemView.findViewById(R.id.tv_book_description); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setOnItemClickListener(OnItemClickListener mListener) { |
||||||
|
this.mClickListener = mListener; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public interface OnItemClickListener { |
||||||
|
void onItemClick(View view, int pos); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelBookTypeListActivity; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.model.protocol.CategoryTypeResp; |
||||||
|
import com.novel.read.utlis.GlideImageLoader; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class StackAdapter extends RecyclerView.Adapter { |
||||||
|
|
||||||
|
private List<CategoryTypeResp.CategoryBean> mList; |
||||||
|
private Context mContext; |
||||||
|
|
||||||
|
public StackAdapter(List<CategoryTypeResp.CategoryBean> mList) { |
||||||
|
this.mList = mList; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { |
||||||
|
if (mContext == null) { |
||||||
|
mContext = viewGroup.getContext(); |
||||||
|
} |
||||||
|
View view; |
||||||
|
view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_type, viewGroup, false); |
||||||
|
return new ViewHolder(view); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int i) { |
||||||
|
if (viewHolder instanceof ViewHolder) { |
||||||
|
|
||||||
|
String input = mList.get(i).getTitle(); |
||||||
|
String regex = "(.{2})"; |
||||||
|
input = input.replaceAll(regex, "$1\n"); |
||||||
|
((ViewHolder) viewHolder).mTvType.setText(input); |
||||||
|
viewHolder.itemView.setOnClickListener(view -> { |
||||||
|
Intent intent = new Intent(mContext, NovelBookTypeListActivity.class); |
||||||
|
intent.putExtra(Constant.Bundle.CategoryId, String.valueOf(mList.get(i).getId())); |
||||||
|
intent.putExtra(Constant.Bundle.mTitle, mList.get(i).getTitle()); |
||||||
|
mContext.startActivity(intent); |
||||||
|
}); |
||||||
|
GlideImageLoader.displayCornerImage(mContext, mList.get(i).getCover(), ((ViewHolder) viewHolder).mIvType, R.drawable.ic_type_default); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder { |
||||||
|
ImageView mIvType; |
||||||
|
TextView mTvType; |
||||||
|
|
||||||
|
public ViewHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
mIvType = itemView.findViewById(R.id.iv_book); |
||||||
|
mTvType = itemView.findViewById(R.id.tv_book_name); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,38 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
|
||||||
|
public abstract class ViewHolderImpl<T> implements IViewHolder<T> { |
||||||
|
private View view; |
||||||
|
private Context context; |
||||||
|
/****************************************************/ |
||||||
|
protected abstract int getItemLayoutId(); |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public View createItemView(ViewGroup parent) { |
||||||
|
view = LayoutInflater.from(parent.getContext()) |
||||||
|
.inflate(getItemLayoutId(), parent, false); |
||||||
|
context = parent.getContext(); |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
protected <V extends View> V findById(int id){ |
||||||
|
return (V) view.findViewById(id); |
||||||
|
} |
||||||
|
|
||||||
|
protected Context getContext(){ |
||||||
|
return context; |
||||||
|
} |
||||||
|
|
||||||
|
protected View getItemView(){ |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
package com.novel.read.adapter; |
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment; |
||||||
|
import androidx.fragment.app.FragmentManager; |
||||||
|
import androidx.fragment.app.FragmentPagerAdapter; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2017/2/24. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class ViewPageAdapter extends FragmentPagerAdapter { |
||||||
|
private List<Fragment> fragmentList; |
||||||
|
|
||||||
|
public ViewPageAdapter(FragmentManager fm, List<Fragment> fragmentList) { |
||||||
|
super(fm); |
||||||
|
this.fragmentList = fragmentList; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Fragment getItem(int position) { |
||||||
|
return fragmentList.get(position); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getCount() { |
||||||
|
return fragmentList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,53 @@ |
|||||||
|
package com.novel.read.adapter.holder; |
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.ViewHolderImpl; |
||||||
|
import com.novel.read.model.db.dbManage.BookManager; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
import com.novel.read.widget.page.TxtChapter; |
||||||
|
|
||||||
|
import static com.novel.read.base.MyApp.getContext; |
||||||
|
|
||||||
|
|
||||||
|
public class CategoryHolder extends ViewHolderImpl<TxtChapter> { |
||||||
|
|
||||||
|
private TextView mTvChapter; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initView() { |
||||||
|
mTvChapter = findById(R.id.category_tv_chapter); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBind(TxtChapter value, int pos){ |
||||||
|
//首先判断是否该章已下载
|
||||||
|
Drawable drawable = null; |
||||||
|
if (value.getBookId() != null && BookManager.isChapterCached(value.getBookId(),value.getTitle())){ |
||||||
|
drawable = ContextCompat.getDrawable(getContext(),R.drawable.selector_category_load); |
||||||
|
} |
||||||
|
else { |
||||||
|
drawable = ContextCompat.getDrawable(getContext(), R.drawable.selector_category_unload); |
||||||
|
} |
||||||
|
|
||||||
|
mTvChapter.setSelected(false); |
||||||
|
mTvChapter.setTextColor(ContextCompat.getColor(getContext(),R.color.colorTitle)); |
||||||
|
mTvChapter.setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null); |
||||||
|
mTvChapter.setText(StringUtils.convertCC(value.getTitle(),getContext())); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getItemLayoutId() { |
||||||
|
return R.layout.rlv_item_category; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSelectedChapter(){ |
||||||
|
mTvChapter.setTextColor(ContextCompat.getColor(getContext(),R.color.light_red)); |
||||||
|
mTvChapter.setSelected(true); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.novel.read.adapter.holder; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
public class EmptyHolder extends RecyclerView.ViewHolder { |
||||||
|
|
||||||
|
public EmptyHolder(@NonNull View itemView) { |
||||||
|
super(itemView); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
package com.novel.read.adapter.holder; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author: LiJun 390057892@qq.com |
||||||
|
* @date: 2018/4/4 9:28 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class MoreHolder extends RecyclerView.ViewHolder{ |
||||||
|
|
||||||
|
public MoreHolder(View itemView) { |
||||||
|
super(itemView); |
||||||
|
} |
||||||
|
|
||||||
|
public void bindModule(){ |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
package com.novel.read.base; |
||||||
|
|
||||||
|
import android.app.Service; |
||||||
|
|
||||||
|
import io.reactivex.disposables.CompositeDisposable; |
||||||
|
import io.reactivex.disposables.Disposable; |
||||||
|
|
||||||
|
public abstract class BaseService extends Service { |
||||||
|
|
||||||
|
private CompositeDisposable mDisposable; |
||||||
|
|
||||||
|
protected void addDisposable(Disposable disposable){ |
||||||
|
if (mDisposable == null){ |
||||||
|
mDisposable = new CompositeDisposable(); |
||||||
|
} |
||||||
|
mDisposable.add(disposable); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
if (mDisposable != null){ |
||||||
|
mDisposable.dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,71 @@ |
|||||||
|
package com.novel.read.base; |
||||||
|
|
||||||
|
import android.app.Application; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.util.Log; |
||||||
|
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate; |
||||||
|
|
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.service.DownloadService; |
||||||
|
import com.novel.read.utlis.LocalManageUtil; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.tencent.bugly.crashreport.CrashReport; |
||||||
|
|
||||||
|
|
||||||
|
import org.litepal.LitePal; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/10 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class MyApp extends Application { |
||||||
|
|
||||||
|
private static Context sInstance; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onCreate() { |
||||||
|
super.onCreate(); |
||||||
|
sInstance = this; |
||||||
|
LitePal.initialize(this); |
||||||
|
setNight(); |
||||||
|
LocalManageUtil.setApplicationLanguage(this); |
||||||
|
startService(new Intent(getContext(), DownloadService.class)); |
||||||
|
CrashReport.initCrashReport(getApplicationContext(), Constant.buglyId, false); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void setNight() { |
||||||
|
if (SpUtil.getBooleanValue(Constant.NIGHT, false)) { |
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); |
||||||
|
} else { |
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static Context getContext() { |
||||||
|
return sInstance; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void attachBaseContext(Context base) { |
||||||
|
SpUtil.init(base); |
||||||
|
//保存系统选择语言
|
||||||
|
LocalManageUtil.saveSystemCurrentLanguage(base); |
||||||
|
super.attachBaseContext(LocalManageUtil.setLocal(base)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onConfigurationChanged(Configuration newConfig) { |
||||||
|
super.onConfigurationChanged(newConfig); |
||||||
|
//保存系统选择语言
|
||||||
|
LocalManageUtil.onConfigurationChanged(getApplicationContext()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,139 @@ |
|||||||
|
package com.novel.read.base; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity; |
||||||
|
import androidx.appcompat.app.AppCompatDelegate; |
||||||
|
|
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.utlis.LocalManageUtil; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.novel.read.utlis.StatusBarUtil; |
||||||
|
|
||||||
|
import butterknife.ButterKnife; |
||||||
|
import butterknife.Unbinder; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/10 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public abstract class NovelBaseActivity extends AppCompatActivity { |
||||||
|
Unbinder mBind; |
||||||
|
private boolean mCheckNet = true;//是否检查网络连接
|
||||||
|
public boolean mNetworkChange = false;//获取网络是否连接
|
||||||
|
private boolean mNowMode; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onCreate(Bundle savedInstanceState) { |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
StatusBarUtil.setBarsStyle(this, R.color.colorPrimary, true); |
||||||
|
mNowMode = SpUtil.getBooleanValue(Constant.NIGHT); |
||||||
|
setContentView(getLayoutId()); |
||||||
|
mBind = ButterKnife.bind(this); |
||||||
|
initView(); |
||||||
|
initData(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
protected void setTheme() { |
||||||
|
if (SpUtil.getBooleanValue(Constant.NIGHT) != mNowMode) { |
||||||
|
if (SpUtil.getBooleanValue(Constant.NIGHT)) { |
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); |
||||||
|
} else { |
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); |
||||||
|
} |
||||||
|
recreate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract int getLayoutId(); |
||||||
|
|
||||||
|
protected abstract void initView(); |
||||||
|
|
||||||
|
protected abstract void initData(); |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
mBind.unbind(); |
||||||
|
} |
||||||
|
|
||||||
|
public void toActivity(Class<?> cls) { |
||||||
|
Intent intent = new Intent(this, cls); |
||||||
|
startActivity(intent); |
||||||
|
} |
||||||
|
|
||||||
|
public void toActivity(Class<?> toClsActivity, Bundle bundle) { |
||||||
|
Intent intent = new Intent(this, toClsActivity); |
||||||
|
if (bundle != null) { |
||||||
|
intent.putExtras(bundle); |
||||||
|
} |
||||||
|
startActivity(intent); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public boolean isNetworkChange() { |
||||||
|
return mNetworkChange; |
||||||
|
} |
||||||
|
|
||||||
|
public void setNetworkChange(boolean mNetworkChange) { |
||||||
|
this.mNetworkChange = mNetworkChange; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean getIsCheckNet() { |
||||||
|
return mCheckNet; |
||||||
|
} |
||||||
|
|
||||||
|
public void setIsCheckNet(boolean checkNet) { |
||||||
|
this.mCheckNet = checkNet; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onResume() { |
||||||
|
super.onResume(); |
||||||
|
setTheme(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onPause() { |
||||||
|
super.onPause(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void gone(final View... views) { |
||||||
|
if (views != null && views.length > 0) { |
||||||
|
for (View view : views) { |
||||||
|
if (view != null) { |
||||||
|
view.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void visible(final View... views) { |
||||||
|
if (views != null && views.length > 0) { |
||||||
|
for (View view : views) { |
||||||
|
if (view != null) { |
||||||
|
view.setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected boolean isVisible(View view) { |
||||||
|
return view.getVisibility() == View.VISIBLE; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void attachBaseContext(Context newBase) { |
||||||
|
super.attachBaseContext(LocalManageUtil.setLocal(newBase)); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
package com.novel.read.base; |
||||||
|
|
||||||
|
|
||||||
|
import android.content.Intent; |
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
import androidx.fragment.app.Fragment; |
||||||
|
|
||||||
|
import butterknife.ButterKnife; |
||||||
|
import butterknife.Unbinder; |
||||||
|
|
||||||
|
|
||||||
|
public abstract class NovelBaseFragment extends Fragment { |
||||||
|
|
||||||
|
private Unbinder bind; |
||||||
|
|
||||||
|
@Override |
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, |
||||||
|
Bundle savedInstanceState) { |
||||||
|
|
||||||
|
View mContextView = inflater.inflate(getLayoutId(), container, false); |
||||||
|
bind = ButterKnife.bind(this, mContextView); |
||||||
|
initView(); |
||||||
|
initData(); |
||||||
|
return mContextView; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected abstract int getLayoutId(); |
||||||
|
|
||||||
|
protected abstract void initView(); |
||||||
|
|
||||||
|
protected abstract void initData(); |
||||||
|
|
||||||
|
public void toActivity(Class<?> cls) { |
||||||
|
Intent intent = new Intent(getActivity(), cls); |
||||||
|
startActivity(intent); |
||||||
|
} |
||||||
|
|
||||||
|
public void toActivity(Class<?> toClsActivity, Bundle bundle) { |
||||||
|
Intent intent = new Intent(getActivity(), toClsActivity); |
||||||
|
if (bundle != null) { |
||||||
|
intent.putExtras(bundle); |
||||||
|
} |
||||||
|
startActivity(intent); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroyView() { |
||||||
|
super.onDestroyView(); |
||||||
|
bind.unbind(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,110 @@ |
|||||||
|
/** |
||||||
|
* Copyright 2016 JustWayward Team |
||||||
|
* <p> |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* <p> |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p> |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.novel.read.constants; |
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.Color; |
||||||
|
|
||||||
|
import com.novel.read.utlis.FileUtils; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
public class Constant { |
||||||
|
public static final String NIGHT = "NIGHT"; |
||||||
|
public static final String Language = "Language"; |
||||||
|
public static final String BookSort = "BookSort"; |
||||||
|
public static final String Uid = "Uid"; |
||||||
|
public static final String Sex = "Sex"; |
||||||
|
public static final String Type = "Type"; |
||||||
|
public static final String DateType = "DateType"; |
||||||
|
public static final String InstallTime = "InstallTime"; //apk的安装时间
|
||||||
|
public static final String InstallCount = "InstallCount"; //apk的打开次数
|
||||||
|
public static final String AppraiseShow = "AppraiseShow"; //评价弹框是否提示过
|
||||||
|
public static final String BookGuide = "BookGuide"; //图书引导是否提示过
|
||||||
|
|
||||||
|
public static final String FORMAT_BOOK_DATE = "yyyy-MM-dd HH:mm:ss"; |
||||||
|
public static final String FORMAT_TIME = "HH:mm"; |
||||||
|
public static final int COMMENT_SIZE = 10; |
||||||
|
|
||||||
|
public static final String FeedBackEmail = "qdxs01@gmail.com"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 百度语音合成 |
||||||
|
*/ |
||||||
|
//壳001 免费小说
|
||||||
|
public static final String appId = "16826023"; |
||||||
|
public static final String appKey = "vEuU5gIWGwq5hivdTAaKz0P9"; |
||||||
|
public static final String secretKey = "FcWRYUIrOPyE7dy51qfYZmg8Y1ZyP1c4 "; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 腾讯bugly |
||||||
|
*/ |
||||||
|
public static final String buglyId = "aec152f916";//壳包001
|
||||||
|
|
||||||
|
|
||||||
|
//BookCachePath (因为getCachePath引用了Context,所以必须是静态变量,不能够是静态常量)
|
||||||
|
public static String BOOK_CACHE_PATH = FileUtils.getCachePath() + File.separator |
||||||
|
+ "book_cache" + File.separator; |
||||||
|
|
||||||
|
public static final int[] tagColors = new int[]{ |
||||||
|
Color.parseColor("#90C5F0"), |
||||||
|
Color.parseColor("#91CED5"), |
||||||
|
Color.parseColor("#F88F55"), |
||||||
|
Color.parseColor("#C0AFD0"), |
||||||
|
Color.parseColor("#E78F8F"), |
||||||
|
Color.parseColor("#67CCB7"), |
||||||
|
Color.parseColor("#F6BC7E"), |
||||||
|
Color.parseColor("#90C5F0"), |
||||||
|
Color.parseColor("#91CED5"), |
||||||
|
}; |
||||||
|
|
||||||
|
//榜单类型
|
||||||
|
public interface ListType { |
||||||
|
String Human = "1"; |
||||||
|
String EditRecommend = "2"; |
||||||
|
String HotSearch = "3"; |
||||||
|
} |
||||||
|
|
||||||
|
public interface GenderType { |
||||||
|
String Man = "1"; |
||||||
|
String Woman = "2"; |
||||||
|
} |
||||||
|
|
||||||
|
public interface DateTyp { |
||||||
|
String General = "3"; |
||||||
|
String Month = "2"; |
||||||
|
String Week = "1"; |
||||||
|
} |
||||||
|
|
||||||
|
public interface Bundle { |
||||||
|
String CategoryId = "category_id"; |
||||||
|
String mTitle = "mTitle"; |
||||||
|
String BookId = "BookId"; |
||||||
|
} |
||||||
|
|
||||||
|
public interface HasImage { |
||||||
|
int has = 1; |
||||||
|
} |
||||||
|
|
||||||
|
public interface RequestCode { |
||||||
|
int REQUEST_READ = 1; |
||||||
|
} |
||||||
|
|
||||||
|
public interface ResultCode { |
||||||
|
String RESULT_IS_COLLECTED = "result_is_collected"; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.mango.mangolib.http.ErrorResponse; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/25 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class AddBookSignEvent extends BaseEvent<ErrorResponse> { |
||||||
|
public AddBookSignEvent(ErrorResponse result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public AddBookSignEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.BookArticleResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class BookArticleEvent : BaseEvent<BookArticleResp> { |
||||||
|
|
||||||
|
constructor(result: BookArticleResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.mango.mangolib.http.ErrorResponse; |
||||||
|
|
||||||
|
public class DeleteBookSignEvent extends BaseEvent<ErrorResponse> { |
||||||
|
public DeleteBookSignEvent(ErrorResponse result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public DeleteBookSignEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-27. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class DeleteResponseEvent extends BaseEvent { |
||||||
|
public boolean isDelete; |
||||||
|
public CollBookBean collBook; |
||||||
|
public DeleteResponseEvent(boolean isDelete, CollBookBean collBook){ |
||||||
|
this.isDelete = isDelete; |
||||||
|
this.collBook = collBook; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-27. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class DeleteTaskEvent extends BaseEvent { |
||||||
|
public CollBookBean collBook; |
||||||
|
|
||||||
|
public DeleteTaskEvent(CollBookBean collBook){ |
||||||
|
this.collBook = collBook; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.RecommendListResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class EditEvent : BaseEvent<RecommendListResp> { |
||||||
|
|
||||||
|
constructor(result: RecommendListResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class ErrorChapterEvent extends BaseEvent { |
||||||
|
public ErrorChapterEvent(Object result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public ErrorChapterEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class FinishChapterEvent extends BaseEvent { |
||||||
|
public FinishChapterEvent(Object result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public FinishChapterEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.BookDetailResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class GetBookDetailEvent : BaseEvent<BookDetailResp> { |
||||||
|
|
||||||
|
constructor(result: BookDetailResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.MarkResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/25 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class GetBookSignEvent : BaseEvent<MarkResp> { |
||||||
|
constructor(result: MarkResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.novel.read.model.protocol.CategoryTypeResp; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class GetCategoryTypeEvent extends BaseEvent<CategoryTypeResp> { |
||||||
|
|
||||||
|
public GetCategoryTypeEvent(CategoryTypeResp result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public GetCategoryTypeEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.RecommendBookResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class GetRecommendBookEvent : BaseEvent<RecommendBookResp> { |
||||||
|
|
||||||
|
constructor(result: RecommendBookResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class HideBottomBarEvent extends BaseEvent<Boolean> { |
||||||
|
public HideBottomBarEvent(Boolean result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public HideBottomBarEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.novel.read.model.protocol.HotSearchResp; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class HotSearchEvent extends BaseEvent<HotSearchResp> { |
||||||
|
|
||||||
|
public HotSearchEvent(HotSearchResp result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public HotSearchEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.RecommendListResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class HumanEvent : BaseEvent<RecommendListResp> { |
||||||
|
|
||||||
|
constructor(result: RecommendListResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.UidResp |
||||||
|
|
||||||
|
class LoginEvent : BaseEvent<UidResp> { |
||||||
|
constructor(result: UidResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
import com.novel.read.model.protocol.RankByUpadateResp; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class RankByUpdateEvent extends BaseEvent<RankByUpadateResp> { |
||||||
|
|
||||||
|
public RankByUpdateEvent(RankByUpadateResp result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public RankByUpdateEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class ReStartEvent extends BaseEvent { |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.RecommendListResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class RecommendListEvent : BaseEvent<RecommendListResp> { |
||||||
|
|
||||||
|
constructor(result: RecommendListResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,79 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import io.reactivex.Observable; |
||||||
|
import io.reactivex.subjects.PublishSubject; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-4-18. |
||||||
|
* 原理:PublishSubject本身作为观察者和被观察者。 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class RxBus { |
||||||
|
private static volatile RxBus sInstance; |
||||||
|
private final PublishSubject<Object> mEventBus = PublishSubject.create(); |
||||||
|
|
||||||
|
public static RxBus getInstance(){ |
||||||
|
if (sInstance == null){ |
||||||
|
synchronized (RxBus.class){ |
||||||
|
if (sInstance == null){ |
||||||
|
sInstance = new RxBus(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return sInstance; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发送事件(post event) |
||||||
|
* @param event : event object(事件的内容) |
||||||
|
*/ |
||||||
|
public void post(Object event){ |
||||||
|
mEventBus.onNext(event); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param code |
||||||
|
* @param event |
||||||
|
*/ |
||||||
|
public void post(int code,Object event){ |
||||||
|
Message msg = new Message(code,event); |
||||||
|
mEventBus.onNext(msg); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回Event的管理者,进行对事件的接受 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Observable toObservable(){ |
||||||
|
return mEventBus; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param cls :保证接受到制定的类型 |
||||||
|
* @param <T> |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public <T> Observable<T> toObservable(Class<T> cls){ |
||||||
|
//ofType起到过滤的作用,确定接受的类型
|
||||||
|
return mEventBus.ofType(cls); |
||||||
|
} |
||||||
|
|
||||||
|
public <T> Observable<T> toObservable(int code,Class<T> cls){ |
||||||
|
return mEventBus.ofType(Message.class) |
||||||
|
.filter(msg -> msg.code == code && cls.isInstance(msg.event)) |
||||||
|
.map( msg -> (T)msg.event); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class Message{ |
||||||
|
int code; |
||||||
|
Object event; |
||||||
|
|
||||||
|
public Message(int code,Object event){ |
||||||
|
this.code = code; |
||||||
|
this.event = event; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.SearchResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class SearchListEvent : BaseEvent<SearchResp> { |
||||||
|
|
||||||
|
constructor(result: SearchResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class SetAdsBgEvent extends BaseEvent { |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class SwitchFragmentEvent extends BaseEvent { |
||||||
|
|
||||||
|
public SwitchFragmentEvent(Object result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public SwitchFragmentEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.novel.read.event; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
public class UpdateBookEvent extends BaseEvent<String> { |
||||||
|
|
||||||
|
public UpdateBookEvent(String result) { |
||||||
|
super(result); |
||||||
|
} |
||||||
|
|
||||||
|
public UpdateBookEvent() { |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
package com.novel.read.event |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent |
||||||
|
import com.novel.read.model.protocol.VersionResp |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/25 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
class VersionEvent : BaseEvent<VersionResp> { |
||||||
|
constructor(result: VersionResp) : super(result) {} |
||||||
|
|
||||||
|
constructor() {} |
||||||
|
} |
||||||
@ -0,0 +1,302 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.app.AlertDialog; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.recyclerview.widget.GridLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelMainActivity; |
||||||
|
import com.novel.read.activity.NovelSearchActivity; |
||||||
|
import com.novel.read.adapter.BookAdapter; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.HideBottomBarEvent; |
||||||
|
import com.novel.read.event.SwitchFragmentEvent; |
||||||
|
import com.novel.read.event.UpdateBookEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.db.BookRecordBean; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
import com.novel.read.model.db.dbManage.BookRepository; |
||||||
|
import com.novel.read.model.protocol.BookDetailResp; |
||||||
|
import com.novel.read.utlis.LocalManageUtil; |
||||||
|
import com.novel.read.utlis.RxUtils; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.novel.read.utlis.ToastUtil; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import org.litepal.LitePal; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import io.reactivex.Single; |
||||||
|
import io.reactivex.SingleObserver; |
||||||
|
import io.reactivex.disposables.Disposable; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/10/14 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class BookFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
@BindView(R.id.title) |
||||||
|
Toolbar title; |
||||||
|
@BindView(R.id.title_edit) |
||||||
|
Toolbar titleEdit; |
||||||
|
@BindView(R.id.rlv_book) |
||||||
|
RecyclerView mRlvBook; |
||||||
|
@BindView(R.id.tv_cancel) |
||||||
|
TextView mTvCancel; |
||||||
|
@BindView(R.id.tv_delete) |
||||||
|
TextView mTvDelete; |
||||||
|
private BookAdapter mAdapter; |
||||||
|
private List<CollBookBean> mList = new ArrayList<>(); |
||||||
|
private boolean isInit = true; |
||||||
|
|
||||||
|
public static BookFragment newInstance() { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
BookFragment fragment = new BookFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_book; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
|
||||||
|
mList.addAll(BookRepository.getInstance().getCollBooks()); |
||||||
|
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3); |
||||||
|
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { |
||||||
|
@Override |
||||||
|
public int getSpanSize(int i) { |
||||||
|
if (mList == null || mList.size() == 0) { |
||||||
|
return 3; |
||||||
|
} else { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
mRlvBook.setLayoutManager(gridLayoutManager); |
||||||
|
mAdapter = new BookAdapter(mList); |
||||||
|
mRlvBook.setAdapter(mAdapter); |
||||||
|
if (isInit) { |
||||||
|
isInit = false; |
||||||
|
update(mList); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
title.inflateMenu(R.menu.title_book); |
||||||
|
titleEdit.inflateMenu(R.menu.title_edit); |
||||||
|
setOnClick(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void setOnClick() { |
||||||
|
title.setOnMenuItemClickListener(menuItem -> { |
||||||
|
switch (menuItem.getItemId()) { |
||||||
|
case R.id.action_search: |
||||||
|
toActivity(NovelSearchActivity.class); |
||||||
|
getActivity().overridePendingTransition(R.anim.message_fade_in, R.anim.message_fade_out); |
||||||
|
break; |
||||||
|
case R.id.edit_book: |
||||||
|
if (mList == null || mList.size() == 0) { //没书的时候提醒用户不能编辑
|
||||||
|
ToastUtil.show(getActivity(), getString(R.string.please_add_book)); |
||||||
|
} else { |
||||||
|
mAdapter.setEdit(true); |
||||||
|
mTvCancel.setVisibility(View.VISIBLE); |
||||||
|
mTvDelete.setVisibility(View.VISIBLE); |
||||||
|
titleEdit.setVisibility(View.VISIBLE); |
||||||
|
title.setVisibility(View.GONE); |
||||||
|
EventManager.Companion.getInstance().postEvent(new HideBottomBarEvent(true)); |
||||||
|
} |
||||||
|
break; |
||||||
|
case R.id.book_sort: |
||||||
|
showBookSortDialog(); |
||||||
|
break; |
||||||
|
case R.id.menu2: |
||||||
|
showLanguageDialog(); |
||||||
|
break; |
||||||
|
case R.id.menu3: |
||||||
|
if (SpUtil.getBooleanValue(Constant.NIGHT)) { |
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); |
||||||
|
SpUtil.setBooleanValue(Constant.NIGHT, false); |
||||||
|
} else { |
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); |
||||||
|
SpUtil.setBooleanValue(Constant.NIGHT, true); |
||||||
|
} |
||||||
|
getActivity().recreate(); |
||||||
|
break; |
||||||
|
} |
||||||
|
return true; |
||||||
|
}); |
||||||
|
titleEdit.setOnMenuItemClickListener(menuItem -> { |
||||||
|
if (menuItem.getItemId() == R.id.action_edit) { |
||||||
|
for (int i = 0; i < mList.size(); i++) { |
||||||
|
mList.get(i).setSelect(true); |
||||||
|
} |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
return true; |
||||||
|
}); |
||||||
|
mTvCancel.setOnClickListener(view -> { |
||||||
|
EventManager.Companion.getInstance().postEvent(new HideBottomBarEvent(false)); |
||||||
|
updateBook(new UpdateBookEvent()); |
||||||
|
}); |
||||||
|
|
||||||
|
mTvDelete.setOnClickListener(view -> { |
||||||
|
List<CollBookBean> deleteList = mAdapter.getSelectList(); |
||||||
|
for (int i = 0; i < deleteList.size(); i++) { |
||||||
|
if (deleteList.get(i).isSaved()) { |
||||||
|
int count = deleteList.get(i).delete(); |
||||||
|
LitePal.deleteAll(BookRecordBean.class, "bookId=?", mList.get(i).getId()); |
||||||
|
Log.e("count", "setOnClick: " + count); |
||||||
|
} |
||||||
|
} |
||||||
|
ToastUtil.show(getActivity(), getString(R.string.delete_success)); |
||||||
|
EventManager.Companion.getInstance().postEvent(new HideBottomBarEvent(false)); |
||||||
|
updateBook(new UpdateBookEvent()); |
||||||
|
}); |
||||||
|
|
||||||
|
mAdapter.setOnItemClickListener((view, pos) -> { |
||||||
|
EventManager.Companion.getInstance().postEvent(new SwitchFragmentEvent()); |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void showLanguageDialog() { |
||||||
|
Log.e("showLanguageDialog", "showLanguageDialog: " + SpUtil.getIntValue(Constant.Language, 0)); |
||||||
|
new AlertDialog.Builder(getActivity()) |
||||||
|
.setTitle(getString(R.string.choose_language)) |
||||||
|
.setSingleChoiceItems(getResources().getStringArray(R.array.setting_dialog_language_choice), SpUtil.getIntValue(Constant.Language, 1), |
||||||
|
(dialog, which) -> { |
||||||
|
String language = getResources().getStringArray(R.array.setting_dialog_language_choice)[which]; |
||||||
|
SpUtil.setIntValue(Constant.Language, which); |
||||||
|
dialog.dismiss(); |
||||||
|
|
||||||
|
if (which == 0) { |
||||||
|
selectLanguage(0); |
||||||
|
} else { |
||||||
|
selectLanguage(1); |
||||||
|
} |
||||||
|
}) |
||||||
|
.create().show(); |
||||||
|
} |
||||||
|
|
||||||
|
private void selectLanguage(int select) { |
||||||
|
LocalManageUtil.saveSelectLanguage(getActivity(), select); |
||||||
|
NovelMainActivity.reStart(getActivity()); |
||||||
|
} |
||||||
|
|
||||||
|
private void showBookSortDialog() { |
||||||
|
new AlertDialog.Builder(getActivity()) |
||||||
|
.setTitle(getString(R.string.choose_language)) |
||||||
|
.setSingleChoiceItems(getResources().getStringArray(R.array.setting_dialog_sort_choice), |
||||||
|
SpUtil.getBooleanValue(Constant.BookSort, false) ? 0 : 1, |
||||||
|
(dialog, which) -> { |
||||||
|
if (which == 0) { |
||||||
|
SpUtil.setBooleanValue(Constant.BookSort, true); |
||||||
|
} else { |
||||||
|
SpUtil.setBooleanValue(Constant.BookSort, false); |
||||||
|
} |
||||||
|
updateBook(new UpdateBookEvent()); |
||||||
|
dialog.dismiss(); |
||||||
|
}) |
||||||
|
.create().show(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResume() { |
||||||
|
super.onResume(); |
||||||
|
updateBook(new UpdateBookEvent()); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void updateBook(UpdateBookEvent event) { |
||||||
|
mTvCancel.setVisibility(View.GONE); |
||||||
|
mTvDelete.setVisibility(View.GONE); |
||||||
|
title.setVisibility(View.VISIBLE); |
||||||
|
titleEdit.setVisibility(View.GONE); |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(BookRepository.getInstance().getCollBooks()); |
||||||
|
mAdapter.setEdit(false); |
||||||
|
} |
||||||
|
|
||||||
|
private void update(List<CollBookBean> collBookBeans) { //检测书籍更新
|
||||||
|
if (collBookBeans == null || collBookBeans.isEmpty()) return; |
||||||
|
List<CollBookBean> collBooks = new ArrayList<>(collBookBeans); |
||||||
|
List<Single<BookDetailResp>> observables = new ArrayList<>(collBooks.size()); |
||||||
|
Iterator<CollBookBean> it = collBooks.iterator(); |
||||||
|
while (it.hasNext()) { |
||||||
|
CollBookBean collBook = it.next(); |
||||||
|
//删除本地文件
|
||||||
|
if (collBook.isLocal()) { |
||||||
|
it.remove(); |
||||||
|
} else { |
||||||
|
observables.add(AccountManager.getInstance().getBookDetails(collBook.getId())); |
||||||
|
} |
||||||
|
} |
||||||
|
//zip可能不是一个好方法。
|
||||||
|
Single.zip(observables, objects -> { |
||||||
|
List<CollBookBean> newCollBooks = new ArrayList<>(objects.length); |
||||||
|
for (int i = 0; i < collBooks.size(); ++i) { |
||||||
|
CollBookBean oldCollBook = collBooks.get(i); |
||||||
|
CollBookBean newCollBook = ((BookDetailResp) objects[i]).getCollBookBean(); |
||||||
|
//如果是oldBook是update状态,或者newCollBook与oldBook章节数不同
|
||||||
|
if (oldCollBook.isUpdate() || !oldCollBook.getLastChapter().equals(newCollBook.getLastChapter())) { |
||||||
|
newCollBook.setIsUpdate(true); |
||||||
|
} else { |
||||||
|
newCollBook.setIsUpdate(false); |
||||||
|
} |
||||||
|
newCollBook.setLastRead(oldCollBook.getLastRead()); |
||||||
|
newCollBooks.add(newCollBook); |
||||||
|
//存储到数据库中
|
||||||
|
BookRepository.getInstance().saveCollBooks(newCollBooks); |
||||||
|
} |
||||||
|
return newCollBooks; |
||||||
|
}) |
||||||
|
.compose(RxUtils::toSimpleSingle) |
||||||
|
.subscribe(new SingleObserver<List<CollBookBean>>() { |
||||||
|
@Override |
||||||
|
public void onSubscribe(Disposable d) { |
||||||
|
// addDisposable(d);
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onSuccess(List<CollBookBean> value) { |
||||||
|
//跟原先比较
|
||||||
|
mList.clear(); |
||||||
|
mList.addAll(BookRepository.getInstance().getCollBooks()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onError(Throwable e) { |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,119 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.RankListAdapter; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.RankByUpadateResp; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import retrofit2.Call; |
||||||
|
import retrofit2.Callback; |
||||||
|
import retrofit2.Response; |
||||||
|
|
||||||
|
import static com.novel.read.constants.Constant.COMMENT_SIZE; |
||||||
|
|
||||||
|
|
||||||
|
public class BookListFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
@BindView(R.id.rlv_book_list) |
||||||
|
RecyclerView mRlvBookList; |
||||||
|
private RankListAdapter mAdapter; |
||||||
|
private List<RankByUpadateResp.BookBean> mList; |
||||||
|
String sex; |
||||||
|
String dateType; |
||||||
|
String type; |
||||||
|
private int page = 1; |
||||||
|
private int loadSize; |
||||||
|
|
||||||
|
public static BookListFragment newInstance(String type, String dateType, String sex) { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
args.putString(Constant.Sex, sex); |
||||||
|
args.putString(Constant.DateType, dateType); |
||||||
|
args.putString(Constant.Type, type); |
||||||
|
BookListFragment fragment = new BookListFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_book_list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
mList = new ArrayList<>(); |
||||||
|
|
||||||
|
mRlvBookList.setLayoutManager(new LinearLayoutManager(getActivity())); |
||||||
|
mAdapter = new RankListAdapter(mList,mRlvBookList); |
||||||
|
mRlvBookList.setAdapter(mAdapter); |
||||||
|
|
||||||
|
if (getArguments() != null) { |
||||||
|
sex = getArguments().getString(Constant.Sex); |
||||||
|
dateType = getArguments().getString(Constant.DateType); |
||||||
|
type = getArguments().getString(Constant.Type); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
getData(); |
||||||
|
mAdapter.setOnLoadMoreListener(() -> { |
||||||
|
if (mAdapter.isLoadingMore()) { |
||||||
|
|
||||||
|
} else { |
||||||
|
if (loadSize >= COMMENT_SIZE) { |
||||||
|
mAdapter.setLoadingMore(true); |
||||||
|
mList.add(null); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
page++; |
||||||
|
getData(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData() { |
||||||
|
AccountManager.getInstance().getRankList(type, sex, dateType, String.valueOf(page), new RankCallBack()); |
||||||
|
} |
||||||
|
|
||||||
|
private class RankCallBack implements Callback<RankByUpadateResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RankByUpadateResp> call, @NonNull Response<RankByUpadateResp> response) { |
||||||
|
if (response.isSuccessful()) { |
||||||
|
|
||||||
|
if (response.body() != null) { |
||||||
|
loadSize = response.body().getBook().size(); |
||||||
|
if (mAdapter.isLoadingMore()) { |
||||||
|
mList.remove(mList.size() - 1); |
||||||
|
mList.addAll(response.body().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
mAdapter.setLoadingMore(false); |
||||||
|
}else { |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(response.body().getBook()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(@NonNull Call<RankByUpadateResp> call, @NonNull Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,173 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.GridLayoutManager; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.adapter.EditRecommendAdapter; |
||||||
|
import com.novel.read.adapter.HumanAdapter; |
||||||
|
import com.novel.read.adapter.RankAdapter; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.widget.HeadLayout; |
||||||
|
import com.novel.read.widget.RefreshLayout; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import retrofit2.Call; |
||||||
|
import retrofit2.Callback; |
||||||
|
import retrofit2.Response; |
||||||
|
|
||||||
|
|
||||||
|
public class ManFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
|
||||||
|
@BindView(R.id.head_pop) |
||||||
|
HeadLayout mHeadPop; |
||||||
|
@BindView(R.id.rlv_pop) |
||||||
|
RecyclerView mRlvPop; |
||||||
|
@BindView(R.id.head_recommend) |
||||||
|
HeadLayout mHeadRecommend; |
||||||
|
@BindView(R.id.rlv_recommend) |
||||||
|
RecyclerView mRlvRecommend; |
||||||
|
@BindView(R.id.head_update) |
||||||
|
HeadLayout headUpdate; |
||||||
|
@BindView(R.id.rlv_update) |
||||||
|
RecyclerView mRlvUpdate; |
||||||
|
@BindView(R.id.swipe) |
||||||
|
RefreshLayout refreshLayout; |
||||||
|
|
||||||
|
private HumanAdapter mHumanAdapter; |
||||||
|
private List<RecommendListResp.ListBean> mHumanList = new ArrayList<>(); |
||||||
|
private EditRecommendAdapter mEditAdapter; |
||||||
|
private List<RecommendListResp.ListBean> mEditList = new ArrayList<>(); |
||||||
|
private RankAdapter mRankAdapter; |
||||||
|
private List<RecommendListResp.ListBean> mRankList = new ArrayList<>(); |
||||||
|
|
||||||
|
public static ManFragment newInstance(String sex) { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
args.putString(Constant.Sex, sex); |
||||||
|
ManFragment fragment = new ManFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_man; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
|
||||||
|
mRlvPop.setLayoutManager(new GridLayoutManager(getActivity(), 3)); |
||||||
|
mHumanAdapter = new HumanAdapter(mHumanList); |
||||||
|
mRlvPop.setAdapter(mHumanAdapter); |
||||||
|
|
||||||
|
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); |
||||||
|
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); |
||||||
|
mRlvRecommend.setLayoutManager(linearLayoutManager); |
||||||
|
mEditAdapter = new EditRecommendAdapter(mEditList); |
||||||
|
mRlvRecommend.setAdapter(mEditAdapter); |
||||||
|
|
||||||
|
mRlvUpdate.setLayoutManager(new GridLayoutManager(getActivity(), 3)); |
||||||
|
mRankAdapter = new RankAdapter(mRankList); |
||||||
|
mRlvUpdate.setAdapter(mRankAdapter); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
refreshLayout.showLoading(); |
||||||
|
getData(); |
||||||
|
refreshLayout.setOnReloadingListener(new RefreshLayout.OnReloadingListener() { |
||||||
|
@Override |
||||||
|
public void onReload() { |
||||||
|
getData(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData() { |
||||||
|
AccountManager.getInstance().getRecommendList(Constant.ListType.Human, new HumanCallBack()); |
||||||
|
AccountManager.getInstance().getRecommendList(Constant.ListType.EditRecommend, new EditCallBack()); |
||||||
|
AccountManager.getInstance().getRecommendList(Constant.ListType.HotSearch, new HotSearchCallBack()); |
||||||
|
} |
||||||
|
|
||||||
|
private class HumanCallBack implements Callback<RecommendListResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RecommendListResp> call, @NonNull Response<RecommendListResp> response) { |
||||||
|
if (response.isSuccessful() && response.body() != null) { |
||||||
|
mHumanList.clear(); |
||||||
|
mHumanList.addAll(response.body().getList()); |
||||||
|
mHumanAdapter.notifyDataSetChanged(); |
||||||
|
|
||||||
|
} else { |
||||||
|
refreshLayout.showError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(Call<RecommendListResp> call, Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class EditCallBack implements Callback<RecommendListResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RecommendListResp> call, @NonNull Response<RecommendListResp> response) { |
||||||
|
if (response.isSuccessful() && response.body() != null) { |
||||||
|
mEditList.clear(); |
||||||
|
mEditList.addAll(response.body().getList()); |
||||||
|
mEditAdapter.notifyDataSetChanged(); |
||||||
|
|
||||||
|
} else { |
||||||
|
refreshLayout.showError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(Call<RecommendListResp> call, Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class HotSearchCallBack implements Callback<RecommendListResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RecommendListResp> call, @NonNull Response<RecommendListResp> response) { |
||||||
|
refreshLayout.showFinish(); |
||||||
|
if (response.isSuccessful() && response.body() != null) { |
||||||
|
|
||||||
|
mRankList.clear(); |
||||||
|
mRankList.addAll(response.body().getList()); |
||||||
|
mRankAdapter.notifyDataSetChanged(); |
||||||
|
} else { |
||||||
|
refreshLayout.showError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(Call<RecommendListResp> call, Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,152 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.net.Uri; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelSearchActivity; |
||||||
|
import com.novel.read.activity.NovelSettingActivity; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.ReStartEvent; |
||||||
|
import com.novel.read.utlis.ToastUtil; |
||||||
|
import com.novel.read.utlis.VersionUtil; |
||||||
|
import com.novel.read.widget.dialog.AppraiseDialog; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/10 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class MoreFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar title; |
||||||
|
@BindView(R.id.tv_options) |
||||||
|
TextView tvOptions; |
||||||
|
@BindView(R.id.tv_appraise) |
||||||
|
TextView tvAppraise; |
||||||
|
@BindView(R.id.tv_setting) |
||||||
|
TextView tvSetting; |
||||||
|
|
||||||
|
|
||||||
|
public static MoreFragment newInstance() { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
MoreFragment fragment = new MoreFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_more; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
title.inflateMenu(R.menu.title_more); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
title.setOnMenuItemClickListener(menuItem -> { |
||||||
|
if (menuItem.getItemId() == R.id.action_search) { |
||||||
|
toActivity(NovelSearchActivity.class); |
||||||
|
getActivity().overridePendingTransition(R.anim.message_fade_in, R.anim.message_fade_out); |
||||||
|
} |
||||||
|
return true; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@OnClick({R.id.tv_options, R.id.tv_appraise, R.id.tv_setting}) |
||||||
|
public void onViewClicked(View view) { |
||||||
|
switch (view.getId()) { |
||||||
|
case R.id.tv_options: |
||||||
|
feedback(); |
||||||
|
break; |
||||||
|
case R.id.tv_appraise: |
||||||
|
final AppraiseDialog dialog = new AppraiseDialog(getActivity()); |
||||||
|
dialog.AppraiseDialog(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
goToMarket(getActivity(), VersionUtil.getPackage(getActivity())); |
||||||
|
dialog.dismiss(); |
||||||
|
} |
||||||
|
}); |
||||||
|
dialog.show(); |
||||||
|
|
||||||
|
break; |
||||||
|
case R.id.tv_setting: |
||||||
|
toActivity(NovelSettingActivity.class); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) { |
||||||
|
super.onActivityResult(requestCode, resultCode, data); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static void goToMarket(Context context, String packageName) { |
||||||
|
Uri uri = Uri.parse("market://details?id=" + packageName); |
||||||
|
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); |
||||||
|
final String GOOGLE_PLAY = "com.android.vending";//这里对应的是谷歌商店,跳转别的商店改成对应的即可
|
||||||
|
|
||||||
|
goToMarket.setPackage(GOOGLE_PLAY);//这里对应的是谷歌商店,跳转别的商店改成对应的即可
|
||||||
|
|
||||||
|
try { |
||||||
|
context.startActivity(goToMarket); |
||||||
|
} catch (ActivityNotFoundException e) { |
||||||
|
if (goToMarket.resolveActivity(context.getPackageManager()) != null) { //有浏览器
|
||||||
|
context.startActivity(goToMarket); |
||||||
|
}else { |
||||||
|
ToastUtil.show(context,"未检测到Google应用商店"); |
||||||
|
} |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void feedback() { |
||||||
|
Intent email = new Intent(Intent.ACTION_SEND); |
||||||
|
//邮件发送类型:无附件,纯文本
|
||||||
|
email.setType("plain/text"); |
||||||
|
//邮件接收者(数组,可以是多位接收者)
|
||||||
|
String[] emailReceiver = new String[]{Constant.FeedBackEmail}; |
||||||
|
String emailTitle = getString(R.string.opinions); |
||||||
|
String emailContent = ""; |
||||||
|
//设置邮件地址
|
||||||
|
email.putExtra(Intent.EXTRA_EMAIL, emailReceiver); |
||||||
|
//设置邮件标题
|
||||||
|
email.putExtra(Intent.EXTRA_SUBJECT, emailTitle); |
||||||
|
//设置发送的内容
|
||||||
|
email.putExtra(Intent.EXTRA_TEXT, emailContent); |
||||||
|
//调用系统的邮件系统
|
||||||
|
startActivity(Intent.createChooser(email, "请选择邮件发送软件")); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void restart(ReStartEvent event) { |
||||||
|
getActivity().recreate(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelSearchActivity; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/10 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class RecommendFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
@BindView(R.id.tv_search) |
||||||
|
TextView mTvSearch; |
||||||
|
|
||||||
|
public static RecommendFragment newInstance() { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
RecommendFragment fragment = new RecommendFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_recommend; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
// List<Fragment> fragmentList = new ArrayList<>();
|
||||||
|
// ManFragment manFragment = ManFragment.newInstance(Constant.GenderType.Man);
|
||||||
|
// WomanFragment womanFragment = WomanFragment.newInstance(Constant.GenderType.Woman);
|
||||||
|
// fragmentList.add(manFragment);
|
||||||
|
// fragmentList.add(womanFragment);
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
} |
||||||
|
|
||||||
|
@OnClick({ R.id.tv_search}) |
||||||
|
public void onViewClicked(View view) { |
||||||
|
switch (view.getId()) { |
||||||
|
case R.id.tv_search: |
||||||
|
toActivity(NovelSearchActivity.class); |
||||||
|
getActivity().overridePendingTransition(R.anim.message_fade_in, R.anim.message_fade_out); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,104 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
|
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelSearchActivity; |
||||||
|
import com.novel.read.adapter.StackAdapter; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
import com.novel.read.event.GetCategoryTypeEvent; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.CategoryTypeResp; |
||||||
|
import com.novel.read.widget.RefreshLayout; |
||||||
|
import com.squareup.otto.Subscribe; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/10 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class StackFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
@BindView(R.id.tv_search) |
||||||
|
TextView tvSearch; |
||||||
|
@BindView(R.id.rlv_book_type) |
||||||
|
RecyclerView mRlBookType; |
||||||
|
private StackAdapter mAdapter; |
||||||
|
@BindView(R.id.refresh) |
||||||
|
RefreshLayout refreshLayout; |
||||||
|
private List<CategoryTypeResp.CategoryBean> mList; |
||||||
|
|
||||||
|
public static StackFragment newInstance() { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
StackFragment fragment = new StackFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_stack; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
mList = new ArrayList<>(); |
||||||
|
mRlBookType.setLayoutManager(new GridLayoutManager(getActivity(),2)); |
||||||
|
mAdapter = new StackAdapter(mList); |
||||||
|
mRlBookType.setAdapter(mAdapter); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
refreshLayout.showLoading(); |
||||||
|
getData(); |
||||||
|
refreshLayout.setOnReloadingListener(new RefreshLayout.OnReloadingListener() { |
||||||
|
@Override |
||||||
|
public void onReload() { |
||||||
|
getData(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData(){ |
||||||
|
AccountManager.getInstance().getCategoryType(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@OnClick(R.id.tv_search) |
||||||
|
public void onViewClicked() { |
||||||
|
toActivity(NovelSearchActivity.class); |
||||||
|
getActivity().overridePendingTransition(R.anim.message_fade_in, R.anim.message_fade_out); |
||||||
|
} |
||||||
|
|
||||||
|
@Subscribe |
||||||
|
public void getCategoryType(GetCategoryTypeEvent event){ |
||||||
|
refreshLayout.showFinish(); |
||||||
|
if (event.isFail()){ |
||||||
|
refreshLayout.showError(); |
||||||
|
}else { |
||||||
|
mList.clear(); |
||||||
|
mList.addAll(event.getResult().getCategory()); |
||||||
|
mAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,209 @@ |
|||||||
|
package com.novel.read.fragment; |
||||||
|
|
||||||
|
import android.os.Bundle; |
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.recyclerview.widget.GridLayoutManager; |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.activity.NovelRankListActivity; |
||||||
|
import com.novel.read.activity.NovelRecommendBookListActivity; |
||||||
|
import com.novel.read.adapter.EditRecommendAdapter; |
||||||
|
import com.novel.read.adapter.HumanAdapter; |
||||||
|
import com.novel.read.adapter.RankAdapter; |
||||||
|
import com.novel.read.base.NovelBaseFragment; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.widget.HeadLayout; |
||||||
|
import com.novel.read.widget.RefreshLayout; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.OnClick; |
||||||
|
import retrofit2.Call; |
||||||
|
import retrofit2.Callback; |
||||||
|
import retrofit2.Response; |
||||||
|
|
||||||
|
|
||||||
|
public class WomanFragment extends NovelBaseFragment { |
||||||
|
|
||||||
|
|
||||||
|
@BindView(R.id.head_pop) |
||||||
|
HeadLayout mHeadPop; |
||||||
|
@BindView(R.id.rlv_pop) |
||||||
|
RecyclerView mRlvPop; |
||||||
|
@BindView(R.id.head_recommend) |
||||||
|
HeadLayout headRecommend; |
||||||
|
@BindView(R.id.rlv_recommend) |
||||||
|
RecyclerView mRlvRecommend; |
||||||
|
@BindView(R.id.head_update) |
||||||
|
HeadLayout headUpdate; |
||||||
|
@BindView(R.id.rlv_update) |
||||||
|
RecyclerView mRlvUpdate; |
||||||
|
@BindView(R.id.swipe) |
||||||
|
RefreshLayout refreshLayout; |
||||||
|
|
||||||
|
private HumanAdapter mHumanAdapter; |
||||||
|
private List<RecommendListResp.ListBean> mHumanList = new ArrayList<>(); |
||||||
|
private EditRecommendAdapter mEditAdapter; |
||||||
|
private List<RecommendListResp.ListBean> mEditList = new ArrayList<>(); |
||||||
|
private RankAdapter mRankAdapter; |
||||||
|
private List<RecommendListResp.ListBean> mRankList = new ArrayList<>(); |
||||||
|
|
||||||
|
public static WomanFragment newInstance(String sex) { |
||||||
|
Bundle args = new Bundle(); |
||||||
|
args.putString(Constant.Sex, sex); |
||||||
|
WomanFragment fragment = new WomanFragment(); |
||||||
|
fragment.setArguments(args); |
||||||
|
return fragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getLayoutId() { |
||||||
|
return R.layout.fragment_man; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initView() { |
||||||
|
EventManager.Companion.getInstance().registerSubscriber(this); |
||||||
|
|
||||||
|
mRlvPop.setLayoutManager(new GridLayoutManager(getActivity(), 3)); |
||||||
|
mHumanAdapter = new HumanAdapter(mHumanList); |
||||||
|
mRlvPop.setAdapter(mHumanAdapter); |
||||||
|
|
||||||
|
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); |
||||||
|
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); |
||||||
|
mRlvRecommend.setLayoutManager(linearLayoutManager); |
||||||
|
mEditAdapter = new EditRecommendAdapter(mEditList); |
||||||
|
mRlvRecommend.setAdapter(mEditAdapter); |
||||||
|
|
||||||
|
mRlvUpdate.setLayoutManager(new GridLayoutManager(getActivity(),3)); |
||||||
|
mRankAdapter = new RankAdapter(mRankList); |
||||||
|
mRlvUpdate.setAdapter(mRankAdapter); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData() { |
||||||
|
if (getArguments() != null) { |
||||||
|
String sex = getArguments().getString(Constant.Sex); |
||||||
|
refreshLayout.showLoading(); |
||||||
|
getData(sex); |
||||||
|
refreshLayout.setOnReloadingListener(new RefreshLayout.OnReloadingListener() { |
||||||
|
@Override |
||||||
|
public void onReload() { |
||||||
|
getData(sex); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
mHeadPop.setRightTextClickListener(new View.OnClickListener() { |
||||||
|
@Override |
||||||
|
public void onClick(View view) { |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void getData(String sex){ |
||||||
|
AccountManager.getInstance().getRecommendList(Constant.ListType.Human,new HumanCallBack()); |
||||||
|
AccountManager.getInstance().getRecommendList(Constant.ListType.EditRecommend,new EditCallBack()); |
||||||
|
AccountManager.getInstance().getRecommendList(Constant.ListType.HotSearch,new HotSearchCallBack()); |
||||||
|
// AccountManager.getInstance().getRankByUpdate(1,9,new HotSearchCallBack());
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@OnClick({R.id.head_pop, R.id.head_recommend, R.id.head_update}) |
||||||
|
public void onViewClicked(View view) { |
||||||
|
Bundle bundle = new Bundle(); |
||||||
|
bundle.putString(Constant.Sex,Constant.GenderType.Woman); |
||||||
|
switch (view.getId()) { |
||||||
|
case R.id.head_pop: |
||||||
|
bundle.putString(Constant.Type,Constant.ListType.Human); |
||||||
|
toActivity(NovelRecommendBookListActivity.class,bundle); |
||||||
|
break; |
||||||
|
case R.id.head_recommend: |
||||||
|
bundle.putString(Constant.Type,Constant.ListType.EditRecommend); |
||||||
|
toActivity(NovelRankListActivity.class,bundle); |
||||||
|
break; |
||||||
|
case R.id.head_update: |
||||||
|
bundle.putString(Constant.Type,Constant.ListType.HotSearch); |
||||||
|
toActivity(NovelRankListActivity.class,bundle); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class HumanCallBack implements Callback<RecommendListResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RecommendListResp> call, @NonNull Response<RecommendListResp> response) { |
||||||
|
if (response.isSuccessful()&& response.body() != null){ |
||||||
|
mHumanList.clear(); |
||||||
|
mHumanList.addAll(response.body().getList()); |
||||||
|
mHumanAdapter.notifyDataSetChanged(); |
||||||
|
|
||||||
|
}else { |
||||||
|
refreshLayout.showError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(Call<RecommendListResp> call, Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class EditCallBack implements Callback<RecommendListResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RecommendListResp> call, @NonNull Response<RecommendListResp> response) { |
||||||
|
if (response.isSuccessful()&& response.body() != null){ |
||||||
|
mEditList.clear(); |
||||||
|
mEditList.addAll(response.body().getList()); |
||||||
|
mEditAdapter.notifyDataSetChanged(); |
||||||
|
|
||||||
|
}else { |
||||||
|
refreshLayout.showError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(Call<RecommendListResp> call, Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class HotSearchCallBack implements Callback<RecommendListResp> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onResponse(@NonNull Call<RecommendListResp> call, @NonNull Response<RecommendListResp> response) { |
||||||
|
refreshLayout.showFinish(); |
||||||
|
if (response.isSuccessful()&&response.body()!=null){ |
||||||
|
mRankList.clear(); |
||||||
|
mRankList.addAll(response.body().getList()); |
||||||
|
mRankAdapter.notifyDataSetChanged(); |
||||||
|
}else { |
||||||
|
refreshLayout.showError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onFailure(Call<RecommendListResp> call, Throwable t) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
EventManager.Companion.getInstance().unregisterSubscriber(this); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,315 @@ |
|||||||
|
package com.novel.read.http; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.text.TextUtils; |
||||||
|
import android.util.Log; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.mango.mangolib.http.ErrorResponse; |
||||||
|
import com.mango.mangolib.http.MyRequestType; |
||||||
|
import com.mango.mangolib.http.ServiceCallback; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.event.AddBookSignEvent; |
||||||
|
import com.novel.read.event.BookArticleEvent; |
||||||
|
import com.novel.read.event.DeleteBookSignEvent; |
||||||
|
import com.novel.read.event.ErrorChapterEvent; |
||||||
|
import com.novel.read.event.FinishChapterEvent; |
||||||
|
import com.novel.read.event.GetBookDetailEvent; |
||||||
|
import com.novel.read.event.GetBookSignEvent; |
||||||
|
import com.novel.read.event.GetCategoryTypeEvent; |
||||||
|
import com.novel.read.event.GetRecommendBookEvent; |
||||||
|
import com.novel.read.event.HotSearchEvent; |
||||||
|
import com.novel.read.event.LoginEvent; |
||||||
|
import com.novel.read.event.SearchListEvent; |
||||||
|
import com.novel.read.event.VersionEvent; |
||||||
|
import com.novel.read.http.service.AccountService; |
||||||
|
import com.novel.read.model.db.ChapterInfoBean; |
||||||
|
import com.novel.read.model.db.dbManage.BookRepository; |
||||||
|
import com.novel.read.model.protocol.BookArticleResp; |
||||||
|
import com.novel.read.model.protocol.BookDetailResp; |
||||||
|
import com.novel.read.model.protocol.CategoryTypeResp; |
||||||
|
import com.novel.read.model.protocol.HotSearchResp; |
||||||
|
import com.novel.read.model.protocol.MarkResp; |
||||||
|
import com.novel.read.model.protocol.RankByUpadateResp; |
||||||
|
import com.novel.read.model.protocol.RecommendBookResp; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.model.protocol.SearchResp; |
||||||
|
import com.novel.read.model.protocol.UidResp; |
||||||
|
import com.novel.read.model.protocol.VersionResp; |
||||||
|
import com.novel.read.utlis.LogUtils; |
||||||
|
import com.novel.read.utlis.PhoneUtils; |
||||||
|
import com.novel.read.widget.page.TxtChapter; |
||||||
|
|
||||||
|
import org.reactivestreams.Subscriber; |
||||||
|
import org.reactivestreams.Subscription; |
||||||
|
|
||||||
|
import java.util.ArrayDeque; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import io.reactivex.Single; |
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers; |
||||||
|
import io.reactivex.schedulers.Schedulers; |
||||||
|
import okhttp3.MediaType; |
||||||
|
import okhttp3.RequestBody; |
||||||
|
import retrofit2.Call; |
||||||
|
import retrofit2.Callback; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by JillFung on 2017/2/14. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class AccountManager { |
||||||
|
|
||||||
|
private AccountService accountService; |
||||||
|
|
||||||
|
private AccountManager() { |
||||||
|
accountService = ServiceGenerator.createService(AccountService.class, MyRequestType.URL_TEXT); |
||||||
|
} |
||||||
|
|
||||||
|
private static AccountManager instance = null; |
||||||
|
|
||||||
|
public static synchronized AccountManager getInstance() { |
||||||
|
if (instance == null) { |
||||||
|
instance = new AccountManager(); |
||||||
|
} |
||||||
|
return instance; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void getRecommendBook(String bookId,String limit) { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("book_id", bookId); |
||||||
|
Call<RecommendBookResp> call = accountService.getRecommendBook(getUrlString(Urls.getRecommend,map)); |
||||||
|
call.enqueue(new ServiceCallback<>(GetRecommendBookEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void getBookDetail(String bookId) { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("book_id", bookId); |
||||||
|
Call<BookDetailResp> call = accountService.getBookDetail(getUrlString(Urls.getBookDetail,map)); |
||||||
|
call.enqueue(new ServiceCallback<>(GetBookDetailEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public Single<BookDetailResp> getBookDetails(String bookId){ //rxjava 获取多书籍详情 合并请求调用
|
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("book_id", bookId); |
||||||
|
return accountService.getBookDetails(getUrlString(Urls.getBookDetail,map)); |
||||||
|
} |
||||||
|
|
||||||
|
public void getCategoryType() { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
Call<CategoryTypeResp> call = accountService.getCategoryType(getUrlString(Urls.getCategoryType,map)); |
||||||
|
call.enqueue(new ServiceCallback<>(GetCategoryTypeEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void getHotSearch() { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
Call<HotSearchResp> call = accountService.getHotSearch(getUrlString(Urls.getHotSearch,map)); |
||||||
|
call.enqueue(new ServiceCallback<>(HotSearchEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void getBookArticle(String bookId,String hasContent,String page,String limit) { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("book_id", bookId); |
||||||
|
map.put("has_content", hasContent); |
||||||
|
map.put("page", page); |
||||||
|
map.put("limit", limit); |
||||||
|
Call<BookArticleResp> call = accountService.getBookArticle(getUrlString(Urls.getBookArticle,map)); |
||||||
|
call.enqueue(new ServiceCallback<>(BookArticleEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void getSearchBookList(String category_id,String key,int page) { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
if (!TextUtils.isEmpty(category_id)) { |
||||||
|
map.put("category_id", category_id); |
||||||
|
}else { |
||||||
|
map.put("category_id", "0"); |
||||||
|
} |
||||||
|
if (!TextUtils.isEmpty(key)){ |
||||||
|
map.put("key", key); |
||||||
|
} |
||||||
|
map.put("page", String.valueOf(page)); |
||||||
|
Call<SearchResp> call = accountService.getSearchList(getUrlString(Urls.getBookList,map)); |
||||||
|
call.enqueue(new ServiceCallback<>(SearchListEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void getRecommendList(String listType, Callback<RecommendListResp> callback) { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("type", listType); |
||||||
|
Call<RecommendListResp> call = accountService.getRecommendList(getUrlString(Urls.getRecommendList,map)); |
||||||
|
call.enqueue(callback); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void getRankByUpdate(int page, int limit, Callback<RankByUpadateResp> callback) { |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
if (!TextUtils.isEmpty(String.valueOf(page))) { |
||||||
|
map.put("page", String.valueOf(page)); |
||||||
|
} |
||||||
|
if (limit!=0){ |
||||||
|
map.put("limit", String.valueOf(limit)); |
||||||
|
} |
||||||
|
Call<RankByUpadateResp> call = accountService.getRankByUpdate(getUrlString(Urls.getRankByUpdate,map)); |
||||||
|
call.enqueue(callback); |
||||||
|
} |
||||||
|
|
||||||
|
public void getRankList(String type, String sex, String dateType, String page, Callback<RankByUpadateResp> callback){ |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("type", type); |
||||||
|
map.put("gender", sex); |
||||||
|
map.put("date_type", dateType); |
||||||
|
map.put("page", page); |
||||||
|
Call<RankByUpadateResp> call = accountService.getRankList(getUrlString(Urls.getRankList, map)); |
||||||
|
call.enqueue(callback); |
||||||
|
} |
||||||
|
|
||||||
|
public void checkVersion(int versionCode){ |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("version", String.valueOf(versionCode)); |
||||||
|
// map.put("shell", Constant.shell);
|
||||||
|
Call<VersionResp> call = accountService.checkVersion(getUrlString(Urls.checkVersion, map)); |
||||||
|
call.enqueue(new ServiceCallback<>(VersionEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void addSign(String bookId,String articleId,String content){ |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("book_id", bookId); |
||||||
|
map.put("article_id", articleId); |
||||||
|
map.put("content", content); |
||||||
|
Call<ErrorResponse> call = accountService.addSign(Urls.addBookSign, mapToBody(map)); |
||||||
|
call.enqueue(new ServiceCallback<>(AddBookSignEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void deleteSign(String signIds){ |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("sign_ids", signIds); |
||||||
|
Call<ErrorResponse> call = accountService.deleteSign(Urls.deleteSign, mapToBody(map)); |
||||||
|
call.enqueue(new ServiceCallback<>(DeleteBookSignEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void getSignList(String bookId){ |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
map.put("book_id", bookId); |
||||||
|
Call<MarkResp> call = accountService.getSignList(getUrlString(Urls.getBookSign, map)); |
||||||
|
call.enqueue(new ServiceCallback<>(GetBookSignEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
public void login(Context mContext){ |
||||||
|
HashMap<String, String> map = new HashMap<>(); |
||||||
|
Log.e("getUniquePsuedoID", "login: "+ PhoneUtils.getUniquePsuedoID()); |
||||||
|
map.put("code", PhoneUtils.getUniquePsuedoID()); |
||||||
|
Call<UidResp> call = accountService.login(Urls.login, mapToBody(map)); |
||||||
|
call.enqueue(new ServiceCallback<>(LoginEvent.class)); |
||||||
|
} |
||||||
|
|
||||||
|
private Subscription mChapterSub; |
||||||
|
|
||||||
|
public void getBookArticleDetail(String bookId,List<TxtChapter> bookChapters){ |
||||||
|
int size = bookChapters.size(); |
||||||
|
//取消上次的任务,防止多次加载
|
||||||
|
if (mChapterSub != null) { |
||||||
|
mChapterSub.cancel(); |
||||||
|
} |
||||||
|
List<Single<ChapterInfoBean>> chapterInfos = new ArrayList<>(bookChapters.size()); |
||||||
|
ArrayDeque<String> titles = new ArrayDeque<>(bookChapters.size()); |
||||||
|
|
||||||
|
// 将要下载章节,转换成网络请求。
|
||||||
|
for (int i = 0; i < size; ++i) { |
||||||
|
TxtChapter bookChapter = bookChapters.get(i); |
||||||
|
// 网络中获取数据
|
||||||
|
Single<ChapterInfoBean> chapterInfoSingle = getChapterInfo(bookChapter.getChapterId()); |
||||||
|
chapterInfos.add(chapterInfoSingle); |
||||||
|
titles.add(bookChapter.getTitle()); |
||||||
|
} |
||||||
|
|
||||||
|
Single.concat(chapterInfos) |
||||||
|
.subscribeOn(Schedulers.io()) |
||||||
|
.observeOn(AndroidSchedulers.mainThread()) |
||||||
|
.subscribe(new Subscriber<ChapterInfoBean>() { |
||||||
|
String title = titles.poll(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onSubscribe(Subscription s) { |
||||||
|
s.request(Integer.MAX_VALUE); |
||||||
|
mChapterSub = s; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onNext(ChapterInfoBean chapterInfoBean) { |
||||||
|
//存储数据
|
||||||
|
BookRepository.getInstance().saveChapterInfo( |
||||||
|
bookId, title, chapterInfoBean.getBody() |
||||||
|
); |
||||||
|
EventManager.Companion.getInstance().postEvent(new FinishChapterEvent()); |
||||||
|
//将获取到的数据进行存储
|
||||||
|
title = titles.poll(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onError(Throwable t) { |
||||||
|
//只有第一个加载失败才会调用errorChapter
|
||||||
|
if (bookChapters.get(0).getTitle().equals(title)) { |
||||||
|
EventManager.Companion.getInstance().postEvent(new ErrorChapterEvent()); |
||||||
|
} |
||||||
|
LogUtils.e(t); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onComplete() { |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 注意这里用的是同步请求 |
||||||
|
*/ |
||||||
|
public Single<ChapterInfoBean> getChapterInfo(String id){ |
||||||
|
HashMap<String,String> map = new HashMap<>(); |
||||||
|
map.put("article_id", id); |
||||||
|
return accountService.getBookArticleDetail(getUrlString(Urls.getDetail, map)) |
||||||
|
.map(bean -> bean.getArticle().get(0)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get方法拼接字符串 |
||||||
|
*/ |
||||||
|
private String getUrlString(String path, HashMap<String, String> query) { |
||||||
|
String mypath = path; |
||||||
|
if (query != null && query.size() > 0) { |
||||||
|
StringBuilder pathWithQuery = new StringBuilder(path); |
||||||
|
if (!path.contains("?")) { |
||||||
|
pathWithQuery.append("?"); |
||||||
|
} else { |
||||||
|
pathWithQuery.append("&"); |
||||||
|
} |
||||||
|
|
||||||
|
for (Map.Entry<String, String> stringStringEntry : query.entrySet()) { |
||||||
|
String key = (String) ((Map.Entry) stringStringEntry).getKey(); |
||||||
|
String val = (String) ((Map.Entry) stringStringEntry).getValue(); |
||||||
|
pathWithQuery.append(key); |
||||||
|
pathWithQuery.append("="); |
||||||
|
pathWithQuery.append(val); |
||||||
|
pathWithQuery.append("&"); |
||||||
|
} |
||||||
|
|
||||||
|
pathWithQuery.deleteCharAt(pathWithQuery.length() - 1); |
||||||
|
mypath = pathWithQuery.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
return mypath; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 减少请求info类的数量,直接用map替代实体类,返回body |
||||||
|
*/ |
||||||
|
private RequestBody mapToBody(HashMap<String,String> map){ |
||||||
|
return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), ServiceGenerator.formatResponse(map)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,37 @@ |
|||||||
|
package com.novel.read.http; |
||||||
|
import androidx.annotation.NonNull; |
||||||
|
|
||||||
|
import com.common_lib.base.utils.SecurityUtils; |
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
import okhttp3.Interceptor; |
||||||
|
import okhttp3.Request; |
||||||
|
import okhttp3.Response; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by alex on 2019/3/1. |
||||||
|
*/ |
||||||
|
public class CommonHeadersInterceptor implements Interceptor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Response intercept(@NonNull Interceptor.Chain chain) throws IOException { |
||||||
|
Request request = chain.request(); |
||||||
|
Request.Builder builder = request.newBuilder(); |
||||||
|
|
||||||
|
String authKey = "Android"; |
||||||
|
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); |
||||||
|
String uid = SpUtil.getStringValue(Constant.Uid, "1"); |
||||||
|
builder.addHeader("Content-Type", "application/json"); |
||||||
|
builder.addHeader("UID", uid); |
||||||
|
builder.addHeader("AUTHKEY", authKey); |
||||||
|
builder.addHeader("TIMESTAMP", timeStamp); |
||||||
|
|
||||||
|
builder.addHeader("SIGN", SecurityUtils.getInstance().MD5Decode(authKey + timeStamp).toUpperCase()); |
||||||
|
|
||||||
|
|
||||||
|
return chain.proceed(builder.build()); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
package com.novel.read.http; |
||||||
|
|
||||||
|
import com.google.gson.Gson; |
||||||
|
import com.google.gson.GsonBuilder; |
||||||
|
import com.mango.mangolib.http.GsonUTCdateAdapter; |
||||||
|
import com.mango.mangolib.http.MyRequestType; |
||||||
|
import com.mango.mangolib.http.ResponseConverterFactory; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
import okhttp3.OkHttpClient; |
||||||
|
import retrofit2.Retrofit; |
||||||
|
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; |
||||||
|
import retrofit2.converter.gson.GsonConverterFactory; |
||||||
|
|
||||||
|
|
||||||
|
public class ServiceGenerator { |
||||||
|
private static final String API_BASE_URL_TEXT = "http://novel.duoduvip.com/"; |
||||||
|
|
||||||
|
private static Gson gson = new GsonBuilder() |
||||||
|
.setPrettyPrinting() |
||||||
|
.registerTypeAdapter(Date.class, new GsonUTCdateAdapter()).create(); |
||||||
|
|
||||||
|
|
||||||
|
private static Retrofit.Builder builderTEXT = new Retrofit.Builder() |
||||||
|
.baseUrl(API_BASE_URL_TEXT) |
||||||
|
.client(getOkHttp()) |
||||||
|
.addConverterFactory(ResponseConverterFactory.Companion.create()) |
||||||
|
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) |
||||||
|
.addConverterFactory(GsonConverterFactory.create(gson)); |
||||||
|
|
||||||
|
private static OkHttpClient getOkHttp(){ |
||||||
|
return new OkHttpClient() |
||||||
|
.newBuilder() |
||||||
|
.addInterceptor(new CommonHeadersInterceptor()) |
||||||
|
.connectTimeout(30, TimeUnit.SECONDS) |
||||||
|
.writeTimeout(30, TimeUnit.SECONDS) |
||||||
|
.readTimeout(30, TimeUnit.SECONDS) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
private ServiceGenerator() { |
||||||
|
} |
||||||
|
|
||||||
|
public static <S> S createService(Class<S> serviceClass) { |
||||||
|
return createService(serviceClass); |
||||||
|
} |
||||||
|
|
||||||
|
public static <S> S createService(Class<S> serviceClass, final MyRequestType type) { |
||||||
|
Retrofit retrofit = builderTEXT.build(); |
||||||
|
return retrofit.create(serviceClass); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static String formatResponse(Object obj) { |
||||||
|
return gson.toJson(obj); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
package com.novel.read.http |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/10/14 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
|
||||||
|
object Urls { |
||||||
|
|
||||||
|
internal const val getRecommend = "api/book/getRecommendByBook/" //获取推荐书籍 |
||||||
|
internal const val getBookDetail = "api/book/getBookDetail/" //获取书籍详情 |
||||||
|
internal const val getCategoryType = "api/category/getCategoryList/" //获取小说分类 |
||||||
|
internal const val getHotSearch = "api/search/getHotSearch/" //获取热搜墙 |
||||||
|
internal const val getBookArticle = "api/book/getBookArticle/" //获取书籍章节 |
||||||
|
|
||||||
|
internal const val getBookList = "api/book/getBookList/" //获取和搜索书籍列表 |
||||||
|
internal const val getRecommendList = "api/rank/getRecommendList/" //获取推荐列表 |
||||||
|
internal const val getRankByUpdate = "api/rank/getRankByUpdate/" //最新更新 |
||||||
|
internal const val getRankList = "api/rank/getRankList/" //获取排行榜 |
||||||
|
internal const val checkVersion = " api/version/checkVersion/" //检测新版本 |
||||||
|
internal const val addBookSign = " api/sign/addBookSign/" //添加书签 |
||||||
|
internal const val getBookSign = " api/sign/getBookSignList/" //获取书签 |
||||||
|
internal const val deleteSign = " api/sign/deleteSign/" //获取书签 |
||||||
|
|
||||||
|
internal const val login = "api/login/checkLogin"//登录 |
||||||
|
|
||||||
|
internal const val getDetail = "api/book/getArticleDetail"//获取章节详情 |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,94 @@ |
|||||||
|
package com.novel.read.http.service; |
||||||
|
|
||||||
|
import com.mango.mangolib.http.ErrorResponse; |
||||||
|
import com.novel.read.model.protocol.BookArticleResp; |
||||||
|
import com.novel.read.model.protocol.BookDetailResp; |
||||||
|
import com.novel.read.model.protocol.CategoryTypeResp; |
||||||
|
import com.novel.read.model.protocol.ChapterInfoPackage; |
||||||
|
import com.novel.read.model.protocol.HotSearchResp; |
||||||
|
import com.novel.read.model.protocol.MarkResp; |
||||||
|
import com.novel.read.model.protocol.RankByUpadateResp; |
||||||
|
import com.novel.read.model.protocol.RecommendBookResp; |
||||||
|
import com.novel.read.model.protocol.RecommendListResp; |
||||||
|
import com.novel.read.model.protocol.SearchResp; |
||||||
|
import com.novel.read.model.protocol.UidResp; |
||||||
|
import com.novel.read.model.protocol.VersionResp; |
||||||
|
|
||||||
|
import io.reactivex.Single; |
||||||
|
import okhttp3.RequestBody; |
||||||
|
import retrofit2.Call; |
||||||
|
import retrofit2.http.Body; |
||||||
|
import retrofit2.http.GET; |
||||||
|
import retrofit2.http.POST; |
||||||
|
import retrofit2.http.Url; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Administrator on 2017/2/14. |
||||||
|
*/ |
||||||
|
|
||||||
|
public interface AccountService { |
||||||
|
|
||||||
|
//获取推荐书籍
|
||||||
|
@GET |
||||||
|
Call<RecommendBookResp> getRecommendBook(@Url String url); |
||||||
|
|
||||||
|
//获取书籍详情
|
||||||
|
@GET |
||||||
|
Call<BookDetailResp> getBookDetail(@Url String url); |
||||||
|
|
||||||
|
//获取书籍详情
|
||||||
|
@GET |
||||||
|
Single<BookDetailResp> getBookDetails(@Url String url); |
||||||
|
|
||||||
|
//小说类型
|
||||||
|
@GET |
||||||
|
Call<CategoryTypeResp> getCategoryType(@Url String url); |
||||||
|
|
||||||
|
//热搜
|
||||||
|
@GET |
||||||
|
Call<HotSearchResp> getHotSearch(@Url String url); |
||||||
|
|
||||||
|
//书籍章节
|
||||||
|
@GET |
||||||
|
Call<BookArticleResp> getBookArticle(@Url String url); |
||||||
|
|
||||||
|
//搜索
|
||||||
|
@GET |
||||||
|
Call<SearchResp> getSearchList(@Url String url); |
||||||
|
|
||||||
|
//获取推荐
|
||||||
|
@GET |
||||||
|
Call<RecommendListResp> getRecommendList(@Url String url); |
||||||
|
|
||||||
|
//获取最新排行
|
||||||
|
@GET |
||||||
|
Call<RankByUpadateResp> getRankByUpdate(@Url String url); |
||||||
|
|
||||||
|
//获取排行
|
||||||
|
@GET |
||||||
|
Call<RankByUpadateResp> getRankList(@Url String url); |
||||||
|
|
||||||
|
//获取新版本
|
||||||
|
@GET |
||||||
|
Call<VersionResp> checkVersion(@Url String url); |
||||||
|
|
||||||
|
//添加标签
|
||||||
|
@POST |
||||||
|
Call<ErrorResponse> addSign(@Url String url, @Body RequestBody body); |
||||||
|
|
||||||
|
//删除标签
|
||||||
|
@POST |
||||||
|
Call<ErrorResponse> deleteSign(@Url String url, @Body RequestBody body); |
||||||
|
|
||||||
|
//获取标签
|
||||||
|
@GET |
||||||
|
Call<MarkResp> getSignList(@Url String url); |
||||||
|
|
||||||
|
//登录
|
||||||
|
@POST |
||||||
|
Call<UidResp> login(@Url String url, @Body RequestBody body); |
||||||
|
|
||||||
|
//获取书籍章节详情
|
||||||
|
@GET |
||||||
|
Single<ChapterInfoPackage> getBookArticleDetail(@Url String url); |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
package com.novel.read.inter |
||||||
|
|
||||||
|
/** |
||||||
|
* create by zlj on 2019/10/14 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
interface OnLoadMoreListener { |
||||||
|
fun onLoadMore() |
||||||
|
} |
||||||
@ -0,0 +1,161 @@ |
|||||||
|
package com.novel.read.model.db; |
||||||
|
|
||||||
|
import org.litepal.crud.LitePalSupport; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-10. |
||||||
|
* 书的章节链接(作为下载的进度数据) |
||||||
|
* 同时作为网络章节和本地章节 (没有找到更好分离两者的办法) |
||||||
|
*/ |
||||||
|
public class BookChapterBean extends LitePalSupport implements Serializable { |
||||||
|
/** |
||||||
|
* title : 第一章 他叫白小纯 |
||||||
|
* link : http://read.qidian.com/chapter/rJgN8tJ_cVdRGoWu-UQg7Q2/6jr-buLIUJSaGfXRMrUjdw2
|
||||||
|
* unreadble : false |
||||||
|
*/ |
||||||
|
private String chapterId; |
||||||
|
|
||||||
|
private String link; |
||||||
|
|
||||||
|
private String title; |
||||||
|
|
||||||
|
//所属的下载任务
|
||||||
|
private String taskName; |
||||||
|
|
||||||
|
private boolean unreadble; |
||||||
|
|
||||||
|
//所属的书籍
|
||||||
|
private String bookId; |
||||||
|
|
||||||
|
//本地书籍参数
|
||||||
|
private CollBookBean collBookBean; |
||||||
|
|
||||||
|
//本地下载参数
|
||||||
|
private DownloadTaskBean downloadTaskBean; |
||||||
|
|
||||||
|
//在书籍文件中的起始位置
|
||||||
|
private long start; |
||||||
|
|
||||||
|
//在书籍文件中的终止位置
|
||||||
|
private long end; |
||||||
|
|
||||||
|
public BookChapterBean(String id, String link, String title, String taskName, |
||||||
|
boolean unreadble, String bookId, long start, long end) { |
||||||
|
this.chapterId = id; |
||||||
|
this.link = link; |
||||||
|
this.title = title; |
||||||
|
this.taskName = taskName; |
||||||
|
this.unreadble = unreadble; |
||||||
|
this.bookId = bookId; |
||||||
|
this.start = start; |
||||||
|
this.end = end; |
||||||
|
} |
||||||
|
public BookChapterBean(String id,String title) { |
||||||
|
this.chapterId = id; |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public BookChapterBean() { |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLink() { |
||||||
|
return link; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLink(String link) { |
||||||
|
this.link = link; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isUnreadble() { |
||||||
|
return unreadble; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUnreadble(boolean unreadble) { |
||||||
|
this.unreadble = unreadble; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTaskName() { |
||||||
|
return taskName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTaskName(String taskName) { |
||||||
|
this.taskName = taskName; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean getUnreadble() { |
||||||
|
return this.unreadble; |
||||||
|
} |
||||||
|
|
||||||
|
public String getBookId() { |
||||||
|
return bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBookId(String bookId) { |
||||||
|
this.bookId = bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getId() { |
||||||
|
return chapterId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(String id) { |
||||||
|
this.chapterId = id; |
||||||
|
} |
||||||
|
|
||||||
|
public long getStart() { |
||||||
|
return start; |
||||||
|
} |
||||||
|
|
||||||
|
public void setStart(long start) { |
||||||
|
this.start = start; |
||||||
|
} |
||||||
|
|
||||||
|
public long getEnd() { |
||||||
|
return end; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnd(long end) { |
||||||
|
this.end = end; |
||||||
|
} |
||||||
|
|
||||||
|
public CollBookBean getCollBookBean() { |
||||||
|
return collBookBean; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCollBookBean(CollBookBean collBookBean) { |
||||||
|
this.collBookBean = collBookBean; |
||||||
|
} |
||||||
|
|
||||||
|
public DownloadTaskBean getDownloadTaskBean() { |
||||||
|
return downloadTaskBean; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDownloadTaskBean(DownloadTaskBean downloadTaskBean) { |
||||||
|
this.downloadTaskBean = downloadTaskBean; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "BookChapterBean{" + |
||||||
|
"chapterId='" + chapterId + '\'' + |
||||||
|
", link='" + link + '\'' + |
||||||
|
", title='" + title + '\'' + |
||||||
|
", taskName='" + taskName + '\'' + |
||||||
|
", unreadble=" + unreadble + |
||||||
|
", bookId='" + bookId + '\'' + |
||||||
|
", start=" + start + |
||||||
|
", end=" + end + |
||||||
|
'}'; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
package com.novel.read.model.db; |
||||||
|
|
||||||
|
import org.litepal.crud.LitePalSupport; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-20. |
||||||
|
*/ |
||||||
|
public class BookRecordBean extends LitePalSupport implements Serializable { |
||||||
|
//所属的书的id
|
||||||
|
private String bookId; |
||||||
|
//阅读到了第几章
|
||||||
|
private int chapter; |
||||||
|
//当前的页码
|
||||||
|
private int pagePos; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getBookId() { |
||||||
|
return bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBookId(String bookId) { |
||||||
|
this.bookId = bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public int getChapter() { |
||||||
|
return chapter; |
||||||
|
} |
||||||
|
|
||||||
|
public void setChapter(int chapter) { |
||||||
|
this.chapter = chapter; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPagePos() { |
||||||
|
return pagePos; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPagePos(int pagePos) { |
||||||
|
this.pagePos = pagePos; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,98 @@ |
|||||||
|
package com.novel.read.model.db; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-10. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class ChapterInfoBean { |
||||||
|
/** |
||||||
|
* title : 第一章 他叫白小纯 |
||||||
|
* content : 帽儿山,位于东林山脉中,山下有一个村子,民风淳朴,以耕田为生,与世隔绝。 |
||||||
|
清晨,村庄的大门前,整个村子里的乡亲,正为一个十五六岁少年送别,这少年瘦弱,但却白白净净,看起来很是乖巧,衣着尽管是寻常的青衫,可却洗的泛白,穿在这少年的身上,与他目中的纯净搭配在一起,透出一股子灵动。 |
||||||
|
他叫白小纯。 |
||||||
|
“父老乡亲们,我要去修仙了,可我舍不得你们啊。”少年满脸不舍,原本就乖巧的样子,此刻看起来更为纯朴。 |
||||||
|
四周的乡亲,面面相觑,顿时摆出难舍之色。 |
||||||
|
“小纯,你爹娘走的早,你是个……好孩子!!难道你不想长生了么,成为仙人就可以长生,能活的很久很久,走吧,雏鹰长大,总有飞出去的那一天。”人群内走出一个头发花白的老者,说道好孩子三个字时,他顿了一下。 |
||||||
|
“在外面遇到任何事情,都要坚持下去,走出村子,就不要回来,因为你的路在前方!”老人神色慈祥,拍了拍少年的肩膀。 |
||||||
|
“长生……”白小纯身体一震,目中慢慢坚定起来,在老者以及四周乡亲鼓励的目光下,他重重的点了点头,深深的看了一眼四周的乡亲,转身迈着大步,渐渐走出了村子。 |
||||||
|
眼看少年的身影远去,村中的众人,一个个都激动起来,目中的难舍刹那就被喜悦代替,那之前满脸慈祥的老者,此刻也在颤抖,眼中流下泪水。 |
||||||
|
“苍天有眼,这白鼠狼,他终于……终于走了,是谁告诉他在附近看到仙人的,你为村子立下了大功!” |
||||||
|
“这白鼠狼终于肯离开了,可怜我家的几只鸡,就因为这白鼠狼怕鸡打鸣,不知用了什么方法,唆使一群孩子吃鸡肉,把全村的鸡都给吃的干干净净……” |
||||||
|
“今天过年了!”欢呼之声,立刻在这不大的村子里,沸腾而起,甚至有人拿出了锣鼓,高兴的敲打起来。 |
||||||
|
村子外,白小纯还没等走远,他就听到了身后村子内,传出了敲锣打鼓的声音,还夹着欢呼。 |
||||||
|
白小纯脚步一顿,神色有些古怪,干咳一声,伴随着耳边传来的锣鼓,白小纯顺着山路,走上了帽儿山。 |
||||||
|
这帽儿山虽不高,却灌木杂多,虽是清晨,可看起来也是黑压压一片,很是安静。 |
||||||
|
“听二狗说,他前几天在这里被一头野猪追赶时,看到天上有仙人飞过……”白小纯走在山路上,心脏怦怦跳动时,忽然一旁的灌林中传来阵阵哗哗声,似野猪一样,这声音来的突然,让本就紧张的白小纯,顿时背后发凉。 |
||||||
|
“谁,谁在那里!”白小纯右手快速从行囊中拿出四把斧头,六把柴刀,还觉得不放心,又从怀里取出了一小根黑色的香,死死的抓住。 |
||||||
|
“别出来,千万别出来,我有斧头,有柴刀,手里的香还可以召唤天雷,能引仙人降临,你敢出来,就劈死你!”白小纯哆嗦的大喊,连滚带爬的夹着那些武器,赶紧顺着山路跑去,沿途叮当乱响,斧头柴刀掉了一地。 |
||||||
|
或许是真的被他给吓住了,很快的哗哗声就消失,没有什么野兽跑出来,白小纯面色苍白,擦了擦冷汗,有心放弃继续上山,可一想到手中这根香是他爹娘去世前留给他的,据说是祖上曾偶然的救下一个落魄的仙人,那仙人离去时留下这根香作为报答,曾言会收下白家血脉一人为弟子,只要点燃,仙人就会到来。 |
||||||
|
可至今为止,这根香他点过十多次,始终不见仙人到来,让白小纯开始怀疑仙人是不是真的会来,这一次之所以下定决心,一方面是香所剩不多,另一方面是他听村子里人说,头几天在这看到有仙人从天上飞过。 |
||||||
|
所以他这才到来,想着距离仙人近一些,或许仙人就察觉到了也说不定。 |
||||||
|
踌躇一番,白小纯咬牙继续,好在此山不高,不久他气喘吁吁的到了山顶,站在那里,他遥望山下的村庄,神色颇为感慨,又低头看着手中的只有指甲盖大小的黑香,此香似乎被燃烧了好多次,所剩不多。 |
||||||
|
“三年了,爹娘保佑我,这次一定要成功!”白小纯深吸口气,小心的将香点燃,立刻四周狂风顿起,天空更是眨眼间乌云密布,一道道闪电划过,还有震耳欲聋的雷鸣在白小纯耳边直接炸开。 |
||||||
|
声音之大,气势之强,让白小纯身体哆嗦,有种随时会被雷劈死的感觉,下意识的就想要吐口唾沫将那根香灭掉,但却挣扎忍住。 |
||||||
|
“三年了,我点这根香点了十二次,这是第十三次,这次一定要忍住,小纯不怕,应该不会被劈死……”白小纯想起了这三年的经历,不算这次,点了十二次,每次都是这样的雷鸣闪电,仙人也没有到来,吓的本就怕死的他每次都吐口唾沫将其熄灭,说来也怪,这根香看似不凡,可实际上一样是浇水就灭。 |
||||||
|
在白小纯这里心惊肉跳,艰难的于那雷声中等待时,距离这里不远处的天空上,有一道长虹正急速的呼啸而来。 |
||||||
|
长虹内是一个中年男子,这男子衣着华丽,仙风道骨,可偏偏风尘仆仆,甚至仔细去看,可以看到他神色内深深的疲惫。 |
||||||
|
“我倒要看看,到底是个什么样的人,竟然点根香点了三年!” |
||||||
|
一想到自己这三年的经历,中年男子就气恼,三年前他察觉有人点燃自己还是凝气时送出的香药,想起了当年在凡俗中的一段人情。 |
||||||
|
这才飞出寻来,原本按照他的打算,很快就会回来,可没成想,刚寻着香气过去,还没等多远,那气息就瞬间消失,断了联系。若是一次也就罢了,这三年,气息出现了十多次。 |
||||||
|
使得他这里,多次在寻找时中断,就这样来来回回,折腾了三年…… |
||||||
|
此刻他遥遥的看到了帽儿山,看到了山顶上白小纯,气不打一处来,一瞬飞出,直接就站在了山顶,大手一挥,那根所剩不多的香,直接熄灭。 |
||||||
|
雷声刹那消失,白小纯愣了一下,抬头一看,看到了自己的身边多了一个中年男子。 |
||||||
|
“仙人?”白小纯小心翼翼的开口,有些拿不准,背后偷偷捡起一把斧头。 |
||||||
|
“本座李青候,你是白家后人?”中年修士目光如电,无视白小纯身后的斧子,打量了白小纯一番,觉得眼前此子眉清目秀,依稀与当年的故人相似,资质也不错,心底的恼意,也不由缓了一些。 |
||||||
|
“晚辈正是白家后人,白小纯。”白小纯眨了眨眼,小声说道,虽然心中有些畏惧,但还是挺了挺腰板。 |
||||||
|
“我问你,点一根香,为什么点了三年!”中年修士淡淡开口,问出了他这三年里,最想要知道的问题。 |
||||||
|
白小纯听到这个问题,脑筋飞速转动,然后脸上摆出惆怅,遥望山下的村庄。 |
||||||
|
“晚辈是一个重情重义的人,舍不得那些乡亲们,每一次我点燃香,他们也都不舍得我离去,如今山下的他们,还在因为我的离去而悲伤呢。” |
||||||
|
中年修士一愣,这个缘由,是他之前没想到的,目中的恼色又少了一些,单单从话语上看,此子的本性还是不错的。 |
||||||
|
可当他的目光落在山下的村子时,他的神识随之扫过,听到了村子里的敲锣打鼓以及那一句句欢呼白鼠狼离去的话语,面色立刻难看起来,有些头疼,看着眼前这个外表乖巧纯朴,人畜无害的白小纯,已心底明朗对方实际上一肚子坏水。 |
||||||
|
“说实话!”中年修士一瞪眼,声音如同雷声一样,白小纯吓得一个哆嗦。 |
||||||
|
“这不怨我啊,你那什么破香啊,每次点燃都会打雷,好几次都差点劈死我,我躲过了十三次,已经很不容易了。”白小纯可怜兮兮的说道。 |
||||||
|
中年修士看着白小纯,半晌无语。 |
||||||
|
“既然你这么害怕,为什么还要强行去点香十多次?”中年修士缓缓开口。 |
||||||
|
“我怕死啊,修仙不是能长生么,我想长生啊。”白小纯委屈的说道。 |
||||||
|
中年修士再次无语,不过觉得此子总算执念可嘉,扔到门派里磨炼一番,或可在性子上改变一二。 |
||||||
|
于是略一思索,大袖一甩卷着白小纯化作一道长虹,直奔天边而去。 |
||||||
|
“跟我走吧。” |
||||||
|
“去哪?这也太高了吧……”白小纯看到自己在天上飞,下面是万丈深渊,立刻脸色苍白,斧头一扔,死死的抱住仙人的大腿。 |
||||||
|
中年修士看了眼自己的腿,无奈开口。 |
||||||
|
“灵溪宗。” |
||||||
|
兄弟姐妹们,阔别2个月,你们想不想我啊,我非常想你们! |
||||||
|
这本书,我做了详细的大纲,每次回顾大纲里的情节,都很兴奋,有种燃烧的感觉,我非常满意,明天,正式更新,依旧是中午一章,晚上一章! |
||||||
|
很兴奋,我们已沉寂了数月,如今归来,要……再战起点! |
||||||
|
新书期,兄弟姐妹,别忘了收藏与推荐啊,收藏与推荐至关重要! |
||||||
|
求收藏!!求推荐!! |
||||||
|
让众人知晓,我们……归来了! |
||||||
|
我们的目标,依旧是……点击榜,推荐榜,第一! |
||||||
|
*/ |
||||||
|
|
||||||
|
private String title; |
||||||
|
private String content; |
||||||
|
private int words; |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getBody() { |
||||||
|
return content; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBody(String body) { |
||||||
|
this.content = body; |
||||||
|
} |
||||||
|
|
||||||
|
public int getWords() { |
||||||
|
return words; |
||||||
|
} |
||||||
|
|
||||||
|
public void setWords(int words) { |
||||||
|
this.words = words; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,198 @@ |
|||||||
|
package com.novel.read.model.db; |
||||||
|
|
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
import org.litepal.crud.LitePalSupport; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-8. |
||||||
|
* 收藏的书籍 |
||||||
|
*/ |
||||||
|
public class CollBookBean extends LitePalSupport implements Serializable { |
||||||
|
|
||||||
|
public static final int STATUS_UNCACHE = 0; //未缓存
|
||||||
|
public static final int STATUS_CACHING = 1; //正在缓存
|
||||||
|
public static final int STATUS_CACHED = 2; //已经缓存
|
||||||
|
/** |
||||||
|
* _id : 53663ae356bdc93e49004474 |
||||||
|
* title : 逍遥派 |
||||||
|
* author : 白马出淤泥 |
||||||
|
* shortIntro : 金庸武侠中有不少的神秘高手,书中或提起名字,或不曾提起,总之他们要么留下了绝世秘笈,要么就名震武林。 独孤九剑的创始者,独孤求败,他真的只创出九剑吗? 残本葵花... |
||||||
|
* cover : /cover/149273897447137 |
||||||
|
* hasCp : true |
||||||
|
* latelyFollower : 60213 |
||||||
|
* retentionRatio : 22.87 |
||||||
|
* updated : 2017-05-07T18:24:34.720Z |
||||||
|
* <p> |
||||||
|
* chaptersCount : 1660 |
||||||
|
* lastChapter : 第1659章 朱长老 |
||||||
|
*/ |
||||||
|
private String bookId; // 本地书籍中,path 的 md5 值作为本地书籍的 id
|
||||||
|
|
||||||
|
private String title; |
||||||
|
private String author; |
||||||
|
private String shortIntro; |
||||||
|
private String cover; // 在本地书籍中,该字段作为本地文件的路径
|
||||||
|
private boolean hasCp; |
||||||
|
private int latelyFollower; |
||||||
|
private double retentionRatio; |
||||||
|
//最新更新日期
|
||||||
|
private String updated; |
||||||
|
//最新阅读日期
|
||||||
|
private String lastRead; |
||||||
|
private int chaptersCount; |
||||||
|
private String lastChapter; |
||||||
|
//是否更新或未阅读
|
||||||
|
private boolean isUpdate = true; |
||||||
|
//是否是本地文件
|
||||||
|
private boolean isLocal = false; |
||||||
|
private boolean isSelect = false; |
||||||
|
private int include_image; |
||||||
|
|
||||||
|
public boolean isSelect() { |
||||||
|
return isSelect; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSelect(boolean select) { |
||||||
|
isSelect = select; |
||||||
|
} |
||||||
|
|
||||||
|
private List<BookChapterBean> bookChapterList = new ArrayList<BookChapterBean>(); |
||||||
|
|
||||||
|
|
||||||
|
public String getId() { |
||||||
|
return bookId == null ? "" : bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(String id) { |
||||||
|
this.bookId = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title == null ? "" : StringUtils.convertCC(title, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author == null ? "" :StringUtils.convertCC(author, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public String getShortIntro() { |
||||||
|
return shortIntro == null ? "" :StringUtils.convertCC(shortIntro, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setShortIntro(String shortIntro) { |
||||||
|
this.shortIntro = shortIntro; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover == null ? "" : cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isHasCp() { |
||||||
|
return hasCp; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHasCp(boolean hasCp) { |
||||||
|
this.hasCp = hasCp; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLatelyFollower() { |
||||||
|
return latelyFollower; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLatelyFollower(int latelyFollower) { |
||||||
|
this.latelyFollower = latelyFollower; |
||||||
|
} |
||||||
|
|
||||||
|
public double getRetentionRatio() { |
||||||
|
return retentionRatio; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRetentionRatio(double retentionRatio) { |
||||||
|
this.retentionRatio = retentionRatio; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUpdated() { |
||||||
|
return updated == null ? "" : updated; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUpdated(String updated) { |
||||||
|
this.updated = updated; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLastRead() { |
||||||
|
return lastRead == null ? "" : lastRead; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLastRead(String lastRead) { |
||||||
|
this.lastRead = lastRead; |
||||||
|
} |
||||||
|
|
||||||
|
public int getChaptersCount() { |
||||||
|
return chaptersCount; |
||||||
|
} |
||||||
|
|
||||||
|
public void setChaptersCount(int chaptersCount) { |
||||||
|
this.chaptersCount = chaptersCount; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLastChapter() { |
||||||
|
return lastChapter == null ? "" : StringUtils.convertCC(lastChapter, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setLastChapter(String lastChapter) { |
||||||
|
this.lastChapter = lastChapter; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isUpdate() { |
||||||
|
return isUpdate; |
||||||
|
} |
||||||
|
|
||||||
|
public void setIsUpdate(boolean update) { |
||||||
|
isUpdate = update; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isLocal() { |
||||||
|
return isLocal; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLocal(boolean local) { |
||||||
|
isLocal = local; |
||||||
|
} |
||||||
|
|
||||||
|
public int getInclude_image() { |
||||||
|
return include_image; |
||||||
|
} |
||||||
|
|
||||||
|
public void setInclude_image(int include_image) { |
||||||
|
this.include_image = include_image; |
||||||
|
} |
||||||
|
|
||||||
|
public List<BookChapterBean> getBookChapters() { |
||||||
|
if (bookChapterList == null) { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
return bookChapterList; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBookChapters(List<BookChapterBean> bookChapterList) { |
||||||
|
this.bookChapterList = bookChapterList; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,157 @@ |
|||||||
|
package com.novel.read.model.db; |
||||||
|
|
||||||
|
import org.litepal.LitePal; |
||||||
|
import org.litepal.crud.LitePalSupport; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-11. |
||||||
|
*/ |
||||||
|
public class DownloadTaskBean extends LitePalSupport { |
||||||
|
public static final int STATUS_LOADING = 1; |
||||||
|
public static final int STATUS_WAIT = 2; |
||||||
|
public static final int STATUS_PAUSE = 3; |
||||||
|
public static final int STATUS_ERROR = 4; |
||||||
|
public static final int STATUS_FINISH = 5; |
||||||
|
|
||||||
|
//任务名称 -> 名称唯一不重复
|
||||||
|
private String taskName; |
||||||
|
//所属的bookId(外健)
|
||||||
|
private String bookId; |
||||||
|
|
||||||
|
private List<BookChapterBean> bookChapterList = new ArrayList<>(); |
||||||
|
//章节的下载进度,默认为初始状态
|
||||||
|
private int currentChapter = 0; |
||||||
|
//最后的章节
|
||||||
|
private int lastChapter = 0; |
||||||
|
//状态:正在下载、下载完成、暂停、等待、下载错误。
|
||||||
|
|
||||||
|
private volatile int status = STATUS_WAIT; |
||||||
|
//总大小 -> (完成之后才会赋值)
|
||||||
|
private long size = 0; |
||||||
|
private CollBookBean collBookBean; |
||||||
|
|
||||||
|
|
||||||
|
public DownloadTaskBean(String taskName, String bookId, int currentChapter, int lastChapter, |
||||||
|
int status, long size) { |
||||||
|
this.taskName = taskName; |
||||||
|
this.bookId = bookId; |
||||||
|
this.currentChapter = currentChapter; |
||||||
|
this.lastChapter = lastChapter; |
||||||
|
this.status = status; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
|
||||||
|
public DownloadTaskBean() { |
||||||
|
} |
||||||
|
|
||||||
|
public String getBookId() { |
||||||
|
return bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBookId(String bookId) { |
||||||
|
this.bookId = bookId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTaskName() { |
||||||
|
return taskName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTaskName(String taskName) { |
||||||
|
this.taskName = taskName; |
||||||
|
if (bookChapterList!=null){ |
||||||
|
for (BookChapterBean bean : bookChapterList){ |
||||||
|
bean.setTaskName(getTaskName()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public List<BookChapterBean> getBookChapterList() { |
||||||
|
if (bookChapterList == null) { |
||||||
|
|
||||||
|
// BookChapterBeanDao targetDao = daoSession.getBookChapterBeanDao();
|
||||||
|
// List<BookChapterBean> bookChapterListNew = targetDao
|
||||||
|
// ._queryDownloadTaskBean_BookChapterList(taskName);
|
||||||
|
|
||||||
|
List<BookChapterBean> bookChapterListNew = LitePal |
||||||
|
.where("taskName=?", taskName).find(BookChapterBean.class); |
||||||
|
|
||||||
|
synchronized (this) { |
||||||
|
if (bookChapterList == null) { |
||||||
|
bookChapterList = bookChapterListNew; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return bookChapterList; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 这才是真正的列表使用类。 |
||||||
|
* |
||||||
|
*/ |
||||||
|
public void setBookChapters(List<BookChapterBean> beans){ |
||||||
|
bookChapterList = beans; |
||||||
|
for (BookChapterBean bean : bookChapterList){ |
||||||
|
bean.setTaskName(getTaskName()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public List<BookChapterBean> getBookChapters(){ |
||||||
|
return bookChapterList; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public int getCurrentChapter() { |
||||||
|
return currentChapter; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCurrentChapter(int current) { |
||||||
|
this.currentChapter = current; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLastChapter() { |
||||||
|
return lastChapter; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLastChapter(int lastChapter) { |
||||||
|
this.lastChapter = lastChapter; |
||||||
|
} |
||||||
|
|
||||||
|
//多线程访问的问题,所以需要同步机制
|
||||||
|
public int getStatus() { |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
public void setStatus(int status){ |
||||||
|
this.status = status; |
||||||
|
} |
||||||
|
|
||||||
|
public long getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSize(long size) { |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
|
||||||
|
public synchronized void resetBookChapterList() { |
||||||
|
bookChapterList = null; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public CollBookBean getCollBookBean() { |
||||||
|
|
||||||
|
List<CollBookBean> list = LitePal.where("bookId=?", bookId).find(CollBookBean.class); |
||||||
|
if (list!=null&&list.size()>0){ |
||||||
|
return list.get(0); |
||||||
|
}else { |
||||||
|
return collBookBean; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setCollBookBean(CollBookBean collBookBean) { |
||||||
|
this.collBookBean = collBookBean; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
package com.novel.read.model.db; |
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable; |
||||||
|
|
||||||
|
import org.litepal.crud.LitePalSupport; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/19 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class SearchListTable extends LitePalSupport implements Serializable { |
||||||
|
|
||||||
|
private String key; |
||||||
|
private long saveTime; |
||||||
|
|
||||||
|
public String getKey() { |
||||||
|
return key == null ? "" : key; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey(String key) { |
||||||
|
this.key = key; |
||||||
|
} |
||||||
|
|
||||||
|
public long getSaveTime() { |
||||||
|
return saveTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSaveTime(long saveTime) { |
||||||
|
this.saveTime = saveTime; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(@Nullable Object obj) { |
||||||
|
if (obj != null && obj.toString().equals(key)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return super.equals(obj); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,223 @@ |
|||||||
|
package com.novel.read.model.db.dbManage; |
||||||
|
|
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.utlis.FileUtils; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.lang.ref.WeakReference; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-20. |
||||||
|
* 处理书籍的工具类,配合PageFactory使用 |
||||||
|
* 已弃用, |
||||||
|
*/ |
||||||
|
|
||||||
|
public class BookManager { |
||||||
|
private static final String TAG = "BookManager"; |
||||||
|
private String chapterName; |
||||||
|
private String bookId; |
||||||
|
private long chapterLen; |
||||||
|
private long position; |
||||||
|
private Map<String, Cache> cacheMap = new HashMap<>(); |
||||||
|
private static volatile BookManager sInstance; |
||||||
|
|
||||||
|
public static BookManager getInstance(){ |
||||||
|
if (sInstance == null){ |
||||||
|
synchronized (BookManager.class){ |
||||||
|
if (sInstance == null){ |
||||||
|
sInstance = new BookManager(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return sInstance; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean openChapter(String bookId, String chapterName){ |
||||||
|
return openChapter(bookId,chapterName,0); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean openChapter(String bookId, String chapterName, long position){ |
||||||
|
//如果文件不存在,则打开失败
|
||||||
|
File file = new File(Constant.BOOK_CACHE_PATH + bookId |
||||||
|
+ File.separator + chapterName + FileUtils.SUFFIX_NB); |
||||||
|
if (!file.exists()){ |
||||||
|
return false; |
||||||
|
} |
||||||
|
this.bookId = bookId; |
||||||
|
this.chapterName = chapterName; |
||||||
|
this.position = position; |
||||||
|
createCache(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private void createCache(){ |
||||||
|
//创建Cache
|
||||||
|
if (!cacheMap.containsKey(chapterName)){ |
||||||
|
Cache cache = new Cache(); |
||||||
|
File file = getBookFile(bookId, chapterName); |
||||||
|
//TODO:数据加载默认utf-8(以后会增加判断),FileUtils采用Reader获取数据的,可能用byte会更好一点
|
||||||
|
char[] array = FileUtils.getFileContent(file).toCharArray(); |
||||||
|
WeakReference<char[]> charReference = new WeakReference<char[]>(array); |
||||||
|
cache.size = array.length; |
||||||
|
cache.data = charReference; |
||||||
|
cacheMap.put(chapterName, cache); |
||||||
|
|
||||||
|
chapterLen = cache.size; |
||||||
|
} |
||||||
|
else { |
||||||
|
chapterLen = cacheMap.get(chapterName).getSize(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setPosition(long position){ |
||||||
|
this.position = position; |
||||||
|
} |
||||||
|
|
||||||
|
public long getPosition(){ |
||||||
|
return position; |
||||||
|
} |
||||||
|
|
||||||
|
//获取上一段
|
||||||
|
public String getPrevPara(){ |
||||||
|
//首先判断是否Position已经达到起始位置,已经越界
|
||||||
|
if (position < 0){ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
//初始化从后向前获取的起始点,终止点,文本
|
||||||
|
int end = (int)position; |
||||||
|
int begin = end; |
||||||
|
char[] array = getContent(); |
||||||
|
|
||||||
|
while (begin >= 0) { //判断指针是否达到章节的起始位置
|
||||||
|
char character = array[begin]; //获取当前指针下的字符
|
||||||
|
|
||||||
|
//判断当前字符是否为换行,如果为换行,就代表获取到了一个段落,并退出。
|
||||||
|
//有可能发生初始指针指的就是换行符的情况。
|
||||||
|
if ((character+"").equals("\n") && begin != end) { |
||||||
|
position = begin; |
||||||
|
//当当前指针指向换行符的时候向后退一步
|
||||||
|
begin++; |
||||||
|
break; |
||||||
|
} |
||||||
|
//向前进一步
|
||||||
|
begin--; |
||||||
|
} |
||||||
|
//最后end获取到段落的起始点,begin是段落的终止点。
|
||||||
|
|
||||||
|
//当越界的时候,保证begin在章节内
|
||||||
|
if (begin < 0){ |
||||||
|
begin = 0;//在章节内
|
||||||
|
position = -1; //越界
|
||||||
|
} |
||||||
|
int size = end+1 - begin; |
||||||
|
return new String(array,begin,size); |
||||||
|
} |
||||||
|
|
||||||
|
//获取下一段
|
||||||
|
public String getNextPara(){ |
||||||
|
//首先判断是否Position已经达到终点位置
|
||||||
|
if (position >= chapterLen){ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
//初始化起始点,终止点。
|
||||||
|
int begin = (int)position; |
||||||
|
int end = begin; |
||||||
|
char[] array = getContent(); |
||||||
|
|
||||||
|
while (end < chapterLen) { //判断指针是否在章节的末尾位置
|
||||||
|
char character = array[end]; //获取当前指针下的字符
|
||||||
|
//判断当前字符是否为换行,如果为换行,就代表获取到了一个段落,并退出。
|
||||||
|
//有可能发生初始指针指的就是换行符的情况。
|
||||||
|
//这里当遇到\n的时候,不需要回退
|
||||||
|
if ((character+"").equals("\n") && begin != end){ |
||||||
|
++end;//指向下一字段
|
||||||
|
position = end; |
||||||
|
break; |
||||||
|
} |
||||||
|
//指向下一字段
|
||||||
|
end++; |
||||||
|
} |
||||||
|
//所要获取的字段的长度
|
||||||
|
int size = end - begin; |
||||||
|
return new String(array,begin,size); |
||||||
|
} |
||||||
|
|
||||||
|
//获取章节的内容
|
||||||
|
public char[] getContent() { |
||||||
|
if (cacheMap.size() == 0){ |
||||||
|
return new char[1]; |
||||||
|
} |
||||||
|
char[] block = cacheMap.get(chapterName).getData().get(); |
||||||
|
if (block == null) { |
||||||
|
File file = getBookFile(bookId, chapterName); |
||||||
|
block = FileUtils.getFileContent(file).toCharArray(); |
||||||
|
Cache cache = cacheMap.get(chapterName); |
||||||
|
cache.data = new WeakReference<char[]>(block); |
||||||
|
} |
||||||
|
return block; |
||||||
|
} |
||||||
|
|
||||||
|
public long getChapterLen(){ |
||||||
|
return chapterLen; |
||||||
|
} |
||||||
|
|
||||||
|
public void clear(){ |
||||||
|
cacheMap.clear(); |
||||||
|
position = 0; |
||||||
|
chapterLen = 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建或获取存储文件 |
||||||
|
* @param folderName |
||||||
|
* @param fileName |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static File getBookFile(String folderName, String fileName){ |
||||||
|
return FileUtils.getFile(Constant.BOOK_CACHE_PATH + folderName |
||||||
|
+ File.separator + fileName + FileUtils.SUFFIX_NB); |
||||||
|
} |
||||||
|
|
||||||
|
public static long getBookSize(String folderName){ |
||||||
|
return FileUtils.getDirSize(FileUtils |
||||||
|
.getFolder(Constant.BOOK_CACHE_PATH + folderName)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据文件名判断是否被缓存过 (因为可能数据库显示被缓存过,但是文件中却没有的情况,所以需要根据文件判断是否被缓存 |
||||||
|
* 过) |
||||||
|
* @param folderName : bookId |
||||||
|
* @param fileName: chapterName |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static boolean isChapterCached(String folderName, String fileName){ |
||||||
|
File file = new File(Constant.BOOK_CACHE_PATH + folderName |
||||||
|
+ File.separator + fileName + FileUtils.SUFFIX_NB); |
||||||
|
return file.exists(); |
||||||
|
} |
||||||
|
|
||||||
|
public class Cache { |
||||||
|
private long size; |
||||||
|
private WeakReference<char[]> data; |
||||||
|
|
||||||
|
public WeakReference<char[]> getData() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
public void setData(WeakReference<char[]> data) { |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
public long getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSize(long size) { |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,371 @@ |
|||||||
|
package com.novel.read.model.db.dbManage; |
||||||
|
|
||||||
|
import android.content.ContentValues; |
||||||
|
import android.util.Log; |
||||||
|
|
||||||
|
import com.novel.read.constants.Constant; |
||||||
|
import com.novel.read.model.db.BookChapterBean; |
||||||
|
import com.novel.read.model.db.BookRecordBean; |
||||||
|
import com.novel.read.model.db.ChapterInfoBean; |
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
import com.novel.read.model.db.DownloadTaskBean; |
||||||
|
import com.novel.read.utlis.FileUtils; |
||||||
|
import com.novel.read.utlis.IOUtils; |
||||||
|
import com.novel.read.utlis.SpUtil; |
||||||
|
import com.novel.read.widget.page.Void; |
||||||
|
|
||||||
|
import org.litepal.LitePal; |
||||||
|
import org.litepal.crud.callback.SaveCallback; |
||||||
|
|
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.BufferedWriter; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileNotFoundException; |
||||||
|
import java.io.FileReader; |
||||||
|
import java.io.FileWriter; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.Reader; |
||||||
|
import java.io.Writer; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import io.reactivex.Single; |
||||||
|
import io.reactivex.SingleEmitter; |
||||||
|
import io.reactivex.SingleOnSubscribe; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-8. |
||||||
|
* 存储关于书籍内容的信息(CollBook(收藏书籍),BookChapter(书籍列表),ChapterInfo(书籍章节),BookRecord(记录)) |
||||||
|
*/ |
||||||
|
|
||||||
|
public class BookRepository { |
||||||
|
private static final String TAG = "CollBookManager"; |
||||||
|
private static volatile BookRepository sInstance; |
||||||
|
|
||||||
|
private BookRepository() { |
||||||
|
} |
||||||
|
|
||||||
|
public static BookRepository getInstance() { |
||||||
|
if (sInstance == null) { |
||||||
|
synchronized (BookRepository.class) { |
||||||
|
if (sInstance == null) { |
||||||
|
sInstance = new BookRepository(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return sInstance; |
||||||
|
} |
||||||
|
|
||||||
|
//存储已收藏书籍
|
||||||
|
public void saveCollBookWithAsync(CollBookBean bean) { |
||||||
|
|
||||||
|
// bean.saveAsync().listen(new SaveCallback() {
|
||||||
|
// @Override
|
||||||
|
// public void onFinish(boolean success) {
|
||||||
|
// System.out.println(success);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// LitePal.saveAll(bean.getBookChapters());
|
||||||
|
// bean.saveOrUpdate("bookId=?", bean.getId());
|
||||||
|
// bean.saveOrUpdateAsync("bookId=?", bean.getId());
|
||||||
|
bean.saveOrUpdate("bookId=?", bean.getId()); |
||||||
|
for (int i = 0; i < bean.getBookChapters().size(); i++) { |
||||||
|
bean.getBookChapters().get(i).setCollBookBean(bean); |
||||||
|
} |
||||||
|
LitePal.saveAllAsync(bean.getBookChapters()).listen(new SaveCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(boolean success) { |
||||||
|
Log.e(TAG, "saveCollBookWithAsync: " + success); |
||||||
|
} |
||||||
|
}); |
||||||
|
// LitePal.saveAll(bean.getBookChapters());
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 异步存储。 |
||||||
|
* 同时保存BookChapter |
||||||
|
* |
||||||
|
* @param beans |
||||||
|
*/ |
||||||
|
public void saveCollBooksWithAsync(List<CollBookBean> beans) { |
||||||
|
// mSession.startAsyncSession()
|
||||||
|
// .runInTx(
|
||||||
|
// () -> {
|
||||||
|
// for (CollBookBean bean : beans){
|
||||||
|
// if (bean.getBookChapters() != null){
|
||||||
|
// //存储BookChapterBean(需要修改,如果存在id相同的则无视)
|
||||||
|
// mSession.getBookChapterBeanDao()
|
||||||
|
// .insertOrReplaceInTx(bean.getBookChapters());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// //存储CollBook (确保先后顺序,否则出错)
|
||||||
|
// mCollBookDao.insertOrReplaceInTx(beans);
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
} |
||||||
|
|
||||||
|
public void saveCollBook(CollBookBean bean) { |
||||||
|
// mCollBookDao.insertOrReplace(bean);
|
||||||
|
ContentValues values = new ContentValues(); |
||||||
|
values.put("isUpdate", bean.isUpdate()); |
||||||
|
values.put("lastRead", bean.getLastRead()); |
||||||
|
values.put("lastChapter", bean.getLastChapter()); |
||||||
|
LitePal.updateAll(CollBookBean.class, values, "bookId=?", bean.getId()); |
||||||
|
// bean.setBookChapters(new ArrayList<>());
|
||||||
|
// bean.saveOrUpdate("bookId=?", bean.getId());
|
||||||
|
// for (int i = 0; i < bean.getBookChapters().size(); i++) {
|
||||||
|
// bean.getBookChapters().get(i).setCollBookBean(bean);
|
||||||
|
// }
|
||||||
|
// LitePal.saveAllAsync(bean.getBookChapters()).listen(new SaveCallback() {
|
||||||
|
// @Override
|
||||||
|
// public void onFinish(boolean success) {
|
||||||
|
// Log.e(TAG, "saveCollBookWithAsync: " + success);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
} |
||||||
|
|
||||||
|
public void saveCollBooks(List<CollBookBean> beans) { |
||||||
|
for (int i = 0; i <beans.size() ; i++) { |
||||||
|
ContentValues values = new ContentValues(); |
||||||
|
values.put("isUpdate", beans.get(i).isUpdate()); |
||||||
|
values.put("lastRead", beans.get(i).getLastRead()); |
||||||
|
values.put("lastChapter", beans.get(i).getLastChapter()); |
||||||
|
values.put("updated",beans.get(i).getUpdated()); |
||||||
|
LitePal.updateAll(CollBookBean.class, values, "bookId=?", beans.get(i).getId()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 异步存储BookChapter |
||||||
|
* |
||||||
|
* @param beans |
||||||
|
*/ |
||||||
|
public void saveBookChaptersWithAsync(List<BookChapterBean> beans, CollBookBean collBookBean) { |
||||||
|
|
||||||
|
// //先删除旧的章节,再异步储存新的章节
|
||||||
|
// LitePal.deleteAll(BookChapterBean.class, "bookId=?", collBookBean.getId());
|
||||||
|
collBookBean.saveOrUpdate("bookId=?", collBookBean.getId()); |
||||||
|
for (int i = 0; i <collBookBean.getBookChapters().size() ; i++) { |
||||||
|
collBookBean.getBookChapters().get(i).setCollBookBean(collBookBean); |
||||||
|
collBookBean.getBookChapters().get(i).saveOrUpdateAsync("bookId=?", collBookBean.getId()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// LitePal.saveAllAsync(beans).listen(new SaveCallback() {
|
||||||
|
// @Override
|
||||||
|
// public void onFinish(boolean success) {
|
||||||
|
// if (success) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// Log.d(TAG, "saveBookChaptersWithAsync: " + "进行存储" + success);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 存储章节 |
||||||
|
* |
||||||
|
* @param folderName |
||||||
|
* @param fileName |
||||||
|
* @param content |
||||||
|
*/ |
||||||
|
public void saveChapterInfo(String folderName, String fileName, String content) { |
||||||
|
String str = content.replaceAll("\\\\n\\\\n", "\n"); |
||||||
|
File file = BookManager.getBookFile(folderName, fileName); |
||||||
|
//获取流并存储
|
||||||
|
Writer writer = null; |
||||||
|
try { |
||||||
|
writer = new BufferedWriter(new FileWriter(file)); |
||||||
|
writer.write(str); |
||||||
|
writer.flush(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
IOUtils.close(writer); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void saveBookRecord(BookRecordBean bean) { |
||||||
|
// mSession.getBookRecordBeanDao()
|
||||||
|
// .insertOrReplace(bean);
|
||||||
|
bean.saveOrUpdateAsync("bookId=?", bean.getBookId()).listen(new SaveCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(boolean success) { |
||||||
|
Log.e("saveBookRecord", "onFinish: " + success); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/*****************************get************************************************/ |
||||||
|
public CollBookBean getCollBook(String bookId) { |
||||||
|
List<CollBookBean> bean = LitePal.where("bookId =?", bookId).find(CollBookBean.class); |
||||||
|
if (bean != null && bean.size() > 0) { |
||||||
|
return bean.get(0); |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public List<CollBookBean> getCollBooks() { |
||||||
|
// return mCollBookDao
|
||||||
|
// .queryBuilder()
|
||||||
|
// .orderDesc(CollBookBeanDao.Properties.LastRead)
|
||||||
|
// .list();
|
||||||
|
List<CollBookBean> collBookBeans; |
||||||
|
if (SpUtil.getBooleanValue(Constant.BookSort, false)) { //默认根据阅读时间排序
|
||||||
|
collBookBeans = LitePal.order("updated desc").find(CollBookBean.class); |
||||||
|
} else { |
||||||
|
collBookBeans = LitePal.order("lastRead desc").find(CollBookBean.class); |
||||||
|
} |
||||||
|
return collBookBeans; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//获取书籍列表
|
||||||
|
public List<BookChapterBean> getBookChaptersInRx(String bookId) { |
||||||
|
// return Single.create(new SingleOnSubscribe<List<BookChapterBean>>() {
|
||||||
|
// @Override
|
||||||
|
// public void subscribe(SingleEmitter<List<BookChapterBean>> e) throws Exception {
|
||||||
|
// List<BookChapterBean> beans = mSession
|
||||||
|
// .getBookChapterBeanDao()
|
||||||
|
// .queryBuilder()
|
||||||
|
// .where(BookChapterBeanDao.Properties.BookId.eq(bookId))
|
||||||
|
// .list();
|
||||||
|
// e.onSuccess(beans);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
List<CollBookBean> bookBeans = LitePal.where("bookId=?", bookId).find(CollBookBean.class, true); |
||||||
|
if (bookBeans != null && bookBeans.size() > 0) { |
||||||
|
return bookBeans.get(0).getBookChapters(); |
||||||
|
} else { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//获取阅读记录
|
||||||
|
public BookRecordBean getBookRecord(String bookId) { |
||||||
|
// return mSession.getBookRecordBeanDao()
|
||||||
|
// .queryBuilder()
|
||||||
|
// .where(BookRecordBeanDao.Properties.BookId.eq(bookId))
|
||||||
|
// .unique();
|
||||||
|
List<BookRecordBean> beans = LitePal.where("bookId=?", bookId).find(BookRecordBean.class); |
||||||
|
if (beans != null && beans.size() > 0) { |
||||||
|
return beans.get(0); |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//TODO:需要进行获取编码并转换的问题
|
||||||
|
public ChapterInfoBean getChapterInfoBean(String folderName, String fileName) { |
||||||
|
File file = new File(Constant.BOOK_CACHE_PATH + folderName |
||||||
|
+ File.separator + fileName + FileUtils.SUFFIX_NB); |
||||||
|
if (!file.exists()) return null; |
||||||
|
Reader reader = null; |
||||||
|
String str = null; |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
try { |
||||||
|
reader = new FileReader(file); |
||||||
|
BufferedReader br = new BufferedReader(reader); |
||||||
|
while ((str = br.readLine()) != null) { |
||||||
|
sb.append(str); |
||||||
|
} |
||||||
|
} catch (FileNotFoundException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} finally { |
||||||
|
IOUtils.close(reader); |
||||||
|
} |
||||||
|
|
||||||
|
ChapterInfoBean bean = new ChapterInfoBean(); |
||||||
|
bean.setTitle(fileName); |
||||||
|
bean.setBody(sb.toString()); |
||||||
|
return bean; |
||||||
|
} |
||||||
|
|
||||||
|
/************************************************************/ |
||||||
|
/************************************************************/ |
||||||
|
public Single<Void> deleteCollBookInRx(CollBookBean bean) { |
||||||
|
return Single.create(new SingleOnSubscribe<Void>() { |
||||||
|
@Override |
||||||
|
public void subscribe(SingleEmitter<Void> e) throws Exception { |
||||||
|
//查看文本中是否存在删除的数据
|
||||||
|
deleteBook(bean.getId()); |
||||||
|
//删除任务
|
||||||
|
deleteDownloadTask(bean.getId()); |
||||||
|
//删除目录
|
||||||
|
deleteBookChapter(bean.getId()); |
||||||
|
//删除CollBook
|
||||||
|
LitePal.deleteAll(CollBookBean.class, "bookId=?", bean.getId()); |
||||||
|
e.onSuccess(new Void()); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
//这个需要用rx,进行删除
|
||||||
|
public void deleteBookChapter(String bookId) { |
||||||
|
// mSession.getBookChapterBeanDao()
|
||||||
|
// .queryBuilder()
|
||||||
|
// .where(BookChapterBeanDao.Properties.BookId.eq(bookId))
|
||||||
|
// .buildDelete()
|
||||||
|
// .executeDeleteWithoutDetachingEntities();
|
||||||
|
} |
||||||
|
|
||||||
|
public void deleteCollBook(CollBookBean collBook) { |
||||||
|
// mCollBookDao.delete(collBook);
|
||||||
|
} |
||||||
|
|
||||||
|
//删除书籍
|
||||||
|
public void deleteBook(String bookId) { |
||||||
|
FileUtils.deleteFile(Constant.BOOK_CACHE_PATH + bookId); |
||||||
|
} |
||||||
|
|
||||||
|
public void deleteBookRecord(String id) { |
||||||
|
// mSession.getBookRecordBeanDao()
|
||||||
|
// .queryBuilder()
|
||||||
|
// .where(BookRecordBeanDao.Properties.BookId.eq(id))
|
||||||
|
// .buildDelete()
|
||||||
|
// .executeDeleteWithoutDetachingEntities();
|
||||||
|
} |
||||||
|
|
||||||
|
//删除任务
|
||||||
|
public void deleteDownloadTask(String bookId) { |
||||||
|
// mSession.getDownloadTaskBeanDao()
|
||||||
|
// .queryBuilder()
|
||||||
|
// .where(DownloadTaskBeanDao.Properties.BookId.eq(bookId))
|
||||||
|
// .buildDelete()
|
||||||
|
// .executeDeleteWithoutDetachingEntities();
|
||||||
|
} |
||||||
|
|
||||||
|
public List<DownloadTaskBean> getDownloadTaskList() { |
||||||
|
return LitePal.findAll(DownloadTaskBean.class); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void saveDownloadTask(DownloadTaskBean bean) { |
||||||
|
bean.saveOrUpdate("bookId=?",bean.getBookId()); |
||||||
|
CollBookBean collBookBean = bean.getCollBookBean(); |
||||||
|
for (int i = 0; i <bean.getBookChapters().size() ; i++) { |
||||||
|
bean.getBookChapters().get(i).setDownloadTaskBean(bean); |
||||||
|
bean.getBookChapters().get(i).setCollBookBean(collBookBean); |
||||||
|
bean.getBookChapters().get(i).saveOrUpdate("chapterId=?", bean.getBookChapters().get(i).getId()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// //先删除旧的章节,再异步储存新的章节
|
||||||
|
// LitePal.deleteAll(BookChapterBean.class, "taskName=?",bean.getTaskName());
|
||||||
|
//
|
||||||
|
// LitePal.saveAllAsync(bean.getBookChapters()).listen(new SaveCallback() {
|
||||||
|
// @Override
|
||||||
|
// public void onFinish(boolean success) {
|
||||||
|
// if (success) {
|
||||||
|
// bean.setBookChapters(bean.getBookChapters());
|
||||||
|
// bean.saveOrUpdate("taskName=?",bean.getTaskName());
|
||||||
|
// }
|
||||||
|
// Log.d(TAG, "saveBookChaptersWithAsync: " + "进行存储" + success);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,92 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.model.db.BookChapterBean; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class BookArticleResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
private List<ArticleBean> article; |
||||||
|
private List<BookChapterBean> bookChapterBean; |
||||||
|
|
||||||
|
public List<ArticleBean> getArticle() { |
||||||
|
return article; |
||||||
|
} |
||||||
|
|
||||||
|
public void setArticle(List<ArticleBean> article) { |
||||||
|
this.article = article; |
||||||
|
} |
||||||
|
|
||||||
|
public static class ArticleBean { |
||||||
|
/** |
||||||
|
* id : 1 |
||||||
|
* title : 第一章 我为帝辛!【求支持】 |
||||||
|
* words : 4272 |
||||||
|
* create_time : 1560048488 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private int words; |
||||||
|
private int create_time; |
||||||
|
private String volume; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return getVolume()+title; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public int getWords() { |
||||||
|
return words; |
||||||
|
} |
||||||
|
|
||||||
|
public void setWords(int words) { |
||||||
|
this.words = words; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public String getVolume() { |
||||||
|
return volume == null ? "" : volume; |
||||||
|
} |
||||||
|
|
||||||
|
public void setVolume(String volume) { |
||||||
|
this.volume = volume; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public List<BookChapterBean> getChapterBean() { |
||||||
|
if (bookChapterBean == null) { |
||||||
|
bookChapterBean = createChapterBean(); |
||||||
|
} |
||||||
|
return bookChapterBean; |
||||||
|
} |
||||||
|
|
||||||
|
public List<BookChapterBean> createChapterBean() { |
||||||
|
List<BookChapterBean> mList = new ArrayList<>(); |
||||||
|
for (ArticleBean articleBean:getArticle()){ |
||||||
|
mList.add(new BookChapterBean(String.valueOf(articleBean.getId()),articleBean.getTitle())); |
||||||
|
} |
||||||
|
return mList; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,203 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.model.db.CollBookBean; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class BookDetailResp { |
||||||
|
|
||||||
|
/** |
||||||
|
* book : {"id":1,"title":"帝逆洪荒","cover":"http://dev.duoduvip.com/uploads/20190609/408f516e930518df187acc911208f004.png","description":" 【群号536o626o6】人族至宝崆峒印逆天回到未来,带来周天附身殷商人皇纣王之身!帝辛怒吼:人族要自强,人族要自立,人族要自主!但随即帝辛现了洪荒并不是那么简单,洪荒在亘古居然被打碎了,有蛮荒,莽荒,大荒三荒并存,四荒合并成就洪荒大世界!兽皇神逆,魔祖罗T,阴阳老祖,乾坤老祖,扬眉大仙,洪荒大能纷纷出世!真龙老祖,凤凰老母,瑞麒麟三族老祖出世,镇压三族!东皇太一,妖皇帝俊设计假死,瞒过众圣,如今万妖齐聚!且看帝辛如何在万族夹击之中求生存,成就一代人族大帝,庇佑人族!<br> 各位书友要是觉得《帝逆洪荒》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!帝逆洪荒最新章节,帝逆洪荒无弹窗,帝逆洪荒全文阅读.","hot":100,"like":20,"author":"天子辉","create_time":1560048488,"words":4637684} |
||||||
|
* last_article : {"id":1,"title":"第一章 我为帝辛!【求支持】","create_time":1560048488} |
||||||
|
*/ |
||||||
|
|
||||||
|
private BookBean book; |
||||||
|
private LastArticleBean last_article; |
||||||
|
private CollBookBean collBookBean; |
||||||
|
|
||||||
|
public BookBean getBook() { |
||||||
|
return book; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook(BookBean book) { |
||||||
|
this.book = book; |
||||||
|
} |
||||||
|
|
||||||
|
public LastArticleBean getLast_article() { |
||||||
|
return last_article; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLast_article(LastArticleBean last_article) { |
||||||
|
this.last_article = last_article; |
||||||
|
} |
||||||
|
|
||||||
|
public static class BookBean { |
||||||
|
/** |
||||||
|
* id : 1 |
||||||
|
* title : 帝逆洪荒 |
||||||
|
* cover : http://dev.duoduvip.com/uploads/20190609/408f516e930518df187acc911208f004.png
|
||||||
|
* description : 【群号536o626o6】人族至宝崆峒印逆天回到未来,带来周天附身殷商人皇纣王之身!帝辛怒吼:人族要自强,人族要自立,人族要自主!但随即帝辛现了洪荒并不是那么简单,洪荒在亘古居然被打碎了,有蛮荒,莽荒,大荒三荒并存,四荒合并成就洪荒大世界!兽皇神逆,魔祖罗T,阴阳老祖,乾坤老祖,扬眉大仙,洪荒大能纷纷出世!真龙老祖,凤凰老母,瑞麒麟三族老祖出世,镇压三族!东皇太一,妖皇帝俊设计假死,瞒过众圣,如今万妖齐聚!且看帝辛如何在万族夹击之中求生存,成就一代人族大帝,庇佑人族!<br> 各位书友要是觉得《帝逆洪荒》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!帝逆洪荒最新章节,帝逆洪荒无弹窗,帝逆洪荒全文阅读. |
||||||
|
* hot : 100 |
||||||
|
* like : 20 |
||||||
|
* author : 天子辉 |
||||||
|
* create_time : 1560048488 |
||||||
|
* words : 4637684 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private String cover; |
||||||
|
private String description; |
||||||
|
private int hot; |
||||||
|
private int like; |
||||||
|
private String author; |
||||||
|
private int create_time; |
||||||
|
private int words; |
||||||
|
private int include_image; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescription() { |
||||||
|
return description == null ? "" : StringUtils.delete160(description); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDescription(String description) { |
||||||
|
this.description = description; |
||||||
|
} |
||||||
|
|
||||||
|
public int getHot() { |
||||||
|
return hot; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHot(int hot) { |
||||||
|
this.hot = hot; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLike() { |
||||||
|
return like+"%"; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLike(int like) { |
||||||
|
this.like = like; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public int getWords() { |
||||||
|
return words; |
||||||
|
} |
||||||
|
|
||||||
|
public void setWords(int words) { |
||||||
|
this.words = words; |
||||||
|
} |
||||||
|
|
||||||
|
public int getInclude_image() { |
||||||
|
return include_image; |
||||||
|
} |
||||||
|
|
||||||
|
public void setInclude_image(int include_image) { |
||||||
|
this.include_image = include_image; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class LastArticleBean { |
||||||
|
/** |
||||||
|
* id : 1 |
||||||
|
* title : 第一章 我为帝辛!【求支持】 |
||||||
|
* create_time : 1560048488 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private long create_time; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title == null ? "" : title; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public long getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(long create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public CollBookBean getCollBookBean(){ |
||||||
|
if (collBookBean == null){ |
||||||
|
collBookBean = createCollBookBean(); |
||||||
|
} |
||||||
|
return collBookBean; |
||||||
|
} |
||||||
|
|
||||||
|
public CollBookBean createCollBookBean(){ |
||||||
|
CollBookBean bean = new CollBookBean(); |
||||||
|
bean.setId(String.valueOf(getBook().getId())); |
||||||
|
bean.setTitle(getBook().getTitle()); |
||||||
|
bean.setAuthor(getBook().getAuthor()); |
||||||
|
bean.setShortIntro(getBook().getDescription()); |
||||||
|
bean.setCover(getBook().getCover()); |
||||||
|
bean.setInclude_image(getBook().getInclude_image()); |
||||||
|
// bean.setHasCp(getBook().isHasCp());
|
||||||
|
// bean.setLatelyFollower(getBook().getLatelyFollower());
|
||||||
|
// bean.setRetentionRatio(Double.parseDouble(getBook().getRetentionRatio()));
|
||||||
|
if (getLast_article()!=null){ |
||||||
|
bean.setUpdated(String.valueOf(getLast_article().getCreate_time())); |
||||||
|
bean.setLastChapter(getLast_article().getTitle()); |
||||||
|
} |
||||||
|
// bean.setChaptersCount(getBook().getChaptersCount());
|
||||||
|
return bean; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,57 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class CategoryTypeResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
private List<CategoryBean> category; |
||||||
|
|
||||||
|
public List<CategoryBean> getCategory() { |
||||||
|
return category; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCategory(List<CategoryBean> category) { |
||||||
|
this.category = category; |
||||||
|
} |
||||||
|
|
||||||
|
public static class CategoryBean { |
||||||
|
/** |
||||||
|
* id : 1 |
||||||
|
* title : 玄幻奇幻 |
||||||
|
* cover : |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private String cover; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return StringUtils.convertCC(title == null ? "" : title, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.model.db.ChapterInfoBean; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class ChapterInfoPackage implements Serializable { |
||||||
|
|
||||||
|
private List<ChapterInfoBean> article; |
||||||
|
|
||||||
|
public List<ChapterInfoBean> getArticle() { |
||||||
|
return article; |
||||||
|
} |
||||||
|
|
||||||
|
public void setArticle(List<ChapterInfoBean> article) { |
||||||
|
this.article = article; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class HotSearchResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
private List<String> key; |
||||||
|
|
||||||
|
public List<String> getKey() { |
||||||
|
return key; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey(List<String> key) { |
||||||
|
this.key = key; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,120 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class MarkResp { |
||||||
|
|
||||||
|
private List<SignBean> sign; |
||||||
|
|
||||||
|
public List<SignBean> getSign() { |
||||||
|
return sign; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSign(List<SignBean> sign) { |
||||||
|
this.sign = sign; |
||||||
|
} |
||||||
|
|
||||||
|
public static class SignBean { |
||||||
|
/** |
||||||
|
* id : 8 |
||||||
|
* uid : 1 |
||||||
|
* book_id : 1 |
||||||
|
* article_id : 1 |
||||||
|
* words : 0 |
||||||
|
* create_time : 1561450031 |
||||||
|
* update_time : 1561450031 |
||||||
|
* delete_time : null |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private int uid; |
||||||
|
private int book_id; |
||||||
|
private int article_id; |
||||||
|
private int words; |
||||||
|
private int create_time; |
||||||
|
private int update_time; |
||||||
|
private Object delete_time; |
||||||
|
private String content; |
||||||
|
private boolean edit; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public int getUid() { |
||||||
|
return uid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUid(int uid) { |
||||||
|
this.uid = uid; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBook_id() { |
||||||
|
return book_id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook_id(int book_id) { |
||||||
|
this.book_id = book_id; |
||||||
|
} |
||||||
|
|
||||||
|
public int getArticle_id() { |
||||||
|
return article_id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setArticle_id(int article_id) { |
||||||
|
this.article_id = article_id; |
||||||
|
} |
||||||
|
|
||||||
|
public int getWords() { |
||||||
|
return words; |
||||||
|
} |
||||||
|
|
||||||
|
public void setWords(int words) { |
||||||
|
this.words = words; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public int getUpdate_time() { |
||||||
|
return update_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUpdate_time(int update_time) { |
||||||
|
this.update_time = update_time; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getDelete_time() { |
||||||
|
return delete_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDelete_time(Object delete_time) { |
||||||
|
this.delete_time = delete_time; |
||||||
|
} |
||||||
|
|
||||||
|
public String getContent() { |
||||||
|
return content == null ? "" : content; |
||||||
|
} |
||||||
|
|
||||||
|
public void setContent(String content) { |
||||||
|
this.content = content; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isEdit() { |
||||||
|
return edit; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEdit(boolean edit) { |
||||||
|
this.edit = edit; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,115 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/20 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class RankByUpadateResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
private List<BookBean> book; |
||||||
|
|
||||||
|
public List<BookBean> getBook() { |
||||||
|
if (book == null) { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
return book; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook(List<BookBean> book) { |
||||||
|
this.book = book; |
||||||
|
} |
||||||
|
|
||||||
|
public static class BookBean { |
||||||
|
/** |
||||||
|
* id : 2446 |
||||||
|
* title : 吞天记 |
||||||
|
* cover : http://api.duoduvip.com/uploads/nocover.jpg
|
||||||
|
* description :     炎黄古域,浩瀚无边,无尽岁月中诞生诸多太古仙妖,撕裂天地,脱三界五行。更有万物神灵,天生神体,穿梭虚空,逆乱阴阳,无所不能。<br>    当今乃仙道盛世,万法通天,众生修道,妖孽横行!<br>    东吴太子吴煜,于绝境中得东方绝世战仙之衣钵,自此横空出世,逆天崛起。<br>    亿万世人心中,他是普渡众生的帝仙!<br>    漫天仙佛眼中,他是吞噬天地的妖魔!<br>    ……<br>    想和作者探讨剧情,加入讨论群,请加我微信:fengqingyang17k。或搜风青阳。<br>    各位书友要是觉得《吞天记》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!吞天记最新章节,吞天记无弹窗,吞天记全文阅读. |
||||||
|
* hot : 41926 |
||||||
|
* like : 65 |
||||||
|
* author : 风青阳 |
||||||
|
* create_time : 1561001132 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private String cover; |
||||||
|
private String description; |
||||||
|
private int hot; |
||||||
|
private int like; |
||||||
|
private String author; |
||||||
|
private int create_time; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title == null ? "" : StringUtils.convertCC(title, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescription() { |
||||||
|
return description == null ? "" : StringUtils.convertCC(StringUtils.delete160(description), MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDescription(String description) { |
||||||
|
this.description = description; |
||||||
|
} |
||||||
|
|
||||||
|
public int getHot() { |
||||||
|
return hot; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHot(int hot) { |
||||||
|
this.hot = hot; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLike() { |
||||||
|
return like; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLike(int like) { |
||||||
|
this.like = like; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author == null ? "" :StringUtils.convertCC(author, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,112 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
|
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/18 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class RecommendBookResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
private List<BookBean> book; |
||||||
|
|
||||||
|
public List<BookBean> getBook() { |
||||||
|
return book; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook(List<BookBean> book) { |
||||||
|
this.book = book; |
||||||
|
} |
||||||
|
|
||||||
|
public static class BookBean { |
||||||
|
/** |
||||||
|
* id : 139 |
||||||
|
* title : 丹师剑宗 |
||||||
|
* cover : http://dev.duoduvip.com/uploads/20190611/b81d831d3310041846444dacca57cef9.png
|
||||||
|
* description : |
||||||
|
* hot : 83146 |
||||||
|
* like : 64 |
||||||
|
* author : 伯爵 |
||||||
|
* create_time : 1560191131 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private String cover; |
||||||
|
private String description; |
||||||
|
private int hot; |
||||||
|
private int like; |
||||||
|
private String author; |
||||||
|
private int create_time; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title == null ? "" : StringUtils.convertCC(title, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescription() { |
||||||
|
return description == null ? "" : StringUtils.convertCC(StringUtils.delete160(description), MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDescription(String description) { |
||||||
|
this.description = description; |
||||||
|
} |
||||||
|
|
||||||
|
public int getHot() { |
||||||
|
return hot; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHot(int hot) { |
||||||
|
this.hot = hot; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLike() { |
||||||
|
return like; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLike(int like) { |
||||||
|
this.like = like; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author == null ? "" : StringUtils.convertCC(author, MyApp.getContext()) ; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,167 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/19 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class RecommendListResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
private List<ListBean> list; |
||||||
|
|
||||||
|
public List<ListBean> getList() { |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
public void setList(List<ListBean> list) { |
||||||
|
this.list = list; |
||||||
|
} |
||||||
|
|
||||||
|
public static class ListBean { |
||||||
|
/** |
||||||
|
* id : 5 |
||||||
|
* book_id : 10 |
||||||
|
* type : 1 |
||||||
|
* gender : 1 |
||||||
|
* sort : 10 |
||||||
|
* create_time : 1560129944 |
||||||
|
* update_time : 1560129944 |
||||||
|
* delete_time : null |
||||||
|
* book_title : 重生之末世宝典 |
||||||
|
* book_cover : http://api.duoduvip.com/uploads/nocover.jpg
|
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private int book_id; |
||||||
|
private int type; |
||||||
|
private int gender; |
||||||
|
private int sort; |
||||||
|
private int create_time; |
||||||
|
private int update_time; |
||||||
|
private Object delete_time; |
||||||
|
private String book_title; |
||||||
|
private String book_cover; |
||||||
|
private String author; |
||||||
|
private String description; |
||||||
|
private int hot; |
||||||
|
private int like; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBook_id() { |
||||||
|
return book_id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook_id(int book_id) { |
||||||
|
this.book_id = book_id; |
||||||
|
} |
||||||
|
|
||||||
|
public int getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public void setType(int type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
public int getGender() { |
||||||
|
return gender; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGender(int gender) { |
||||||
|
this.gender = gender; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSort() { |
||||||
|
return sort; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSort(int sort) { |
||||||
|
this.sort = sort; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public int getUpdate_time() { |
||||||
|
return update_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUpdate_time(int update_time) { |
||||||
|
this.update_time = update_time; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getDelete_time() { |
||||||
|
return delete_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDelete_time(Object delete_time) { |
||||||
|
this.delete_time = delete_time; |
||||||
|
} |
||||||
|
|
||||||
|
public String getBook_title() { |
||||||
|
return book_title == null ? "" : StringUtils.convertCC(book_title, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook_title(String book_title) { |
||||||
|
this.book_title = book_title; |
||||||
|
} |
||||||
|
|
||||||
|
public String getBook_cover() { |
||||||
|
return book_cover == null ? "" : book_cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook_cover(String book_cover) { |
||||||
|
this.book_cover = book_cover; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author == null ? "" : StringUtils.convertCC(author, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescription() { |
||||||
|
return description == null ? "" : StringUtils.convertCC(StringUtils.delete160(description), MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDescription(String description) { |
||||||
|
this.description = description; |
||||||
|
} |
||||||
|
|
||||||
|
public String getHot() { |
||||||
|
return String.valueOf(hot); |
||||||
|
} |
||||||
|
|
||||||
|
public void setHot(int hot) { |
||||||
|
this.hot = hot; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLike() { |
||||||
|
return like+"%"; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLike(int like) { |
||||||
|
this.like = like; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,135 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
import com.novel.read.base.MyApp; |
||||||
|
import com.novel.read.utlis.StringUtils; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class SearchResp implements Serializable { |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* book : [{"id":92,"title":"极品全能狂少","category_id":3,"cover":"http://dev.duoduvip.com/uploads/20190610/64512ebcd7e79923bc59ffc1d3afb597.png","description":"","hot":99437,"like":41,"author":"一支烟的快感","create_time":1560159443},{"id":170,"title":"抬棺匠","category_id":1,"cover":"http://dev.duoduvip.com/uploads/20190611/19cfa1ff96a4bec66b14e16b997ffba9.png","description":"","hot":99184,"like":54,"author":"陈八仙","create_time":1560205316},{"id":47,"title":"都市超级医圣","category_id":3,"cover":"http://dev.duoduvip.com/uploads/20190610/868b69fdf75dc303ca70fef4ccc8bc87.png","description":" 财法侣地,修行其实是一项非常耗钱的奢侈运动。无意中得到传说中道教学家,炼丹家,医药家葛洪的传承,淳朴的山里人葛东旭开始努力赚钱。当大多数人还在读高中时,他为了炼丹修行已经开始一边读书一边赚钱。当大多数人读大学还在为交女朋友的开销愁时,他已经是一名老板。当大多数人大学毕业在为找工作四处投简历,当富二代开着跑车,在美女面前炫耀时,他已经是一名级富一代,当然还是一名大隐隐于市的至尊医圣。<br> 各位书友要是觉得《都市超级医圣》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!都市超级医圣最新章节,都市超级医圣无弹窗,都市超级医圣全文阅读.","hot":99056,"like":21,"author":"断桥残雪","create_time":1560129236},{"id":105,"title":"神医高手在都市","category_id":3,"cover":"http://dev.duoduvip.com/uploads/20190610/ccab1913cdaf9aee2cfeaef84910a700.png","description":"","hot":98517,"like":28,"author":"复仇","create_time":1560167691},{"id":21,"title":"夜少的心尖宝贝","category_id":1,"cover":"http://dev.duoduvip.com/uploads/20190609/c0f5c2ff7fa532e4bd399625e5edacf3.png","description":" 简介:<br> 为了能正大光明的睡乔小姐,夜少不惜采用了108种追妻方式结果有两个小萝卜头冒了出来,对他说,\u201c帅叔叔,你想追我妈咪吗我们可以教你哦\u201d夜少掀桌,\u201c叫什么叔叔乖,叫爹地\u201d夜少一生最风光得意的事情就是睡了乔小姐,留下了种,让她给自己生了两个宝贝儿子,在她的身上永恒的打上了自己的烙印夜少漫漫追妻之旅,甜甜甜,超甜宠文,1v1<br> 各位书友要是觉得《夜少的心尖宝贝》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!夜少的心尖宝贝最新章节,夜少的心尖宝贝无弹窗,夜少的心尖宝贝全文阅读.","hot":97296,"like":64,"author":"慕欢颜","create_time":1560095819},{"id":102,"title":"万域灵神","category_id":4,"cover":"http://dev.duoduvip.com/uploads/20190610/847703596e2af187311bb9f5ab7c26b4.png","description":"","hot":97157,"like":56,"author":"乾多多","create_time":1560165904},{"id":87,"title":"至尊剑皇","category_id":4,"cover":"http://dev.duoduvip.com/uploads/20190610/711a87b0df3446885739845fba33fce4.png","description":"","hot":96684,"like":23,"author":"半步沧桑","create_time":1560156886},{"id":166,"title":"生活在美利坚的森林游侠","category_id":3,"cover":"http://dev.duoduvip.com/uploads/20190611/d663219f43a8bbba3d0718637fa0724a.png","description":"","hot":96427,"like":77,"author":"酱疙瘩","create_time":1560203771},{"id":171,"title":"三界红包群","category_id":3,"cover":"http://dev.duoduvip.com/uploads/nocover.jpg","description":"","hot":96362,"like":47,"author":"小教主","create_time":1560205922},{"id":131,"title":"命之途","category_id":2,"cover":"http://dev.duoduvip.com/uploads/nocover.jpg","description":"","hot":94835,"like":27,"author":"莫若梦兮","create_time":1560186387}] |
||||||
|
* limit : 10 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int limit; |
||||||
|
private List<BookBean> book; |
||||||
|
|
||||||
|
public int getLimit() { |
||||||
|
return limit; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLimit(int limit) { |
||||||
|
this.limit = limit; |
||||||
|
} |
||||||
|
|
||||||
|
public List<BookBean> getBook() { |
||||||
|
if (book == null) { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
return book; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBook(List<BookBean> book) { |
||||||
|
this.book = book; |
||||||
|
} |
||||||
|
|
||||||
|
public static class BookBean { |
||||||
|
/** |
||||||
|
* id : 92 |
||||||
|
* title : 极品全能狂少 |
||||||
|
* category_id : 3 |
||||||
|
* cover : http://dev.duoduvip.com/uploads/20190610/64512ebcd7e79923bc59ffc1d3afb597.png
|
||||||
|
* description : |
||||||
|
* hot : 99437 |
||||||
|
* like : 41 |
||||||
|
* author : 一支烟的快感 |
||||||
|
* create_time : 1560159443 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String title; |
||||||
|
private int category_id; |
||||||
|
private String cover; |
||||||
|
private String description; |
||||||
|
private int hot; |
||||||
|
private int like; |
||||||
|
private String author; |
||||||
|
private int create_time; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title == null ? "" : StringUtils.convertCC(title, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCategory_id() { |
||||||
|
return category_id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCategory_id(int category_id) { |
||||||
|
this.category_id = category_id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescription() { |
||||||
|
return description == null ? "" : StringUtils.convertCC(StringUtils.delete160(description), MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDescription(String description) { |
||||||
|
this.description = description; |
||||||
|
} |
||||||
|
|
||||||
|
public int getHot() { |
||||||
|
return hot; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHot(int hot) { |
||||||
|
this.hot = hot; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLike() { |
||||||
|
return like; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLike(int like) { |
||||||
|
this.like = like; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author == null ? "" : StringUtils.convertCC(author, MyApp.getContext()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
public class UidResp { |
||||||
|
|
||||||
|
/** |
||||||
|
* uid : 3 |
||||||
|
*/ |
||||||
|
|
||||||
|
private int uid; |
||||||
|
|
||||||
|
public int getUid() { |
||||||
|
return uid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUid(int uid) { |
||||||
|
this.uid = uid; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,138 @@ |
|||||||
|
package com.novel.read.model.protocol; |
||||||
|
|
||||||
|
/** |
||||||
|
* create by 赵利君 on 2019/6/25 |
||||||
|
* describe: |
||||||
|
*/ |
||||||
|
public class VersionResp { |
||||||
|
|
||||||
|
/** |
||||||
|
* version : {"id":2,"version":"1.0.0","size":"5096","content":"正式上线","download":"https://play.google.com/store/apps/details?id=com.freebook.bookreader","coerce":1,"status":1,"push_time":1560060702,"create_time":1560060772,"update_time":1560752842,"delete_time":null} |
||||||
|
*/ |
||||||
|
|
||||||
|
private VersionBean version; |
||||||
|
|
||||||
|
public VersionBean getVersion() { |
||||||
|
return version; |
||||||
|
} |
||||||
|
|
||||||
|
public void setVersion(VersionBean version) { |
||||||
|
this.version = version; |
||||||
|
} |
||||||
|
|
||||||
|
public static class VersionBean { |
||||||
|
/** |
||||||
|
* id : 2 |
||||||
|
* version : 1.0.0 |
||||||
|
* size : 5096 |
||||||
|
* content : 正式上线 |
||||||
|
* download : https://play.google.com/store/apps/details?id=com.freebook.bookreader
|
||||||
|
* coerce : 1 |
||||||
|
* status : 1 |
||||||
|
* push_time : 1560060702 |
||||||
|
* create_time : 1560060772 |
||||||
|
* update_time : 1560752842 |
||||||
|
* delete_time : null |
||||||
|
*/ |
||||||
|
|
||||||
|
private int id; |
||||||
|
private String version; |
||||||
|
private String size; |
||||||
|
private String content; |
||||||
|
private String download; |
||||||
|
private int coerce; |
||||||
|
private int status; |
||||||
|
private int push_time; |
||||||
|
private int create_time; |
||||||
|
private int update_time; |
||||||
|
private Object delete_time; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getVersion() { |
||||||
|
return version; |
||||||
|
} |
||||||
|
|
||||||
|
public void setVersion(String version) { |
||||||
|
this.version = version; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSize(String size) { |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
|
||||||
|
public String getContent() { |
||||||
|
return content; |
||||||
|
} |
||||||
|
|
||||||
|
public void setContent(String content) { |
||||||
|
this.content = content; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDownload() { |
||||||
|
return download; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDownload(String download) { |
||||||
|
this.download = download; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCoerce() { |
||||||
|
return coerce; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCoerce(int coerce) { |
||||||
|
this.coerce = coerce; |
||||||
|
} |
||||||
|
|
||||||
|
public int getStatus() { |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
public void setStatus(int status) { |
||||||
|
this.status = status; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPush_time() { |
||||||
|
return push_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPush_time(int push_time) { |
||||||
|
this.push_time = push_time; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreate_time() { |
||||||
|
return create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreate_time(int create_time) { |
||||||
|
this.create_time = create_time; |
||||||
|
} |
||||||
|
|
||||||
|
public int getUpdate_time() { |
||||||
|
return update_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUpdate_time(int update_time) { |
||||||
|
this.update_time = update_time; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getDelete_time() { |
||||||
|
return delete_time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDelete_time(Object delete_time) { |
||||||
|
this.delete_time = delete_time; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
package com.novel.read.service; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.BaseEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-10. |
||||||
|
* 下载进度事件 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class DownloadMessage extends BaseEvent { |
||||||
|
|
||||||
|
public String message; |
||||||
|
|
||||||
|
public DownloadMessage(String message){ |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,448 @@ |
|||||||
|
package com.novel.read.service; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.os.Binder; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.IBinder; |
||||||
|
import android.text.TextUtils; |
||||||
|
|
||||||
|
import androidx.annotation.Nullable; |
||||||
|
|
||||||
|
import com.mango.mangolib.event.EventManager; |
||||||
|
import com.novel.read.R; |
||||||
|
import com.novel.read.base.BaseService; |
||||||
|
import com.novel.read.event.DeleteResponseEvent; |
||||||
|
import com.novel.read.event.DeleteTaskEvent; |
||||||
|
import com.novel.read.event.RxBus; |
||||||
|
import com.novel.read.http.AccountManager; |
||||||
|
import com.novel.read.model.db.BookChapterBean; |
||||||
|
import com.novel.read.model.db.DownloadTaskBean; |
||||||
|
import com.novel.read.model.db.dbManage.BookManager; |
||||||
|
import com.novel.read.model.db.dbManage.BookRepository; |
||||||
|
import com.novel.read.utlis.LocalManageUtil; |
||||||
|
import com.novel.read.utlis.LogUtils; |
||||||
|
import com.novel.read.utlis.NetworkUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.ExecutorService; |
||||||
|
import java.util.concurrent.Executors; |
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers; |
||||||
|
import io.reactivex.disposables.Disposable; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by newbiechen on 17-5-10. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class DownloadService extends BaseService { |
||||||
|
private static final String TAG = "DownloadService"; |
||||||
|
//加载状态
|
||||||
|
private static final int LOAD_ERROR = -1; |
||||||
|
private static final int LOAD_NORMAL = 0; |
||||||
|
private static final int LOAD_PAUSE = 1; |
||||||
|
private static final int LOAD_DELETE = 2; //正在加载时候,用户删除收藏书籍的情况。
|
||||||
|
|
||||||
|
//下载状态
|
||||||
|
public static final int STATUS_CONTINUE = DownloadTaskBean.STATUS_LOADING; |
||||||
|
public static final int STATUS_PAUSE = DownloadTaskBean.STATUS_PAUSE; |
||||||
|
|
||||||
|
//线程池
|
||||||
|
private final ExecutorService mSingleExecutor = Executors.newSingleThreadExecutor(); |
||||||
|
//加载队列
|
||||||
|
private final List<DownloadTaskBean> mDownloadTaskQueue = Collections.synchronizedList(new ArrayList<>()); |
||||||
|
//Handler
|
||||||
|
private Handler mHandler; |
||||||
|
|
||||||
|
//包含所有的DownloadTask
|
||||||
|
private List<DownloadTaskBean> mDownloadTaskList; |
||||||
|
|
||||||
|
private OnDownloadListener mDownloadListener; |
||||||
|
private boolean isBusy = false; |
||||||
|
private boolean isCancel = false; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void attachBaseContext(Context base) { |
||||||
|
super.attachBaseContext(LocalManageUtil.setLocal(base)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onCreate() { |
||||||
|
super.onCreate(); |
||||||
|
mHandler = new Handler(getMainLooper()); |
||||||
|
//从数据库中获取所有的任务
|
||||||
|
mDownloadTaskList = BookRepository |
||||||
|
.getInstance() |
||||||
|
.getDownloadTaskList(); |
||||||
|
} |
||||||
|
|
||||||
|
@Nullable |
||||||
|
@Override |
||||||
|
public IBinder onBind(Intent intent) { |
||||||
|
return new TaskBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) { |
||||||
|
|
||||||
|
//接受创建的DownloadTask
|
||||||
|
Disposable disposable = RxBus.getInstance() |
||||||
|
.toObservable(DownloadTaskBean.class) |
||||||
|
.observeOn(AndroidSchedulers.mainThread()) |
||||||
|
.subscribe( |
||||||
|
(event) -> { |
||||||
|
//判断任务是否为轮询标志
|
||||||
|
//判断任务是否存在,并修改任务
|
||||||
|
if (TextUtils.isEmpty(event.getBookId()) || !checkAndAlterDownloadTask(event)) { |
||||||
|
addToExecutor(event); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
addDisposable(disposable); |
||||||
|
|
||||||
|
//是否删除数据的问题
|
||||||
|
Disposable deleteDisp = RxBus.getInstance() |
||||||
|
.toObservable(DeleteTaskEvent.class) |
||||||
|
.observeOn(AndroidSchedulers.mainThread()) |
||||||
|
.subscribe( |
||||||
|
(event) -> { |
||||||
|
//判断是否该数据存在加载列表中
|
||||||
|
boolean isDelete = true; |
||||||
|
for (DownloadTaskBean bean : mDownloadTaskQueue) { |
||||||
|
if (bean.getBookId().equals(event.collBook.getId())) { |
||||||
|
isDelete = false; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
//如果不存在则删除List中的task
|
||||||
|
if (isDelete) { |
||||||
|
//
|
||||||
|
Iterator<DownloadTaskBean> taskIt = mDownloadTaskList.iterator(); |
||||||
|
while (taskIt.hasNext()) { |
||||||
|
DownloadTaskBean task = taskIt.next(); |
||||||
|
if (task.getBookId().equals(event.collBook.getId())) { |
||||||
|
taskIt.remove(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//返回状态
|
||||||
|
RxBus.getInstance().post(new DeleteResponseEvent(isDelete, event.collBook)); |
||||||
|
} |
||||||
|
); |
||||||
|
addDisposable(deleteDisp); |
||||||
|
return super.onStartCommand(intent, flags, startId); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 1. 查看是否任务已存在 |
||||||
|
* 2. 修改DownloadTask的 taskName 和 list |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private boolean checkAndAlterDownloadTask(DownloadTaskBean newTask) { |
||||||
|
boolean isExist = false; |
||||||
|
for (DownloadTaskBean downloadTask : mDownloadTaskList) { |
||||||
|
//如果不相同则不往下执行,往下执行都是存在相同的情况
|
||||||
|
if (!downloadTask.getTaskName().equals(newTask.getTaskName())) continue; |
||||||
|
|
||||||
|
if (downloadTask.getStatus() == DownloadTaskBean.STATUS_FINISH) { |
||||||
|
//判断是否newTask是已完成
|
||||||
|
if (downloadTask.getLastChapter() == newTask.getLastChapter()) { |
||||||
|
isExist = true; |
||||||
|
//发送回去已缓存
|
||||||
|
postMessage(getString(R.string.cached)); |
||||||
|
} |
||||||
|
//判断,是否已完成的章节的起始点比新Task大,如果更大则表示新Task中的该章节已被加载,所以需要剪切
|
||||||
|
else if (downloadTask.getLastChapter() > (newTask.getLastChapter() - newTask.getBookChapterList().size())) { |
||||||
|
if (downloadTask.getLastChapter() > newTask.getLastChapter()) { |
||||||
|
isExist = true; |
||||||
|
//发送回去已缓存
|
||||||
|
postMessage(getString(R.string.cached)); |
||||||
|
} else { |
||||||
|
//删除掉已经完成的章节
|
||||||
|
List<BookChapterBean> remainChapterBeans = newTask.getBookChapterList().subList(downloadTask.getLastChapter(), newTask.getLastChapter()); |
||||||
|
String taskName = newTask.getTaskName() |
||||||
|
+ getString(R.string.nb_download_chapter_scope, |
||||||
|
downloadTask.getLastChapter(), newTask.getLastChapter()); |
||||||
|
//重置任务
|
||||||
|
newTask.setBookChapters(remainChapterBeans); |
||||||
|
newTask.setTaskName(taskName); |
||||||
|
|
||||||
|
//发送添加到任务的提示
|
||||||
|
postMessage(getString(R.string.cache_success)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//表示该任务已经在 下载、等待、暂停、网络错误中
|
||||||
|
else { |
||||||
|
isExist = true; |
||||||
|
//发送回去:已经在加载队列中。
|
||||||
|
postMessage(getString(R.string.task_exist)); |
||||||
|
} |
||||||
|
} |
||||||
|
//重置名字
|
||||||
|
if (!isExist) { |
||||||
|
String taskName = newTask.getTaskName() |
||||||
|
+ getString(R.string.nb_download_chapter_scope, |
||||||
|
1, newTask.getLastChapter()); |
||||||
|
newTask.setTaskName(taskName); |
||||||
|
postMessage(getString(R.string.cache_success)); |
||||||
|
} |
||||||
|
return isExist; |
||||||
|
} |
||||||
|
|
||||||
|
private void addToExecutor(DownloadTaskBean taskEvent) { |
||||||
|
|
||||||
|
//判断是否为轮询请求
|
||||||
|
if (!TextUtils.isEmpty(taskEvent.getBookId())) { |
||||||
|
|
||||||
|
if (!mDownloadTaskList.contains(taskEvent)) { |
||||||
|
//加入总列表中,表示创建,修改CollBean的状态。
|
||||||
|
mDownloadTaskList.add(taskEvent); |
||||||
|
} |
||||||
|
// 添加到下载队列
|
||||||
|
mDownloadTaskQueue.add(taskEvent); |
||||||
|
} |
||||||
|
|
||||||
|
// 从队列顺序取出第一条下载
|
||||||
|
if (mDownloadTaskQueue.size() > 0 && !isBusy) { |
||||||
|
isBusy = true; |
||||||
|
executeTask(mDownloadTaskQueue.get(0)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void executeTask(DownloadTaskBean taskEvent) { |
||||||
|
Runnable runnable = () -> { |
||||||
|
|
||||||
|
taskEvent.setStatus(DownloadTaskBean.STATUS_LOADING); |
||||||
|
|
||||||
|
int result = LOAD_NORMAL; |
||||||
|
List<BookChapterBean> bookChapterBeans = taskEvent.getBookChapters(); |
||||||
|
|
||||||
|
//调用for循环,下载数据 //todo
|
||||||
|
// for (int i=taskEvent.getCurrentChapter(); i<bookChapterBeans.size();++i) {
|
||||||
|
for (int i = taskEvent.getCurrentChapter(); i <= taskEvent.getLastChapter() && i < bookChapterBeans.size(); ++i) { |
||||||
|
|
||||||
|
BookChapterBean bookChapterBean = bookChapterBeans.get(i); |
||||||
|
//首先判断该章节是否曾经被加载过 (从文件中判断)
|
||||||
|
if (BookManager.isChapterCached(taskEvent.getBookId(), bookChapterBean.getTitle())) { |
||||||
|
|
||||||
|
//设置任务进度
|
||||||
|
taskEvent.setCurrentChapter(i); |
||||||
|
|
||||||
|
//章节加载完成
|
||||||
|
postDownloadChange(taskEvent, DownloadTaskBean.STATUS_LOADING, i + ""); |
||||||
|
|
||||||
|
//无需进行下一步
|
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
//判断网络是否出问题
|
||||||
|
if (!NetworkUtils.isAvailable()) { |
||||||
|
//章节加载失败
|
||||||
|
result = LOAD_ERROR; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
if (isCancel) { |
||||||
|
result = LOAD_PAUSE; |
||||||
|
isCancel = false; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
//加载数据
|
||||||
|
result = loadChapter(taskEvent.getBookId(), bookChapterBean); |
||||||
|
//章节加载完成
|
||||||
|
if (result == LOAD_NORMAL) { |
||||||
|
taskEvent.setCurrentChapter(i); |
||||||
|
postDownloadChange(taskEvent, DownloadTaskBean.STATUS_LOADING, i + ""); |
||||||
|
} |
||||||
|
//章节加载失败
|
||||||
|
else { |
||||||
|
//遇到错误退出
|
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
if (result == LOAD_NORMAL) { |
||||||
|
//存储DownloadTask的状态
|
||||||
|
taskEvent.setStatus(DownloadTaskBean.STATUS_FINISH);//Task的状态
|
||||||
|
taskEvent.setCurrentChapter(taskEvent.getBookChapters().size());//当前下载的章节数量
|
||||||
|
taskEvent.setSize(BookManager.getBookSize(taskEvent.getBookId()));//Task的大小
|
||||||
|
|
||||||
|
//发送完成状态
|
||||||
|
postDownloadChange(taskEvent, DownloadTaskBean.STATUS_FINISH, getString(R.string.download_success)); |
||||||
|
} else if (result == LOAD_ERROR) { |
||||||
|
taskEvent.setStatus(DownloadTaskBean.STATUS_ERROR);//Task的状态
|
||||||
|
//任务加载失败
|
||||||
|
postDownloadChange(taskEvent, DownloadTaskBean.STATUS_ERROR, getString(R.string.download_error)); |
||||||
|
} else if (result == LOAD_PAUSE) { |
||||||
|
taskEvent.setStatus(DownloadTaskBean.STATUS_PAUSE);//Task的状态
|
||||||
|
postDownloadChange(taskEvent, DownloadTaskBean.STATUS_PAUSE, getString(R.string.download_pause)); |
||||||
|
} else if (result == LOAD_DELETE) { |
||||||
|
//没想好怎么做
|
||||||
|
} |
||||||
|
|
||||||
|
//存储状态
|
||||||
|
BookRepository.getInstance().saveDownloadTask(taskEvent); |
||||||
|
|
||||||
|
//轮询下一个事件,用RxBus用来保证事件是在主线程
|
||||||
|
|
||||||
|
//移除完成的任务
|
||||||
|
mDownloadTaskQueue.remove(taskEvent); |
||||||
|
//设置为空闲
|
||||||
|
isBusy = false; |
||||||
|
//轮询
|
||||||
|
post(new DownloadTaskBean()); |
||||||
|
}; |
||||||
|
mSingleExecutor.execute(runnable); |
||||||
|
} |
||||||
|
|
||||||
|
private int loadChapter(String folderName, BookChapterBean bean) { |
||||||
|
//加载的结果参数
|
||||||
|
final int[] result = {LOAD_NORMAL}; |
||||||
|
|
||||||
|
//问题:(这里有个问题,就是body其实比较大,如何获取数据流而不是对象,)是不是直接使用OkHttpClient交互会更好一点
|
||||||
|
Disposable disposable = AccountManager.getInstance() |
||||||
|
.getChapterInfo(bean.getId()) |
||||||
|
//表示在当前环境下执行
|
||||||
|
.subscribe( |
||||||
|
chapterInfo -> { |
||||||
|
//TODO:这里文件的名字用的是BookChapter的title,而不是chapter的title。
|
||||||
|
//原因是Chapter的title可能重复,但是BookChapter的title不会重复
|
||||||
|
//BookChapter的title = 卷名 + 章节名 chapter 的 title 就是章节名。。
|
||||||
|
BookRepository.getInstance().saveChapterInfo(folderName, bean.getTitle(), chapterInfo.getBody()); |
||||||
|
}, |
||||||
|
e -> { |
||||||
|
//当前进度加载错误(这里需要判断是什么问题,根据相应的问题做出相应的回答)
|
||||||
|
LogUtils.e(e); |
||||||
|
//设置加载结果
|
||||||
|
result[0] = LOAD_ERROR; |
||||||
|
} |
||||||
|
); |
||||||
|
addDisposable(disposable); |
||||||
|
return result[0]; |
||||||
|
} |
||||||
|
|
||||||
|
private void postDownloadChange(DownloadTaskBean task, int status, String msg) { |
||||||
|
if (mDownloadListener != null && msg != null) { |
||||||
|
int position = mDownloadTaskList.indexOf(task); |
||||||
|
//通过handler,切换回主线程
|
||||||
|
mHandler.post(() -> mDownloadListener.onDownloadChange( |
||||||
|
position, status, msg) |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void postMessage(String msg) { |
||||||
|
// RxBus.getInstance().post(new DownloadMessage(msg));
|
||||||
|
EventManager.Companion.getInstance().postEvent(new DownloadMessage(msg)); |
||||||
|
} |
||||||
|
|
||||||
|
private void post(DownloadTaskBean task) { |
||||||
|
RxBus.getInstance().post(task); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onUnbind(Intent intent) { |
||||||
|
|
||||||
|
mDownloadListener = null; |
||||||
|
return super.onUnbind(intent); |
||||||
|
} |
||||||
|
|
||||||
|
class TaskBuilder extends Binder implements IDownloadManager { |
||||||
|
@Override |
||||||
|
public List<DownloadTaskBean> getDownloadTaskList() { |
||||||
|
return Collections.unmodifiableList(mDownloadTaskList); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setOnDownloadListener(OnDownloadListener listener) { |
||||||
|
mDownloadListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setDownloadStatus(String taskName, int status) { |
||||||
|
//修改某个Task的状态
|
||||||
|
switch (status) { |
||||||
|
//加入缓存队列
|
||||||
|
case DownloadTaskBean.STATUS_WAIT: |
||||||
|
for (int i = 0; i < mDownloadTaskList.size(); ++i) { |
||||||
|
DownloadTaskBean bean = mDownloadTaskList.get(i); |
||||||
|
if (taskName.equals(bean.getTaskName())) { |
||||||
|
bean.setStatus(DownloadTaskBean.STATUS_WAIT); |
||||||
|
mDownloadListener.onDownloadResponse(i, DownloadTaskBean.STATUS_WAIT); |
||||||
|
addToExecutor(bean); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
//从缓存队列中删除
|
||||||
|
case DownloadTaskBean.STATUS_PAUSE: |
||||||
|
Iterator<DownloadTaskBean> it = mDownloadTaskQueue.iterator(); |
||||||
|
while (it.hasNext()) { |
||||||
|
DownloadTaskBean bean = it.next(); |
||||||
|
if (bean.getTaskName().equals(taskName)) { |
||||||
|
if (bean.getStatus() == DownloadTaskBean.STATUS_LOADING |
||||||
|
&& bean.getTaskName().equals(taskName)) { |
||||||
|
isCancel = true; |
||||||
|
break; |
||||||
|
} else { |
||||||
|
bean.setStatus(DownloadTaskBean.STATUS_PAUSE); |
||||||
|
mDownloadTaskQueue.remove(bean); |
||||||
|
int position = mDownloadTaskList.indexOf(bean); |
||||||
|
mDownloadListener.onDownloadResponse(position, DownloadTaskBean.STATUS_PAUSE); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setAllDownloadStatus(int status) { |
||||||
|
//修改所有Task的状态
|
||||||
|
} |
||||||
|
|
||||||
|
//首先判断是否在加载队列中。
|
||||||
|
//如果在加载队列中首先判断是否正在下载,
|
||||||
|
//然后判断是否在完成队列中。
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
super.onDestroy(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public interface IDownloadManager { |
||||||
|
List<DownloadTaskBean> getDownloadTaskList(); |
||||||
|
|
||||||
|
void setOnDownloadListener(OnDownloadListener listener); |
||||||
|
|
||||||
|
void setDownloadStatus(String taskName, int status); |
||||||
|
|
||||||
|
void setAllDownloadStatus(int status); |
||||||
|
} |
||||||
|
|
||||||
|
public interface OnDownloadListener { |
||||||
|
/** |
||||||
|
* @param pos : Task在item中的位置 |
||||||
|
* @param status : Task的状态 |
||||||
|
* @param msg: 传送的Msg |
||||||
|
*/ |
||||||
|
void onDownloadChange(int pos, int status, String msg); |
||||||
|
|
||||||
|
/** |
||||||
|
* 回复 |
||||||
|
*/ |
||||||
|
void onDownloadResponse(int pos, int status); |
||||||
|
} |
||||||
|
} |
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue