編輯:關於Android編程
import android.content.Context;
import android.os.Environment;
import android.support.annotation.Nullable;
import com.lidroid.xutils.db.annotation.NotNull;
import junit.framework.Assert;
import .R;
import .utils.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by xiaoyee on 7/12/15.
* 緩存管理工具類
*
* 如若想添加緩存路徑,則在{@link .constants.IYDCache.DirType DirType}中添加對應的類型 *
*/ public class IYDCache { private static final String TAG = IYDCache; public static final String CACHE_ROOT = root_cache; public static final String CACHE_VIDEO = video_cache; public static final String CACHE_IMAGE = image_cache; public static final String CACHE_VIDEO_MATERIAL = material_cache; //TODO 此項待修改 private static String mCacheDir; private static String mPicCachePath; private static String ROOT_DIR; /** * 存儲所有的緩存文件路徑 *
*
key--{@link DirType#dirName() DirType的dirName方法返回值}
*
value--完整路徑,如 /storage/emulated/0/Android/root_cache/video_cache
* *
*/ private static HashMap mCacheDirBox = new HashMap<>(); /** * 第一次因為父目錄未先初始化而失敗的類型 */ private static List mInitFailedDirType = new ArrayList<>(); /** * 一般文件的前綴,如視頻文件名為iydXXXX.mp4 */ private static final String IYD = iyd; /** * 是否成功初始化 */ private static boolean mIsInited = false; /** * 文件類型 */ public enum FileType { PNG(.png), JPG(.jpg), MP4(.mp4); /** * 後綴名 */ final String mSuffix; FileType(String suffix) { this.mSuffix = suffix; } /** * 獲取後綴名 * * @return 指定類型的後綴名,如'.mp4' */ public String suffix() { return this.mSuffix; } } /** * 根據緩存類型,緩存文件類型以及其url獲取此項該有的完整路徑,如/storage/emulated/0/Android/root_cache/video_cache/iyd1736054267.mp4 * * @param type 緩存類型。 此處用枚舉,目的是確保想用的緩存路徑已經添加了,如果沒有記得添加 * @param url 緩存目標的url,如圖片對應的鏈接 * @param fileType 文件類型,如mp4,png等,如需擴展,請在{@link .constants.IYDCache.FileType FileType}中添加 * @return 結果形如 /storage/emulated/0/Android/root_cache/video_cache/iyd1736054267.mp4 */ public static String getFileNameWithPath(DirType type, String url, FileType fileType) { return getIYDCacheDirThisType(type) + File.separator + generateNameFromUrl(url, fileType); } /** * 根據url生成文件名,此處保證如果url相同,那麼返回值也相同 *
* //NOTE: 注意:此文件名含有後綴 *
*
* 實際是 iyd + url的哈希值 + 後綴名 的拼接 *
* * @param url 目標對應的url * @param fileType 文件類型 * @return 結果形如 iyd1736054267.mp4 */ public static String generateNameFromUrl(String url, FileType fileType) { if (StringUtils.isBlank(url)) { return StringUtils.empty(); } return IYD + url.hashCode() + fileType.suffix(); } /** * 根據哈希值,生成文件名 無後綴名 * * @param hashcode 目標哈希值 * @return 返回結果形如 iyd1736054267 */ public static String generateNameFromHashcode(int hashcode) { return IYD + hashcode; } /** * 基於對象,生成文件名;無後綴名 *
* 此處目的是保證同一個對象,返回同樣的文件名,但是依賴於對象的equal方法和hashCode方法 *
* * @return 返回結果形如 iyd1736054267 */ public static String generateNameFromObj(Object obj) { return IYD + obj.hashCode(); } /** * 獲取指定緩存類型的 緩存文件夾 *
* 注意,返回值可以為空 *
* * @param type 緩存類型 {@link .constants.IYDCache.DirType} * @return 形如/storage/emulated/0/Android/root_cache/video_cache或“/storage/emulated/0/Android/root_cache” */ @Nullable public static String getIYDCacheDirThisType(DirType type) { if (!mIsInited) { throw new IllegalArgumentException(ResourceUtils.getString(R.string.not_init) + 確保在application中調用了本類的initCacheDir方法); } String key = type.dirName(); if (mCacheDirBox.containsKey(key)) { return mCacheDirBox.get(key); } else { LogCus.e(TAG, 沒找到與此對應的目錄 + key); return StringUtils.empty(); } } /** * 清空指定緩存文件夾中的所有內容 * @param dirType 指定緩存文件夾類型 對應{@link .constants.IYDCache.DirType DirType} */ public static void clearCacheThisDir(final DirType dirType) { new Thread( new Runnable() { @Override public void run() { FileUtils.clearDir(getIYDCacheDirThisType(dirType)); } } ).start(); } /** * 初始化所有緩存文件夾,應該在application的onCreate方法中調用 */ public static void initCacheDir(Context context) { if (!SDCardUtil.isSDCardExist()) { ToastUtils.show(context, ResourceUtils.getString(R.string.check_memory_is_ok)); return; } File androidDir = Environment.getExternalStoragePublicDirectory(Android); ROOT_DIR = androidDir.getAbsolutePath(); mIsInited = true; //初始化所有緩存文件夾 DirType[] allDirType = DirType.values(); for (DirType dirType : allDirType) { initDirWithParentDirType(dirType); } //初始化失敗的那些 for (DirType dirType : mInitFailedDirType) { initDirWithParentDirType(dirType); } } private static void initDirWithParentDirType(DirType childDir) { String parentDirPath; //TODO 先後問題,如果父目錄未初始化時,先初始化了子目錄。。。 //獲取父目錄文件夾路徑 if (childDir == DirType.ROOT) { //如果是根目錄,那麼直接定義 if (StringUtils.isBlank(ROOT_DIR)) { throw new IllegalArgumentException(請先初始化根目錄,也就是先調用 ROOT_DIR = androidDir.getAbsolutePath(); ); } parentDirPath = ROOT_DIR; } else { //否則,直接設置;父目錄文件夾完整路徑,應該通過 父目錄對應的目錄名獲得 parentDirPath = mCacheDirBox.get(childDir.parentDirType().dirName()); } LogCus.d(父路徑>>> + parentDirPath); if (StringUtils.isBlank(parentDirPath) || !parentDirPath.contains(ROOT_DIR)) { mInitFailedDirType.add(childDir); return; } String dirPath = spliceSeparator(parentDirPath, childDir.dirName()); if (!FileUtils.isFolderExistOrCreateSuccess(dirPath)) { LogCus.d(初始化文件夾失敗 + dirPath); return; } mCacheDirBox.put(childDir.dirName(), dirPath); } private static String spliceSeparator(String... dir) { StringBuilder result = new StringBuilder(); for (String s : dir) { result.append(s); result.append(File.separator); } return result.toString(); } public static String getCacheDir() { return mCacheDir; } public static void setCacheDir(String mCacheDir) { IYDCache.mCacheDir = mCacheDir; } /** * 緩存文件夾類型,//NOTE: 確保添加進來的類型,其dir與parentDir路徑在此類中定義 *
* 要注意此枚舉類型中的順序,父目錄一定要寫在子目錄之前 *
*/ public enum DirType { /** * 緩存根目錄 iyd_cache */ ROOT(CACHE_ROOT, ROOT_DIR), /** * 視頻緩存目錄 video_cache; 其父目錄為 CACHE_ROOT */ VIDEO(CACHE_VIDEO, CACHE_ROOT), /** * 圖片緩存目錄 image_cache; 其父目錄為 CACHE_ROOT */ IMAGE(CACHE_IMAGE, CACHE_ROOT), /** * 素材緩存目錄 material_cache; 其父目錄為 CACHE_ROOT */ MATERIAL(CACHE_VIDEO_MATERIAL, CACHE_ROOT),; private String mDir; private String mParentDir; public String getParentDir() { return mParentDir; } /** * @param dir 當前目錄名 * @param parentDir 父目錄名 */ DirType(String dir, String parentDir) { this.mDir = dir; this.mParentDir = parentDir; } public void setParentDir(String parentDir) { this.mParentDir = parentDir; } /** * 獲取緩存文件夾名稱,如video_cache * * @return 返回結果形如 video_cache */ public String dirName() { return mDir; } /** * 獲取父目錄的DirType,調用此方法時,一定確保其不是ROOT */ public DirType parentDirType() { DirType[] dirTypes = DirType.values(); for (DirType dirType : dirTypes) { //此項的父目錄,和某項的當前目錄對應 if (mParentDir.equals(dirType.dirName())) { return dirType; } } throw new IllegalArgumentException(沒找到對應的父文件夾>>> + mParentDir + ;1、請確保已經添加了並且mParentDir是對應的;2、一定確保調用此方法的類型不是ROOT); } } }
清空文件夾中的方法
/**
* removes subdirectories and their contents
*/
static void purgeDirectory(File dir) {
for (File file: dir.listFiles()) {
if (file.isDirectory()) purgeDirectory(file);
file.delete();
}
}
/**
* 清空文件夾中的內容,包括子目錄
* @param path
*/
public static void clearDir(String path) {
//LogCus.d(刪除 + path + 目錄下的所有內容);
if (StringUtils.isBlank(path)) {
return;
}
File file = new File(path);
purgeDirectory(file);
}
我們先實現拍照按鈕的圓形效果哈,Android開發中,當然可以找美工人員設計圖片,然後直接拿進來,不過我們可以自己寫代碼實現這個效果哈,最常用的的是用layout-lis
9.4 ListView的Choice ModeListView本身帶有單選和多選功能,也就是說在單選模式下,它能夠記住當前選中的唯一的列表項;在多選模式下,它能夠記住目
提煉為常量是從臨時變量快速提煉出靜態常量,這也是我們常用的重構手段.操作步驟:? 菜單欄: Refactor —> Extract —>
一 背景概述:ScrollView裡嵌套ListView,一直是Android開發者(反正至少是我們組)最討厭的設計之一,完美打破ListView(RecyclerVie