深度优先删除文件夹
文件夹删除的规律:删除文件夹必须要保证文件夹为空才可以删除,所以删除某个文件夹之前需要先删除该文件夹下的所有孩子
可以借助栈的特性来记录要删除的文件夹的删除顺序,栈的特性先进后出,如果要删除文件夹则进栈,遍历其孩子,如果发现其孩子是文件夹则继续进栈,
所以可以看出子文件夹在父文件夹上面,因此处理过程也是先处理了子文件夹,才到父文件夹
/**
* 删除文件夹
*
* @param folder
*/
private void deleteDirectory(File folder) {
//记录当前要删除的文件夹
Stack<File> deleteStack = new Stack<>();
//将要删的目标先入栈记录起来
deleteStack.push(folder);
//介于要删除的文件夹必须为空的原则,需要将记录中最上面的文件的孩子都删掉
while (!deleteStack.isEmpty()) {
//检测栈顶的元素的孩子个数是否为0
//peek表示读取栈顶的元素,不移除
File[] fs = deleteStack.peek().listFiles(); //读取栈顶元素的孩子
//如果有孩子,则需要删除其中的孩子
if (fs != null && fs.length > 0) {
//删除该文件夹内部的孩子
for (int i = 0; i < fs.length; i++) {
File child = fs[i];
if (child.isDirectory()) {
deleteStack.push(child);
} else {
//删除文件
child.delete();
}
}
}
fs = deleteStack.peek().listFiles();
if (fs == null || fs.length == 0) {
//该文件夹为空,可以直接删除
deleteStack.pop().delete();
}
}
}
适配器中某个item不可用的配置
可以在适配器中重写isEnable方法通过返回true或者false来实现某个item的是否可用的控制
public class ToolsMenuAdapter extends ItemAdapter<String> {
...
//如果选择了多个文件,则需要让重命名不可用
@Override
public boolean isEnabled(int position) {
if (position == 2) {
if (currentSelectList != null && currentSelectList.size() > 1) {
return false;
}
}
return super.isEnabled(position);
}
...
}
PopuWindow显示列表
//操作菜单的窗口
private PopupWindow toolsMenuWindow;
//菜单的适配器
private ToolsMenuAdapter menuAdapter;
private void showTooldMenuWindow(View v){
if(null == toolsMenuWindow){
ListView menuList = new ListView(getActivity());
//分割线的高度设置为0
menuList.setDividerHeight(0);
menuAdapter = new ToolsMenuAdapter(getActivity());
menuList.setAdapter(menuAdapter);
menuList.setBackgroundColor(0xff3D4043);
//创建PopuWindow对象
toolsMenuWindow=new PopupWindow(menuList,200,ViewGroup.LayoutParams.WRAP_CONTENT);
toolsMenuWindow.setFocusable(true);
toolsMenuWindow.setBackgroundDrawable(new ColorDrawable());
toolsMenuWindow.setOutsideTouchable(true);
}
menuAdapter.setCurrentSelectList(currentSelectItems);
//显示窗口
toolsMenuWindow.showAsDropDown(v,-150,30);
}
文件夹复制
文件夹主要是管理其他的文件或者文件夹的,其中并没有实质性的内容,因此文件夹分复制过程为创建目标文件夹,搬运子文件从源文件夹到目标文件夹
中,介于需要现有文件夹才搬运因此可以使用广度优先从第一级往下逐级创建和搬运即可
/**
* 复制文件夹
*
* @param from 起始的文件夹 (如:/mnt/sdcard/a/)
* @param to 目标文件夹 (如:/mnt/sdcard/abc/)
*/
private void copyFolder(String from, String to) {
//记录当前要复制的文件夹
LinkedList<File> copyFolder = new LinkedList<>();
//第一个要复制的文件夹
File folder = new File(from);
copyFolder.addLast(folder);
//记录拷贝的源文件夹所在的文件夹路径
String fromParent = folder.getParent();
while (!copyFolder.isEmpty()) {
//从头部获取当前记录中第一个要复制的文件夹
File firstFolder = copyFolder.removeFirst();
//创建目标文件
//假如/mnt/sdcard/abc/ 现在要创建的是/mnt/sdcard/a/b/对应的文件夹/mnt/sdcard/abc/a/b/
//获取起始文件夹的相对路径
String fromRelativePath = firstFolder.getPath().substring(fromParent.length());
//目标文件夹的路径
String toPath;
//判断目标路径是否有/结尾
if (to.endsWith(File.separator)) {
toPath = to + fromRelativePath;
} else {
toPath = to + File.separator + fromRelativePath;
}
new File(toPath).mkdir();
//搬运孩子文件(如果是文件复制,如果是文件夹,添加记录)
File[] fs = firstFolder.listFiles();
for (int i = 0; i < fs.length; i++) {
File child = fs[i];
if (child.isDirectory()) {
//记录起来
copyFolder.addLast(child);
} else {
//复制文件
String toFilePath;
//获取文件在源文件夹下的相对路劲
String pathRelative = child.getAbsolutePath().substring(fromParent.length());
if (to.endsWith(File.separator)) {
toFilePath = to + pathRelative;
} else {
toFilePath = to + File.separator + pathRelative;
}
copyFile(child.getAbsolutePath(), toFilePath);
}
}
}
}
文本框处理选择
et.selectAll();//全选
et.setSelectAllOnFocus(true);//得到焦点时全选
跟在xml中使用
android:selectAllOnFocus="true"
部分选择
设定一个开始位置到结束位置选择
et.setSelection(start,end);
位图–Bitmap
是Android中像素表的描述
模式:
RGB_565 --> R=5 G=6 B=5总共16-->2个字节 100x100 ==> 100*100*2/1024=20k
ARGB_4444 --> A=4 R=4 G=4 B=4总共16
ARGB_8888 --> A=8 R=8 G=8 B=8总共32位-->4字节 100x100 ==>100*100*4/1024=40k
ALPHA_8 每个像素占4位只有透明度
从资源中加载
BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.drawable.pic3);
//获取位图对象
Bitmap bitmap = drawable.getBitmap();
//图像的宽度
int width = bitmap.getWidth();
//图像的高度
int height = bitmap.getHeight();
iv.setImageBitmap(bitmap);
位图的操作
Bitmap.create方法可以创建一个新的位图
//基于原有的一张位图,创建新位图
//第二第三个参数表示原位图的起始坐标
//第三第四个参数表示新位图的宽高
Bitmap newBitmap = Bitmap.createBitmap(bitmap,50,50,100,100);
从磁盘中加载位图,如果图片过大,从磁盘中加载的图像被存储到内存中时,如果内存不够则会出现java.lang.OutOfMemoryError(内存溢出),可以通过
BitmapFactory来解码图像,并且配置解码的比例取其中均匀分布的部分像素来组成一个新的像素表实现缩略图生成的效果
/**
* 获取图片缩略图
* @param path 原图的地址
* @param maxWidth 缩略图的宽度
* @param maxHeight 缩略图的高度
* @return
*/
private Bitmap getBitmap(String path, int maxWidth, int maxHeight) {
//解码位图的配置对象
BitmapFactory.Options optins = new BitmapFactory.Options();
optins.inPreferredConfig= Bitmap.Config.RGB_565;
//只解析图像的宽高
optins.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, optins);
//在不加载像素到内存的情况下得到了原图的宽高
int width = optins.outWidth;
int height = optins.outHeight;
//计算款方向的倍数 // 1.1 -->2 1.9-->2
int w = (int) Math.ceil((float) width / maxWidth);
//高方向的倍数
int h = (int) Math.ceil((float) height / maxHeight);
if (w > 1 || h > 1) {
if (w > h) {
//设置取缩略的倍数
optins.inSampleSize = w; //只能设置一个大于1的数 --> 最终取1/optins.inSampleSize
} else {
optins.inSampleSize = h;
}
}
//解码,获取具体的像素信息
optins.inJustDecodeBounds = false;
Bitmap b = BitmapFactory.decodeFile(path,optins);
return b;
}
位图保存
/**
* 保存位图
* @param bitmap
* @param path
*/
private void saveBitmap(Bitmap bitmap,String path){
FileOutputStream out= null;
//保存位图
try {
out = new FileOutputStream(path);
bitmap.compress(Bitmap.CompressFormat.JPEG,80,out);
out.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
if(null != out){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}