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