@ -1,7 +1,6 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="SqlDialectMappings"> |
||||
<file url="file://$PROJECT_DIR$/app/src/main/java/xyz/fycz/myreader/model/backup/UserService.java" dialect="GenericSQL" /> |
||||
<file url="PROJECT" dialect="MySQL" /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,3 @@ |
||||
1、 正确填写WebDAV 服务器地址、WebDAV 账号、WebDAV 密码;(要获得这三项的信息,需要注册一个坚果云账号,如果直接在手机上注册,坚果云会让你下载app,过程比较麻烦,为了一步到位,最好是在电脑上打开这个注册链接:https://www.jianguoyun.com/d/signup;注册后,进入坚果云;点击右上角账户名处选择 “账户信息”,然后选择“安全选项”;在“安全选项” 中找到“第三方应用管理”,并选择“添加应用”,输入名称如“阅读”后,会生成密码,选择完成;其中https://dav.jianguoyun.com/dav/就是填入“WebDAV 服务器地址”的内容,“使用情况”后面的邮箱地址就是你的“WebDAV 账号”,点击显示密码后得到的密码就是你的“WebDAV 密码”。) |
||||
|
||||
2、 无需操作,APP默认每天自动云备份一次。 |
@ -1,244 +0,0 @@ |
||||
package xyz.fycz.myreader.base; |
||||
|
||||
import android.annotation.SuppressLint; |
||||
import android.content.Intent; |
||||
import android.graphics.PorterDuff; |
||||
import android.graphics.drawable.Drawable; |
||||
import android.os.Bundle; |
||||
|
||||
import android.view.Menu; |
||||
import android.view.MenuItem; |
||||
import androidx.annotation.LayoutRes; |
||||
import androidx.annotation.Nullable; |
||||
import androidx.appcompat.app.ActionBar; |
||||
import androidx.appcompat.app.AppCompatActivity; |
||||
import androidx.appcompat.app.AppCompatDelegate; |
||||
import androidx.appcompat.widget.Toolbar; |
||||
import butterknife.ButterKnife; |
||||
import butterknife.Unbinder; |
||||
|
||||
import io.reactivex.disposables.CompositeDisposable; |
||||
import io.reactivex.disposables.Disposable; |
||||
import xyz.fycz.myreader.ActivityManage; |
||||
import xyz.fycz.myreader.R; |
||||
import xyz.fycz.myreader.application.MyApplication; |
||||
import xyz.fycz.myreader.application.SysManager; |
||||
import xyz.fycz.myreader.entity.Setting; |
||||
import xyz.fycz.myreader.util.StatusBarUtil; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.util.ArrayList; |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2020/8/12 20:02 |
||||
*/ |
||||
public abstract class BaseActivity2 extends AppCompatActivity { |
||||
private static final int INVALID_VAL = -1; |
||||
|
||||
protected CompositeDisposable mDisposable; |
||||
//ButterKnife
|
||||
private Toolbar mToolbar; |
||||
|
||||
private Unbinder unbinder; |
||||
|
||||
private int curNightMode; |
||||
/****************************abstract area*************************************/ |
||||
|
||||
@LayoutRes |
||||
protected abstract int getContentId(); |
||||
|
||||
/************************init area************************************/ |
||||
protected void addDisposable(Disposable d){ |
||||
if (mDisposable == null){ |
||||
mDisposable = new CompositeDisposable(); |
||||
} |
||||
mDisposable.add(d); |
||||
} |
||||
|
||||
/** |
||||
* 配置Toolbar |
||||
* @param toolbar |
||||
*/ |
||||
protected void setUpToolbar(Toolbar toolbar){ |
||||
} |
||||
|
||||
protected void initData(Bundle savedInstanceState){ |
||||
} |
||||
/** |
||||
* 初始化零件 |
||||
*/ |
||||
protected void initWidget() { |
||||
|
||||
} |
||||
/** |
||||
* 初始化点击事件 |
||||
*/ |
||||
protected void initClick(){ |
||||
} |
||||
/** |
||||
* 逻辑使用区 |
||||
*/ |
||||
protected void processLogic(){ |
||||
} |
||||
/** |
||||
* @return 是否夜间模式 |
||||
*/ |
||||
protected boolean isNightTheme() { |
||||
return !SysManager.getSetting().isDayStyle(); |
||||
} |
||||
|
||||
/** |
||||
* 设置夜间模式 |
||||
* @param isNightMode |
||||
*/ |
||||
protected void setNightTheme(boolean isNightMode) { |
||||
Setting setting = SysManager.getSetting(); |
||||
setting.setDayStyle(!isNightMode); |
||||
MyApplication.getApplication().initNightTheme(); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
/*************************lifecycle area*****************************************************/ |
||||
|
||||
@Override |
||||
protected void onCreate(@Nullable Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
initTheme(); |
||||
ActivityManage.addActivity(this); |
||||
setContentView(getContentId()); |
||||
initData(savedInstanceState); |
||||
unbinder = ButterKnife.bind(this); |
||||
initToolbar(); |
||||
initWidget(); |
||||
initClick(); |
||||
processLogic(); |
||||
} |
||||
|
||||
private void initToolbar(){ |
||||
//更严谨是通过反射判断是否存在Toolbar
|
||||
mToolbar = findViewById(R.id.toolbar); |
||||
if (mToolbar != null){ |
||||
supportActionBar(mToolbar); |
||||
setUpToolbar(mToolbar); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onResume() { |
||||
super.onResume(); |
||||
if (isThemeChange()){ |
||||
recreate(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onDestroy() { |
||||
super.onDestroy(); |
||||
ActivityManage.removeActivity(this); |
||||
unbinder.unbind(); |
||||
if (mDisposable != null){ |
||||
mDisposable.dispose(); |
||||
} |
||||
} |
||||
/** |
||||
* 初始化主题 |
||||
*/ |
||||
public void initTheme() { |
||||
//if (isNightTheme()) {
|
||||
//setTheme(R.style.AppNightTheme);
|
||||
curNightMode = AppCompatDelegate.getDefaultNightMode(); |
||||
/*} else { |
||||
//curNightMode = false;
|
||||
//setTheme(R.style.AppDayTheme);
|
||||
}*/ |
||||
} |
||||
|
||||
protected boolean isThemeChange(){ |
||||
return curNightMode != AppCompatDelegate.getDefaultNightMode(); |
||||
} |
||||
/**************************used method area*******************************************/ |
||||
|
||||
protected void startActivity(Class<? extends AppCompatActivity> activity){ |
||||
Intent intent = new Intent(this, activity); |
||||
startActivity(intent); |
||||
} |
||||
|
||||
protected ActionBar supportActionBar(Toolbar toolbar){ |
||||
setSupportActionBar(toolbar); |
||||
ActionBar actionBar = getSupportActionBar(); |
||||
if (actionBar != null){ |
||||
actionBar.setDisplayHomeAsUpEnabled(true); |
||||
actionBar.setDisplayShowHomeEnabled(true); |
||||
} |
||||
mToolbar.setNavigationOnClickListener( |
||||
(v) -> finish() |
||||
); |
||||
return actionBar; |
||||
} |
||||
|
||||
protected void setStatusBarColor(int statusColor, boolean dark){ |
||||
//沉浸式代码配置
|
||||
//当FitsSystemWindows设置 true 时,会在屏幕最上方预留出状态栏高度的 padding
|
||||
StatusBarUtil.setRootViewFitsSystemWindows(this, true); |
||||
//设置状态栏透明
|
||||
StatusBarUtil.setTranslucentStatus(this); |
||||
StatusBarUtil.setStatusBarColor(this, getResources().getColor(statusColor)); |
||||
|
||||
//一般的手机的状态栏文字和图标都是白色的, 可如果你的应用也是纯白色的, 或导致状态栏文字看不清
|
||||
//所以如果你是这种情况,请使用以下代码, 设置状态使用深色文字图标风格, 否则你可以选择性注释掉这个if内容
|
||||
if (!dark) { |
||||
if (!StatusBarUtil.setStatusBarDarkTheme(this, true)) { |
||||
//如果不支持设置深色风格 为了兼容总不能让状态栏白白的看不清, 于是设置一个状态栏颜色为半透明,
|
||||
//这样半透明+白=灰, 状态栏的文字能看得清
|
||||
StatusBarUtil.setStatusBarColor(this, 0x55000000); |
||||
} |
||||
} |
||||
} /** |
||||
* 设置MENU图标颜色 |
||||
*/ |
||||
@Override |
||||
public boolean onCreateOptionsMenu(Menu menu) { |
||||
for (int i = 0; i < menu.size(); i++) { |
||||
Drawable drawable = menu.getItem(i).getIcon(); |
||||
if (drawable != null) { |
||||
drawable.mutate(); |
||||
drawable.setColorFilter(getColor(R.color.textPrimary), PorterDuff.Mode.SRC_ATOP); |
||||
} |
||||
} |
||||
return super.onCreateOptionsMenu(menu); |
||||
} |
||||
|
||||
@SuppressLint("PrivateApi") |
||||
@SuppressWarnings("unchecked") |
||||
@Override |
||||
public boolean onMenuOpened(int featureId, Menu menu) { |
||||
if (menu != null) { |
||||
//展开菜单显示图标
|
||||
if (menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) { |
||||
try { |
||||
Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); |
||||
method.setAccessible(true); |
||||
method.invoke(menu, true); |
||||
method = menu.getClass().getDeclaredMethod("getNonActionItems"); |
||||
ArrayList<MenuItem> menuItems = (ArrayList<MenuItem>) method.invoke(menu); |
||||
if (!menuItems.isEmpty()) { |
||||
for (MenuItem menuItem : menuItems) { |
||||
Drawable drawable = menuItem.getIcon(); |
||||
if (drawable != null) { |
||||
drawable.mutate(); |
||||
drawable.setColorFilter(getResources().getColor(R.color.textPrimary), PorterDuff.Mode.SRC_ATOP); |
||||
} |
||||
} |
||||
} |
||||
} catch (Exception ignored) { |
||||
} |
||||
} |
||||
|
||||
} |
||||
return super.onMenuOpened(featureId, menu); |
||||
} |
||||
|
||||
} |
@ -1,129 +0,0 @@ |
||||
package xyz.fycz.myreader.model.backup; |
||||
|
||||
import xyz.fycz.myreader.application.SysManager; |
||||
import xyz.fycz.myreader.common.APPCONST; |
||||
import xyz.fycz.myreader.entity.Setting; |
||||
import xyz.fycz.myreader.greendao.entity.Book; |
||||
import xyz.fycz.myreader.greendao.service.BookService; |
||||
import xyz.fycz.myreader.util.IOUtils; |
||||
import xyz.fycz.myreader.util.utils.FileUtils; |
||||
import java.io.*; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2020/4/25 9:07 |
||||
*/ |
||||
|
||||
public class BackupAndRestore { |
||||
|
||||
BookService mBookService = BookService.getInstance(); |
||||
|
||||
/** |
||||
* 备份书架 |
||||
* @return 是否备份成功 |
||||
*/ |
||||
public boolean backup(String backupName){ |
||||
List<Book> books = mBookService.getAllBooks(); |
||||
StringBuilder s = new StringBuilder(); |
||||
for (Book book : books) { |
||||
s.append(book); |
||||
s.append(",\n"); |
||||
} |
||||
s.deleteCharAt(s.lastIndexOf(",")); |
||||
File booksFile = FileUtils.getFile(APPCONST.FILE_DIR + backupName + "/books" + FileUtils.SUFFIX_FY); |
||||
File settingFile = FileUtils.getFile(APPCONST.FILE_DIR + backupName + "/setting" + FileUtils.SUFFIX_FY); |
||||
BufferedWriter bw = null; |
||||
ObjectOutputStream oos = null; |
||||
try { |
||||
bw = new BufferedWriter(new FileWriter(booksFile)); |
||||
bw.write(s.toString()); |
||||
bw.flush(); |
||||
oos = new ObjectOutputStream(new FileOutputStream(settingFile)); |
||||
oos.writeObject(SysManager.getSetting()); |
||||
oos.flush(); |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
IOUtils.close(bw, oos); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 恢复书架 |
||||
* @return 是否恢复成功 |
||||
*/ |
||||
public boolean restore(String backupName) { |
||||
File booksFile = FileUtils.getFile(APPCONST.FILE_DIR + backupName + "/books" + FileUtils.SUFFIX_FY); |
||||
File settingFile = FileUtils.getFile(APPCONST.FILE_DIR + backupName + "/setting" + FileUtils.SUFFIX_FY); |
||||
if (!booksFile.exists() || !settingFile.exists()){ |
||||
return false; |
||||
} |
||||
BufferedReader br = null; |
||||
ObjectInputStream ois = null; |
||||
try { |
||||
br = new BufferedReader(new FileReader(booksFile)); |
||||
String tem = ""; |
||||
StringBuilder s = new StringBuilder(); |
||||
while ((tem = br.readLine()) != null){ |
||||
s.append(tem).append("\n"); |
||||
} |
||||
String[] sBooks = s.toString().split("\\},"); |
||||
List<Book> books = new ArrayList<>(); |
||||
for (String sBook : sBooks){ |
||||
sBook.replace("{", ""); |
||||
sBook.replace("}", ""); |
||||
String[] sBookFields = sBook.split(",\n"); |
||||
for (int i = 0; i < sBookFields.length; i++) { |
||||
sBookFields[i] = sBookFields[i].substring(sBookFields[i].indexOf("'") + 1, sBookFields[i].lastIndexOf("'")); |
||||
} |
||||
String source = "null"; |
||||
boolean isCloseUpdate = false; |
||||
boolean isDownloadAll = true; |
||||
String group = "allBook"; |
||||
String infoUrl = ""; |
||||
if(!sBookFields[2].contains("novel.fycz.xyz")){ |
||||
source = sBookFields[17]; |
||||
} |
||||
if ("本地书籍".equals(sBookFields[4])){ |
||||
sBookFields[15] = "0"; |
||||
} |
||||
if (sBookFields.length >= 19){ |
||||
isCloseUpdate = Boolean.parseBoolean(sBookFields[18]); |
||||
} |
||||
if (sBookFields.length >= 20){ |
||||
isDownloadAll = Boolean.parseBoolean(sBookFields[19]); |
||||
} |
||||
if (sBookFields.length >= 21){ |
||||
group = sBookFields[20]; |
||||
} |
||||
if (sBookFields.length >= 22){ |
||||
infoUrl = sBookFields[21]; |
||||
} |
||||
Book book = new Book(sBookFields[0], sBookFields[1], sBookFields[2], infoUrl, sBookFields[3], sBookFields[4], |
||||
sBookFields[5], sBookFields[6], sBookFields[7], sBookFields[8], sBookFields[9], sBookFields[10], |
||||
sBookFields[11], Integer.parseInt(sBookFields[12]), Integer.parseInt(sBookFields[13]), |
||||
Integer.parseInt(sBookFields[14]), Integer.parseInt(sBookFields[15]), Integer.parseInt(sBookFields[16]) |
||||
, source, isCloseUpdate, isDownloadAll, group, 0); |
||||
books.add(book); |
||||
} |
||||
mBookService.deleteAllBooks(); |
||||
mBookService.addBooks(books); |
||||
ois = new ObjectInputStream(new FileInputStream(settingFile)); |
||||
Object obj = ois.readObject(); |
||||
if (obj instanceof Setting){ |
||||
Setting setting = (Setting) obj; |
||||
SysManager.saveSetting(setting); |
||||
} |
||||
return true; |
||||
} catch (IOException | ClassNotFoundException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
IOUtils.close(br, ois); |
||||
} |
||||
} |
||||
} |
@ -1,333 +0,0 @@ |
||||
package xyz.fycz.myreader.model.backup; |
||||
|
||||
import io.reactivex.annotations.NonNull; |
||||
import xyz.fycz.myreader.application.MyApplication; |
||||
import xyz.fycz.myreader.model.storage.Backup; |
||||
import xyz.fycz.myreader.model.storage.Restore; |
||||
import xyz.fycz.myreader.webapi.callback.ResultCallback; |
||||
import xyz.fycz.myreader.common.APPCONST; |
||||
import xyz.fycz.myreader.common.URLCONST; |
||||
import xyz.fycz.myreader.util.*; |
||||
import xyz.fycz.myreader.util.utils.FileUtils; |
||||
|
||||
import java.io.*; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2020/4/26 11:03 |
||||
*/ |
||||
public class UserService { |
||||
/** |
||||
* 登录 |
||||
* @param userLoginInfo 用户名输入的用户名和密码等登录信息 |
||||
* @return 是否成功登录 |
||||
*/ |
||||
public static void login(final Map<String, String> userLoginInfo, final ResultCallback resultCallback) { |
||||
MyApplication.getApplication().newThread(() -> { |
||||
HttpURLConnection conn = null; |
||||
try { |
||||
URL url = new URL(URLCONST.APP_WEB_URL + "login"); |
||||
conn = (HttpURLConnection) url.openConnection(); |
||||
conn.setRequestMethod("POST"); |
||||
conn.setConnectTimeout(60 * 1000); |
||||
conn.setReadTimeout(60 * 1000); |
||||
conn.setDoInput(true); |
||||
conn.setDoOutput(true); |
||||
String params = "username=" + userLoginInfo.get("loginName") + |
||||
"&password=" + userLoginInfo.get("loginPwd") + makeSignalParam(); |
||||
// 获取URLConnection对象对应的输出流
|
||||
PrintWriter out = new PrintWriter(conn.getOutputStream()); |
||||
// 发送请求参数
|
||||
out.print(params); |
||||
// flush输出流的缓冲
|
||||
out.flush(); |
||||
InputStream in = conn.getInputStream(); |
||||
BufferedReader bw = new BufferedReader(new InputStreamReader(in, "utf-8")); |
||||
StringBuilder sb = new StringBuilder(); |
||||
String line = bw.readLine(); |
||||
while (line != null) { |
||||
sb.append(line); |
||||
line = bw.readLine(); |
||||
} |
||||
resultCallback.onFinish(sb.toString(), 1); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
resultCallback.onError(e); |
||||
}finally { |
||||
if (conn != null) { |
||||
conn.disconnect(); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public static void register(final Map<String, String> userRegisterInfo, final ResultCallback resultCallback) { |
||||
MyApplication.getApplication().newThread(() -> { |
||||
HttpURLConnection conn = null; |
||||
try { |
||||
URL url = new URL(URLCONST.APP_WEB_URL + "reg"); |
||||
conn = (HttpURLConnection) url.openConnection(); |
||||
conn.setRequestMethod("POST"); |
||||
conn.setDoInput(true); |
||||
conn.setDoOutput(true); |
||||
String params = "username=" + userRegisterInfo.get("username") + "&password=" + |
||||
CyptoUtils.encode(APPCONST.KEY, userRegisterInfo.get("password")) + "&key=" + |
||||
CyptoUtils.encode(APPCONST.KEY, APPCONST.publicKey) + makeSignalParam(); |
||||
// 获取URLConnection对象对应的输出流
|
||||
PrintWriter out = new PrintWriter(conn.getOutputStream()); |
||||
// 发送请求参数
|
||||
out.print(params); |
||||
// flush输出流的缓冲
|
||||
out.flush(); |
||||
BufferedReader bw = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); |
||||
StringBuilder sb = new StringBuilder(); |
||||
String line = bw.readLine(); |
||||
while (line != null) { |
||||
sb.append(line); |
||||
line = bw.readLine(); |
||||
} |
||||
resultCallback.onFinish(sb.toString(), 1); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
resultCallback.onError(e); |
||||
} finally { |
||||
if (conn != null) { |
||||
conn.disconnect(); |
||||
} |
||||
} |
||||
|
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 写配置 |
||||
* @param userLoginInfo |
||||
* @return |
||||
*/ |
||||
public static boolean writeConfig(Map<String,String> userLoginInfo){ |
||||
FileOutputStream fos = null; |
||||
try { |
||||
fos = MyApplication.getApplication().openFileOutput("userConfig.fy", MyApplication.getApplication().MODE_PRIVATE); |
||||
String userInfo = "username='" + userLoginInfo.get("loginName") + "',\npassword='" + userLoginInfo.get("loginPwd") + "'"; |
||||
byte[] bs = userInfo.getBytes(); |
||||
fos.write(bs); |
||||
//写完后一定要刷新
|
||||
fos.flush(); |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
IOUtils.close(fos); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 读配置 |
||||
* @return |
||||
*/ |
||||
public static Map<String,String> readConfig(){ |
||||
File file = MyApplication.getApplication().getFileStreamPath("userConfig.fy"); |
||||
if (!file.exists()){ |
||||
return null; |
||||
} |
||||
BufferedReader br = null; |
||||
try { |
||||
br = new BufferedReader(new FileReader(file)); |
||||
String tem; |
||||
StringBuilder config = new StringBuilder(); |
||||
while ((tem = br.readLine()) != null){ |
||||
config.append(tem); |
||||
} |
||||
String[] user = config.toString().split(","); |
||||
String userName = user[0].substring(user[0].indexOf("'") + 1, user[0].lastIndexOf("'")); |
||||
String password = user[1].substring(user[1].indexOf("'") + 1, user[1].lastIndexOf("'")); |
||||
Map<String,String> userInfo = new HashMap<>(); |
||||
userInfo.put("userName", userName); |
||||
userInfo.put("password", password); |
||||
return userInfo; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
}finally { |
||||
IOUtils.close(br); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static void writeUsername(String username){ |
||||
File file = FileUtils.getFile(APPCONST.QQ_DATA_DIR + "user"); |
||||
BufferedWriter bw = null; |
||||
try { |
||||
bw = new BufferedWriter(new FileWriter(file)); |
||||
bw.write(username); |
||||
bw.flush(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
}finally { |
||||
IOUtils.close(bw); |
||||
} |
||||
} |
||||
|
||||
public static String readUsername(){ |
||||
File file = new File(APPCONST.QQ_DATA_DIR + "user"); |
||||
if (!file.exists()){ |
||||
return ""; |
||||
} |
||||
BufferedReader br = null; |
||||
try { |
||||
br = new BufferedReader(new FileReader(file)); |
||||
return br.readLine(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return ""; |
||||
} finally { |
||||
IOUtils.close(br); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 网络备份 |
||||
* @return |
||||
*/ |
||||
public static void webBackup(ResultCallback rc){ |
||||
Map<String,String> userInfo = readConfig(); |
||||
if (userInfo == null){ |
||||
rc.onFinish(false, 0); |
||||
} |
||||
Backup.INSTANCE.backup(MyApplication.getmContext(), APPCONST.FILE_DIR + "webBackup/", new Backup.CallBack() { |
||||
@Override |
||||
public void backupSuccess() { |
||||
MyApplication.getApplication().newThread(() ->{ |
||||
File inputFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup"); |
||||
if (!inputFile.exists()) { |
||||
rc.onFinish(false, 0); |
||||
} |
||||
File zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip"); |
||||
FileInputStream fis = null; |
||||
HttpURLConnection conn = null; |
||||
try { |
||||
//压缩文件
|
||||
ZipUtils.zipFile(inputFile, zipFile); |
||||
fis = new FileInputStream(zipFile); |
||||
URL url = new URL(URLCONST.APP_WEB_URL + "bak?username=" + userInfo.get("userName") + |
||||
makeSignalParam()); |
||||
conn = (HttpURLConnection) url.openConnection(); |
||||
conn.setRequestMethod("POST"); |
||||
conn.setRequestProperty("Content-type", "multipart/form-data"); |
||||
conn.setDoInput(true); |
||||
conn.setDoOutput(true); |
||||
OutputStream out = conn.getOutputStream(); |
||||
byte[] bytes = new byte[1024]; |
||||
int len = -1; |
||||
while ((len = fis.read(bytes)) != -1){ |
||||
out.write(bytes, 0, len); |
||||
} |
||||
out.flush(); |
||||
zipFile.delete(); |
||||
BufferedReader bw = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); |
||||
StringBuilder sb = new StringBuilder(); |
||||
String line = bw.readLine(); |
||||
while (line != null) { |
||||
sb.append(line); |
||||
line = bw.readLine(); |
||||
} |
||||
String[] info = sb.toString().split(":"); |
||||
int code = Integer.parseInt(info[0].trim()); |
||||
rc.onFinish(code == 104, 0); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
rc.onError(e); |
||||
} finally { |
||||
IOUtils.close(fis); |
||||
if (conn != null) { |
||||
conn.disconnect(); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public void backupError(@NonNull String msg) { |
||||
ToastUtils.showError(msg); |
||||
rc.onFinish(false, 0); |
||||
} |
||||
}, false); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 网络恢复 |
||||
* @return |
||||
*/ |
||||
public static void webRestore(ResultCallback rc){ |
||||
Map<String,String> userInfo = readConfig(); |
||||
if (userInfo == null){ |
||||
rc.onFinish(false, 0); |
||||
} |
||||
FileOutputStream fos = null; |
||||
File zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip"); |
||||
HttpURLConnection conn = null; |
||||
try { |
||||
URL url = new URL(URLCONST.APP_WEB_URL + "ret?username=" + userInfo.get("userName") + |
||||
makeSignalParam()); |
||||
conn = (HttpURLConnection) url.openConnection(); |
||||
conn.setRequestMethod("POST"); |
||||
conn.setDoInput(true); |
||||
InputStream is = conn.getInputStream(); |
||||
fos = new FileOutputStream(zipFile); |
||||
//一边读,一边写
|
||||
byte[] bytes = new byte[512]; |
||||
int readCount = 0; |
||||
while ((readCount = is.read(bytes)) != -1) { |
||||
fos.write(bytes,0, readCount); |
||||
} |
||||
//刷新,输出流一定要刷新
|
||||
fos.flush(); |
||||
if (zipFile.length() == 0){ |
||||
zipFile.delete(); |
||||
rc.onFinish(false, 0); |
||||
} |
||||
ZipUtils.unzipFile(zipFile.getAbsolutePath(), APPCONST.FILE_DIR); |
||||
Restore.INSTANCE.restore(APPCONST.FILE_DIR + "webBackup/", new Restore.CallBack() { |
||||
@Override |
||||
public void restoreSuccess() { |
||||
zipFile.delete(); |
||||
rc.onFinish(true, 0); |
||||
} |
||||
|
||||
@Override |
||||
public void restoreError(@NonNull String msg) { |
||||
ToastUtils.showError(msg); |
||||
rc.onFinish(false, 0); |
||||
} |
||||
}); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
rc.onError(e); |
||||
}finally { |
||||
IOUtils.close(fos); |
||||
if (conn != null) { |
||||
conn.disconnect(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
private static String makeSignalParam(){ |
||||
return "&signal=" + AppInfoUtils.getSingInfo(MyApplication.getmContext(), |
||||
MyApplication.getApplication().getPackageName(), AppInfoUtils.SHA1); |
||||
} |
||||
|
||||
/** |
||||
* 判断是否登录 |
||||
* @return |
||||
*/ |
||||
public static boolean isLogin(){ |
||||
File file = MyApplication.getApplication().getFileStreamPath("userConfig.fy"); |
||||
return file.exists(); |
||||
} |
||||
} |
@ -1,231 +0,0 @@ |
||||
package xyz.fycz.myreader.ui.activity; |
||||
|
||||
import android.annotation.SuppressLint; |
||||
import android.app.Activity; |
||||
import android.app.ProgressDialog; |
||||
import android.content.Intent; |
||||
import android.graphics.Bitmap; |
||||
import android.os.Bundle; |
||||
import android.os.Handler; |
||||
import android.os.Message; |
||||
import android.text.Editable; |
||||
import android.text.TextWatcher; |
||||
import android.view.MotionEvent; |
||||
import android.view.View; |
||||
import android.view.inputmethod.InputMethodManager; |
||||
import android.widget.Button; |
||||
import android.widget.ImageView; |
||||
import android.widget.TextView; |
||||
import androidx.appcompat.widget.Toolbar; |
||||
import butterknife.BindView; |
||||
import com.google.android.material.textfield.TextInputLayout; |
||||
import xyz.fycz.myreader.R; |
||||
import xyz.fycz.myreader.model.backup.UserService; |
||||
import xyz.fycz.myreader.base.BaseActivity2; |
||||
import xyz.fycz.myreader.webapi.callback.ResultCallback; |
||||
import xyz.fycz.myreader.common.APPCONST; |
||||
import xyz.fycz.myreader.ui.dialog.DialogCreator; |
||||
import xyz.fycz.myreader.util.CodeUtil; |
||||
import xyz.fycz.myreader.util.CyptoUtils; |
||||
import xyz.fycz.myreader.util.ToastUtils; |
||||
import xyz.fycz.myreader.util.utils.NetworkUtils; |
||||
import xyz.fycz.myreader.util.utils.StringUtils; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2020/9/18 22:27 |
||||
*/ |
||||
public class LoginActivity extends BaseActivity2 implements TextWatcher { |
||||
@BindView(R.id.et_user) |
||||
TextInputLayout user; |
||||
@BindView(R.id.et_password) |
||||
TextInputLayout password; |
||||
@BindView(R.id.bt_login) |
||||
Button loginBtn; |
||||
@BindView(R.id.tv_register) |
||||
TextView tvRegister; |
||||
@BindView(R.id.et_captcha) |
||||
TextInputLayout etCaptcha; |
||||
@BindView(R.id.iv_captcha) |
||||
ImageView ivCaptcha; |
||||
|
||||
private String code; |
||||
|
||||
@SuppressLint("HandlerLeak") |
||||
private Handler mHandler = new Handler() { |
||||
@SuppressLint("HandlerLeak") |
||||
@Override |
||||
public void handleMessage(Message msg) { |
||||
switch (msg.what) { |
||||
case 1: |
||||
loginBtn.setEnabled(true); |
||||
break; |
||||
case 2: |
||||
createCaptcha(); |
||||
break; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
@Override |
||||
protected int getContentId() { |
||||
return R.layout.activity_login; |
||||
} |
||||
|
||||
@Override |
||||
protected void setUpToolbar(Toolbar toolbar) { |
||||
super.setUpToolbar(toolbar); |
||||
setStatusBarColor(R.color.colorPrimary, true); |
||||
getSupportActionBar().setTitle("登录"); |
||||
} |
||||
|
||||
@Override |
||||
protected void initData(Bundle savedInstanceState) { |
||||
super.initData(savedInstanceState); |
||||
} |
||||
|
||||
@Override |
||||
protected void initWidget() { |
||||
super.initWidget(); |
||||
mHandler.sendMessage(mHandler.obtainMessage(2)); |
||||
String username = UserService.readUsername(); |
||||
user.getEditText().setText(username); |
||||
user.getEditText().requestFocus(username.length()); |
||||
//监听内容改变 -> 控制按钮的点击状态
|
||||
user.getEditText().addTextChangedListener(this); |
||||
password.getEditText().addTextChangedListener(this); |
||||
etCaptcha.getEditText().addTextChangedListener(this); |
||||
} |
||||
|
||||
@Override |
||||
protected void initClick() { |
||||
super.initClick(); |
||||
ivCaptcha.setOnClickListener(v -> mHandler.sendMessage(mHandler.obtainMessage(2))); |
||||
|
||||
loginBtn.setOnClickListener(v -> { |
||||
mHandler.sendMessage(mHandler.obtainMessage(2)); |
||||
if (!code.toLowerCase().equals(etCaptcha.getEditText().getText().toString().toLowerCase())){ |
||||
DialogCreator.createTipDialog(this, "验证码错误!"); |
||||
return; |
||||
} |
||||
if (!NetworkUtils.isNetWorkAvailable()) { |
||||
ToastUtils.showError("无网络连接!"); |
||||
return; |
||||
} |
||||
ProgressDialog dialog = DialogCreator.createProgressDialog(this, null, "正在登陆..."); |
||||
loginBtn.setEnabled(false); |
||||
final String loginName = user.getEditText().getText().toString().trim(); |
||||
String loginPwd = password.getEditText().getText().toString(); |
||||
final Map<String, String> userLoginInfo = new HashMap<>(); |
||||
userLoginInfo.put("loginName", loginName); |
||||
userLoginInfo.put("loginPwd", CyptoUtils.encode(APPCONST.KEY, loginPwd)); |
||||
//验证用户名和密码
|
||||
UserService.login(userLoginInfo, new ResultCallback() { |
||||
@Override |
||||
public void onFinish(Object o, int code) { |
||||
String result = (String) o; |
||||
String[] info = result.split(":"); |
||||
int resultCode = Integer.parseInt(info[0].trim()); |
||||
String resultName = info[1].trim(); |
||||
//最后输出结果
|
||||
if (resultCode == 102) { |
||||
UserService.writeConfig(userLoginInfo); |
||||
UserService.writeUsername(loginName); |
||||
Intent intent = new Intent(); |
||||
intent.putExtra("isLogin", true); |
||||
setResult(Activity.RESULT_OK, intent); |
||||
finish(); |
||||
ToastUtils.showSuccess(resultName); |
||||
} else { |
||||
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||
dialog.dismiss(); |
||||
ToastUtils.showWarring(resultName); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void onError(Exception e) { |
||||
ToastUtils.showError("登录失败\n" + e.getLocalizedMessage()); |
||||
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||
dialog.dismiss(); |
||||
} |
||||
}); |
||||
|
||||
}); |
||||
|
||||
tvRegister.setOnClickListener(v -> { |
||||
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); |
||||
startActivity(intent); |
||||
}); |
||||
} |
||||
|
||||
public void createCaptcha() { |
||||
code = CodeUtil.getInstance().createCode(); |
||||
Bitmap codeBitmap = CodeUtil.getInstance().createBitmap(code); |
||||
ivCaptcha.setImageBitmap(codeBitmap); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 当有控件获得焦点focus 自动弹出键盘 |
||||
* 1. 点击软键盘的enter键 自动收回键盘 |
||||
* 2. 代码控制 InputMethodManager |
||||
* requestFocus |
||||
* showSoftInput:显示键盘 必须先让这个view成为焦点requestFocus |
||||
* |
||||
* hideSoftInputFromWindow 隐藏键盘 |
||||
*/ |
||||
@Override |
||||
public boolean onTouchEvent(MotionEvent event) { |
||||
if (event.getAction() == MotionEvent.ACTION_DOWN){ |
||||
//隐藏键盘
|
||||
//1.获取系统输入的管理器
|
||||
InputMethodManager inputManager = |
||||
(InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); |
||||
|
||||
//2.隐藏键盘
|
||||
inputManager.hideSoftInputFromWindow(user.getWindowToken(),0); |
||||
|
||||
//3.取消焦点
|
||||
View focusView = getCurrentFocus(); |
||||
if (focusView != null) { |
||||
focusView.clearFocus(); //取消焦点
|
||||
} |
||||
|
||||
//getCurrentFocus().clearFocus();
|
||||
|
||||
//focusView.requestFocus();//请求焦点
|
||||
} |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void afterTextChanged(Editable s) { |
||||
//禁止输入中文
|
||||
StringUtils.isNotChinese(s); |
||||
//判断两个输入框是否有内容
|
||||
if (user.getEditText().getText().toString().length() > 0 && |
||||
password.getEditText().getText().toString().length() > 0 && |
||||
etCaptcha.getEditText().getText().toString().length() > 0){ |
||||
//按钮可以点击
|
||||
loginBtn.setEnabled(true); |
||||
}else{ |
||||
//按钮不能点击
|
||||
loginBtn.setEnabled(false); |
||||
} |
||||
} |
||||
} |
@ -1,271 +0,0 @@ |
||||
package xyz.fycz.myreader.ui.activity; |
||||
|
||||
import android.annotation.SuppressLint; |
||||
import android.app.ProgressDialog; |
||||
import android.graphics.Bitmap; |
||||
import android.os.Handler; |
||||
import android.os.Message; |
||||
import android.text.Editable; |
||||
import android.text.TextWatcher; |
||||
import android.text.method.LinkMovementMethod; |
||||
import android.view.View; |
||||
import android.widget.Button; |
||||
import android.widget.CheckBox; |
||||
import android.widget.ImageView; |
||||
import android.widget.TextView; |
||||
import androidx.appcompat.widget.Toolbar; |
||||
import butterknife.BindView; |
||||
import com.google.android.material.textfield.TextInputLayout; |
||||
import xyz.fycz.myreader.R; |
||||
import xyz.fycz.myreader.model.backup.UserService; |
||||
import xyz.fycz.myreader.base.BaseActivity2; |
||||
import xyz.fycz.myreader.webapi.callback.ResultCallback; |
||||
import xyz.fycz.myreader.ui.dialog.DialogCreator; |
||||
import xyz.fycz.myreader.util.CodeUtil; |
||||
import xyz.fycz.myreader.util.ToastUtils; |
||||
import xyz.fycz.myreader.util.utils.StringUtils; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2020/9/18 22:37 |
||||
*/ |
||||
public class RegisterActivity extends BaseActivity2 { |
||||
@BindView(R.id.et_username) |
||||
TextInputLayout etUsername; |
||||
@BindView(R.id.et_password) |
||||
TextInputLayout etPassword; |
||||
@BindView(R.id.et_rp_password) |
||||
TextInputLayout etRpPassword; |
||||
@BindView(R.id.et_captcha) |
||||
TextInputLayout etCaptcha; |
||||
@BindView(R.id.iv_captcha) |
||||
ImageView ivCaptcha; |
||||
@BindView(R.id.bt_register) |
||||
Button btRegister; |
||||
@BindView(R.id.tv_register_tip) |
||||
TextView tvRegisterTip; |
||||
@BindView(R.id.cb_agreement) |
||||
CheckBox cbAgreement; |
||||
@BindView(R.id.tv_agreement) |
||||
TextView tvAgreement; |
||||
private String code; |
||||
private String username = ""; |
||||
private String password = ""; |
||||
private String rpPassword = ""; |
||||
private String inputCode = ""; |
||||
|
||||
@SuppressLint("HandlerLeak") |
||||
private Handler mHandler = new Handler() { |
||||
@SuppressLint("HandlerLeak") |
||||
@Override |
||||
public void handleMessage(Message msg) { |
||||
switch (msg.what) { |
||||
case 1: |
||||
createCaptcha(); |
||||
break; |
||||
case 2: |
||||
showTip((String) msg.obj); |
||||
break; |
||||
case 3: |
||||
tvRegisterTip.setVisibility(View.GONE); |
||||
break; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
|
||||
@Override |
||||
protected int getContentId() { |
||||
return R.layout.activity_register; |
||||
} |
||||
|
||||
@Override |
||||
protected void setUpToolbar(Toolbar toolbar) { |
||||
super.setUpToolbar(toolbar); |
||||
setStatusBarColor(R.color.colorPrimary, true); |
||||
getSupportActionBar().setTitle("注册"); |
||||
} |
||||
|
||||
@Override |
||||
protected void initWidget() { |
||||
super.initWidget(); |
||||
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||
etUsername.requestFocus(); |
||||
etUsername.getEditText().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) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void afterTextChanged(Editable s) { |
||||
StringUtils.isNotChinese(s); |
||||
username = s.toString(); |
||||
if (username.length() < 6 || username.length() >14){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, "用户名必须在6-14位之间")); |
||||
} else if(!username.substring(0, 1).matches("^[A-Za-z]$")){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, |
||||
"用户名只能以字母开头")); |
||||
}else if(!username.matches("^[A-Za-z0-9-_]+$")){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, |
||||
"用户名只能由数字、字母、下划线、减号组成")); |
||||
}else { |
||||
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||
} |
||||
checkNotNone(); |
||||
} |
||||
}); |
||||
|
||||
etPassword.getEditText().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) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void afterTextChanged(Editable s) { |
||||
password = s.toString(); |
||||
if (password.length() < 8 || password.length() > 16){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, "密码必须在8-16位之间")); |
||||
} else if(password.matches("^\\d+$")){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, "密码不能是纯数字")); |
||||
} else { |
||||
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||
} |
||||
checkNotNone(); |
||||
} |
||||
}); |
||||
|
||||
etRpPassword.getEditText().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) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void afterTextChanged(Editable s) { |
||||
rpPassword = s.toString(); |
||||
if (!rpPassword.equals(password)){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, "两次输入的密码不一致")); |
||||
} else { |
||||
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||
} |
||||
checkNotNone(); |
||||
} |
||||
}); |
||||
|
||||
etCaptcha.getEditText().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) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void afterTextChanged(Editable s) { |
||||
inputCode = s.toString().trim().toLowerCase(); |
||||
if (!inputCode.equals(code.toLowerCase())){ |
||||
mHandler.sendMessage(mHandler.obtainMessage(2, "验证码错误")); |
||||
} else { |
||||
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||
} |
||||
checkNotNone(); |
||||
} |
||||
}); |
||||
|
||||
tvAgreement.setMovementMethod(LinkMovementMethod.getInstance()); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
protected void initClick() { |
||||
super.initClick(); |
||||
ivCaptcha.setOnClickListener(v -> mHandler.sendMessage(mHandler.obtainMessage(1))); |
||||
|
||||
btRegister.setOnClickListener(v -> { |
||||
if (!username.matches("^[A-Za-z][A-Za-z0-9]{5,13}$")){ |
||||
DialogCreator.createTipDialog(this, "用户名格式错误", |
||||
"用户名必须在6-14位之间\n用户名只能以字母开头\n用户名只能由数字、字母、下划线、减号组成"); |
||||
}else if(password.matches("^\\d+$") || !password.matches("^.{8,16}$")){ |
||||
DialogCreator.createTipDialog(this, "密码格式错误", |
||||
"密码必须在8-16位之间\n密码不能是纯数字"); |
||||
}else if(!password.equals(rpPassword)){ |
||||
DialogCreator.createTipDialog(this, "重复密码错误", |
||||
"两次输入的密码不一致"); |
||||
}else if(!inputCode.trim().toLowerCase().equals(code.toLowerCase())){ |
||||
DialogCreator.createTipDialog(this, "验证码错误"); |
||||
}else if(!cbAgreement.isChecked()){ |
||||
DialogCreator.createTipDialog(this, "请勾选同意《用户服务协议》"); |
||||
}else { |
||||
ProgressDialog dialog = DialogCreator.createProgressDialog(this, null, "正在注册..."); |
||||
Map<String, String> userRegisterInfo = new HashMap<>(); |
||||
userRegisterInfo.put("username", username); |
||||
userRegisterInfo.put("password", password); |
||||
UserService.register(userRegisterInfo, new ResultCallback() { |
||||
@Override |
||||
public void onFinish(Object o, int code) { |
||||
String[] info = ((String) o).split(":"); |
||||
int result = Integer.parseInt(info[0].trim()); |
||||
if (result == 101){ |
||||
UserService.writeUsername(username); |
||||
ToastUtils.showSuccess(info[1]); |
||||
finish(); |
||||
}else { |
||||
ToastUtils.showWarring(info[1]); |
||||
} |
||||
dialog.dismiss(); |
||||
} |
||||
@Override |
||||
public void onError(Exception e) { |
||||
ToastUtils.showError("注册失败:\n" + e.getLocalizedMessage()); |
||||
dialog.dismiss(); |
||||
} |
||||
}); |
||||
} |
||||
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||
}); |
||||
|
||||
} |
||||
|
||||
public void createCaptcha() { |
||||
code = CodeUtil.getInstance().createCode(); |
||||
Bitmap codeBitmap = CodeUtil.getInstance().createBitmap(code); |
||||
ivCaptcha.setImageBitmap(codeBitmap); |
||||
} |
||||
|
||||
public void showTip(String tip) { |
||||
tvRegisterTip.setVisibility(View.VISIBLE); |
||||
tvRegisterTip.setText(tip); |
||||
} |
||||
|
||||
public void checkNotNone(){ |
||||
if ("".equals(username) || "".equals(password) || "".equals(rpPassword) || "".equals(inputCode)){ |
||||
btRegister.setEnabled(false); |
||||
}else { |
||||
btRegister.setEnabled(true); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,62 @@ |
||||
package xyz.fycz.myreader.ui.dialog; |
||||
|
||||
import android.app.Dialog; |
||||
import android.content.Context; |
||||
import android.os.Bundle; |
||||
import android.view.Gravity; |
||||
import android.view.Window; |
||||
import android.view.WindowManager; |
||||
import android.widget.TextView; |
||||
import androidx.annotation.NonNull; |
||||
import butterknife.BindView; |
||||
import butterknife.ButterKnife; |
||||
import xyz.fycz.myreader.R; |
||||
|
||||
/** |
||||
* Created by Zhouas666 on 2019-04-14 |
||||
* Github: https://github.com/zas023
|
||||
* <p> |
||||
* 自由复制dialog |
||||
*/ |
||||
|
||||
public class CopyContentDialog extends Dialog { |
||||
|
||||
private static final String TAG = "CopyContentDialog"; |
||||
|
||||
@BindView(R.id.dialog_tv_content) |
||||
TextView dialogTvContent; |
||||
|
||||
private String content; |
||||
|
||||
/***************************************************************************/ |
||||
|
||||
public CopyContentDialog(@NonNull Context context, String content) { |
||||
super(context); |
||||
this.content = content; |
||||
} |
||||
|
||||
/*****************************Initialization********************************/ |
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.dialog_copy_content); |
||||
ButterKnife.bind(this); |
||||
|
||||
setUpWindow(); |
||||
|
||||
dialogTvContent.setText(content); |
||||
} |
||||
|
||||
/** |
||||
* 设置Dialog显示的位置 |
||||
*/ |
||||
private void setUpWindow() { |
||||
Window window = getWindow(); |
||||
WindowManager.LayoutParams lp = window.getAttributes(); |
||||
lp.width = WindowManager.LayoutParams.MATCH_PARENT; |
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT; |
||||
lp.gravity = Gravity.CENTER; |
||||
window.setAttributes(lp); |
||||
} |
||||
|
||||
} |
@ -1,72 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
|
||||
import android.app.AlarmManager; |
||||
import android.app.PendingIntent; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.os.Build; |
||||
|
||||
import xyz.fycz.myreader.common.APPCONST; |
||||
|
||||
import java.util.Date; |
||||
|
||||
import static android.content.Context.ALARM_SERVICE; |
||||
import static android.content.Intent.FLAG_INCLUDE_STOPPED_PACKAGES; |
||||
|
||||
|
||||
|
||||
public class AlarmHelper { |
||||
|
||||
private static String alarmActicon = "xyz.fycz.kl.gxdw"; |
||||
private static String AntiHijackingActicon = "xyz.fycz.kl.gxdw.AntiHijacking"; |
||||
|
||||
public static void addOneShotAlarm(Context context, long time, String msg, int id){ |
||||
Date date = new Date(); |
||||
if(time <= date.getTime()){ |
||||
return; |
||||
} |
||||
Intent intent = new Intent(alarmActicon); |
||||
intent.putExtra(APPCONST.ALARM_SCHEDULE_MSG,msg); |
||||
intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES); |
||||
PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT); |
||||
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE); |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { |
||||
alarmManager.setExact(AlarmManager.RTC_WAKEUP,time,pi); |
||||
}else { |
||||
alarmManager.set(AlarmManager.RTC_WAKEUP,time,pi); |
||||
} |
||||
} |
||||
|
||||
public static void removeOneShotAlarm(Context context, int id){ |
||||
Intent intent = new Intent(alarmActicon); |
||||
intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES); |
||||
PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT); |
||||
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE); |
||||
alarmManager.cancel(pi); |
||||
} |
||||
|
||||
public static void addAlarm(Context context, long time, int id){ |
||||
// Date date = new Date();
|
||||
/* if(time <= date.getTime()){ |
||||
return; |
||||
}*/ |
||||
Intent intent = new Intent(AntiHijackingActicon); |
||||
|
||||
intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES); |
||||
PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT); |
||||
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE); |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { |
||||
alarmManager.setExact(AlarmManager.RTC_WAKEUP,new Date().getTime() + time,pi); |
||||
}else { |
||||
alarmManager.set(AlarmManager.RTC_WAKEUP,new Date().getTime() + time,pi); |
||||
} |
||||
} |
||||
|
||||
public static void removeAlarm(Context context, int id){ |
||||
Intent intent = new Intent(AntiHijackingActicon); |
||||
intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES); |
||||
PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT); |
||||
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE); |
||||
alarmManager.cancel(pi); |
||||
} |
||||
} |
@ -1,125 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
|
||||
import android.widget.Toast; |
||||
|
||||
import androidx.appcompat.app.AppCompatActivity; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Timer; |
||||
import java.util.TimerTask; |
||||
|
||||
import xyz.fycz.myreader.R; |
||||
|
||||
/** |
||||
* 防界面劫持提示 |
||||
*/ |
||||
public class Anti_hijackingUtils { |
||||
|
||||
// private int id = 12345678;//记录定时ID
|
||||
|
||||
private static boolean home; |
||||
private static boolean back; |
||||
|
||||
|
||||
/** |
||||
* 用于执行定时任务 |
||||
*/ |
||||
private Timer timer = null; |
||||
|
||||
/** |
||||
* 用于保存当前任务 |
||||
*/ |
||||
private List<MyTimerTask> tasks = null; |
||||
|
||||
/** |
||||
* 唯一实例 |
||||
*/ |
||||
private static Anti_hijackingUtils anti_hijackingUtils; |
||||
|
||||
private Anti_hijackingUtils() { |
||||
// 初始化
|
||||
tasks = new ArrayList<MyTimerTask>(); |
||||
timer = new Timer(); |
||||
} |
||||
|
||||
/** |
||||
* 获取唯一实例 |
||||
* |
||||
* @return 唯一实例 |
||||
*/ |
||||
public static Anti_hijackingUtils getinstance() { |
||||
if (anti_hijackingUtils == null) { |
||||
anti_hijackingUtils = new Anti_hijackingUtils(); |
||||
} |
||||
return anti_hijackingUtils; |
||||
} |
||||
|
||||
/** |
||||
* 在activity的onPause()方法中调用 |
||||
* |
||||
* @param activity |
||||
*/ |
||||
public void onPause(final AppCompatActivity activity) { |
||||
MyTimerTask task = new MyTimerTask(activity); |
||||
tasks.add(task); |
||||
timer.schedule(task, 2000); |
||||
// AlarmHelper.addAlarm(activity,2000,id);
|
||||
} |
||||
|
||||
/** |
||||
* 在activity的onResume()方法中调用 |
||||
*/ |
||||
public void onResume(final AppCompatActivity activity) { |
||||
if (tasks.size() > 0) { |
||||
tasks.get(tasks.size() - 1).setCanRun(false); |
||||
tasks.remove(tasks.size() - 1); |
||||
} |
||||
// AlarmHelper.removeAlarm(activity,id);
|
||||
} |
||||
|
||||
/** |
||||
* 自定义TimerTask类 |
||||
*/ |
||||
class MyTimerTask extends TimerTask { |
||||
/** |
||||
* 任务是否有效 |
||||
*/ |
||||
private boolean canRun = true; |
||||
private AppCompatActivity activity; |
||||
|
||||
private void setCanRun(boolean canRun) { |
||||
this.canRun = canRun; |
||||
} |
||||
|
||||
public MyTimerTask(AppCompatActivity activity) { |
||||
this.activity = activity; |
||||
} |
||||
|
||||
@Override |
||||
public void run() { |
||||
activity.runOnUiThread(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
if (canRun) { |
||||
// 程序退到后台,进行风险警告
|
||||
if (home || back){ |
||||
Toast.makeText(activity, activity.getString(R.string.anti_hijacking_tips_home), Toast.LENGTH_LONG).show(); |
||||
|
||||
tasks.remove(MyTimerTask.this); |
||||
home = false; |
||||
}else { |
||||
Toast.makeText(activity, activity.getString(R.string.anti_hijacking_tips), Toast.LENGTH_LONG).show(); |
||||
// TextHelper.showLongText(MyApplication.getApplication().getString(R.string.anti_hijacking_tips));
|
||||
tasks.remove(MyTimerTask.this); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
|
@ -1,125 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
import java.lang.reflect.Method; |
||||
import java.util.Arrays; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Created by Kodulf |
||||
*/ |
||||
public class BeanPropertiesUtil { |
||||
/** |
||||
* 利用反射实现对象之间属性复制 |
||||
* @param from |
||||
* @param to |
||||
*/ |
||||
public static void copyProperties(Object from, Object to) throws Exception { |
||||
copyPropertiesExclude(from, to, null); |
||||
} |
||||
|
||||
/** |
||||
* 复制对象属性 |
||||
* @param from |
||||
* @param to |
||||
* @param excludsArray 排除属性列表 |
||||
* @throws Exception |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
public static void copyPropertiesExclude(Object from, Object to, String[] excludsArray) throws Exception { |
||||
List<String> excludesList = null; |
||||
if(excludsArray != null && excludsArray.length > 0) { |
||||
excludesList = Arrays.asList(excludsArray); //构造列表对象
|
||||
} |
||||
Method[] fromMethods = from.getClass().getDeclaredMethods(); |
||||
Method[] toMethods = to.getClass().getDeclaredMethods(); |
||||
Method fromMethod = null, toMethod = null; |
||||
String fromMethodName = null, toMethodName = null; |
||||
for (int i = 0; i < fromMethods.length; i++) { |
||||
fromMethod = fromMethods[i]; |
||||
fromMethodName = fromMethod.getName(); |
||||
if (!fromMethodName.contains("get") || fromMethodName.contains("getId")) |
||||
continue; |
||||
//排除列表检测
|
||||
if(excludesList != null && excludesList.contains(fromMethodName.substring(3).toLowerCase())) { |
||||
continue; |
||||
} |
||||
toMethodName = "set" + fromMethodName.substring(3); |
||||
toMethod = findMethodByName(toMethods, toMethodName); |
||||
if (toMethod == null) |
||||
continue; |
||||
Object value = fromMethod.invoke(from); |
||||
if(value == null) |
||||
continue; |
||||
//集合类判空处理
|
||||
if(value instanceof Collection) { |
||||
Collection newValue = (Collection)value; |
||||
if(newValue.size() <= 0) |
||||
continue; |
||||
} |
||||
toMethod.invoke(to, value); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 对象属性值复制,仅复制指定名称的属性值 |
||||
* @param from |
||||
* @param to |
||||
* @param includsArray |
||||
* @throws Exception |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
public static void copyPropertiesInclude(Object from, Object to, String[] includsArray) throws Exception { |
||||
List<String> includesList = null; |
||||
if(includsArray != null && includsArray.length > 0) { |
||||
includesList = Arrays.asList(includsArray); //构造列表对象
|
||||
} else { |
||||
return; |
||||
} |
||||
Method[] fromMethods = from.getClass().getDeclaredMethods(); |
||||
Method[] toMethods = to.getClass().getDeclaredMethods(); |
||||
Method fromMethod = null, toMethod = null; |
||||
String fromMethodName = null, toMethodName = null; |
||||
for (int i = 0; i < fromMethods.length; i++) { |
||||
fromMethod = fromMethods[i]; |
||||
fromMethodName = fromMethod.getName(); |
||||
if (!fromMethodName.contains("get")) |
||||
continue; |
||||
//排除列表检测
|
||||
String str = fromMethodName.substring(3); |
||||
if(!includesList.contains(str.substring(0,1).toLowerCase() + str.substring(1))) { |
||||
continue; |
||||
} |
||||
toMethodName = "set" + fromMethodName.substring(3); |
||||
toMethod = findMethodByName(toMethods, toMethodName); |
||||
if (toMethod == null) |
||||
continue; |
||||
Object value = fromMethod.invoke(from); |
||||
if(value == null) |
||||
continue; |
||||
//集合类判空处理
|
||||
if(value instanceof Collection) { |
||||
Collection newValue = (Collection)value; |
||||
if(newValue.size() <= 0) |
||||
continue; |
||||
} |
||||
toMethod.invoke(to, value); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* 从方法数组中获取指定名称的方法 |
||||
* |
||||
* @param methods |
||||
* @param name |
||||
* @return |
||||
*/ |
||||
public static Method findMethodByName(Method[] methods, String name) { |
||||
for (int j = 0; j < methods.length; j++) { |
||||
if (methods[j].getName().equals(name)) |
||||
return methods[j]; |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -1,431 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
|
||||
import android.Manifest; |
||||
import android.app.DownloadManager; |
||||
import android.content.BroadcastReceiver; |
||||
import android.content.Context; |
||||
import android.content.DialogInterface; |
||||
import android.content.Intent; |
||||
import android.content.IntentFilter; |
||||
import android.content.pm.PackageManager; |
||||
import android.net.Uri; |
||||
import android.os.Build; |
||||
import android.os.Environment; |
||||
import android.util.Log; |
||||
|
||||
import androidx.appcompat.app.AppCompatActivity; |
||||
import androidx.core.app.ActivityCompat; |
||||
import androidx.core.content.ContextCompat; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import xyz.fycz.myreader.common.APPCONST; |
||||
import xyz.fycz.myreader.ui.dialog.DialogCreator; |
||||
|
||||
import static android.app.DownloadManager.Request.VISIBILITY_HIDDEN; |
||||
|
||||
|
||||
|
||||
public class DownloadMangerUtils { |
||||
|
||||
public static final String FILE_DIR = "gxdw"; |
||||
private static Map<Long, BroadcastReceiver> mBroadcastReceiverMap = new HashMap<>(); |
||||
|
||||
/** |
||||
* 文件下载 |
||||
* |
||||
* @param context |
||||
* @param fileDir |
||||
* @param url |
||||
* @param fileName |
||||
*/ |
||||
public static void downloadFile(Context context, String fileDir, String url, String fileName) { |
||||
|
||||
try { |
||||
Log.d("http download:", url); |
||||
//String Url = "10.10.123.16:8080/gxqdw_ubap/mEmailController.thumb?getAttachmentStream&fileId=1&fileName=自我探索——我是谁.ppt&emailId=36&token=d1828248-cc71-4719-8218-adc31ffc9cca&type=inbox&fileSize=14696446";
|
||||
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); |
||||
// DownloadManager.Request.setDestinationInExternalPublicDir();
|
||||
|
||||
request.setDescription(fileName); |
||||
request.setTitle("附件"); |
||||
// in order for this if to run, you must use the android 3.2 to compile your app
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||
request.allowScanningByMediaScanner(); |
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); |
||||
// request.setNotificationVisibility(VISIBILITY_HIDDEN);
|
||||
} |
||||
// int i = Build.VERSION.SDK_INT;
|
||||
if (Build.VERSION.SDK_INT > 17) { |
||||
request.setDestinationInExternalPublicDir(fileDir, fileName); |
||||
} else { |
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
||||
request.setDestinationInExternalPublicDir(fileDir, fileName); |
||||
} else { |
||||
Log.d("download", "android版本过低,不存在外部存储,下载路径无法指定,默认路径:/data/data/com.android.providers.downloads/cache/"); |
||||
DialogCreator.createCommonDialog(context, "文件下载", "android版本过低或系统兼容性问题,不存在外部存储,无法指定下载路径,文件下载到系统默认路径,请到文件管理搜索文件名", true, |
||||
"关闭", new DialogInterface.OnClickListener() { |
||||
@Override |
||||
public void onClick(DialogInterface dialog, int which) { |
||||
dialog.dismiss(); |
||||
} |
||||
}); |
||||
|
||||
} |
||||
} |
||||
// get download service and enqueue file
|
||||
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); |
||||
manager.enqueue(request); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
lowVersionNoSDDownload(context, url, fileName); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 低版本无外置存储下载 |
||||
* |
||||
* @param context |
||||
* @param url |
||||
* @param fileName |
||||
*/ |
||||
private static void lowVersionNoSDDownload(Context context, String url, String fileName) { |
||||
try { |
||||
Log.d("http download:", url); |
||||
//String Url = "10.10.123.16:8080/gxqdw_ubap/mEmailController.thumb?getAttachmentStream&fileId=1&fileName=自我探索——我是谁.ppt&emailId=36&token=d1828248-cc71-4719-8218-adc31ffc9cca&type=inbox&fileSize=14696446";
|
||||
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); |
||||
// DownloadManager.Request.setDestinationInExternalPublicDir();
|
||||
|
||||
request.setDescription(fileName); |
||||
request.setTitle("附件"); |
||||
// in order for this if to run, you must use the android 3.2 to compile your app
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||
request.allowScanningByMediaScanner(); |
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); |
||||
// request.setNotificationVisibility(VISIBILITY_HIDDEN);
|
||||
} |
||||
// int i = Build.VERSION.SDK_INT;
|
||||
|
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
||||
request.setDestinationInExternalPublicDir(APPCONST.FILE_DIR, fileName); |
||||
} else { |
||||
Log.d("download", "android版本过低,不存在外部存储,下载路径无法指定,默认路径:/data/data/com.android.providers.downloads/cache/"); |
||||
DialogCreator.createCommonDialog(context, "文件下载", "android版本过低或系统兼容性问题,不存在外部存储,无法指定下载路径,文件下载到系统默认路径,请到文件管理搜索文件名", true, |
||||
"关闭", new DialogInterface.OnClickListener() { |
||||
@Override |
||||
public void onClick(DialogInterface dialog, int which) { |
||||
dialog.dismiss(); |
||||
} |
||||
}); |
||||
} |
||||
// get download service and enqueue file
|
||||
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); |
||||
manager.enqueue(request); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
ToastUtils.showError("下载错误:" + e.getLocalizedMessage()); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
/** |
||||
* 文件下载(有回调,无通知) |
||||
* |
||||
* @param context |
||||
* @param fileDir |
||||
* @param fileName |
||||
* @param url |
||||
* @param listener |
||||
*/ |
||||
public static void downloadFileByFinishListener(Context context, String fileDir, String fileName, String url, |
||||
final DownloadCompleteListener listener) { |
||||
try { |
||||
if (isPermission(context)) { |
||||
Log.d("http download:", url); |
||||
// String Url = "10.10.123.16:8080/gxqdw_ubap/mEmailController.thumb?getAttachmentStream&fileId=1&fileName=自我探索——我是谁.ppt&emailId=36&token=d1828248-cc71-4719-8218-adc31ffc9cca&type=inbox&fileSize=14696446";
|
||||
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); |
||||
// DownloadManager.Request.setDestinationInExternalPublicDir();
|
||||
|
||||
/* request.setDescription(fileName); |
||||
request.setTitle("附件");*/ |
||||
// in order for this if to run, you must use the android 3.2 to compile your app
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||
request.allowScanningByMediaScanner(); |
||||
// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||
request.setNotificationVisibility(VISIBILITY_HIDDEN); |
||||
} |
||||
// int i = Build.VERSION.SDK_INT;
|
||||
if (Build.VERSION.SDK_INT > 17) { |
||||
request.setDestinationInExternalPublicDir(fileDir, fileName); |
||||
} else { |
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
||||
request.setDestinationInExternalPublicDir(fileDir, fileName); |
||||
} else { |
||||
Log.i("download", "android版本过低,不存在外部存储,下载路径无法指定,默认路径:/data/data/com.android.providers.downloads/cache/"); |
||||
} |
||||
} |
||||
// get download service and enqueue file
|
||||
final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); |
||||
|
||||
final long id = manager.enqueue(request); |
||||
// 注册广播监听系统的下载完成事件。
|
||||
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); |
||||
|
||||
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { |
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); |
||||
if (ID == id) { |
||||
listener.onFinish(manager.getUriForDownloadedFile(id)); |
||||
context.unregisterReceiver(mBroadcastReceiverMap.get(id)); |
||||
mBroadcastReceiverMap.remove(id); |
||||
/* Toast.makeText(getApplicationContext(), "任务:" + Id + " 下载完成!", Toast.LENGTH_LONG).show();*/ |
||||
} |
||||
} |
||||
}; |
||||
context.registerReceiver(broadcastReceiver, intentFilter); |
||||
mBroadcastReceiverMap.put(id, broadcastReceiver); |
||||
} |
||||
} catch (Exception e) { |
||||
lowVersionNoSDDownloadFileByFinishListener(context, fileDir, fileName, url, listener); |
||||
// listener.onError(e.toString());
|
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 低版本无外置存储文件下载(有回调,无通知) |
||||
* |
||||
* @param context |
||||
* @param fileDir |
||||
* @param fileName |
||||
* @param url |
||||
* @param listener |
||||
*/ |
||||
private static void lowVersionNoSDDownloadFileByFinishListener(Context context, String fileDir, String fileName, String url, |
||||
final DownloadCompleteListener listener) { |
||||
try { |
||||
|
||||
Log.d("http download:", url); |
||||
// String Url = "10.10.123.16:8080/gxqdw_ubap/mEmailController.thumb?getAttachmentStream&fileId=1&fileName=自我探索——我是谁.ppt&emailId=36&token=d1828248-cc71-4719-8218-adc31ffc9cca&type=inbox&fileSize=14696446";
|
||||
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); |
||||
// DownloadManager.Request.setDestinationInExternalPublicDir();
|
||||
|
||||
/* request.setDescription(fileName); |
||||
request.setTitle("附件");*/ |
||||
// in order for this if to run, you must use the android 3.2 to compile your app
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||
request.allowScanningByMediaScanner(); |
||||
// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||
request.setNotificationVisibility(VISIBILITY_HIDDEN); |
||||
} |
||||
// int i = Build.VERSION.SDK_INT;
|
||||
|
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
||||
request.setDestinationInExternalPublicDir(APPCONST.FILE_DIR, fileName); |
||||
} else { |
||||
Log.d("download", "android版本过低,不存在外部存储,下载路径无法指定,默认路径:/data/data/com.android.providers.downloads/cache/"); |
||||
} |
||||
|
||||
// get download service and enqueue file
|
||||
final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); |
||||
|
||||
final long id = manager.enqueue(request); |
||||
// 注册广播监听系统的下载完成事件。
|
||||
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); |
||||
|
||||
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { |
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); |
||||
if (ID == id) { |
||||
listener.onFinish(manager.getUriForDownloadedFile(id)); |
||||
context.unregisterReceiver(mBroadcastReceiverMap.get(id)); |
||||
mBroadcastReceiverMap.remove(id); |
||||
/* Toast.makeText(getApplicationContext(), "任务:" + Id + " 下载完成!", Toast.LENGTH_LONG).show();*/ |
||||
} |
||||
} |
||||
}; |
||||
context.registerReceiver(broadcastReceiver, intentFilter); |
||||
mBroadcastReceiverMap.put(id, broadcastReceiver); |
||||
|
||||
} catch (Exception e) { |
||||
listener.onError(e.toString()); |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 文件下载(有回调,有通知) |
||||
* |
||||
* @param context |
||||
* @param fileDir |
||||
* @param fileName |
||||
* @param url |
||||
* @param title |
||||
* @param listener |
||||
*/ |
||||
public static void downloadFileOnNotificationByFinishListener(final Context context, final String fileDir, final String fileName, final String url, |
||||
final String title, final DownloadCompleteListener listener) { |
||||
try { |
||||
if (isPermission(context)) { |
||||
Log.d("http download:", url); |
||||
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); |
||||
request.setTitle(title); |
||||
|
||||
// in order for this if to run, you must use the android 3.2 to compile your app
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||
request.allowScanningByMediaScanner(); |
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); |
||||
} |
||||
|
||||
if (Build.VERSION.SDK_INT > 17) { |
||||
/* File file = new File(Environment.getExternalStorageDirectory() + "/gxdw/apk/app_gxdw_186.apk"); |
||||
if (!file.exists()){ |
||||
boolean flag = file.createNewFile(); |
||||
}*/ |
||||
request.setDestinationInExternalPublicDir(fileDir, fileName); |
||||
|
||||
} else { |
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
||||
request.setDestinationInExternalPublicDir(fileDir, fileName); |
||||
} else { |
||||
Log.d("download", "android版本过低,不存在外部存储,下载路径无法指定,默认路径:/data/data/com.android.providers.downloads/cache/"); |
||||
} |
||||
} |
||||
|
||||
// get download service and enqueue file
|
||||
final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); |
||||
|
||||
final long id = manager.enqueue(request); |
||||
// 注册广播监听系统的下载完成事件。
|
||||
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); |
||||
|
||||
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { |
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); |
||||
if (ID == id) { |
||||
listener.onFinish(manager.getUriForDownloadedFile(id)); |
||||
context.unregisterReceiver(mBroadcastReceiverMap.get(id)); |
||||
mBroadcastReceiverMap.remove(id); |
||||
/* Toast.makeText(getApplicationContext(), "任务:" + Id + " 下载完成!", Toast.LENGTH_LONG).show();*/ |
||||
} |
||||
} |
||||
}; |
||||
context.registerReceiver(broadcastReceiver, intentFilter); |
||||
mBroadcastReceiverMap.put(id, broadcastReceiver); |
||||
} |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
lowVersionDownloadFileOnNotificationByFinishListener(context, fileDir, fileName, url, title, listener); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 低版本文件下载(有回调,有通知) |
||||
* |
||||
* @param context |
||||
* @param fileDir |
||||
* @param fileName |
||||
* @param url |
||||
* @param title |
||||
* @param listener |
||||
*/ |
||||
private static void lowVersionDownloadFileOnNotificationByFinishListener(final Context context, final String fileDir, final String fileName, final String url, |
||||
final String title, final DownloadCompleteListener listener) { |
||||
|
||||
|
||||
try { |
||||
|
||||
Log.d("http download:", url); |
||||
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); |
||||
request.setTitle(title); |
||||
|
||||
// in order for this if to run, you must use the android 3.2 to compile your app
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||
request.allowScanningByMediaScanner(); |
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); |
||||
|
||||
} |
||||
|
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
||||
request.setDestinationInExternalPublicDir(APPCONST.FILE_DIR, fileName); |
||||
} else { |
||||
Log.d("download", "android版本过低,不存在外部存储,下载路径无法指定,默认路径:/data/data/com.android.providers.downloads/cache/"); |
||||
} |
||||
|
||||
|
||||
// get download service and enqueue file
|
||||
final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); |
||||
|
||||
final long id = manager.enqueue(request); |
||||
// 注册广播监听系统的下载完成事件。
|
||||
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); |
||||
|
||||
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { |
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); |
||||
if (ID == id) { |
||||
listener.onFinish(manager.getUriForDownloadedFile(id)); |
||||
context.unregisterReceiver(mBroadcastReceiverMap.get(id)); |
||||
mBroadcastReceiverMap.remove(id); |
||||
} |
||||
} |
||||
}; |
||||
context.registerReceiver(broadcastReceiver, intentFilter); |
||||
mBroadcastReceiverMap.put(id, broadcastReceiver); |
||||
|
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
listener.onError(e.toString()); |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
/** |
||||
* 读写权限判断 |
||||
* |
||||
* @param context |
||||
* @return |
||||
*/ |
||||
public static boolean isPermission(Context context) { |
||||
boolean permission = false; |
||||
if (Build.VERSION.SDK_INT >= 23) { |
||||
int checkReadPhoneStatePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE); |
||||
if (checkReadPhoneStatePermission != PackageManager.PERMISSION_GRANTED) { |
||||
// 弹出对话框接收权限
|
||||
ActivityCompat.requestPermissions((AppCompatActivity) context, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); |
||||
ToastUtils.showWarring("当前应用未拥有存储设备读写权限"); |
||||
} else if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { |
||||
// 弹出对话框接收权限
|
||||
ActivityCompat.requestPermissions((AppCompatActivity) context, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); |
||||
ToastUtils.showWarring("当前应用未拥有存储设备读写权限"); |
||||
} else { |
||||
permission = true; |
||||
} |
||||
} else { |
||||
permission = true; |
||||
} |
||||
return permission; |
||||
} |
||||
|
||||
public interface DownloadCompleteListener { |
||||
void onFinish(Uri uri); |
||||
|
||||
void onError(String s); |
||||
} |
||||
|
||||
|
||||
} |
@ -1,14 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
|
||||
|
||||
|
||||
public class IdHelper { |
||||
|
||||
public static String getId(){ |
||||
java.util.Date date = new java.util.Date(); |
||||
int rand = (int)(1+ Math.random()*(25-0+1)); |
||||
// char c = (char) ('a' + rand);
|
||||
return String.valueOf(date.getTime()%100000000); |
||||
|
||||
} |
||||
} |
@ -1,266 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
|
||||
import java.text.ParseException; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Calendar; |
||||
import java.util.Date; |
||||
|
||||
|
||||
|
||||
public class Lunar |
||||
{ |
||||
private int year; |
||||
private int month; |
||||
private int day; |
||||
private boolean leap; |
||||
final static String chineseNumber[] = |
||||
{ "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" }; |
||||
final static String Big_Or_Small[] = |
||||
{ "大", "小", "大", "小", "大", "小", "大", "大", "小", "大", "小", "大" }; |
||||
private String[] LunarHolDayName = |
||||
{ "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", |
||||
"小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", |
||||
"冬至" }; |
||||
|
||||
static SimpleDateFormat chineseDateFormat = new SimpleDateFormat(" yyyy年MM月dd日 "); |
||||
final static long[] lunarInfo = new long[] |
||||
{ 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, |
||||
0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, |
||||
0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, |
||||
0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, |
||||
0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, |
||||
0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, |
||||
0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, |
||||
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, |
||||
0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, |
||||
0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, |
||||
0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, |
||||
0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, |
||||
0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, |
||||
0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, |
||||
0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, |
||||
0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, |
||||
0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, |
||||
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, |
||||
0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, |
||||
0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, |
||||
0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, |
||||
0x06d20, 0x0ada0 }; |
||||
|
||||
// ====== 传回农历 y年的总天数
|
||||
final private static int yearDays(int y) |
||||
{ |
||||
int i, sum = 348; |
||||
for (i = 0x8000; i > 0x8; i >>= 1) |
||||
{ |
||||
if ((lunarInfo[y - 1900] & i) != 0) |
||||
sum += 1; |
||||
} |
||||
return (sum + leapDays(y)); |
||||
} |
||||
|
||||
// ====== 传回农历 y年闰月的天数
|
||||
final private static int leapDays(int y) |
||||
{ |
||||
if (leapMonth(y) != 0) |
||||
{ |
||||
if ((lunarInfo[y - 1900] & 0x10000) != 0) |
||||
return 30; |
||||
else |
||||
return 29; |
||||
} |
||||
else |
||||
return 0; |
||||
} |
||||
|
||||
// ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
|
||||
final private static int leapMonth(int y) |
||||
{ |
||||
return (int) (lunarInfo[y - 1900] & 0xf); |
||||
} |
||||
|
||||
// ====== 传回农历 y年m月的总天数
|
||||
final private static int monthDays(int y, int m) |
||||
{ |
||||
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) |
||||
return 29; |
||||
else |
||||
return 30; |
||||
} |
||||
|
||||
// ====== 传回农历 y年的生肖
|
||||
final public String animalsYear() |
||||
{ |
||||
final String[] Animals = new String[] |
||||
{ "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; |
||||
return Animals[(year - 4) % 12]; |
||||
} |
||||
|
||||
// ====== 传入 月日的offset 传回干支, 0=甲子
|
||||
final private static String cyclicalm(int num) |
||||
{ |
||||
final String[] Gan = new String[] |
||||
{ "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }; |
||||
final String[] Zhi = new String[] |
||||
{ "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }; |
||||
return (Gan[num % 10] + Zhi[num % 12]); |
||||
} |
||||
|
||||
// ====== 传入 offset 传回干支, 0=甲子
|
||||
final public String cyclical() |
||||
{ |
||||
int num = year - 1900 + 36; |
||||
return (cyclicalm(num)); |
||||
} |
||||
|
||||
/** */ |
||||
/** |
||||
* 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数 |
||||
* dayCyl5:与1900年1月31日相差的天数,再加40 ? |
||||
* |
||||
* @param cal |
||||
* @return |
||||
*/ |
||||
public Lunar(Calendar cal) |
||||
{ |
||||
// cal.add(cal.get(Calendar.DAY_OF_MONTH),1);
|
||||
@SuppressWarnings(" unused ") |
||||
int yearCyl, monCyl, dayCyl; |
||||
int leapMonth = 0; |
||||
Date baseDate = null; |
||||
try |
||||
{ |
||||
baseDate = chineseDateFormat.parse(" 1900年1月31日 "); |
||||
} |
||||
catch (ParseException e) |
||||
{ |
||||
e.printStackTrace(); // To change body of catch statement use
|
||||
// Options | File Templates.
|
||||
} |
||||
|
||||
// 求出和1900年1月31日相差的天数
|
||||
int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L); |
||||
dayCyl = offset + 40; |
||||
monCyl = 14; |
||||
|
||||
// 用offset减去每农历年的天数
|
||||
// 计算当天是农历第几天
|
||||
// i最终结果是农历的年份
|
||||
// offset是当年的第几天
|
||||
int iYear, daysOfYear = 0; |
||||
for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) |
||||
{ |
||||
daysOfYear = yearDays(iYear); |
||||
offset -= daysOfYear; |
||||
monCyl += 12; |
||||
} |
||||
if (offset < 0) |
||||
{ |
||||
offset += daysOfYear; |
||||
iYear--; |
||||
monCyl -= 12; |
||||
} |
||||
// 农历年份
|
||||
year = iYear; |
||||
|
||||
yearCyl = iYear - 1864; |
||||
leapMonth = leapMonth(iYear); // 闰哪个月,1-12
|
||||
leap = false; |
||||
|
||||
// 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
|
||||
int iMonth, daysOfMonth = 0; |
||||
for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) |
||||
{ |
||||
// 闰月
|
||||
if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) |
||||
{ |
||||
--iMonth; |
||||
leap = true; |
||||
daysOfMonth = leapDays(year); |
||||
} |
||||
else |
||||
daysOfMonth = monthDays(year, iMonth); |
||||
|
||||
offset -= daysOfMonth; |
||||
// 解除闰月
|
||||
if (leap && iMonth == (leapMonth + 1)) |
||||
leap = false; |
||||
if (!leap) |
||||
monCyl++; |
||||
} |
||||
// offset为0时,并且刚才计算的月份是闰月,要校正
|
||||
if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) |
||||
{ |
||||
if (leap) |
||||
{ |
||||
leap = false; |
||||
} |
||||
else |
||||
{ |
||||
leap = true; |
||||
--iMonth; |
||||
--monCyl; |
||||
} |
||||
} |
||||
// offset小于0时,也要校正
|
||||
if (offset < 0) |
||||
{ |
||||
offset += daysOfMonth; |
||||
--iMonth; |
||||
--monCyl; |
||||
} |
||||
month = iMonth; |
||||
day = offset + 1; |
||||
} |
||||
|
||||
public static String getChinaDayString(int day) |
||||
{ |
||||
String chineseTen[] = |
||||
{ "初", "十", "廿", "卅" }; |
||||
int n = day % 10 == 0 ? 9 : day % 10 - 1; |
||||
if (day > 30) |
||||
return ""; |
||||
if (day == 10) |
||||
return "初十"; |
||||
else |
||||
return chineseTen[day / 10] + chineseNumber[n]; |
||||
} |
||||
|
||||
public String toString() |
||||
{ |
||||
return /* cyclical() + "年" + */(leap ? "闰" : "") |
||||
+ chineseNumber[month - 1] + "月" + getChinaDayString(day); |
||||
} |
||||
|
||||
public String numeric_md() |
||||
{// 返回阿拉伯数字的阴历日期
|
||||
String temp_day; |
||||
String temp_mon; |
||||
temp_mon = month < 10 ? "0" + month : "" + month; |
||||
temp_day = day < 10 ? "0" + day : "" + day; |
||||
|
||||
return temp_mon + temp_day; |
||||
} |
||||
|
||||
public String get_month() |
||||
{// 返回阴历的月份
|
||||
return chineseNumber[month - 1]; |
||||
} |
||||
|
||||
public String get_date(int year, int month, int date) |
||||
{ |
||||
/* // 返回阴历的天
|
||||
LunarCalendar lunarCalendar = LunarCalendar.getInstance(); |
||||
String str = lunarCalendar.CalculateLunarCalendar(year,month,date); |
||||
if(StringHelper.isEmpty(str)){ |
||||
str = getChinaDayString(day); |
||||
}*/ |
||||
return getChinaDayString(day); |
||||
} |
||||
|
||||
public String get_Big_Or_Small() |
||||
{// 返回的月份的大或小
|
||||
return Big_Or_Small[month - 1]; |
||||
} |
||||
|
||||
} |
@ -1,326 +0,0 @@ |
||||
package xyz.fycz.myreader.util; |
||||
|
||||
|
||||
|
||||
import java.text.ParseException; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Calendar; |
||||
import java.util.Date; |
||||
|
||||
public class LunarCalendar { |
||||
|
||||
private int lyear; |
||||
|
||||
private int lmonth; |
||||
|
||||
private int lday; |
||||
|
||||
private boolean leap; |
||||
|
||||
private String solarTerms = ""; |
||||
|
||||
private int yearCyl, monCyl, dayCyl; |
||||
|
||||
private String solarFestival = ""; |
||||
|
||||
private String lunarFestival = ""; |
||||
|
||||
private Calendar baseDate = Calendar.getInstance(); |
||||
|
||||
private Calendar offDate = Calendar.getInstance(); |
||||
|
||||
private SimpleDateFormat chineseDateFormat = new SimpleDateFormat( |
||||
"yyyy年MM月dd日"); |
||||
|
||||
final static long[] lunarInfo = new long[]{0x04bd8, 0x04ae0, 0x0a570, |
||||
0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, |
||||
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, |
||||
0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, |
||||
0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, |
||||
0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, |
||||
0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, |
||||
0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, |
||||
0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, |
||||
0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, |
||||
0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, |
||||
0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, |
||||
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, |
||||
0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, |
||||
0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, |
||||
0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, |
||||
0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, |
||||
0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, |
||||
0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, |
||||
0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, |
||||
0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, |
||||
0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0}; |
||||
|
||||
final static String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", |
||||
"庚", "辛", "壬", "癸"}; |
||||
|
||||
final static String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", |
||||
"午", "未", "申", "酉", "戌", "亥"}; |
||||
|
||||
final static String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", |
||||
"蛇", "马", "羊", "猴", "鸡", "狗", "猪"}; |
||||
|
||||
final static String[] SolarTerm = new String[]{"小寒", "大寒", "立春", "雨水", |
||||
"惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", |
||||
"处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"}; |
||||
final static long[] STermInfo = new long[]{0, 21208, 42467, 63836, 85337, |
||||
107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, |
||||
285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, |
||||
462224, 483532, 504758}; |
||||
|
||||
final static String chineseMonthNumber[] = {"正", "二", "三", "四", "五", "六", |
||||
"七", "八", "九", "十", "冬", "腊"}; |
||||
|
||||
final static String[] sFtv = new String[]{"0101*元旦", "0214 情人节", |
||||
"0308 妇女节", "0312 植树节", /*"0314 国际警察日", "0315 消费者权益日", "0323 世界气象日",*/ |
||||
"0401 愚人节", /*"0407 世界卫生日",*/ "0501*劳动节", "0504 青年节", /*"0508 红十字日",*/ |
||||
"0512 护士节", /*"0515 国际家庭日", "0517 世界电信日", "0519 全国助残日", "0531 世界无烟日",*/ |
||||
"0601 儿童节", /*"0605 世界环境日", "0606 全国爱眼日", "0623 奥林匹克日", "0625 全国土地日",*/ |
||||
/*"0626 反毒品日",*/ "0701 建党节", /*"0707 抗战纪念日", "0711 世界人口日",*/ "0801 建军节", |
||||
/* "0908 国际扫盲日", "0909 毛xx逝世纪念",*/ "0910 教师节", /*"0917 国际和平日",*/ |
||||
/* "0920 国际爱牙日", "0922 国际聋人节", "0927 世界旅游日", "0928 孔子诞辰",*/ "1001*国庆节", |
||||
/* "1004 世界动物日", "1006 老人节", "1007 国际住房日", "1009 世界邮政日", "1015 国际盲人节",*/ |
||||
/* "1016 世界粮食日", "1024 联合国日", */"1031 万圣节",/* "1108 中国记者日", "1109 消防宣传日",*/ |
||||
/* "1112 孙中山诞辰", "1114 世界糖尿病日", "1117 国际大学生节",*/ "1128 感恩节", |
||||
/* "1201 世界艾滋病日", "1203 世界残疾人日", "1209 世界足球日", "1220 澳门回归",*/ |
||||
"1225 圣诞节", /*"1226 毛xx诞辰"*/}; |
||||
|
||||
final static String[] lFtv = {"0101*春节", "0115 元宵", "0505 端午", |
||||
"0707 七夕", "0815 中秋", "0909 重阳", "1208 腊八", "1223 小年", |
||||
"0100*除夕"}; |
||||
|
||||
final static String[] wFtv = {"0521 母亲节", "0631 父亲节"};//每年6月第3个星期日是父亲节,5月的第2个星期日是母亲节
|
||||
|
||||
//星期日是一个周的第1天第3个星期日也就是第3个完整周的第一天
|
||||
|
||||
//
|
||||
private LunarCalendar() { |
||||
baseDate.setMinimalDaysInFirstWeek(7);//设置一个月的第一个周是一个完整周
|
||||
|
||||
} |
||||
|
||||
final private static int lYearDays(int y)//====== 传回农历 y年的总天数
|
||||
{ |
||||
int i, sum = 348; |
||||
for (i = 0x8000; i > 0x8; i >>= 1) { |
||||
if ((lunarInfo[y - 1900] & i) != 0) |
||||
sum += 1; |
||||
} |
||||
return (sum + leapDays(y)); |
||||
} |
||||
|
||||
final private static int leapDays(int y)//====== 传回农历 y年闰月的天数
|
||||
{ |
||||
if (leapMonth(y) != 0) { |
||||
if ((lunarInfo[y - 1900] & 0x10000) != 0) |
||||
return 30; |
||||
else |
||||
return 29; |
||||
} else |
||||
return 0; |
||||
} |
||||
|
||||
final private static int leapMonth(int y)//====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
|
||||
{ |
||||
return (int) (lunarInfo[y - 1900] & 0xf); |
||||
} |
||||
|
||||
final public static int monthDays(int y, int m)//====== 传回农历 y年m月的总天数
|
||||
{ |
||||
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) |
||||
return 29; |
||||
else |
||||
return 30; |
||||
} |
||||
|
||||
final private static String AnimalsYear(int y)//====== 传回农历 y年的生肖
|
||||
{ |
||||
|
||||
return Animals[(y - 4) % 12]; |
||||
} |
||||
|
||||
final private static String cyclical(int num)//====== 传入 的offset 传回干支,
|
||||
// 0=甲子
|
||||
{ |
||||
|
||||
return (Gan[num % 10] + Zhi[num % 12]); |
||||
} |
||||
|
||||
// ===== 某年的第n个节气为几日(从0小寒起算)
|
||||
final private int sTerm(int y, int n) { |
||||
|
||||
offDate.set(1900, 0, 6, 2, 5, 0); |
||||
long temp = offDate.getTime().getTime(); |
||||
offDate |
||||
.setTime(new Date( |
||||
(long) ((31556925974.7 * (y - 1900) + STermInfo[n] * 60000L) + temp))); |
||||
|
||||
return offDate.get(Calendar.DAY_OF_MONTH); |
||||
} |
||||
|
||||
/** |
||||
* 传出y年m月d日对应的农历. |
||||
*/ |
||||
public String CalculateLunarCalendar(int y, int m, int d) { |
||||
|
||||
int leapMonth = 0; |
||||
|
||||
try { |
||||
baseDate.setTime(chineseDateFormat.parse("1900年1月31日")); |
||||
|
||||
} catch (ParseException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
long base = baseDate.getTimeInMillis(); |
||||
try { |
||||
baseDate.setTime(chineseDateFormat.parse(y + "年" + m + "月" + d |
||||
+ "日")); |
||||
|
||||
} catch (ParseException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
long obj = baseDate.getTimeInMillis(); |
||||
|
||||
|
||||
int offset = (int) ((obj - base) / 86400000L); |
||||
//System.out.println(offset);
|
||||
//求出和1900年1月31日相差的天数
|
||||
|
||||
dayCyl = offset + 40;//干支天
|
||||
monCyl = 14;//干支月
|
||||
|
||||
//用offset减去每农历年的天数
|
||||
// 计算当天是农历第几天
|
||||
//i最终结果是农历的年份
|
||||
//offset是当年的第几天
|
||||
int iYear, daysOfYear = 0; |
||||
for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) { |
||||
daysOfYear = lYearDays(iYear); |
||||
offset -= daysOfYear; |
||||
monCyl += 12; |
||||
} |
||||
if (offset < 0) { |
||||
offset += daysOfYear; |
||||
iYear--; |
||||
monCyl -= 12; |
||||
} |
||||
//农历年份
|
||||
lyear = iYear; |
||||
|
||||
yearCyl = iYear - 1864;//***********干支年**********//
|
||||
|
||||
leapMonth = leapMonth(iYear); //闰哪个月,1-12
|
||||
leap = false; |
||||
|
||||
//用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
|
||||
int iMonth, daysOfMonth = 0; |
||||
for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) { |
||||
//闰月
|
||||
if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { |
||||
--iMonth; |
||||
leap = true; |
||||
daysOfMonth = leapDays(iYear); |
||||
} else |
||||
daysOfMonth = monthDays(iYear, iMonth); |
||||
|
||||
offset -= daysOfMonth; |
||||
//解除闰月
|
||||
if (leap && iMonth == (leapMonth + 1)) |
||||
leap = false; |
||||
if (!leap) |
||||
monCyl++; |
||||
} |
||||
//offset为0时,并且刚才计算的月份是闰月,要校正
|
||||
if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { |
||||
if (leap) { |
||||
leap = false; |
||||
} else { |
||||
leap = true; |
||||
--iMonth; |
||||
--monCyl; |
||||
} |
||||
} |
||||
//offset小于0时,也要校正
|
||||
if (offset < 0) { |
||||
offset += daysOfMonth; |
||||
--iMonth; |
||||
--monCyl; |
||||
} |
||||
lmonth = iMonth; |
||||
lday = offset + 1; |
||||
|
||||
//******************计算节气**********//
|
||||
|
||||
if (d == sTerm(y, (m - 1) * 2)) |
||||
solarTerms = SolarTerm[(m - 1) * 2]; |
||||
else if (d == sTerm(y, (m - 1) * 2 + 1)) |
||||
solarTerms = SolarTerm[(m - 1) * 2 + 1]; |
||||
else |
||||
solarTerms = ""; |
||||
|
||||
//计算公历节日
|
||||
this.solarFestival = ""; |
||||
for (int i = 0; i < sFtv.length; i++) { |
||||
if (Integer.parseInt(sFtv[i].substring(0, 2)) == m |
||||
&& Integer.parseInt(sFtv[i].substring(2, 4)) == d) { |
||||
solarFestival = sFtv[i].substring(5); |
||||
break; |
||||
} |
||||
} |
||||
//计算农历节日
|
||||
this.lunarFestival = ""; |
||||
for (int i = 0; i < lFtv.length; i++) { |
||||
if (Integer.parseInt(lFtv[i].substring(0, 2)) == lmonth |
||||
&& Integer.parseInt(lFtv[i].substring(2, 4)) == lday) { |
||||
lunarFestival = lFtv[i].substring(5); |
||||
break; |
||||
} |
||||
} |
||||
//计算月周节日
|
||||
|
||||
// System.out.println(baseDate.get(Calendar.WEEK_OF_MONTH) + ""
|
||||
// + baseDate.get(Calendar.DAY_OF_WEEK));
|
||||
|
||||
for (int i = 0; i < wFtv.length; i++) { |
||||
if (Integer.parseInt(wFtv[i].substring(0, 2)) == m |
||||
&& Integer.parseInt(wFtv[i].substring(2, 3)) == baseDate |
||||
.get(Calendar.WEEK_OF_MONTH) |
||||
&& Integer.parseInt(wFtv[i].substring(3, 4)) == baseDate |
||||
.get(Calendar.DAY_OF_WEEK)) { |
||||
solarFestival += wFtv[i].substring(5); |
||||
} |
||||
} |
||||
if(!StringHelper.isEmpty(lunarFestival)){ |
||||
return lunarFestival; |
||||
} |
||||
if(!StringHelper.isEmpty(solarFestival)){ |
||||
return solarFestival; |
||||
} |
||||
if(!StringHelper.isEmpty(solarTerms)){ |
||||
return solarTerms; |
||||
} |
||||
return ""; |
||||
|
||||
} |
||||
|
||||
//set方法
|
||||
public void set(int y, int m, int d) { |
||||
|
||||
CalculateLunarCalendar(y, m, d); |
||||
} |
||||
|
||||
public void set(Calendar cal) { |
||||
|
||||
CalculateLunarCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH)); |
||||
} |
||||
|
||||
// //get方法组
|
||||
public static LunarCalendar getInstance() { |
||||
|
||||
return new LunarCalendar(); |
||||
} |
||||
} |
@ -0,0 +1,68 @@ |
||||
package xyz.fycz.myreader.util.utils; |
||||
|
||||
import android.graphics.drawable.Drawable; |
||||
import android.view.View; |
||||
import android.widget.TextView; |
||||
import androidx.annotation.NonNull; |
||||
import com.google.android.material.snackbar.Snackbar; |
||||
import xyz.fycz.myreader.R; |
||||
import xyz.fycz.myreader.application.MyApplication; |
||||
|
||||
|
||||
/** |
||||
* Created by zhouas666 on 2017/12/28. |
||||
* Snackbar工具类 |
||||
*/ |
||||
public class SnackbarUtils { |
||||
|
||||
|
||||
public static void show(@NonNull View view, @NonNull String msg) { |
||||
show(view, msg, true, null, null); |
||||
} |
||||
|
||||
/** |
||||
* 展示snackBar |
||||
* |
||||
* @param view view |
||||
* @param msg 消息 |
||||
* @param isDismiss 是否自动消失 |
||||
* @param action 事件名 |
||||
* @param iSnackBarClickEvent 事件处理接口 |
||||
*/ |
||||
public static void show(@NonNull View view, @NonNull String msg, boolean isDismiss, String action, final ISnackBarClickEvent iSnackBarClickEvent) { |
||||
//snackBar默认显示时间为LENGTH_LONG
|
||||
int duringTime = Snackbar.LENGTH_LONG; |
||||
if (!isDismiss) { |
||||
duringTime = Snackbar.LENGTH_INDEFINITE; |
||||
} |
||||
Snackbar snackbar; |
||||
snackbar = Snackbar.make(view, msg, duringTime); |
||||
if (action != null) |
||||
snackbar.setAction(action, view1 -> { |
||||
//以接口方式发送出去,便于使用者处理自己的业务逻辑
|
||||
iSnackBarClickEvent.clickEvent(); |
||||
}); |
||||
//设置snackBar和titleBar颜色一致
|
||||
snackbar.getView().setBackgroundColor(MyApplication.getmContext().getColor(R.color.textPrimary)); |
||||
//设置action文字的颜色
|
||||
snackbar.setActionTextColor(MyApplication.getmContext().getColor(R.color.md_white_1000)); |
||||
//设置snackBar图标 这里是获取到snackBar的textView 然后给textView增加左边图标的方式来实现的
|
||||
View snackBarView = snackbar.getView(); |
||||
TextView textView = snackBarView.findViewById(R.id.snackbar_text); |
||||
/*Drawable drawable = getResources().getDrawable(R.mipmap.ic_notification);//图片自己选择
|
||||
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight()); |
||||
textView.setCompoundDrawables(drawable, null, null, null);*/ |
||||
//增加文字和图标的距离
|
||||
textView.setCompoundDrawablePadding(20); |
||||
//展示snackBar
|
||||
snackbar.show(); |
||||
} |
||||
|
||||
/** |
||||
* snackBar的action事件 |
||||
*/ |
||||
public interface ISnackBarClickEvent { |
||||
void clickEvent(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,161 @@ |
||||
package xyz.fycz.myreader.util.utils; |
||||
|
||||
import android.app.Activity; |
||||
import android.os.Build; |
||||
import android.view.View; |
||||
import android.view.WindowManager; |
||||
|
||||
/** |
||||
* 基于 Android 4.4 |
||||
* |
||||
* 主要参数说明: |
||||
* |
||||
* SYSTEM_UI_FLAG_FULLSCREEN : 隐藏StatusBar |
||||
* SYSTEM_UI_FLAG_HIDE_NAVIGATION : 隐藏NavigationBar |
||||
* SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN: 视图扩展到StatusBar的位置,并且StatusBar不消失。 |
||||
* 这里需要一些处理,一般是将StatusBar设置为全透明或者半透明。之后还需要使用fitSystemWindows=防止视图扩展到Status |
||||
* Bar上面(会在StatusBar上加一层View,该View可被移动) |
||||
* SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION: 视图扩展到NavigationBar的位置 |
||||
* SYSTEM_UI_FLAG_LAYOUT_STABLE:稳定效果 |
||||
* SYSTEM_UI_FLAG_IMMERSIVE_STICKY:保证点击任意位置不会退出 |
||||
* |
||||
* 可设置特效说明: |
||||
* 1. 全屏特效 |
||||
* 2. 全屏点击不退出特效 |
||||
* 3. 注意在19 <=sdk <=21 时候,必须通过Window设置透明栏 |
||||
*/ |
||||
|
||||
public class SystemBarUtils { |
||||
|
||||
private static final int UNSTABLE_STATUS = View.SYSTEM_UI_FLAG_FULLSCREEN; |
||||
private static final int UNSTABLE_NAV = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; |
||||
private static final int STABLE_STATUS = View.SYSTEM_UI_FLAG_FULLSCREEN | |
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | |
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | |
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; |
||||
private static final int STABLE_NAV = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | |
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | |
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | |
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; |
||||
private static final int EXPAND_STATUS = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE; |
||||
private static final int EXPAND_NAV = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE; |
||||
|
||||
|
||||
//设置隐藏StatusBar(点击任意地方会恢复)
|
||||
public static void hideUnStableStatusBar(Activity activity){ |
||||
//App全屏,隐藏StatusBar
|
||||
setFlag(activity, UNSTABLE_STATUS); |
||||
} |
||||
|
||||
public static void showUnStableStatusBar(Activity activity){ |
||||
clearFlag(activity, UNSTABLE_STATUS); |
||||
} |
||||
|
||||
//隐藏NavigationBar(点击任意地方会恢复)
|
||||
public static void hideUnStableNavBar(Activity activity){ |
||||
setFlag(activity,UNSTABLE_NAV); |
||||
} |
||||
|
||||
public static void showUnStableNavBar(Activity activity){ |
||||
clearFlag(activity,UNSTABLE_NAV); |
||||
} |
||||
|
||||
public static void hideStableStatusBar(Activity activity){ |
||||
//App全屏,隐藏StatusBar
|
||||
setFlag(activity,STABLE_STATUS); |
||||
} |
||||
|
||||
public static void showStableStatusBar(Activity activity){ |
||||
clearFlag(activity,STABLE_STATUS); |
||||
} |
||||
|
||||
public static void hideStableNavBar(Activity activity){ |
||||
//App全屏,隐藏StatusBar
|
||||
setFlag(activity,STABLE_NAV); |
||||
} |
||||
|
||||
public static void showStableNavBar(Activity activity){ |
||||
clearFlag(activity,STABLE_NAV); |
||||
} |
||||
|
||||
/** |
||||
* 视图扩充到StatusBar |
||||
*/ |
||||
public static void expandStatusBar(Activity activity){ |
||||
setFlag(activity, EXPAND_STATUS); |
||||
} |
||||
|
||||
/** |
||||
* 视图扩充到NavBar |
||||
* @param activity |
||||
*/ |
||||
public static void expandNavBar(Activity activity){ |
||||
setFlag(activity, EXPAND_NAV); |
||||
} |
||||
|
||||
public static void transparentStatusBar(Activity activity){ |
||||
if (Build.VERSION.SDK_INT >= 21){ |
||||
expandStatusBar(activity); |
||||
activity.getWindow() |
||||
.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent)); |
||||
} |
||||
else if (Build.VERSION.SDK_INT >= 19){ |
||||
WindowManager.LayoutParams attrs = activity.getWindow().getAttributes(); |
||||
attrs.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | attrs.flags); |
||||
activity.getWindow().setAttributes(attrs); |
||||
} |
||||
} |
||||
|
||||
public static void transparentNavBar(Activity activity){ |
||||
if (Build.VERSION.SDK_INT >= 21){ |
||||
expandNavBar(activity); |
||||
//下面这个方法在sdk:21以上才有
|
||||
activity.getWindow() |
||||
.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent)); |
||||
} |
||||
} |
||||
|
||||
public static void setFlag(Activity activity, int flag){ |
||||
if (Build.VERSION.SDK_INT >= 19){ |
||||
View decorView = activity.getWindow().getDecorView(); |
||||
int option = decorView.getSystemUiVisibility() | flag; |
||||
decorView.setSystemUiVisibility(option); |
||||
} |
||||
} |
||||
|
||||
//取消flag
|
||||
public static void clearFlag(Activity activity, int flag){ |
||||
if (Build.VERSION.SDK_INT >= 19){ |
||||
View decorView = activity.getWindow().getDecorView(); |
||||
int option = decorView.getSystemUiVisibility() & (~flag); |
||||
decorView.setSystemUiVisibility(option); |
||||
} |
||||
} |
||||
|
||||
public static void setToggleFlag(Activity activity, int option){ |
||||
if (Build.VERSION.SDK_INT >= 19){ |
||||
if (isFlagUsed(activity,option)){ |
||||
clearFlag(activity,option); |
||||
} |
||||
else { |
||||
setFlag(activity,option); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param activity |
||||
* @return flag是否已被使用 |
||||
*/ |
||||
public static boolean isFlagUsed(Activity activity, int flag) { |
||||
int currentFlag = activity.getWindow().getDecorView().getSystemUiVisibility(); |
||||
if((currentFlag & flag) |
||||
== flag) { |
||||
return true; |
||||
}else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<translate |
||||
android:fromYDelta="100%" |
||||
android:toYDelta="0" |
||||
android:duration="200"/> |
||||
</set> |
@ -0,0 +1,7 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<translate |
||||
android:fromYDelta="0" |
||||
android:toYDelta="100%" |
||||
android:duration="200"/> |
||||
</set> |
@ -0,0 +1,8 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<translate android:fromXDelta="0" |
||||
android:fromYDelta="-100%" |
||||
android:toXDelta="0" |
||||
android:toYDelta="0" |
||||
android:duration="200"/> |
||||
</set> |
@ -0,0 +1,6 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<translate android:fromYDelta="0" |
||||
android:toYDelta="-100%" |
||||
android:duration="200"/> |
||||
</set> |
Before Width: | Height: | Size: 169 B |
Before Width: | Height: | Size: 463 B |
Before Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 137 B |
Before Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 428 KiB |
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 604 B |
Before Width: | Height: | Size: 550 B |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 247 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 834 B |
Before Width: | Height: | Size: 244 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
@ -1,11 +1,12 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="24dp" |
||||
android:height="24dp" |
||||
android:viewportWidth="24" |
||||
android:viewportHeight="24"> |
||||
|
||||
android:viewportWidth="1024" |
||||
android:viewportHeight="1024"> |
||||
<path |
||||
android:fillColor="@color/white" |
||||
android:pathData="M5.938,4v16h1.414l4.648-2.789L16.649,20h1.411V4H5.938z M16.606,18.278l-4.605-2.763l-4.609,2.764 V5.454h9.215V18.278z" /> |
||||
android:fillColor="#FFFFFF" |
||||
android:pathData="M364.9,460.4c-51.5,0 -93.5,-41.9 -93.5,-93.5 0,-51.5 41.9,-93.5 93.5,-93.5s93.5,41.9 93.5,93.5c-0.1,51.5 -42,93.5 -93.5,93.5zM364.9,319.2c-26.3,0 -47.7,21.4 -47.7,47.7 0,26.3 21.4,47.7 47.7,47.7s47.7,-21.4 47.7,-47.7c0,-26.3 -21.4,-47.7 -47.7,-47.7z"/> |
||||
<path |
||||
android:fillColor="#FFFFFF" |
||||
android:pathData="M951.1,588.1L437.3,73.4c-5.3,-5.4 -12.5,-8.4 -20,-8.4L93,64c-7.7,0 -15.2,3 -20.6,8.5 -5.5,5.4 -8.5,12.8 -8.4,20.5l0.7,321.7c0.1,7.4 3.1,14.6 8.4,19.8l359,360.7c10.6,10.6 27.6,11.2 38.9,1.4 12.6,-10.9 13.3,-30.1 1.6,-41.9L127.8,408.3c-3.9,-3.9 -6.1,-9.1 -6.2,-14.6l0.3,-250.9c-0.2,-11.8 9.4,-21.4 21.1,-21.3l253.4,0.6c5.5,0 10.8,2.2 14.7,6.2l464.5,465.5c8.2,8.2 8.2,21.5 0,29.7L626.2,873c-8.2,8.2 -21.5,8.2 -29.7,0l-19,-19c-10.6,-10.6 -27.6,-11.2 -38.9,-1.4 -12.6,10.9 -13.3,30.1 -1.6,41.9l53.9,53.9c11.3,11.3 29.6,11.3 40.9,0L951.1,629c11.3,-11.3 11.3,-29.6 0,-40.9z"/> |
||||
</vector> |
@ -0,0 +1,9 @@ |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="24dp" |
||||
android:height="24dp" |
||||
android:viewportWidth="1024" |
||||
android:viewportHeight="1024"> |
||||
<path |
||||
android:fillColor="#FFFFFF" |
||||
android:pathData="M640,320 L192,320C156.61,320 128,348.61 128,384l0,512c0,35.33 28.61,64 64,64l448,0c35.39,0 64,-28.67 64,-64L704,384C704,348.61 675.39,320 640,320zM640,896 L192,896 192,384l448,0L640,896zM832,128 L352,128C334.34,128 320,142.34 320,160S334.34,192 352,192L832,192l0,544c0,17.66 14.34,32 32,32s32,-14.34 32,-32L896,192C896,156.61 867.39,128 832,128z"/> |
||||
</vector> |
@ -1,14 +1,12 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="24dp" |
||||
android:height="24dp" |
||||
android:viewportWidth="24" |
||||
android:viewportHeight="24"> |
||||
|
||||
android:viewportWidth="1024" |
||||
android:viewportHeight="1024"> |
||||
<path |
||||
android:fillColor="#FFFFFF" |
||||
android:pathData="M18.545,18.304c0,0.131-0.11,0.242-0.241,0.242H5.696c-0.131,0-0.242-0.111-0.242-0.242V5.697 c0-0.131,0.111-0.243,0.242-0.243H12V4H5.696C4.76,4,4,4.762,4,5.697v12.606C4,19.239,4.76,20,5.696,20h12.607 C19.239,20,20,19.239,20,18.304v-6.303h-1.455V18.304z" /> |
||||
android:pathData="M762.24,506.88a32,32 0,0 1,-46.08 -44.16l55.68,-58.24a125.76,125.76 0,0 0,-12.16 -171.2c-48.32,-50.24 -119.68,-54.72 -160,-12.48L444.16,384a125.76,125.76 0,0 0,12.16 171.2,32 32,0 0,1 0,45.12 32,32 0,0 1,-45.44 0,189.44 189.44,0 0,1 -12.16,-259.52l155.52,-162.24c66.88,-69.76 180.48,-64 252.8,12.8A189.44,189.44 0,0 1,818.24 448z"/> |
||||
<path |
||||
android:fillColor="#FFFFFF" |
||||
android:pathData="M 19.272 4 L 13.843 4 L 13.843 5.454 L 17.517 5.454 L 7.464 15.508 L 8.491 16.536 L 18.545 6.482 L 18.545 10.157 L 20 10.157 L 20 4.727 L 20 4 Z" /> |
||||
android:pathData="M229.76,517.12a32,32 0,0 1,46.08 44.16l-55.68,58.24a125.76,125.76 0,0 0,12.16 171.2c48.32,50.24 119.68,54.72 160,12.48L547.84,640a125.76,125.76 0,0 0,-12.16 -171.2,32 32,0 0,1 0,-45.12 32,32 0,0 1,45.44 0,189.44 189.44,0 0,1 12.16,259.52L437.76,845.44c-66.88,69.76 -180.48,64 -252.8,-12.8A189.44,189.44 0,0 1,173.76 576z"/> |
||||
</vector> |
@ -0,0 +1,9 @@ |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="24.117188dp" |
||||
android:height="24dp" |
||||
android:viewportWidth="1029" |
||||
android:viewportHeight="1024"> |
||||
<path |
||||
android:fillColor="#9fc6ff" |
||||
android:pathData="M918.39,829.23 L749.22,660.07c-2.93,-2.93 -6.58,-4.37 -9.99,-6.58 98.28,-138.95 86.08,-332.16 -38.34,-456.58 -139.01,-139.07 -364.46,-139.07 -503.54,0 -139.07,139.01 -139.07,364.4 0,503.54 125.79,125.79 321.64,136.56 460.95,34.81 2.21,3.17 3.59,6.64 6.34,9.45l169.16,169.16c23.45,23.39 61.25,23.39 84.58,0C941.71,890.43 941.71,852.56 918.39,829.23L918.39,829.23zM629.65,629.09c-99.65,99.65 -261.22,99.65 -360.93,0 -99.65,-99.65 -99.65,-261.28 0,-360.93 99.65,-99.65 261.22,-99.65 360.93,0C729.36,367.87 729.36,529.43 629.65,629.09L629.65,629.09z"/> |
||||
</vector> |
@ -1,241 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout 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:fitsSystemWindows="true" |
||||
android:orientation="vertical"> |
||||
|
||||
<include layout="@layout/toolbar" /> |
||||
|
||||
<RelativeLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
<!--背景图片--> |
||||
<ImageView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:scaleType="fitXY" |
||||
app:srcCompat="@drawable/bg_login" /> |
||||
<!--添加虚化层--> |
||||
<io.alterac.blurkit.BlurLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
app:blk_blurRadius="5" |
||||
app:blk_fps="0" /> |
||||
|
||||
<!-- 猫头鹰--> |
||||
<!-- <RelativeLayout--> |
||||
<!-- android:layout_width="300dp"--> |
||||
<!-- android:layout_height="200dp"--> |
||||
<!-- android:layout_centerHorizontal="true"--> |
||||
<!-- android:layout_alignTop="@+id/bg"--> |
||||
<!-- android:layout_marginTop="-75dp">--> |
||||
|
||||
<!-- <!–头像–>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_head"--> |
||||
<!-- android:layout_width="wrap_content"--> |
||||
<!-- android:layout_height="wrap_content"--> |
||||
<!-- android:src="@drawable/owl_head"--> |
||||
<!-- android:layout_centerHorizontal="true"--> |
||||
<!-- />--> |
||||
|
||||
<!-- <!–手掌–>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_left_hand"--> |
||||
<!-- android:layout_width="50dp"--> |
||||
<!-- android:layout_height="60dp"--> |
||||
<!-- android:src="@drawable/icon_hand"--> |
||||
<!-- android:layout_alignParentLeft="true"--> |
||||
<!-- android:layout_alignBottom="@+id/iv_head"--> |
||||
<!-- android:layout_marginBottom="-25dp"--> |
||||
<!-- android:layout_marginLeft="10dp"/>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_right_hand"--> |
||||
<!-- android:layout_width="50dp"--> |
||||
<!-- android:layout_height="60dp"--> |
||||
<!-- android:src="@drawable/icon_hand"--> |
||||
<!-- android:layout_alignParentRight="true"--> |
||||
<!-- android:layout_alignBottom="@+id/iv_head"--> |
||||
<!-- android:layout_marginBottom="-25dp"--> |
||||
<!-- android:layout_marginRight="10dp"/>--> |
||||
|
||||
<!-- <!–翅膀–>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_left_arm"--> |
||||
<!-- android:layout_width="65dp"--> |
||||
<!-- android:layout_height="40dp"--> |
||||
<!-- android:src="@drawable/arm_left"--> |
||||
<!-- android:layout_below="@+id/iv_head"--> |
||||
<!-- android:layout_alignParentLeft="true"--> |
||||
<!-- android:layout_marginLeft="20dp"/>--> |
||||
|
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_right_arm"--> |
||||
<!-- android:layout_width="65dp"--> |
||||
<!-- android:layout_height="40dp"--> |
||||
<!-- android:src="@drawable/arm_right"--> |
||||
<!-- android:layout_below="@+id/iv_head"--> |
||||
<!-- android:layout_alignParentRight="true"--> |
||||
<!-- android:layout_marginRight="20dp"/>--> |
||||
<!-- </RelativeLayout>--> |
||||
|
||||
<View |
||||
android:id="@+id/bg" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="280dp" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
android:background="@drawable/input_bg_shape" /> |
||||
|
||||
<io.alterac.blurkit.BlurLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="280dp" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
app:blk_blurRadius="20" |
||||
app:blk_fps="0" /> |
||||
|
||||
<!--添加标题和输入框--> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
android:orientation="vertical" |
||||
android:padding="20dp"> |
||||
|
||||
<!--标题--> |
||||
<TextView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/text_login" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textSecondary" |
||||
android:textSize="20dp" /> |
||||
|
||||
<!--添加输入框--> |
||||
<!--<EditText |
||||
android:id="@+id/et_user" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="50dp" |
||||
android:background="@drawable/editview_shape" |
||||
android:drawableStart="@drawable/iconfont_user" |
||||
android:drawablePadding="10dp" |
||||
android:hint="@string/et_account_tip" |
||||
android:inputType="text" |
||||
android:maxLines="1" |
||||
android:paddingStart="10dp" |
||||
android:textSize="18dp" />--> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_user" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="20dp" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="14"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_account_tip" |
||||
android:inputType="text"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
<!--<EditText |
||||
android:id="@+id/et_password" |
||||
style="@style/EditTextStyle" |
||||
android:background="@drawable/editview_shape" |
||||
android:drawableStart="@drawable/iconfont_password" |
||||
android:hint="@string/et_password_tip" |
||||
android:inputType="textPassword" |
||||
android:textSize="18dp" />--> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_password" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="16" |
||||
app:passwordToggleEnabled="true" |
||||
app:passwordToggleTintMode="src_in"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_password_tip" |
||||
android:inputType="textPassword"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
|
||||
<!--<EditText |
||||
android:id="@+id/et_captcha" |
||||
style="@style/EditTextStyle" |
||||
android:layout_width="match_parent" |
||||
android:layout_weight="1" |
||||
android:background="@drawable/editview_shape" |
||||
android:hint="@string/et_rp_captcha" |
||||
android:inputType="text" |
||||
android:textSize="18dp" />--> |
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="4"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_rp_captcha" |
||||
android:inputType="text"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<ImageView |
||||
android:id="@+id/iv_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="3" |
||||
android:layout_gravity="center_vertical" |
||||
android:paddingStart="7dp" /> |
||||
|
||||
</LinearLayout> |
||||
<!--登录按钮--> |
||||
<Button |
||||
android:id="@+id/bt_login" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="50dp" |
||||
android:layout_marginTop="20dp" |
||||
android:background="@drawable/login_btn_selector" |
||||
android:enabled="false" |
||||
android:text="@string/text_login" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textPrimaryInverted" |
||||
android:textSize="25dp" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_register" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp" |
||||
android:text="@string/tv_register" |
||||
android:textColor="@color/colorAccent" /> |
||||
</LinearLayout> |
||||
</RelativeLayout> |
||||
|
||||
|
||||
</LinearLayout> |
@ -0,0 +1,199 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> |
||||
|
||||
<com.google.android.material.appbar.AppBarLayout |
||||
android:id="@+id/read_abl_top_menu" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:background="@color/read_menu_bg" |
||||
android:visibility="gone" |
||||
tools:visibility="visible"> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="vertical"> |
||||
|
||||
<androidx.appcompat.widget.Toolbar |
||||
android:id="@+id/toolbar" |
||||
style="@style/NoPaddingToolbar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="45dp" |
||||
android:minHeight="?attr/actionBarSize" |
||||
android:gravity="center_vertical" |
||||
android:theme="?attr/actionBarStyle" |
||||
android:transitionName="sharedView" |
||||
app:title="大主宰" |
||||
app:layout_scrollFlags="scroll|enterAlways" |
||||
app:popupTheme="@style/AppTheme.PopupOverlay"> |
||||
</androidx.appcompat.widget.Toolbar> |
||||
<View |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="0.5dp" |
||||
android:background="@color/sys_dialog_setting_line" /> |
||||
<LinearLayout |
||||
android:id="@+id/ll_chapter_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="40dp" |
||||
android:orientation="vertical"> |
||||
<TextView android:id="@+id/tv_chapter_title_top" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginStart="14dp" |
||||
android:layout_marginEnd="14dp" |
||||
android:textSize="15sp" |
||||
android:text="章节名称" |
||||
android:ellipsize="end" |
||||
android:maxLines="1" |
||||
android:textColor="@color/read_menu_text"> |
||||
</TextView> |
||||
<TextView android:id="@+id/tv_chapter_url" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginStart="14dp" |
||||
android:layout_marginEnd="14dp" |
||||
android:ellipsize="end" |
||||
android:textSize="13sp" |
||||
android:text="章节链接" |
||||
android:maxLines="1" |
||||
android:textColor="@color/read_menu_text"> |
||||
</TextView> |
||||
</LinearLayout> |
||||
</LinearLayout> |
||||
</com.google.android.material.appbar.AppBarLayout> |
||||
|
||||
<!--阅读页面--> |
||||
<xyz.fycz.myreader.widget.page.PageView |
||||
android:id="@+id/read_pv_content" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:clickable="true" |
||||
tools:visibility="gone"/> |
||||
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:layout_marginTop="20dp" |
||||
android:layout_marginBottom="20dp"> |
||||
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBar |
||||
android:id="@+id/pb_nextPage" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:splitTrack="false" |
||||
app:seekBarRotation="CW270" |
||||
android:visibility="invisible" |
||||
tools:visibility="visible"/> |
||||
</com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper> |
||||
<ProgressBar |
||||
android:id="@+id/pb_loading" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_centerInParent="true" |
||||
android:visibility="gone" |
||||
tools:visibility="visible"/> |
||||
|
||||
<!--切换页面提示--> |
||||
<TextView |
||||
android:id="@+id/read_tv_page_tip" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_above="@+id/read_ll_bottom_menu" |
||||
android:layout_centerHorizontal="true" |
||||
android:layout_marginBottom="10dp" |
||||
android:background="@color/read_menu_bg" |
||||
android:gravity="center" |
||||
android:paddingLeft="12dp" |
||||
android:paddingTop="8dp" |
||||
android:paddingRight="12dp" |
||||
android:paddingBottom="8dp" |
||||
android:text="1/12" |
||||
android:textColor="@color/md_white_1000" |
||||
android:visibility="gone"/> |
||||
|
||||
<!--底部页面--> |
||||
<LinearLayout |
||||
android:id="@+id/read_ll_bottom_menu" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignParentBottom="true" |
||||
android:background="@color/read_menu_bg" |
||||
android:clickable="true" |
||||
android:orientation="vertical" |
||||
android:visibility="gone" |
||||
tools:visibility="visible"> |
||||
|
||||
<!--页面进度栏--> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="60dp" |
||||
android:gravity="center_vertical" |
||||
android:orientation="horizontal"> |
||||
|
||||
<TextView |
||||
android:id="@+id/read_tv_pre_chapter" |
||||
style="@style/MAppTheme.TextAppearance.Read.BottomMenu" |
||||
android:layout_width="80dp" |
||||
android:layout_height="match_parent" |
||||
android:gravity="center" |
||||
android:text="上一章"/> |
||||
|
||||
<SeekBar |
||||
android:id="@+id/read_sb_chapter_progress" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:max="100" |
||||
android:maxHeight="3dp" |
||||
android:minHeight="3dp" |
||||
android:progressDrawable="@drawable/seekbar_bg" |
||||
android:thumb="@mipmap/thumb" |
||||
android:thumbOffset="10dp"/> |
||||
|
||||
<TextView |
||||
android:id="@+id/read_tv_next_chapter" |
||||
style="@style/MAppTheme.TextAppearance.Read.BottomMenu" |
||||
android:layout_width="80dp" |
||||
android:layout_height="match_parent" |
||||
android:gravity="center" |
||||
android:text="下一章"/> |
||||
</LinearLayout> |
||||
<View |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="0.5dp" |
||||
android:background="@color/sys_dialog_setting_line" /> |
||||
<!--菜单栏--> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="72dp" |
||||
android:orientation="horizontal" |
||||
android:paddingTop="12dp" |
||||
android:paddingBottom="12dp"> |
||||
|
||||
<TextView |
||||
android:id="@+id/read_tv_category" |
||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||
android:drawableTop="@mipmap/t3" |
||||
android:text="目录"/> |
||||
|
||||
<TextView |
||||
android:id="@+id/read_tv_download" |
||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||
android:drawableTop="@mipmap/download" |
||||
android:text="下载"/> |
||||
|
||||
<TextView |
||||
android:id="@+id/read_tv_night_mode" |
||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||
android:drawableTop="@mipmap/ao" |
||||
android:text="夜间"/> |
||||
|
||||
<TextView |
||||
android:id="@+id/read_tv_setting" |
||||
style="@style/AppTheme.TextAppearance.Read.BottomMenu.Button" |
||||
android:drawableTop="@mipmap/t6" |
||||
android:text="设置"/> |
||||
</LinearLayout> |
||||
</LinearLayout> |
||||
</RelativeLayout> |
@ -1,59 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.drawerlayout.widget.DrawerLayout |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:fitsSystemWindows="true" |
||||
android:id="@+id/read_activity_new" |
||||
tools:context="xyz.fycz.myreader.ui.activity.ReadActivity"> |
||||
|
||||
<RelativeLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<!--阅读页面--> |
||||
<xyz.fycz.myreader.widget.page.PageView |
||||
android:id="@+id/read_pv_page" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:clickable="true" |
||||
tools:visibility="gone"/> |
||||
|
||||
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:layout_marginTop="20dp" |
||||
android:layout_marginBottom="20dp"> |
||||
<com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBar |
||||
android:id="@+id/pb_nextPage" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:splitTrack="false" |
||||
app:seekBarRotation="CW270" |
||||
android:visibility="invisible"/> |
||||
</com.h6ah4i.android.widget.verticalseekbar.VerticalSeekBarWrapper> |
||||
|
||||
<ProgressBar |
||||
android:id="@+id/pb_loading" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_centerInParent="true" |
||||
android:visibility="gone"/> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_end_page_tip" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="35dp" |
||||
android:layout_alignParentBottom="true" |
||||
android:background="@color/sys_dialog_setting_line" |
||||
android:textColor="@color/sys_dialog_setting_word_bright" |
||||
android:text="@string/end_page_tip" |
||||
android:gravity="center_vertical|start" |
||||
android:paddingStart="15dp" |
||||
android:textSize="14sp" |
||||
android:visibility="gone"/> |
||||
|
||||
</RelativeLayout> |
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout> |
@ -1,205 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout 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:fitsSystemWindows="true" |
||||
android:orientation="vertical"> |
||||
|
||||
<include layout="@layout/toolbar" /> |
||||
|
||||
<RelativeLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
<!--背景图片--> |
||||
<ImageView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:scaleType="fitXY" |
||||
app:srcCompat="@drawable/bg_login" /> |
||||
<!--添加虚化层--> |
||||
<io.alterac.blurkit.BlurLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
app:blk_blurRadius="5" |
||||
app:blk_fps="0" /> |
||||
|
||||
<View |
||||
android:id="@+id/bg" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="280dp" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
android:background="@drawable/input_bg_shape" /> |
||||
|
||||
<io.alterac.blurkit.BlurLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="400dp" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
app:blk_blurRadius="20" |
||||
app:blk_fps="0" /> |
||||
|
||||
<!--添加标题和输入框--> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
android:orientation="vertical" |
||||
android:padding="20dp"> |
||||
|
||||
<!--标题--> |
||||
<TextView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/text_register" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/sys_word_little" |
||||
android:textSize="20dp" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_register_tip" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp" |
||||
android:text="" |
||||
android:textColor="@color/textError" |
||||
android:visibility="gone" /> |
||||
<!--添加输入框--> |
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_username" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="14"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_account_tip" |
||||
android:inputType="text"/> |
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_password" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="16" |
||||
app:passwordToggleEnabled="true" |
||||
app:passwordToggleTintMode="src_in"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_password_tip" |
||||
android:inputType="textPassword"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_rp_password" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="16" |
||||
app:passwordToggleEnabled="true" |
||||
app:passwordToggleTintMode="src_in"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_password_tip" |
||||
android:inputType="textPassword"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="4"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_rp_captcha" |
||||
android:inputType="text"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
|
||||
<ImageView |
||||
android:id="@+id/iv_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_vertical" |
||||
android:layout_weight="3" |
||||
android:paddingStart="7dp" /> |
||||
|
||||
</LinearLayout> |
||||
|
||||
<!--登录按钮--> |
||||
<Button |
||||
android:id="@+id/bt_register" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="50dp" |
||||
android:layout_marginTop="10dp" |
||||
android:background="@drawable/login_btn_selector" |
||||
android:enabled="false" |
||||
android:text="@string/text_register" |
||||
android:textAlignment="center" |
||||
android:textColor="#ffffff" |
||||
android:textSize="25dp" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp" |
||||
android:orientation="horizontal"> |
||||
|
||||
<CheckBox |
||||
android:id="@+id/cb_agreement" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/text_agreement_tip" |
||||
android:textColor="@color/textSecondaryInverted" |
||||
android:theme="@style/MyCheckBox" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_agreement" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/link_agreement" |
||||
android:textColor="@color/colorAccent" |
||||
android:textSize="14dp" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="》" |
||||
android:textColor="@color/textSecondaryInverted" /> |
||||
</LinearLayout> |
||||
</LinearLayout> |
||||
</RelativeLayout> |
||||
|
||||
|
||||
</LinearLayout> |
@ -0,0 +1,16 @@ |
||||
<?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:id="@+id/dialog_tv_content" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:textIsSelectable="true" |
||||
android:textColor="@color/textSecondary" |
||||
android:textSize="@dimen/text_normal_size" |
||||
android:text="神墓(辰东)"/> |
||||
|
||||
</LinearLayout> |
@ -1,297 +0,0 @@ |
||||
<?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:layout_gravity="center_vertical" > |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="86dp" |
||||
android:orientation="vertical"> |
||||
<RelativeLayout |
||||
android:id="@+id/rl_title_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="45dp" |
||||
android:background="@color/sys_dialog_setting_bg"> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_title" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:orientation="horizontal"> |
||||
<LinearLayout |
||||
android:id="@+id/ll_title_back" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:orientation="horizontal" |
||||
android:paddingLeft="10dp"> |
||||
<ImageView |
||||
android:layout_width="20dp" |
||||
android:layout_height="20dp" |
||||
android:layout_gravity="center" |
||||
android:layout_margin="5dip" |
||||
app:srcCompat="@mipmap/larrow3"/> |
||||
</LinearLayout> |
||||
|
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_book_name" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:gravity="center" |
||||
android:orientation="horizontal" |
||||
android:paddingRight="10dp"> |
||||
<TextView |
||||
android:id="@+id/tv_book_name_top" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:gravity="center" |
||||
android:layout_marginLeft="15dp" |
||||
android:text="@string/app_name" |
||||
android:textSize="20sp" |
||||
android:textColor="@color/sys_dialog_setting_word"> |
||||
</TextView> |
||||
</LinearLayout> |
||||
</LinearLayout> |
||||
<LinearLayout |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="match_parent" |
||||
android:layout_alignParentRight="true" |
||||
android:gravity="center" |
||||
android:orientation="horizontal" |
||||
android:paddingRight="10dp"> |
||||
<ImageView |
||||
android:id="@+id/iv_change_source" |
||||
android:layout_width="30dp" |
||||
android:layout_height="match_parent" |
||||
android:src="@drawable/ic_change_source" |
||||
app:tint="@color/little_black_white"/> |
||||
<ImageView |
||||
android:id="@+id/iv_refresh" |
||||
android:layout_marginLeft="15dp" |
||||
android:layout_width="30dp" |
||||
android:layout_height="match_parent" |
||||
android:src="@drawable/ic_refresh" |
||||
app:tint="@color/little_black_white"/> |
||||
<ImageView |
||||
android:id="@+id/iv_book_mark" |
||||
android:layout_marginLeft="12dp" |
||||
android:layout_width="33dp" |
||||
android:layout_height="match_parent" |
||||
android:src="@drawable/ic_bookmark" |
||||
app:tint="@color/little_black_white"/> |
||||
<ImageView |
||||
android:id="@+id/iv_voice_read" |
||||
android:layout_width="25dp" |
||||
android:layout_height="match_parent" |
||||
android:layout_marginLeft="20dp" |
||||
app:srcCompat="@mipmap/bd" |
||||
android:visibility="gone"/> |
||||
|
||||
<ImageView |
||||
android:id="@+id/iv_more" |
||||
android:layout_width="25dp" |
||||
android:layout_height="match_parent" |
||||
android:layout_marginLeft="20dp" |
||||
app:srcCompat="@mipmap/t8" |
||||
android:visibility="gone"/> |
||||
</LinearLayout> |
||||
</RelativeLayout> |
||||
<View |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="1dp" |
||||
android:background="@color/sys_dialog_setting_line" /> |
||||
<LinearLayout |
||||
android:id="@+id/ll_chapter_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="40dp" |
||||
android:background="@color/sys_dialog_setting_bg" |
||||
android:orientation="vertical"> |
||||
<TextView android:id="@+id/tv_chapter_title_top" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="14dp" |
||||
android:textSize="15sp" |
||||
android:text="章节名称" |
||||
android:maxLines="1" |
||||
android:textColor="@color/sys_dialog_setting_word"> |
||||
</TextView> |
||||
<TextView android:id="@+id/tv_chapter_url" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="15dp" |
||||
android:textSize="13sp" |
||||
android:text="章节链接" |
||||
android:maxLines="1" |
||||
android:textColor="@color/sys_dialog_setting_word"> |
||||
</TextView> |
||||
</LinearLayout> |
||||
</LinearLayout> |
||||
|
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_bottom_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignParentBottom="true" |
||||
android:layout_alignParentStart="true" |
||||
android:background="@color/sys_dialog_setting_bg" |
||||
android:orientation="vertical"> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal" |
||||
android:paddingBottom="30dp" |
||||
android:paddingLeft="10dp" |
||||
android:paddingRight="10dp" |
||||
android:paddingTop="30dp"> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_last_chapter" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="上一章" |
||||
android:textColor="@color/sys_dialog_setting_word" |
||||
android:textSize="15sp" /> |
||||
|
||||
<SeekBar |
||||
android:id="@+id/sb_read_chapter_progress" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:layout_marginRight="10dp" |
||||
android:layout_weight="1" |
||||
android:maxHeight="1dp" |
||||
android:minHeight="1dp" |
||||
android:progressDrawable="@drawable/seekbar_bg" |
||||
android:thumb="@mipmap/thumb"/> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_next_chapter" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="下一章" |
||||
android:textColor="@color/sys_dialog_setting_word" |
||||
android:textSize="15sp"/> |
||||
|
||||
</LinearLayout> |
||||
|
||||
<ImageView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="1px" |
||||
app:srcCompat="@color/sys_dialog_setting_line" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:paddingBottom="10dp" |
||||
android:paddingTop="10dp" |
||||
android:gravity="center"> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_chapter_list" |
||||
android:layout_width="match_parent" |
||||
android:layout_weight="1" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="vertical" |
||||
android:gravity="center"> |
||||
|
||||
<ImageView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:srcCompat="@mipmap/t3" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="5dp" |
||||
android:text="目录" |
||||
android:textColor="@color/sys_dialog_setting_word" /> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_download_cache" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:orientation="vertical" |
||||
android:gravity="center"> |
||||
|
||||
<ImageView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:srcCompat="@mipmap/download" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_download_progress" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="5dp" |
||||
android:text="缓存" |
||||
android:textColor="@color/sys_dialog_setting_word" /> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_night_and_day" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:gravity="center" |
||||
android:orientation="vertical"> |
||||
|
||||
<ImageView |
||||
android:id="@+id/iv_night_and_day" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:srcCompat="@mipmap/ao" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_night_and_day" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="5dp" |
||||
android:text="夜间" |
||||
android:textColor="@color/sys_dialog_setting_word" /> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_setting" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:orientation="vertical" |
||||
android:gravity="center"> |
||||
|
||||
<ImageView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:srcCompat="@mipmap/t6" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="5dp" |
||||
android:text="设置" |
||||
android:textColor="@color/sys_dialog_setting_word" /> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
|
||||
|
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,34 @@ |
||||
<?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" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<item |
||||
android:id="@+id/action_change_source" |
||||
android:icon="@drawable/ic_change_source" |
||||
android:title="@string/menu_change_source" |
||||
app:showAsAction="ifRoom"/> |
||||
<item |
||||
android:id="@+id/action_reload" |
||||
android:icon="@drawable/ic_refresh" |
||||
android:title="@string/menu_reload" |
||||
app:showAsAction="ifRoom"/> |
||||
|
||||
<group android:id="@+id/action_load_finish"> |
||||
<item |
||||
android:id="@+id/action_add_bookmark" |
||||
android:icon="@drawable/ic_bookmark" |
||||
android:title="@string/menu_add_bookmark" |
||||
app:showAsAction="never"/> |
||||
<item |
||||
android:id="@+id/action_copy_content" |
||||
android:icon="@drawable/ic_copy" |
||||
android:title="@string/menu_copy_content" |
||||
app:showAsAction="never"/> |
||||
<item |
||||
android:id="@+id/action_open_link" |
||||
android:icon="@drawable/ic_link" |
||||
android:title="@string/menu_open_link" |
||||
app:showAsAction="never"/> |
||||
</group> |
||||
</menu> |
@ -0,0 +1,10 @@ |
||||
<?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_tip" |
||||
android:icon="@drawable/ic_question" |
||||
android:title="提示" |
||||
app:showAsAction="always" |
||||
android:visible="true"/> |
||||
</menu> |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 110 B |
Before Width: | Height: | Size: 638 B |
Before Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 487 KiB |