Diycode开源项目 SettingActivity分析
Posted Jason_Jan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Diycode开源项目 SettingActivity分析相关的知识,希望对你有一定的参考价值。
1.整体效果预览及布局分析
1.1.设置界面预览
1.2.主体对应关系
注意这里的线条用ImageView来实现
有一个TextView是检查更新,默认隐藏,具体出现时间还得之后确认。
最后一个LinearLayout是用于登录用户还是未登录用户的区分。
其他都是确定好的静态布局。当然缓存大小和当前版本会变化。
1.3.外层布局和内层布局的关联
这里toolbar也是不能少的。
然后将剩下的布局用一个NestedScrollView包括,紧接着是一个LinearLayout布局。
NestedScrollView支持嵌套布局。
如果我把下面的LinearLayout加长,可以做到类似这样的效果:
1.4.布局源代码
<?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright 2017 GcsSloop ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. ~ ~ Last modified 2017-03-22 04:30:23 ~ ~ GitHub: https://github.com/GcsSloop ~ Website: http://www.gcssloop.com ~ Weibo: http://weibo.com/GcsSloop --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_setting" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.gcssloop.diycode.activity.SettingActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content"/> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/diy_white_bg"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white_bg" android:padding="12dp" android:text="应用" android:textStyle="bold"/> <RelativeLayout android:id="@+id/clear_cache" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="清除缓存" android:textSize="16sp"/> <TextView android:id="@+id/cache_size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:textSize="16sp" tools:text="1.00M"/> </RelativeLayout> <ImageView android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/diy_white" android:paddingLeft="16dp" android:paddingRight="16dp" android:src="@color/diy_gray"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="当前版本" android:textSize="16sp"/> <TextView android:id="@+id/app_version" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:checked="true" tools:text="v0.0.1"/> </RelativeLayout> <ImageView android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/diy_white" android:paddingLeft="16dp" android:paddingRight="16dp" android:src="@color/diy_gray"/> <TextView android:visibility="gone" android:id="@+id/check_version" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white" android:padding="16dp" android:text="检测更新" android:textSize="16sp"/> <TextView android:id="@+id/about" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white" android:padding="16dp" android:text="关于" android:textSize="16sp"/> <ImageView android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/diy_white" android:paddingLeft="16dp" android:paddingRight="16dp" android:src="@color/diy_gray"/> <TextView android:id="@+id/contribute" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white" android:gravity="center" android:padding="16dp" android:text="¥ 捐赠一杯咖啡" android:textColor="#4AC432" android:textSize="16sp"/> <LinearLayout android:id="@+id/user" android:layout_width="match_parent" android:layout_height="600dp" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white_bg" android:padding="12dp" android:text="用户" android:textStyle="bold"/> <TextView android:id="@+id/logout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/diy_white" android:gravity="center" android:padding="16dp" android:text="退出登录" android:textColor="@color/diy_red" android:textSize="16sp"/> </LinearLayout> </LinearLayout> </android.support.v4.widget.NestedScrollView> </LinearLayout>
SettingActivity活动的布局名称为:activity_setting.xml
2.SettingActivity源代码分析
2.1.成员变量分析
成员变量仅仅只有一个Config。
Config类为用户设置,在通用类中定义,源代码为:
/* * Copyright 2017 GcsSloop * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Last modified 2017-03-28 04:48:02 * * GitHub: https://github.com/GcsSloop * Website: http://www.gcssloop.com * Weibo: http://weibo.com/GcsSloop */ package com.gcssloop.diycode.utils; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.LruCache; import com.gcssloop.diycode_sdk.utils.ACache; import java.io.Serializable; /** * 用户设置 */ public class Config { private static int M = 1024 * 1024; private volatile static Config mConfig; private static LruCache<String, Object> mLruCache = new LruCache<>(1 * M); private static ACache mDiskCache; private Config(Context context) { mDiskCache = ACache.get(context, "config"); } public static Config init(Context context) { if (null == mConfig) { synchronized (Config.class) { if (null == mConfig) { mConfig = new Config(context); } } } return mConfig; } public static Config getSingleInstance() { return mConfig; } //--- 基础 ----------------------------------------------------------------------------------- public <T extends Serializable> void saveData(@NonNull String key, @NonNull T value) { mLruCache.put(key, value); mDiskCache.put(key, value); } public <T extends Serializable> T getData(@NonNull String key, @Nullable T defaultValue) { T result = (T) mLruCache.get(key); if (result != null) { return result; } result = (T) mDiskCache.getAsObject(key); if (result != null) { mLruCache.put(key, result); return result; } return defaultValue; } //--- 浏览器 --------------------------------------------------------------------------------- private static String Key_Browser = "UseInsideBrowser_"; public void setUesInsideBrowser(@NonNull Boolean bool) { saveData(Key_Browser, bool); } public Boolean isUseInsideBrowser() { return getData(Key_Browser, Boolean.TRUE); } //--- 首页状态 ------------------------------------------------------------------------------- private String Key_MainViewPager_Position = "Key_MainViewPager_Position"; public void saveMainViewPagerPosition(Integer position) { mLruCache.put(Key_MainViewPager_Position, position); } public Integer getMainViewPagerPosition() { return getData(Key_MainViewPager_Position, 0); } //--- Topic状态 ------------------------------------------------------------------------------ private String Key_TopicList_LastPosition = "Key_TopicList_LastPosition"; private String Key_TopicList_LastOffset = "Key_TopicList_LastOffset"; public void saveTopicListState(Integer lastPosition, Integer lastOffset) { saveData(Key_TopicList_LastPosition, lastPosition); saveData(Key_TopicList_LastOffset, lastOffset); } public Integer getTopicListLastPosition() { return getData(Key_TopicList_LastPosition, 0); } public Integer getTopicListLastOffset() { return getData(Key_TopicList_LastOffset, 0); } private String Key_TopicList_PageIndex = "Key_TopicList_PageIndex"; public void saveTopicListPageIndex(Integer pageIndex) { saveData(Key_TopicList_PageIndex, pageIndex); } public Integer getTopicListPageIndex() { return getData(Key_TopicList_PageIndex, 0); } //--- News状态 ------------------------------------------------------------------------------ private String Key_NewsList_LastScroll = "Key_NewsList_LastScroll"; public void saveNewsListScroll(Integer lastScrollY) { saveData(Key_NewsList_LastScroll, lastScrollY); } public Integer getNewsLastScroll() { return getData(Key_NewsList_LastScroll, 0); } private String Key_NewsList_LastPosition = "Key_NewsList_LastPosition"; public void saveNewsListPosition(Integer lastPosition) { saveData(Key_NewsList_LastPosition, lastPosition); } public Integer getNewsListLastPosition() { return getData(Key_NewsList_LastPosition, 0); } private String Key_NewsList_PageIndex = "Key_NewsList_PageIndex"; public void saveNewsListPageIndex(Integer pageIndex) { saveData(Key_NewsList_PageIndex, pageIndex); } public Integer getNewsListPageIndex() { return getData(Key_NewsList_PageIndex, 0); } }
2.2.然后加载布局代码
2.3.然后初始化视图
首先将标题设置好。
获得缓存大小。
从BaseActivity中的成员变量mDiycode中来获取登录信息,如果登录了,则下面要显示退出登录字样。
然后设置监听事件。
2.4.显示缓存大小
首先从FileUtil通用类中获取缓存地址。
FileUitl源代码如下:
/* * Copyright 2017 GcsSloop * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Last modified 2017-03-08 01:01:18 * * GitHub: https://github.com/GcsSloop * Website: http://www.gcssloop.com * Weibo: http://weibo.com/GcsSloop */ package com.gcssloop.diycode.utils; import android.content.Context; import android.os.Environment; import java.io.File; public class FileUtil { private FileUtil() { } //****系统文件目录********************************************************************************************** /** * @return 程序系统文件目录 */ public static String getFileDir(Context context) { return String.valueOf(context.getFilesDir()); } /** * @param context 上下文 * @param customPath 自定义路径 * @return 程序系统文件目录绝对路径 */ public static String getFileDir(Context context, String customPath) { String path = context.getFilesDir() + formatPath(customPath); mkdir(path); return path; } //****系统缓存目录********************************************************************************************** /** * @return 程序系统缓存目录 */ public static String getCacheDir(Context context) { return String.valueOf(context.getCacheDir()); } /** * @param context 上下文 * @param customPath 自定义路径 * @return 程序系统缓存目录 */ public static String getCacheDir(Context context, String customPath) { String path = context.getCacheDir() + formatPath(customPath); mkdir(path); return path; } //****Sdcard文件目录********************************************************************************************** /** * @return 内存卡文件目录 */ public static String getExternalFileDir(Context context) { return String.valueOf(context.getExternalFilesDir("")); } /** * @param context 上下文 * @param customPath 自定义路径 * @return 内存卡文件目录 */ public static String getExternalFileDir(Context context, String customPath) { String path = context.getExternalFilesDir("") + formatPath(customPath); mkdir(path); return path; } //****Sdcard缓存目录********************************************************************************************** /** * @return 内存卡缓存目录 */ public static String getExternalCacheDir(Context context) { return String.valueOf(context.getExternalCacheDir()); } /** * @param context 上下文 * @param customPath 自定义路径 * @return 内存卡缓存目录 */ public static String getExternalCacheDir(Context context, String customPath) { String path = context.getExternalCacheDir() + formatPath(customPath); mkdir(path); return path; } //****公共文件夹********************************************************************************************** /** * @return 公共下载文件夹 */ public static String getPublicDownloadDir() { return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(); } //****相关工具********************************************************************************************** /** * 创建文件夹 * * @param DirPath 文件夹路径 */ public static void mkdir(String DirPath) { File file = new File(DirPath); if (!(file.exists() && file.isDirectory())) { file.mkdirs(); } } /** * 格式化文件路径 * 示例: 传入 "sloop" "/sloop" "sloop/" "/sloop/" * 返回 "/sloop" */ private static String formatPath(String path) { if (!path.startsWith("/")) path = "/" + path; while (path.endsWith("/")) path = new String(path.toCharArray(), 0, path.length() - 1); return path; } /** * @return 存储卡是否挂载(存在) */ public static boolean isMountSdcard() { String status = Environment.getExternalStorageState(); return status.equals(Environment.MEDIA_MOUNTED); } }
然后从DataCleanManager通用类中获取缓存大小。
DataCleanManager源代码如下:
/* * Copyright 2017 GcsSloop * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Last modified 2017-03-26 03:46:50 * * GitHub: https://github.com/GcsSloop * Website: http://www.gcssloop.com * Weibo: http://weibo.com/GcsSloop */ package com.gcssloop.diycode.utils; import android.content.Context; import android.os.Environment; import android.text.TextUtils; import java.io.File; import java.math.BigDecimal; /** * 本应用数据清除管理器 */ public class DataCleanManager { /** * * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * * * @param context */ public static void cleanInternalCache(Context context) { deleteFilesByDirectory(context.getCacheDir()); } /** * * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * * * @param context */ public static void cleanDatabases(Context context) { deleteFilesByDirectory(new File("/data/data/" + context.getPackageName() + "/databases")); } /** * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * * @param context */ public static void cleanSharedPreference(Context context) { deleteFilesByDirectory(new File("/data/data/" + context.getPackageName() + "/shared_prefs")); } /** * * 按名字清除本应用数据库 * * * * @param context * @param dbName */ public static void cleanDatabaseByName(Context context, String dbName) { context.deleteDatabase(dbName); } /** * * 清除/data/data/com.xxx.xxx/files下的内容 * * * * @param context */ public static void cleanFiles(Context context) { deleteFilesByDirectory(context.getFilesDir()); } /** * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param context */ public static void cleanExternalCache(Context context) { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { deleteFilesByDirectory(context.getExternalCacheDir()); } } /** * * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * * * * @param filePath */ public static void cleanCustomCache(String filePath) { deleteFilesByDirectory(new File(filePath)); } /** * * 清除本应用所有的数据 * * * * @param context * @param filepath */ public static void cleanApplicationData(Context context, String... filepath) { cleanInternalCache(context); cleanExternalCache(context); cleanDatabases(context); cleanSharedPreference(context); cleanFiles(context); if (filepath == null) { return; } for (String filePath : filepath) { cleanCustomCache(filePath); } } /** * * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * * * * @param directory */ private static void deleteFilesByDirectory(File directory) { if (directory != null && directory.exists() && directory.isDirectory()) { for (File item : directory.listFiles()) { item.delete(); } } } // 获取文件 //Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据 //Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据 public static long getFolderSize(File file) throws Exception { long size = 0; try { File[] fileList = file.listFiles(); for (int i = 0; i < fileList.length; i++) { // 如果下面还有文件 if (fileList[i].isDirectory()) { size = size + getFolderSize(fileList[i]); } else { size = size + fileList[i].length(); } } } catch (Exception e) { e.printStackTrace(); } return size; } /** * 删除指定目录下文件及目录 * * @param deleteThisPath * @param filePath * @return */ public static void deleteFolderFile(String filePath, boolean deleteThisPath) { if (!TextUtils.isEmpty(filePath)) { try { File file = new File(filePath); if (file.isDirectory()) {// 如果下面还有文件 File files[] = file.listFiles(); for (int i = 0; i < files.length; i++) { deleteFolderFile(files[i].getAbsolutePath(), true); } } if (deleteThisPath) { if (!file.isDirectory()) {// 如果是文件,删除 file.delete(); } else {// 目录 if (file.listFiles().length == 0) {// 目录下没有文件或者目录,删除 file.delete(); } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 格式化单位 * * @param size * @return */ public static String getFormatSize(double size) { double kiloByte = size / 1024; if (kiloByte < 1) { return size + "Byte"; } double megaByte = kiloByte / 1024; if (megaByte < 1) { BigDecimal result1 = new BigDecimal(Double.toString(kiloByte)); return result1.setScale(2, BigDecimal.ROUND_HALF_UP) .toPlainString() + "KB"; } double gigaByte = megaByte / 1024; if (gigaByte < 1) { BigDecimal result2 = new BigDecimal(Double.toString(megaByte)); return result2.setScale(2, BigDecimal.ROUND_HALF_UP) .toPlainString() + "MB"; } double teraBytes = gigaByte / 1024; if (teraBytes < 1) { BigDecimal result3 = new BigDecimal(Double.toString(gigaByte)); return result3.setScale(2, BigDecimal.ROUND_HALF_UP) .toPlainString() + "GB"; } BigDecimal result4 = new BigDecimal(teraBytes); return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB"; } public static String getCacheSize(File file) throws Exception { return以上是关于Diycode开源项目 SettingActivity分析的主要内容,如果未能解决你的问题,请参考以下文章