Initial commit
This commit is contained in:
2
library/FilePicker/.gitignore
vendored
Normal file
2
library/FilePicker/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/*.iml
|
||||
11
library/FilePicker/build.gradle
Normal file
11
library/FilePicker/build.gradle
Normal file
@@ -0,0 +1,11 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
ext {
|
||||
isLibrary = true
|
||||
pomArtifactId = "FilePicker"
|
||||
pomDescription = "file picker for android"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":library:Common")
|
||||
}
|
||||
7
library/FilePicker/src/main/AndroidManifest.xml
Normal file
7
library/FilePicker/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.qqtheme.framework.filepicker">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,225 @@
|
||||
package cn.qqtheme.framework.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import cn.qqtheme.framework.entity.FileItem;
|
||||
import cn.qqtheme.framework.filepicker.R;
|
||||
import cn.qqtheme.framework.util.CompatUtils;
|
||||
import cn.qqtheme.framework.util.ConvertUtils;
|
||||
import cn.qqtheme.framework.util.FileUtils;
|
||||
import cn.qqtheme.framework.util.LogUtils;
|
||||
|
||||
/**
|
||||
* The type File adapter.
|
||||
*/
|
||||
public class FileAdapter extends BaseAdapter {
|
||||
/**
|
||||
* The constant DIR_ROOT.
|
||||
*/
|
||||
public static final String DIR_ROOT = "..";
|
||||
/**
|
||||
* The constant DIR_PARENT.
|
||||
*/
|
||||
public static final String DIR_PARENT = "";
|
||||
private Context context;
|
||||
private ArrayList<FileItem> data = new ArrayList<FileItem>();
|
||||
private String rootPath = null;
|
||||
private String currentPath = null;
|
||||
private String[] allowExtensions = null;//允许的扩展名
|
||||
private boolean onlyListDir = false;//是否仅仅读取目录
|
||||
private boolean showHomeDir = false;//是否显示返回主目录
|
||||
private boolean showUpDir = true;//是否显示返回上一级
|
||||
private boolean showHideDir = true;//是否显示隐藏的目录(以“.”开头)
|
||||
private int homeIcon = R.drawable.file_picker_home;
|
||||
private int upIcon = R.drawable.file_picker_updir;
|
||||
private int folderIcon = R.drawable.file_picker_folder;
|
||||
private int fileIcon = R.drawable.file_picker_file;
|
||||
|
||||
/**
|
||||
* Instantiates a new File adapter.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public FileAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current path.
|
||||
*
|
||||
* @return the current path
|
||||
*/
|
||||
public String getCurrentPath() {
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets allow extensions.
|
||||
*
|
||||
* @param allowExtensions the allow extensions
|
||||
*/
|
||||
public void setAllowExtensions(String[] allowExtensions) {
|
||||
this.allowExtensions = allowExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets only list dir.
|
||||
*
|
||||
* @param onlyListDir the only list dir
|
||||
*/
|
||||
public void setOnlyListDir(boolean onlyListDir) {
|
||||
this.onlyListDir = onlyListDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets show home dir.
|
||||
*
|
||||
* @param showHomeDir the show home dir
|
||||
*/
|
||||
public void setShowHomeDir(boolean showHomeDir) {
|
||||
this.showHomeDir = showHomeDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets show up dir.
|
||||
*
|
||||
* @param showUpDir the show up dir
|
||||
*/
|
||||
public void setShowUpDir(boolean showUpDir) {
|
||||
this.showUpDir = showUpDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets show hide dir.
|
||||
*
|
||||
* @param showHideDir the show hide dir
|
||||
*/
|
||||
public void setShowHideDir(boolean showHideDir) {
|
||||
this.showHideDir = showHideDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load data array list.
|
||||
*
|
||||
* @param path the path
|
||||
*/
|
||||
public void loadData(String path) {
|
||||
if (path == null) {
|
||||
LogUtils.warn("current directory is null");
|
||||
return;
|
||||
}
|
||||
ArrayList<FileItem> datas = new ArrayList<FileItem>();
|
||||
if (rootPath == null) {
|
||||
rootPath = path;
|
||||
}
|
||||
LogUtils.debug("current directory path: " + path);
|
||||
currentPath = path;
|
||||
if (showHomeDir) {
|
||||
//添加“返回主目录”
|
||||
FileItem fileRoot = new FileItem();
|
||||
fileRoot.setDirectory(true);
|
||||
fileRoot.setIcon(homeIcon);
|
||||
fileRoot.setName(DIR_ROOT);
|
||||
fileRoot.setSize(0);
|
||||
fileRoot.setPath(rootPath);
|
||||
datas.add(fileRoot);
|
||||
}
|
||||
if (showUpDir && !path.equals("/")) {
|
||||
//添加“返回上一级目录”
|
||||
FileItem fileParent = new FileItem();
|
||||
fileParent.setDirectory(true);
|
||||
fileParent.setIcon(upIcon);
|
||||
fileParent.setName(DIR_PARENT);
|
||||
fileParent.setSize(0);
|
||||
fileParent.setPath(new File(path).getParent());
|
||||
datas.add(fileParent);
|
||||
}
|
||||
File[] files;
|
||||
if (allowExtensions == null) {
|
||||
if (onlyListDir) {
|
||||
files = FileUtils.listDirs(currentPath);
|
||||
} else {
|
||||
files = FileUtils.listDirsAndFiles(currentPath);
|
||||
}
|
||||
} else {
|
||||
if (onlyListDir) {
|
||||
files = FileUtils.listDirs(currentPath, allowExtensions);
|
||||
} else {
|
||||
files = FileUtils.listDirsAndFiles(currentPath, allowExtensions);
|
||||
}
|
||||
}
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!showHideDir && file.getName().startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
FileItem fileItem = new FileItem();
|
||||
boolean isDirectory = file.isDirectory();
|
||||
fileItem.setDirectory(isDirectory);
|
||||
if (isDirectory) {
|
||||
fileItem.setIcon(folderIcon);
|
||||
fileItem.setSize(0);
|
||||
} else {
|
||||
fileItem.setIcon(fileIcon);
|
||||
fileItem.setSize(file.length());
|
||||
}
|
||||
fileItem.setName(file.getName());
|
||||
fileItem.setPath(file.getAbsolutePath());
|
||||
datas.add(fileItem);
|
||||
}
|
||||
}
|
||||
data.clear();
|
||||
data.addAll(datas);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileItem getItem(int position) {
|
||||
return data.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(context).inflate(android.R.layout.activity_list_item, null);
|
||||
CompatUtils.setBackground(convertView, ConvertUtils.toStateListDrawable(Color.WHITE, Color.LTGRAY));
|
||||
holder = new ViewHolder();
|
||||
holder.imageView = (ImageView) convertView.findViewById(android.R.id.icon);
|
||||
holder.textView = (TextView) convertView.findViewById(android.R.id.text1);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
FileItem item = data.get(position);
|
||||
holder.imageView.setImageResource(item.getIcon());
|
||||
holder.textView.setText(item.getName());
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private class ViewHolder {
|
||||
ImageView imageView;
|
||||
TextView textView;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package cn.qqtheme.framework.entity;
|
||||
|
||||
/**
|
||||
* 文件项信息
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2014 -05-23 18:02
|
||||
*/
|
||||
public class FileItem {
|
||||
private int icon;
|
||||
private String name;
|
||||
private String path = "/";
|
||||
private long size = 0;
|
||||
private boolean isDirectory = false;
|
||||
|
||||
/**
|
||||
* Sets icon.
|
||||
*
|
||||
* @param icon the icon
|
||||
*/
|
||||
public void setIcon(int icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets icon.
|
||||
*
|
||||
* @return the icon
|
||||
*/
|
||||
public int getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name.
|
||||
*
|
||||
* @param name the name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets path.
|
||||
*
|
||||
* @return the path
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets path.
|
||||
*
|
||||
* @param path the path
|
||||
*/
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets size.
|
||||
*
|
||||
* @return the size
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets size.
|
||||
*
|
||||
* @param size the size
|
||||
*/
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is directory boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isDirectory() {
|
||||
return isDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets directory.
|
||||
*
|
||||
* @param isDirectory the is directory
|
||||
*/
|
||||
public void setDirectory(boolean isDirectory) {
|
||||
this.isDirectory = isDirectory;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresPermission;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import cn.qqtheme.framework.adapter.FileAdapter;
|
||||
import cn.qqtheme.framework.entity.FileItem;
|
||||
import cn.qqtheme.framework.popup.ConfirmPopup;
|
||||
import cn.qqtheme.framework.util.ConvertUtils;
|
||||
import cn.qqtheme.framework.util.LogUtils;
|
||||
import cn.qqtheme.framework.util.StorageUtils;
|
||||
import cn.qqtheme.framework.widget.MarqueeTextView;
|
||||
|
||||
/**
|
||||
* 文件目录选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /9/29
|
||||
*/
|
||||
public class FilePicker extends ConfirmPopup<LinearLayout> implements AdapterView.OnItemClickListener {
|
||||
/**
|
||||
* Directory mode.
|
||||
*/
|
||||
public static final int DIRECTORY = 0;
|
||||
/**
|
||||
* File mode.
|
||||
*/
|
||||
public static final int FILE = 1;
|
||||
|
||||
private String initPath;
|
||||
private FileAdapter adapter;
|
||||
private MarqueeTextView textView;
|
||||
private OnFilePickListener onFilePickListener;
|
||||
private int mode;
|
||||
|
||||
@IntDef(flag = false, value = {DIRECTORY, FILE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Mode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new File picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
* @param mode data mode
|
||||
* @see #FILE #FILE#FILE
|
||||
* @see #DIRECTORY #DIRECTORY#DIRECTORY
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
@RequiresPermission(anyOf = {Manifest.permission.READ_EXTERNAL_STORAGE})
|
||||
public FilePicker(Activity activity, @Mode int mode) {
|
||||
super(activity);
|
||||
setHalfScreen(true);
|
||||
this.initPath = StorageUtils.getRootPath(activity);
|
||||
this.mode = mode;
|
||||
this.adapter = new FileAdapter(activity);
|
||||
adapter.setOnlyListDir(mode == DIRECTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected LinearLayout makeCenterView() {
|
||||
LinearLayout rootLayout = new LinearLayout(activity);
|
||||
rootLayout.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
|
||||
rootLayout.setBackgroundColor(Color.WHITE);
|
||||
rootLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
ListView listView = new ListView(activity);
|
||||
listView.setBackgroundColor(Color.WHITE);
|
||||
listView.setDivider(new ColorDrawable(0xFFDDDDDD));
|
||||
listView.setDividerHeight(1);
|
||||
listView.setCacheColorHint(Color.TRANSPARENT);
|
||||
listView.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||
listView.setAdapter(adapter);
|
||||
listView.setOnItemClickListener(this);
|
||||
rootLayout.addView(listView);
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected View makeFooterView() {
|
||||
textView = new MarqueeTextView(activity);
|
||||
textView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||
textView.setTextColor(Color.BLACK);
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
int padding = ConvertUtils.toPx(activity, 10);
|
||||
textView.setPadding(padding, padding, padding, padding);
|
||||
return textView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets root path.
|
||||
*
|
||||
* @param initPath the init path
|
||||
*/
|
||||
public void setRootPath(String initPath) {
|
||||
this.initPath = initPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets allow extensions.
|
||||
*
|
||||
* @param allowExtensions the allow extensions
|
||||
*/
|
||||
public void setAllowExtensions(String[] allowExtensions) {
|
||||
adapter.setAllowExtensions(allowExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets show up dir.
|
||||
*
|
||||
* @param showUpDir the show up dir
|
||||
*/
|
||||
public void setShowUpDir(boolean showUpDir) {
|
||||
adapter.setShowUpDir(showUpDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets show home dir.
|
||||
*
|
||||
* @param showHomeDir the show home dir
|
||||
*/
|
||||
public void setShowHomeDir(boolean showHomeDir) {
|
||||
adapter.setShowHomeDir(showHomeDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets show hide dir.
|
||||
*
|
||||
* @param showHideDir the show hide dir
|
||||
*/
|
||||
public void setShowHideDir(boolean showHideDir) {
|
||||
adapter.setShowHideDir(showHideDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setContentViewBefore() {
|
||||
boolean isPickFile = mode == FILE;
|
||||
setCancelVisible(!isPickFile);
|
||||
setSubmitText(isPickFile ? "取消" : "确定");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setContentViewAfter(View contentView) {
|
||||
refreshCurrentDirPath(initPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit() {
|
||||
if (mode == FILE) {
|
||||
LogUtils.debug("已放弃选择!");
|
||||
} else {
|
||||
String currentPath = adapter.getCurrentPath();
|
||||
LogUtils.debug("已选择目录:" + currentPath);
|
||||
if (onFilePickListener != null) {
|
||||
onFilePickListener.onFilePicked(currentPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current path.
|
||||
*
|
||||
* @return the current path
|
||||
*/
|
||||
public String getCurrentPath() {
|
||||
return adapter.getCurrentPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应选择器的列表项点击事件
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
|
||||
FileItem fileItem = adapter.getItem(position);
|
||||
if (fileItem.isDirectory()) {
|
||||
refreshCurrentDirPath(fileItem.getPath());
|
||||
} else {
|
||||
String clickPath = fileItem.getPath();
|
||||
if (mode == DIRECTORY) {
|
||||
LogUtils.debug("选择的不是有效的目录: " + clickPath);
|
||||
} else {
|
||||
dismiss();
|
||||
LogUtils.debug("已选择文件:" + clickPath);
|
||||
if (onFilePickListener != null) {
|
||||
onFilePickListener.onFilePicked(clickPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshCurrentDirPath(String currentPath) {
|
||||
if (currentPath.equals("/")) {
|
||||
textView.setText("根目录");
|
||||
} else {
|
||||
textView.setText(currentPath);
|
||||
}
|
||||
adapter.loadData(currentPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on file pick listener.
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void setOnFilePickListener(OnFilePickListener listener) {
|
||||
this.onFilePickListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On file pick listener.
|
||||
*/
|
||||
public interface OnFilePickListener {
|
||||
|
||||
/**
|
||||
* On file picked.
|
||||
*
|
||||
* @param currentPath the current path
|
||||
*/
|
||||
void onFilePicked(String currentPath);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,224 @@
|
||||
package cn.qqtheme.framework.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 存储设备工具类
|
||||
*
|
||||
* @author 李玉江[QQ :1023694760]
|
||||
* @version 2013 -11-2
|
||||
*/
|
||||
public final class StorageUtils {
|
||||
|
||||
/**
|
||||
* 判断外置存储是否可用
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public static boolean externalMounted() {
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (state.equals(Environment.MEDIA_MOUNTED)) {
|
||||
return true;
|
||||
}
|
||||
LogUtils.warn("external storage unmounted");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以“/”结尾的外置存储根目录,可选若外置存储不可用则是否使用内部存储
|
||||
*
|
||||
* @param context the context
|
||||
* @param onlyExternalStorage the only external storage
|
||||
* @param subdir the subdir
|
||||
* @return 诸如 :/mnt/sdcard/subdir
|
||||
*/
|
||||
public static String getRootPath(Context context, boolean onlyExternalStorage, String subdir) {
|
||||
File file;
|
||||
if (externalMounted()) {
|
||||
file = Environment.getExternalStorageDirectory();
|
||||
} else {
|
||||
if (onlyExternalStorage) {
|
||||
file = new File("/");
|
||||
} else {
|
||||
file = context.getFilesDir();
|
||||
}
|
||||
}
|
||||
if (!TextUtils.isEmpty(subdir)) {
|
||||
file = new File(file, subdir);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs();
|
||||
}
|
||||
String path = "/";
|
||||
if (file != null) {
|
||||
path = FileUtils.separator(file.getAbsolutePath());
|
||||
}
|
||||
LogUtils.debug("storage root path: " + path);
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以“/”结尾的外置存储根目录,可选若外置存储不可用则是否使用内部存储
|
||||
*
|
||||
* @param context the context
|
||||
* @param subdir the subdir
|
||||
* @return 诸如 :/mnt/sdcard/
|
||||
*/
|
||||
public static String getRootPath(Context context, String subdir) {
|
||||
return getRootPath(context, false, subdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以“/”结尾的外置存储根目录,可选若外置存储不可用则是否使用内部存储
|
||||
*
|
||||
* @param context the context
|
||||
* @param onlyExternalStorage the only external storage
|
||||
* @return 诸如 :/mnt/sdcard/
|
||||
*/
|
||||
public static String getRootPath(Context context, boolean onlyExternalStorage) {
|
||||
return getRootPath(context, onlyExternalStorage, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以“/”结尾的外置存储根目录,若外置存储不可用则使用内部存储
|
||||
*
|
||||
* @param context the context
|
||||
* @return 诸如 :/mnt/sdcard/
|
||||
*/
|
||||
public static String getRootPath(Context context) {
|
||||
return getRootPath(context, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载的文件的保存路径,以“/”结尾
|
||||
*
|
||||
* @param context the context
|
||||
* @return 诸如 :/mnt/sdcard/Download/
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public static String getDownloadPath(Context context) throws Exception {
|
||||
File file;
|
||||
if (externalMounted()) {
|
||||
file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||
} else {
|
||||
throw new Exception("外置存储不可用!");
|
||||
}
|
||||
return FileUtils.separator(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 各种类型的文件的专用的保存路径,以“/”结尾
|
||||
*
|
||||
* @param context the context
|
||||
* @param type the type
|
||||
* @return 诸如 :/mnt/sdcard/Android/data/[package]/files/[type]/
|
||||
*/
|
||||
public static String getPrivatePath(Context context, String type) {
|
||||
File file = null;
|
||||
if (externalMounted()) {
|
||||
file = context.getExternalFilesDir(type);
|
||||
}
|
||||
if (file == null) {
|
||||
//SD卡不可用或暂时繁忙?
|
||||
if (type == null) {
|
||||
file = context.getFilesDir();
|
||||
} else {
|
||||
file = new File(FileUtils.separator(context.getFilesDir().getAbsolutePath()) + type);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs();
|
||||
}
|
||||
}
|
||||
return FileUtils.separator(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets internal root path.
|
||||
*
|
||||
* @param context the context
|
||||
* @return the internal root path
|
||||
*/
|
||||
public static String getInternalRootPath(Context context) {
|
||||
return FileUtils.separator(context.getFilesDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets private root path.
|
||||
*
|
||||
* @param context the context
|
||||
* @return the private root path
|
||||
*/
|
||||
public static String getPrivateRootPath(Context context) {
|
||||
return getPrivatePath(context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plugin path.
|
||||
*
|
||||
* @param context the context
|
||||
* @return the plugin path
|
||||
*/
|
||||
public static String getPluginPath(Context context) {
|
||||
return getPrivatePath(context, "plugin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets temporary dir path.
|
||||
*
|
||||
* @param context the context
|
||||
* @return the temporary dir path
|
||||
*/
|
||||
public static String getTemporaryDirPath(Context context) {
|
||||
return getPrivatePath(context, "temporary");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets temporary file path.
|
||||
*
|
||||
* @param context the context
|
||||
* @return the temporary file path
|
||||
*/
|
||||
public static String getTemporaryFilePath(Context context) {
|
||||
try {
|
||||
return File.createTempFile("lyj_", ".tmp", context.getCacheDir()).getAbsolutePath();
|
||||
} catch (IOException e) {
|
||||
return getTemporaryDirPath(context) + "lyj.tmp";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cache path.
|
||||
*
|
||||
* @param context the context
|
||||
* @param type the type
|
||||
* @return the cache path
|
||||
*/
|
||||
public static String getCachePath(Context context, String type) {
|
||||
File file;
|
||||
if (externalMounted()) {
|
||||
file = context.getExternalCacheDir();
|
||||
} else {
|
||||
file = context.getCacheDir();
|
||||
}
|
||||
if (type != null) {
|
||||
file = new File(file, type);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.mkdirs();
|
||||
}
|
||||
return FileUtils.separator(file != null ? file.getAbsolutePath() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cache root path.
|
||||
*
|
||||
* @param context the context
|
||||
* @return the cache root path
|
||||
*/
|
||||
public static String getCacheRootPath(Context context) {
|
||||
return getCachePath(context, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.qqtheme.framework.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* 文本水平自动滚动(从右到左)。
|
||||
*
|
||||
* @author 李玉江[QQ :1023694760]
|
||||
* @version 2013 -1-11
|
||||
*/
|
||||
public class MarqueeTextView extends TextView {
|
||||
|
||||
/**
|
||||
* Instantiates a new Marquee text view.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public MarqueeTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Marquee text view.
|
||||
*
|
||||
* @param context the context
|
||||
* @param attr the attr
|
||||
*/
|
||||
public MarqueeTextView(Context context, AttributeSet attr) {
|
||||
super(context, attr);
|
||||
setEllipsize(TextUtils.TruncateAt.MARQUEE);
|
||||
setMarqueeRepeatLimit(-1);
|
||||
setSingleLine(true);
|
||||
setHorizontallyScrolling(true);
|
||||
setClickable(true);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
setGravity(Gravity.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 必须已获取到焦点,才能即显滚动
|
||||
*/
|
||||
@Override
|
||||
public boolean isFocused() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPressed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 535 B |
Binary file not shown.
|
After Width: | Height: | Size: 762 B |
Binary file not shown.
|
After Width: | Height: | Size: 808 B |
Binary file not shown.
|
After Width: | Height: | Size: 753 B |
Reference in New Issue
Block a user