parent
5f73042209
commit
f2a98582f1
Binary file not shown.
@ -1,9 +1,11 @@ |
|||||||
package xyz.fycz.myreader.base; |
package xyz.fycz.myreader.base.adapter; |
||||||
|
|
||||||
import android.os.Handler; |
import android.os.Handler; |
||||||
import android.view.View; |
import android.view.View; |
||||||
import android.view.ViewGroup; |
import android.view.ViewGroup; |
||||||
import androidx.recyclerview.widget.RecyclerView; |
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
import xyz.fycz.myreader.base.BaseViewHolder; |
||||||
|
import xyz.fycz.myreader.base.IViewHolder; |
||||||
|
|
||||||
import java.util.ArrayList; |
import java.util.ArrayList; |
||||||
import java.util.Collections; |
import java.util.Collections; |
@ -0,0 +1,353 @@ |
|||||||
|
package xyz.fycz.myreader.ui.bookinfo; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.content.Intent; |
||||||
|
import android.net.Uri; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Message; |
||||||
|
import android.view.Menu; |
||||||
|
import android.view.MenuItem; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.ProgressBar; |
||||||
|
import android.widget.TextView; |
||||||
|
import androidx.appcompat.app.AlertDialog; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.recyclerview.widget.RecyclerView; |
||||||
|
import butterknife.BindView; |
||||||
|
import com.bumptech.glide.Glide; |
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners; |
||||||
|
import com.bumptech.glide.request.RequestOptions; |
||||||
|
import xyz.fycz.myreader.R; |
||||||
|
import xyz.fycz.myreader.base.BaseActivity2; |
||||||
|
import xyz.fycz.myreader.callback.ResultCallback; |
||||||
|
import xyz.fycz.myreader.common.APPCONST; |
||||||
|
import xyz.fycz.myreader.crawler.BookInfoCrawler; |
||||||
|
import xyz.fycz.myreader.crawler.ReadCrawler; |
||||||
|
import xyz.fycz.myreader.crawler.ReadCrawlerUtil; |
||||||
|
import xyz.fycz.myreader.creator.ChangeSourceDialog; |
||||||
|
import xyz.fycz.myreader.creator.DialogCreator; |
||||||
|
import xyz.fycz.myreader.enums.BookSource; |
||||||
|
import xyz.fycz.myreader.greendao.entity.Book; |
||||||
|
import xyz.fycz.myreader.greendao.service.BookService; |
||||||
|
import xyz.fycz.myreader.ui.read.ReadActivity; |
||||||
|
import xyz.fycz.myreader.util.StringHelper; |
||||||
|
import xyz.fycz.myreader.util.TextHelper; |
||||||
|
import xyz.fycz.myreader.util.utils.NetworkUtils; |
||||||
|
import xyz.fycz.myreader.webapi.CommonApi; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/8/17 11:39 |
||||||
|
*/ |
||||||
|
public class BookDetailedActivity extends BaseActivity2 { |
||||||
|
@BindView(R.id.book_detail_iv_cover) |
||||||
|
ImageView mIvCover; |
||||||
|
@BindView(R.id.book_detail_tv_author) |
||||||
|
TextView mTvAuthor; |
||||||
|
@BindView(R.id.book_detail_tv_type) |
||||||
|
TextView mTvType; |
||||||
|
@BindView(R.id.book_detail_newest_chapter) |
||||||
|
TextView mTvNewestChapter; |
||||||
|
@BindView(R.id.book_detail_source) |
||||||
|
TextView mTvSource; |
||||||
|
@BindView(R.id.book_detail_tv_add) |
||||||
|
TextView bookDetailTvAdd; |
||||||
|
@BindView(R.id.book_detail_tv_open) |
||||||
|
TextView bookDetailTvOpen; |
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.book_detail_tv_desc) |
||||||
|
TextView mTvDesc; |
||||||
|
@BindView(R.id.tv_disclaimer) |
||||||
|
TextView mTvDisclaimer; |
||||||
|
@BindView(R.id.fl_add_bookcase) |
||||||
|
FrameLayout flAddBookcase; |
||||||
|
@BindView(R.id.fl_open_book) |
||||||
|
FrameLayout flOpenBook; |
||||||
|
@BindView(R.id.book_detail_rv_catalog) |
||||||
|
RecyclerView bookDetailRvCatalog; |
||||||
|
@BindView(R.id.pb_loading) |
||||||
|
ProgressBar pbLoading; |
||||||
|
|
||||||
|
|
||||||
|
private Book mBook; |
||||||
|
private ArrayList<Book> aBooks; |
||||||
|
private BookService mBookService; |
||||||
|
private ReadCrawler mReadCrawler; |
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
private Handler mHandler = new Handler() { |
||||||
|
@Override |
||||||
|
public void handleMessage(Message msg) { |
||||||
|
switch (msg.what) { |
||||||
|
case 1: |
||||||
|
initBookInfo(); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
createChangeSourceDia(); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
pbLoading.setVisibility(View.GONE); |
||||||
|
DialogCreator.createTipDialog(BookDetailedActivity.this, "未搜索到该书籍,书源加载失败!"); |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
initOtherInfo(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getContentId() { |
||||||
|
return R.layout.activity_book_detail; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData(Bundle savedInstanceState) { |
||||||
|
super.initData(savedInstanceState); |
||||||
|
mBookService = BookService.getInstance(); |
||||||
|
aBooks = (ArrayList<Book>) getIntent().getSerializableExtra(APPCONST.SEARCH_BOOK_BEAN); |
||||||
|
if (aBooks != null) { |
||||||
|
mBook = aBooks.get(0); |
||||||
|
} else { |
||||||
|
mBook = (Book) getIntent().getSerializableExtra(APPCONST.BOOK); |
||||||
|
} |
||||||
|
mReadCrawler = ReadCrawlerUtil.getReadCrawler(mBook.getSource()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setUpToolbar(Toolbar toolbar) { |
||||||
|
super.setUpToolbar(toolbar); |
||||||
|
getSupportActionBar().setTitle(mBook.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initWidget() { |
||||||
|
super.initWidget(); |
||||||
|
initBookInfo(); |
||||||
|
mTvDisclaimer.setOnClickListener(v -> DialogCreator.createAssetTipDialog(this, "免责声明", "disclaimer.fy")); |
||||||
|
if (isBookCollected()) { |
||||||
|
bookDetailTvAdd.setText("移除书籍"); |
||||||
|
bookDetailTvOpen.setText("继续阅读"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initClick() { |
||||||
|
super.initClick(); |
||||||
|
flAddBookcase.setOnClickListener(view -> { |
||||||
|
if (!isBookCollected()) { |
||||||
|
mBookService.addBook(mBook); |
||||||
|
TextHelper.showText("成功加入书架"); |
||||||
|
bookDetailTvAdd.setText("移除书籍"); |
||||||
|
} else { |
||||||
|
mBookService.deleteBookById(mBook.getId()); |
||||||
|
TextHelper.showText("成功移除书籍"); |
||||||
|
bookDetailTvAdd.setText("加入书架"); |
||||||
|
bookDetailTvOpen.setText("开始阅读"); |
||||||
|
} |
||||||
|
}); |
||||||
|
flOpenBook.setOnClickListener(view -> { |
||||||
|
final boolean isCollected; |
||||||
|
if (isBookCollected()) { |
||||||
|
isCollected = true; |
||||||
|
} else { |
||||||
|
mBookService.addBook(mBook); |
||||||
|
isCollected = false; |
||||||
|
CommonApi.getBookChapters(mBook.getChapterUrl(), mReadCrawler, new ResultCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(Object o, int code) { |
||||||
|
mBookService.updateEntity(mBook); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onError(Exception e) { |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
Intent intent = new Intent(this, ReadActivity.class); |
||||||
|
intent.putExtra(APPCONST.BOOK, mBook); |
||||||
|
intent.putExtra("isCollected", isCollected); |
||||||
|
startActivityForResult(intent, APPCONST.REQUEST_READ); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void processLogic() { |
||||||
|
super.processLogic(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isBookCollected() { |
||||||
|
Book book = mBookService.findBookByAuthorAndName(mBook.getName(), mBook.getAuthor()); |
||||||
|
if (book == null) { |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
mBook = book; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initBookInfo() { |
||||||
|
mTvAuthor.setText(mBook.getAuthor()); |
||||||
|
if (StringHelper.isEmpty(mBook.getImgUrl())) { |
||||||
|
mBook.setImgUrl(""); |
||||||
|
} |
||||||
|
assert mBook.getNewestChapterTitle() != null; |
||||||
|
mTvNewestChapter.setText("最新章节:" + mBook.getNewestChapterTitle().replace("最近更新 ", "")); |
||||||
|
mTvDesc.setText(""); |
||||||
|
mTvType.setText(""); |
||||||
|
if (!"null".equals(mBook.getSource())) { |
||||||
|
mTvSource.setText("书源:" + BookSource.fromString(mBook.getSource()).text); |
||||||
|
} |
||||||
|
ReadCrawler rc = ReadCrawlerUtil.getReadCrawler(mBook.getSource()); |
||||||
|
if (rc instanceof BookInfoCrawler && StringHelper.isEmpty(mBook.getImgUrl())) { |
||||||
|
BookInfoCrawler bic = (BookInfoCrawler) rc; |
||||||
|
CommonApi.getBookInfo(mBook, bic, new ResultCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(Object o, int code) { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(4)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onError(Exception e) { |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
initOtherInfo(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initOtherInfo() { |
||||||
|
mTvDesc.setText(mBook.getDesc()); |
||||||
|
mTvType.setText(mBook.getType()); |
||||||
|
Glide.with(this) |
||||||
|
.load(mBook.getImgUrl()) |
||||||
|
.error(R.mipmap.no_image) |
||||||
|
.placeholder(R.mipmap.no_image) |
||||||
|
//设置圆角
|
||||||
|
.apply(RequestOptions.bitmapTransform(new RoundedCorners(8))) |
||||||
|
.into(mIvCover); |
||||||
|
} |
||||||
|
|
||||||
|
private void createChangeSourceDia() { |
||||||
|
if (aBooks == null){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||||
|
return; |
||||||
|
} |
||||||
|
pbLoading.setVisibility(View.GONE); |
||||||
|
CharSequence[] sources = new CharSequence[aBooks.size()]; |
||||||
|
int checkedItem = 0; |
||||||
|
for (int i = 0; i < sources.length; i++) { |
||||||
|
sources[i] = BookSource.fromString(aBooks.get(i).getSource()).text |
||||||
|
+ "\n" + aBooks.get(i).getNewestChapterTitle(); |
||||||
|
if (sources[i].equals(BookSource.fromString(mBook.getSource()).text |
||||||
|
+ "\n" + aBooks.get(i).getNewestChapterTitle())) { |
||||||
|
checkedItem = i; |
||||||
|
} |
||||||
|
} |
||||||
|
final int finalCheckedItem = checkedItem; |
||||||
|
AlertDialog dialog = new AlertDialog.Builder(this) |
||||||
|
.setTitle("切换书源") |
||||||
|
.setCancelable(true) |
||||||
|
.setSingleChoiceItems(sources, checkedItem, (dialog1, which) -> { |
||||||
|
boolean isBookCollected = isBookCollected(); |
||||||
|
if (finalCheckedItem == which) { |
||||||
|
dialog1.dismiss(); |
||||||
|
return; |
||||||
|
} |
||||||
|
Book book = aBooks.get(which); |
||||||
|
Book bookTem = new Book(mBook); |
||||||
|
bookTem.setChapterUrl(book.getChapterUrl()); |
||||||
|
bookTem.setImgUrl(book.getImgUrl()); |
||||||
|
bookTem.setType(book.getType()); |
||||||
|
bookTem.setDesc(book.getDesc()); |
||||||
|
bookTem.setSource(book.getSource()); |
||||||
|
if (isBookCollected) { |
||||||
|
mBookService.updateBook(mBook, bookTem); |
||||||
|
} |
||||||
|
mBook = bookTem; |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||||
|
if (isBookCollected) { |
||||||
|
DialogCreator.createTipDialog(this, |
||||||
|
"换源成功,由于不同书源的章节数量不一定相同,故换源后历史章节可能出错!"); |
||||||
|
} |
||||||
|
dialog1.dismiss(); |
||||||
|
}).create(); |
||||||
|
dialog.show(); |
||||||
|
} |
||||||
|
|
||||||
|
/********************************Event***************************************/ |
||||||
|
@Override |
||||||
|
public boolean onCreateOptionsMenu(Menu menu) { |
||||||
|
getMenuInflater().inflate(R.menu.menu_book_detail, menu); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 导航栏菜单点击事件 |
||||||
|
* |
||||||
|
* @param item |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean onOptionsItemSelected(MenuItem item) { |
||||||
|
switch (item.getItemId()) { |
||||||
|
case R.id.action_change_source: //换源
|
||||||
|
if (!NetworkUtils.isNetWorkAvailable()){ |
||||||
|
TextHelper.showText("无网络连接!"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
pbLoading.setVisibility(View.VISIBLE); |
||||||
|
if (aBooks == null) { |
||||||
|
ChangeSourceDialog csd = new ChangeSourceDialog(this, mBook); |
||||||
|
csd.init(new ResultCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(Object o, int code) { |
||||||
|
aBooks = (ArrayList<Book>) o; |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onError(Exception e) { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
createChangeSourceDia(); |
||||||
|
} |
||||||
|
break; |
||||||
|
case R.id.action_reload: //重新加载
|
||||||
|
initWidget(); |
||||||
|
processLogic(); |
||||||
|
break; |
||||||
|
case R.id.action_open_link: //打开链接
|
||||||
|
Uri uri = Uri.parse(mBook.getChapterUrl()); |
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri); |
||||||
|
startActivity(intent); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
return super.onOptionsItemSelected(item); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
||||||
|
if (requestCode == APPCONST.REQUEST_READ) { |
||||||
|
if (data == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
boolean isCollected = data.getBooleanExtra(APPCONST.RESULT_IS_COLLECTED, false); |
||||||
|
if (isCollected) { |
||||||
|
bookDetailTvAdd.setText("移除书籍"); |
||||||
|
bookDetailTvOpen.setText("继续阅读"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package xyz.fycz.myreader.util.notification; |
||||||
|
|
||||||
|
import android.content.BroadcastReceiver; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import xyz.fycz.myreader.application.MyApplication; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/8/14 22:04 |
||||||
|
*/ |
||||||
|
public class NotificationClickReceiver extends BroadcastReceiver { |
||||||
|
|
||||||
|
public static final String CANCEL_ACTION = "cancelAction"; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onReceive(Context context, Intent intent) { |
||||||
|
//todo 跳转之前要处理的逻辑
|
||||||
|
if (CANCEL_ACTION.equals(intent.getAction())){ |
||||||
|
MyApplication.getApplication().shutdownThreadPool(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,171 @@ |
|||||||
|
package xyz.fycz.myreader.util.notification; |
||||||
|
|
||||||
|
import android.annotation.TargetApi; |
||||||
|
import android.app.*; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
import android.content.pm.ApplicationInfo; |
||||||
|
import android.graphics.BitmapFactory; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.net.Uri; |
||||||
|
import android.os.Build; |
||||||
|
import android.provider.Settings; |
||||||
|
import androidx.appcompat.app.AlertDialog; |
||||||
|
import androidx.core.app.NotificationCompat; |
||||||
|
import androidx.core.app.NotificationManagerCompat; |
||||||
|
import xyz.fycz.myreader.R; |
||||||
|
import xyz.fycz.myreader.application.MyApplication; |
||||||
|
import xyz.fycz.myreader.common.APPCONST; |
||||||
|
import xyz.fycz.myreader.creator.DialogCreator; |
||||||
|
import xyz.fycz.myreader.greendao.service.BookMarkService; |
||||||
|
|
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.lang.reflect.Method; |
||||||
|
|
||||||
|
import static xyz.fycz.myreader.util.notification.NotificationClickReceiver.CANCEL_ACTION; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/8/14 22:07 |
||||||
|
*/ |
||||||
|
public class NotificationUtil { |
||||||
|
private static volatile NotificationUtil sInstance; |
||||||
|
private NotificationManager notificationManager; |
||||||
|
|
||||||
|
public static NotificationUtil getInstance() { |
||||||
|
if (sInstance == null){ |
||||||
|
synchronized (NotificationUtil.class){ |
||||||
|
if (sInstance == null){ |
||||||
|
sInstance = new NotificationUtil(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return sInstance; |
||||||
|
} |
||||||
|
|
||||||
|
public NotificationUtil() { |
||||||
|
notificationManager = (NotificationManager) MyApplication.getmContext().getSystemService(Context.NOTIFICATION_SERVICE); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public NotificationCompat.Builder createBuilder(Context context, String channelId){ |
||||||
|
return new NotificationCompat.Builder(context, channelId); |
||||||
|
} |
||||||
|
|
||||||
|
@TargetApi(26) |
||||||
|
public void createNotificationChannel(String channelId, String channelName) { |
||||||
|
NotificationManager notificationManager = (NotificationManager) MyApplication.getApplication().getSystemService(Context.NOTIFICATION_SERVICE); |
||||||
|
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW); |
||||||
|
channel.enableLights(true);//是否在桌面icon右上角展示小红点
|
||||||
|
channel.setLightColor(Color.RED);//小红点颜色
|
||||||
|
channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
|
||||||
|
notificationManager.createNotificationChannel(channel); |
||||||
|
} |
||||||
|
|
||||||
|
public NotificationCompat.Builder build(String channelId){ |
||||||
|
return new NotificationCompat.Builder(MyApplication.getmContext(), channelId); |
||||||
|
} |
||||||
|
|
||||||
|
public void sendDownloadNotification(String title, String text, PendingIntent pendingIntent){ |
||||||
|
NotificationCompat.Builder builder = build(APPCONST.channelIdDownload) |
||||||
|
.setSmallIcon(R.drawable.ic_download) |
||||||
|
//通知栏大图标
|
||||||
|
.setLargeIcon(BitmapFactory.decodeResource(MyApplication.getApplication().getResources(), R.mipmap.ic_launcher)) |
||||||
|
.setOngoing(true) |
||||||
|
//点击通知后自动清除
|
||||||
|
.setAutoCancel(true) |
||||||
|
.setContentTitle(title) |
||||||
|
.setContentText(text); |
||||||
|
if (pendingIntent == null) { |
||||||
|
pendingIntent = getChancelPendingIntent(NotificationClickReceiver.class); |
||||||
|
} |
||||||
|
builder.addAction(R.drawable.ic_stop_black_24dp, "停止", pendingIntent); |
||||||
|
notificationManager.notify(1000, builder.build()); |
||||||
|
} |
||||||
|
|
||||||
|
public PendingIntent getChancelPendingIntent(Class<?> clz) { |
||||||
|
Intent intent = new Intent(MyApplication.getmContext(), clz); |
||||||
|
intent.setAction(CANCEL_ACTION); |
||||||
|
return PendingIntent.getBroadcast(MyApplication.getmContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); |
||||||
|
} |
||||||
|
|
||||||
|
public void cancel(int id){ |
||||||
|
notificationManager.cancel(id); |
||||||
|
} |
||||||
|
public void cancelAll(){ |
||||||
|
notificationManager.cancelAll(); |
||||||
|
} |
||||||
|
public void notify(int id, Notification notification){ |
||||||
|
notificationManager.notify(id, notification); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 跳到通知栏设置界面 |
||||||
|
* @param context |
||||||
|
*/ |
||||||
|
public void requestNotificationPermission(Context context){ |
||||||
|
if (!isNotificationEnabled(context)) { |
||||||
|
try { |
||||||
|
// 根据isOpened结果,判断是否需要提醒用户跳转AppInfo页面,去打开App通知权限
|
||||||
|
Intent intent = new Intent(); |
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
||||||
|
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); |
||||||
|
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
||||||
|
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); |
||||||
|
intent.putExtra(Settings.EXTRA_CHANNEL_ID, context.getApplicationInfo().uid); |
||||||
|
|
||||||
|
//这种方案适用于 API21——25,即 5.0——7.1 之间的版本可以使用
|
||||||
|
intent.putExtra("app_package", context.getPackageName()); |
||||||
|
intent.putExtra("app_uid", context.getApplicationInfo().uid); |
||||||
|
|
||||||
|
// 小米6 -MIUI9.6-8.0.0系统,是个特例,通知设置界面只能控制"允许使用通知圆点"——然而这个玩意并没有卵用,我想对雷布斯说:I'm not ok!!!
|
||||||
|
if ("MI 6".equals(Build.MODEL)) { |
||||||
|
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); |
||||||
|
Uri uri = Uri.fromParts("package", context.getPackageName(), null); |
||||||
|
intent.setData(uri); |
||||||
|
intent.setAction("com.android.settings/.SubSettings"); |
||||||
|
} |
||||||
|
context.startActivity(intent); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
// 出现异常则跳转到应用设置界面:锤子坚果3——OC105 API25
|
||||||
|
Intent intent = new Intent(); |
||||||
|
//下面这种方案是直接跳转到当前应用的设置界面。
|
||||||
|
//https://blog.csdn.net/ysy950803/article/details/71910806
|
||||||
|
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); |
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
||||||
|
Uri uri = Uri.fromParts("package", context.getPackageName(), null); |
||||||
|
intent.setData(uri); |
||||||
|
context.startActivity(intent); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void requestNotificationPermissionDialog(Context context){ |
||||||
|
if (!isNotificationEnabled(context)) { |
||||||
|
new AlertDialog.Builder(context) |
||||||
|
.setTitle("开启通知") |
||||||
|
.setMessage("检测到未开启通知权限,无法在通知栏查看缓存进度,是否前往开启?") |
||||||
|
.setCancelable(true) |
||||||
|
.setPositiveButton("确定", (dialog, which) -> requestNotificationPermission(context)) |
||||||
|
.setNegativeButton("取消", null) |
||||||
|
.show(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取通知权限 |
||||||
|
* @param context |
||||||
|
*/ |
||||||
|
public boolean isNotificationEnabled(Context context) { |
||||||
|
boolean isOpened = false; |
||||||
|
try { |
||||||
|
NotificationManagerCompat manager = NotificationManagerCompat.from(context); |
||||||
|
isOpened = manager.areNotificationsEnabled(); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return isOpened; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="24dp" |
||||||
|
android:height="24dp" |
||||||
|
android:viewportWidth="1065.0" |
||||||
|
android:viewportHeight="1024.0"> |
||||||
|
<path |
||||||
|
android:pathData="M486.4,1024h-102.4a76.9,76.9 0,0 1,-76.8 -76.8V76.8A76.9,76.9 0,0 1,384 0h102.4a76.9,76.9 0,0 1,76.8 76.8v870.4a76.9,76.9 0,0 1,-76.8 76.8zM384,51.2A25.6,25.6 0,0 0,358.4 76.8v870.4a25.6,25.6 0,0 0,25.6 25.6h102.4a25.6,25.6 0,0 0,25.6 -25.6V76.8a25.6,25.6 0,0 0,-25.6 -25.6zM179.2,1024H76.8A76.9,76.9 0,0 1,0 947.2V128a76.9,76.9 0,0 1,76.8 -76.8H179.2a76.9,76.9 0,0 1,76.8 76.8v819.2A76.9,76.9 0,0 1,179.2 1024zM76.8,102.4a25.6,25.6 0,0 0,-25.6 25.6v819.2a25.6,25.6 0,0 0,25.6 25.6H179.2a25.6,25.6 0,0 0,25.6 -25.6V128A25.6,25.6 0,0 0,179.2 102.4z" |
||||||
|
android:fillColor="@color/black"/> |
||||||
|
<path |
||||||
|
android:pathData="M799.4,636.8l-130.9,-488.6a25.6,25.6 0,0 1,18.1 -31.4l98.9,-26.5a25.3,25.3 0,0 1,6.7 -0.9,25.6 25.6,0 0,1 24.7,19l141.6,528.4h53L866.3,95.2a76.7,76.7 0,0 0,-94.1 -54.3l-98.9,26.5a76.9,76.9 0,0 0,-54.3 94.1l127.4,475.3zM1065.6,841.6h-128v-128h-51.2v128h-128v51.2h128v128h51.2v-128h128v-51.2z" |
||||||
|
android:fillColor="@color/black"/> |
||||||
|
</vector> |
@ -0,0 +1,9 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="24dp" |
||||||
|
android:height="24dp" |
||||||
|
android:viewportWidth="1024.0" |
||||||
|
android:viewportHeight="1024.0"> |
||||||
|
<path |
||||||
|
android:pathData="M911.8,44L663.3,44c-63.7,0 -119.6,33.4 -150.9,83.4 -31.3,-50.1 -87.1,-83.4 -150.8,-83.4L111.3,44c-49,0 -88.7,39.5 -88.7,88.2v706.8c0,48.7 39.7,88.2 88.7,88.2h298.3c22.4,32 59.7,52.9 101.9,52.9 42.2,0 79.5,-20.9 101.9,-52.9h298.3c49,0 88.7,-39.5 88.7,-88.2L1000.6,132.2c0,-48.7 -39.7,-88.2 -88.7,-88.2zM947.3,839c0,9.3 -3.7,18.3 -10.4,24.9a35.8,35.8 0,0 1,-25.1 10.3L580.3,874.3c-7.9,30.4 -35.7,52.9 -68.8,52.9 -33.1,0 -60.9,-22.5 -68.8,-52.9L111.3,874.3c-9.4,0 -18.5,-3.7 -25.1,-10.3a35.2,35.2 0,0 1,-10.4 -24.9L75.8,132.2a35.2,35.2 0,0 1,10.4 -24.9c6.6,-6.6 15.7,-10.3 25.1,-10.3h250.4c68.6,0 124.2,55.3 124.2,123.4v473.5h0.1c1.1,13.8 12.6,24.4 26.5,24.4 13.9,0 25.5,-10.6 26.5,-24.4h0.1L539.1,220.4c0,-68.2 55.6,-123.4 124.2,-123.4h248.5a35.7,35.7 0,0 1,25.1 10.3,35.2 35.2,0 0,1 10.4,24.9v706.8h0z" |
||||||
|
android:fillColor="@color/white"/> |
||||||
|
</vector> |
@ -1,6 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
<item android:drawable="@mipmap/pwd_visiable" android:state_checked="true"/> |
|
||||||
<item android:drawable="@mipmap/pwd_gone" android:state_checked="false"/> |
|
||||||
<item android:drawable="@mipmap/pwd_gone" /> |
|
||||||
</selector> |
|
@ -0,0 +1,79 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<RelativeLayout |
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="@color/white"> |
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout |
||||||
|
android:id="@+id/app_bar" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> |
||||||
|
|
||||||
|
<com.google.android.material.appbar.CollapsingToolbarLayout |
||||||
|
android:id="@+id/toolbar_layout" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:fitsSystemWindows="true" |
||||||
|
app:contentScrim="?attr/colorPrimary" |
||||||
|
app:expandedTitleGravity="top" |
||||||
|
app:expandedTitleMarginStart="114dp" |
||||||
|
app:expandedTitleMarginTop="66dp" |
||||||
|
app:expandedTitleTextAppearance="@style/Base.TextAppearance.AppCompat.Title" |
||||||
|
app:layout_scrollFlags="scroll|exitUntilCollapsed"> |
||||||
|
|
||||||
|
<include layout="@layout/layout_book_detail_header"/> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar |
||||||
|
android:id="@+id/toolbar" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="?attr/actionBarSize" |
||||||
|
app:layout_collapseMode="pin" |
||||||
|
app:popupTheme="@style/Theme.ToolBar.Menu"/> |
||||||
|
|
||||||
|
</com.google.android.material.appbar.CollapsingToolbarLayout> |
||||||
|
</com.google.android.material.appbar.AppBarLayout> |
||||||
|
|
||||||
|
<!--详情简介--> |
||||||
|
<androidx.core.widget.NestedScrollView |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_marginBottom="56dp" |
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"> |
||||||
|
|
||||||
|
<include layout="@layout/layout_book_detail_content"/> |
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView> |
||||||
|
|
||||||
|
<!--底部button--> |
||||||
|
<FrameLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="bottom" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<include layout="@layout/layout_book_detail_bottom"/> |
||||||
|
|
||||||
|
<View |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="1dp" |
||||||
|
android:layout_gravity="top" |
||||||
|
android:background="#140000"/> |
||||||
|
</FrameLayout> |
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout> |
||||||
|
|
||||||
|
<ProgressBar |
||||||
|
android:id="@+id/pb_loading" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_centerInParent="true" |
||||||
|
android:visibility="gone"/> |
||||||
|
</RelativeLayout> |
@ -0,0 +1,43 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<LinearLayout |
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
style="@style/BottomNavigation.GroupView" |
||||||
|
android:background="@color/white"> |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout |
||||||
|
android:id="@+id/fl_add_bookcase" |
||||||
|
style="@style/BottomNavigation.ItemView"> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView |
||||||
|
style="@style/BottomNavigation.ItemView.Icon" |
||||||
|
android:background="@drawable/ic_vector_add_bookcase"/> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_add" |
||||||
|
style="@style/BottomNavigation.ItemView.Title" |
||||||
|
android:text="加入书架" |
||||||
|
android:textColor="@color/black"/> |
||||||
|
|
||||||
|
</FrameLayout> |
||||||
|
|
||||||
|
<FrameLayout |
||||||
|
android:id="@+id/fl_open_book" |
||||||
|
style="@style/BottomNavigation.ItemView" |
||||||
|
android:background="?colorPrimary"> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView |
||||||
|
style="@style/BottomNavigation.ItemView.Icon" |
||||||
|
android:background="@drawable/ic_vector_book_read"/> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_open" |
||||||
|
style="@style/BottomNavigation.ItemView.Title" |
||||||
|
android:text="开始阅读" |
||||||
|
android:textColor="@color/white"/> |
||||||
|
|
||||||
|
</FrameLayout> |
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout> |
@ -0,0 +1,98 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<!--简介--> |
||||||
|
<TextView |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:padding="10dp" |
||||||
|
android:text="简介:" |
||||||
|
android:textColor="@color/black" |
||||||
|
android:textSize="18sp"/> |
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_desc" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginTop="-10dp" |
||||||
|
android:ellipsize="end" |
||||||
|
android:maxLines="5" |
||||||
|
android:padding="15dp" |
||||||
|
android:lineSpacingMultiplier="1.2" |
||||||
|
android:text="简介: " |
||||||
|
android:textColor="@color/title_black" |
||||||
|
android:textSize="16sp" /> |
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:padding="10dp" |
||||||
|
android:orientation="vertical"> |
||||||
|
<TextView |
||||||
|
android:layout_marginTop="5dp" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:lineSpacingMultiplier="1.2" |
||||||
|
android:textSize="14sp" |
||||||
|
android:text="@string/statement" |
||||||
|
android:textColor="@color/title_black" |
||||||
|
/> |
||||||
|
<TextView |
||||||
|
android:id="@+id/tv_disclaimer" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginTop="10dp" |
||||||
|
android:text="@string/disclaimer" |
||||||
|
android:textColor="#2196F3" |
||||||
|
android:textSize="14sp"/> |
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
<View |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="10dp" |
||||||
|
android:background="@color/sys_window_back" |
||||||
|
android:visibility="gone"/> |
||||||
|
|
||||||
|
<!--书籍目录--> |
||||||
|
<RelativeLayout |
||||||
|
android:id="@+id/book_detail_rl_catalog" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:visibility="gone"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_catalog" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:padding="15dp" |
||||||
|
android:text="最新章节" |
||||||
|
android:textColor="@color/black" |
||||||
|
android:textSize="15sp" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_catalog_more" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:gravity="right" |
||||||
|
android:padding="15dp" |
||||||
|
android:text="更多" |
||||||
|
android:textColor="@color/title_black" |
||||||
|
android:textSize="15sp" /> |
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView |
||||||
|
android:id="@+id/book_detail_rv_catalog" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_below="@+id/book_detail_tv_catalog" |
||||||
|
android:foregroundGravity="center" /> |
||||||
|
</RelativeLayout> |
||||||
|
|
||||||
|
|
||||||
|
<!--底部空白,给底部bottom预留位置--> |
||||||
|
<!--<View--> |
||||||
|
<!--android:layout_width="match_parent"--> |
||||||
|
<!--android:layout_height="56dp"--> |
||||||
|
<!--android:background="@color/divider_wide" />--> |
||||||
|
|
||||||
|
</LinearLayout> |
@ -0,0 +1,98 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:background="?colorPrimary" |
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin" |
||||||
|
android:paddingTop="64.0dp" |
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin" |
||||||
|
android:paddingBottom="16.0dp" |
||||||
|
app:layout_collapseMode="parallax" |
||||||
|
app:layout_collapseParallaxMultiplier="0.7"> |
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView |
||||||
|
android:id="@+id/cover" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
app:cardCornerRadius="0dp" |
||||||
|
app:cardElevation="2dp"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/book_detail_iv_cover" |
||||||
|
android:layout_width="82dp" |
||||||
|
android:layout_height="110dp" |
||||||
|
android:scaleType="centerCrop" |
||||||
|
android:background="@color/colorPrimary" |
||||||
|
tools:src="@mipmap/no_image" /> |
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:id="@+id/book_detail_author_type" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_alignTop="@+id/cover" |
||||||
|
android:layout_marginLeft="14dp" |
||||||
|
android:layout_marginTop="30dp" |
||||||
|
android:layout_toRightOf="@+id/cover"> |
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_author" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:ellipsize="end" |
||||||
|
android:maxLines="1" |
||||||
|
android:textColor="@color/white" |
||||||
|
tools:text=" 茶叶蛋" /> |
||||||
|
<TextView |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:text=" | " |
||||||
|
android:textColor="@color/little_black_white"/> |
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_tv_type" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:ellipsize="end" |
||||||
|
android:maxLines="1" |
||||||
|
android:textColor="@color/white" |
||||||
|
tools:text="仙侠" /> |
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_newest_chapter" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_below="@+id/book_detail_author_type" |
||||||
|
android:layout_alignLeft="@id/book_detail_author_type" |
||||||
|
android:layout_marginTop="6dp" |
||||||
|
android:ellipsize="end" |
||||||
|
android:maxLines="1" |
||||||
|
android:textColor="@color/white" |
||||||
|
tools:text="最新章节" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/book_detail_source" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_below="@id/book_detail_newest_chapter" |
||||||
|
android:layout_alignLeft="@id/book_detail_newest_chapter" |
||||||
|
android:layout_marginTop="6dp" |
||||||
|
android:textColor="@color/white" |
||||||
|
tools:text="书源" /> |
||||||
|
|
||||||
|
<!--<TextView--> |
||||||
|
<!--android:id="@+id/book_detail_tv_lately_update"--> |
||||||
|
<!--android:layout_width="wrap_content"--> |
||||||
|
<!--android:layout_height="wrap_content"--> |
||||||
|
<!--android:layout_below="@id/book_detail_tv_author"--> |
||||||
|
<!--android:layout_marginTop="10dp"--> |
||||||
|
<!--android:layout_toRightOf="@id/cover"--> |
||||||
|
<!--android:ellipsize="end"--> |
||||||
|
<!--android:singleLine="true"--> |
||||||
|
<!--android:textColor="@color/textAssist"--> |
||||||
|
<!--android:textSize="13sp"--> |
||||||
|
<!--tools:text="4月前"/>--> |
||||||
|
|
||||||
|
</RelativeLayout> |
@ -0,0 +1,19 @@ |
|||||||
|
<?xml version ="1.0" encoding ="utf-8"?> |
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"> |
||||||
|
|
||||||
|
<item |
||||||
|
android:id="@+id/action_change_source" |
||||||
|
android:icon="@mipmap/ic_menu_exchange" |
||||||
|
android:title="更换书源" |
||||||
|
app:showAsAction="always" /> |
||||||
|
<item |
||||||
|
android:id="@+id/action_reload" |
||||||
|
android:icon="@mipmap/ic_menu_refresh" |
||||||
|
android:title="重新加载"/> |
||||||
|
|
||||||
|
<item |
||||||
|
android:id="@+id/action_open_link" |
||||||
|
android:title="打开链接" /> |
||||||
|
|
||||||
|
</menu> |
After Width: | Height: | Size: 659 B |
After Width: | Height: | Size: 901 B |
Before Width: | Height: | Size: 920 B |
Before Width: | Height: | Size: 1.4 KiB |
@ -1,2 +1,2 @@ |
|||||||
#Wed Aug 12 21:27:50 CST 2020 |
#Sat Aug 15 23:51:09 CST 2020 |
||||||
VERSION_CODE=141 |
VERSION_CODE=142 |
||||||
|
Loading…
Reference in new issue