本文主要记录一些零碎的东西
使用recycleeView实现一个相册,相册里面的编辑可以参考这篇,主要是扫描系统相册,然后展示出来
主要是使用 getLoaderManager().initLoader 查询数据库,其实遍历文件也是可以的,不过偷懒啦,而且提供的查询是异步的
看看list界面
/**
* 相册列表
* Create by slack on 2016/09/06 15:58
*/
public class AlbumListActivity extends BaseFullScreenActivity {
private RecyclerView mRecyclerView;
private Boolean isVideo;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_album_list);
initView();
initData();
}
private void initData() {
if(getIntent() != null ){
isVideo = getIntent().getBooleanExtra("video",false);
}
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == REQ_SACN_ALBUM_LIST){
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(
new AlbumListAdapter(mRecyclerView,albumImageList,itemClickListener));
// 进入第一个 相册详情界面
/***
* 发现会有一个假死的现象,从相册返回后整个界面无法点击
* so 来个延时
*/
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// 点击视频首打开视频,点击照片首打开照片
for (int i = 0; i < albumImageList.size(); i++) {
AlbumImage a = albumImageList.get(i);
if(isVideo && a.imagePath.startsWith("v")){
enterAlbumView(i);
break;
}else if(!isVideo && a.imagePath.startsWith("i")){
enterAlbumView(i);
break;
}
}
}
}, 100);
}
}
};
// 虽然使用了 getLoaderManager ,结果操作在主线程里跑
initAlbumImages(mHandler);
}
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.album_list);
textView = (TextView) findViewById(R.id.album_scanning);
textView.setVisibility(View.VISIBLE);
((TextView)findViewById(R.id.top_center)).setText(getString(R.string.album_choose));
((ImageView)findViewById(R.id.top_left)).setImageResource(R.drawable.home_red);
findViewById(R.id.top_left).setOnClickListener(this);
((ImageView)findViewById(R.id.top_right)).setImageResource(R.drawable.home_red);
findViewById(R.id.top_right).setOnClickListener(this);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setVisibility(View.GONE);
}
AlbumListAdapter.ItemClickListener itemClickListener = new AlbumListAdapter.ItemClickListener() {
@Override
public void onItemClick(int pos) {
if(pos >= 0 && pos < albumImageList.size()){
enterAlbumView(pos);
}
}
};
private void enterAlbumView(int position){
textView.setVisibility(View.GONE);
List childList = mGruopMap.get(albumImageList.get(position).folderName);
// if(childList.get(0).endsWith("gif")){
// startNewActivity(PhotoSelectActivity.class,false);
// }else
{
Intent mIntent = new Intent(AlbumListActivity.this, AlbumImagesActivity.class);
mIntent.putStringArrayListExtra("list", (ArrayList) childList);
startActivity(mIntent);
}
}
public abstract class BaseFullScreenActivity
{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
protected final int REQ_SACN_ALBUM_LIST = 0x01;
// 一个文件夹,下面好多文件 父目录名 : 子文件list(文件路径)
protected Map> mGruopMap = new HashMap<>();
private final long imagesSize = 1024 * 50; // 图片size > 50KB = ( 1024 * 50 )
protected List albumImageList = new ArrayList<>();
private String[] prefix = {"i","v"};// images video
// 查询条件 大小50kb以上
public void initAlbumImages(final Handler handler){
mGruopMap.clear();
final String[] imagesColums = new String[]{
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.SIZE,
MediaStore.Images.Media.DATE_MODIFIED
};
getLoaderManager().initLoader(DEFAULT_QUERY_LOADER_ID, null, new LoaderManager.LoaderCallbacks() {
@Override
public Loader onCreateLoader(int id, Bundle args) {
return new CursorLoader(BaseFullScreenActivity.this,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imagesColums,
// MediaStore.Images.Media.MIME_TYPE + "=? or "
// + MediaStore.Images.Media.MIME_TYPE + "=?",
// new String[] { "image/jpeg", "image/png" },
// error 单位是什么 B 图片size > 50KB = ( 1024 * 50 )
MediaStore.Images.Media.SIZE + "> ? and "
+ MediaStore.Images.Media.MIME_TYPE + "!= ? ",
// 不扫描 gif
new String[] { String.valueOf(imagesSize) , "image/gif"},
// null,null,
MediaStore.Images.Media.DATE_MODIFIED + " DESC");
}
@Override
public void onLoadFinished(Loader loader, Cursor data) {
if (data != null && !data.isClosed() && data.getCount() > 0) {
D.i("slack","count: " + data.getCount());
while (data.moveToNext()) {
String path = prefix[0] + data.getString(data.getColumnIndex(MediaStore.Images.Media.DATA));
//获取该图片的父路径名
File file = new File(path);
String parentName = file.getParentFile().getName();
// long size = data.getLong(data.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE));
// D.i("slack", "pic: " + path + ", " + parentName + ", " +
//// file.getTotalSpace() + ", " + file.getUsableSpace() + ", " + file.getFreeSpace() +
// size);
//根据父路径名将图片放入到mGruopMap中
if (mGruopMap.containsKey(parentName)) {
mGruopMap.get(parentName).add(path);
} else {
List chileList = new ArrayList();
chileList.add(path);
mGruopMap.put(parentName, chileList);
}
}
// 通知完成扫描 TODO
data.close();
getLoaderManager().destroyLoader(DEFAULT_QUERY_LOADER_ID);
initAlbumVideos(handler);
// // 没有图片? 不会有这情况吧
// formatGroupImages(mGruopMap);
// handler.sendEmptyMessage(REQ_SACN_ALBUM_LIST);
} else {
D.i("slack", "pic no data");
getLoaderManager().destroyLoader(DEFAULT_QUERY_LOADER_ID);
initAlbumVideos(handler);
}
}
@Override
public void onLoaderReset(Loader loader) {
}
});
}
public void initAlbumVideos(final Handler handler){
final String[] mediaColumns = new String[]{
MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID
};
getLoaderManager().initLoader(DEFAULT_QUERY_LOADER_ID, null, new LoaderManager.LoaderCallbacks() {
@Override
public Loader onCreateLoader(int id, Bundle args) {
return new CursorLoader(BaseFullScreenActivity.this,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
mediaColumns,
null, null, MediaStore.Video.Media.DATE_MODIFIED + " DESC");
}
@Override
public void onLoadFinished(Loader loader, Cursor data) {
if (data != null && !data.isClosed() && data.getCount() > 0) {
D.i("slack","video count: " + data.getCount());
while (data.moveToNext()) {
String path = prefix[1] + data.getString(data.getColumnIndex(MediaStore.Video.Media.DATA));
String parentName = new File(path).getParentFile().getName();
// video 和 images 不会在同一个文件夹下吧,会存在的
if (mGruopMap.containsKey(parentName)) {
mGruopMap.get(parentName).add(path);
} else {
List chileList = new ArrayList<>();
chileList.add(path);
mGruopMap.put(parentName, chileList);
}
}
data.close();
// 没有图片? 不会有这情况吧
formatGroupImages(mGruopMap);
handler.sendEmptyMessage(REQ_SACN_ALBUM_LIST);
} else {
D.i("slack", "Video no data");
}
getLoaderManager().destroyLoader(DEFAULT_QUERY_LOADER_ID);
}
@Override
public void onLoaderReset(Loader loader) {
}
});
}
// 因为扫描手机的时候将图片信息放在HashMap中
// 所以需要遍历HashMap将数据组装成List
private List formatGroupImages(Map> map) {
if(map.size() == 0){
return null;
}
albumImageList.clear();
Iterator>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry> entry = it.next();
AlbumImage mAlbumImage = new AlbumImage();
String key = entry.getKey();
List value = entry.getValue();
mAlbumImage.folderName = key;
mAlbumImage.imageCount = value.size();
mAlbumImage.imagePath = value.get(0);//获取该组的第一张图片
albumImageList.add(mAlbumImage);
}
D.i("slack", "pic list " + albumImageList.size() );
return albumImageList;
}
}
布局就一个RecycleView
/**
* Description: 相册 列表
* Created by slack on 2016/9/7 10:54 .
*/
public class AlbumImagesAdapter extends BaseAdapter {
private List imagesList;
private ItemClickListener mClickListener;
public AlbumImagesAdapter(@NonNull RecyclerView recyclerView,List list,ItemClickListener itemClickListener) {
super(recyclerView.getContext());
this.imagesList = list;
this.mClickListener = itemClickListener;
}
@Override
public AlbumImagesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AlbumImagesHolder(mLayoutInflater.inflate(R.layout.item_album_images,parent,false));
}
@Override
public void onBindViewHolder(AlbumImagesHolder holder, int position) {
holder.bindView(position);
}
@Override
public int getItemCount() {
return imagesList.size();
}
class AlbumImagesHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView photoView;
public AlbumImagesHolder(View itemView) {
super(itemView);
photoView = (ImageView) itemView.findViewById(R.id.album_item_img);
ViewGroup.LayoutParams lp = photoView.getLayoutParams();
lp.height = lp.width = (WT.mScreenWidth - 100) / 4 ;// 每个图片 屏幕的 1/4 (减去padding)
photoView.setLayoutParams(lp);
}
public void bindView(int position){
String path = imagesList.get(position);
if(path.startsWith("v")){
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(mContext, Uri.fromFile(new File(path.substring(1))));
photoView.setImageBitmap(mmr.getFrameAtTime());
}else{
WTUtils.showAlbumImage(photoView,path.substring(1));
}
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
D.i("slack","click :" + getAdapterPosition());
// 进入相册详情界面
if(mClickListener != null){
mClickListener.onItemClick(getAdapterPosition());
}
}
}
}
recycleview的item布局
base里面
public abstract class BaseAdapter extends RecyclerView.Adapter
{
protected Context mContext;
protected LayoutInflater mLayoutInflater;
protected OnItemClickListener mItemClickListener = null;
public BaseAdapter(@NonNull Context context)
{
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
public void setItemClickListener(OnItemClickListener listener)
{
mItemClickListener = listener;
}
public interface OnItemClickListener
{
void onItemClicked(Adapter adapter, VH holder);
}
public interface ItemClickListener{
void onItemClick(int pos);
}
/*
* 从Assets中读取图片
*/
public Bitmap getImageFromAssetsFile(String path,String fileFullName)
{
Bitmap image = null;
AssetManager am = mContext.getResources().getAssets();
try {
// InputStream is = am.open( path + File.separator + fileName + ".png");
InputStream is = am.open( path + File.separator + fileFullName);
image = BitmapFactory.decodeStream(is);
is.close();
}
catch (IOException e) {
e.printStackTrace();
}
return image;
}
}
/**
* 展示相册图片
* Create by slack on 2016/09/07 10:40
*/
public class AlbumImagesActivity extends BaseFullScreenActivity {
private List imagesList;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_album_images);
initData();
initView();
}
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.album_images);
((TextView)findViewById(R.id.top_center)).setText(new File(imagesList.get(0)).getParentFile().getName());
findViewById(R.id.top_left).setOnClickListener(this);
((ImageView)findViewById(R.id.top_right)).setImageResource(R.drawable.home_red);
findViewById(R.id.top_right).setOnClickListener(this);
mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));
mRecyclerView.setAdapter(new AlbumImagesAdapter(mRecyclerView,imagesList,itemClickListener));
}
AlbumListAdapter.ItemClickListener itemClickListener = new AlbumListAdapter.ItemClickListener() {
@Override
public void onItemClick(int pos) {
if(pos >= 0 && pos < imagesList.size()){
D.i("slack","pos:" + pos);
String path = imagesList.get(pos);
if(path.startsWith("v")){
if (WTRenderer.mProcessVideoCtrl.prepare(new File(path.substring(1)))) {
startNewActivity(EditVideoActivity.class, false);
}
}else {
Bitmap bitmap = ImageUtils.getCorrectBitmap(path.substring(1));
if (WTRenderer.mPictureCtrl.processPicture(bitmap)) {
startNewActivity(EditPhotoActivity.class, false);
}
}
}
}
};
private void initData() {
if(getIntent() != null ){
imagesList = getIntent().getStringArrayListExtra("list");
if(imagesList.size() == 0){
finish();
}
}
}
/**
* Description: 相册 列表
* Created by slack on 2016/9/7 10:54 .
*/
public class AlbumImagesAdapter extends BaseAdapter {
private List imagesList;
private ItemClickListener mClickListener;
public AlbumImagesAdapter(@NonNull RecyclerView recyclerView,List list,ItemClickListener itemClickListener) {
super(recyclerView.getContext());
this.imagesList = list;
this.mClickListener = itemClickListener;
}
@Override
public AlbumImagesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AlbumImagesHolder(mLayoutInflater.inflate(R.layout.item_album_images,parent,false));
}
@Override
public void onBindViewHolder(AlbumImagesHolder holder, int position) {
holder.bindView(position);
}
@Override
public int getItemCount() {
return imagesList.size();
}
class AlbumImagesHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView photoView;
public AlbumImagesHolder(View itemView) {
super(itemView);
photoView = (ImageView) itemView.findViewById(R.id.album_item_img);
ViewGroup.LayoutParams lp = photoView.getLayoutParams();
lp.height = lp.width = (WT.mScreenWidth - 100) / 4 ;// 每个图片 屏幕的 1/4 (减去padding)
photoView.setLayoutParams(lp);
}
public void bindView(int position){
String path = imagesList.get(position);
if(path.startsWith("v")){
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(mContext, Uri.fromFile(new File(path.substring(1))));
photoView.setImageBitmap(mmr.getFrameAtTime());
}else{
WTUtils.showAlbumImage(photoView,path.substring(1));
}
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
D.i("slack","click :" + getAdapterPosition());
// 进入相册详情界面
if(mClickListener != null){
mClickListener.onItemClick(getAdapterPosition());
}
}
}
}
recycleview的item布局,就一个imageView
这样就完成啦,代码都贴出来了
- - - - update - - -
太傻太傻,发现视频加载时缓慢,是我自己处理了视频图片,还没有做缓存,可以使用lrucache做缓存
// 手机内存的 1/10
LruCache lruCache = new LruCache<>( ((int)(Runtime.getRuntime().maxMemory() / 1024 )) / 10 );
https://github.com/nostra13/Android-Universal-Image-Loader
private static DisplayImageOptions fileOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.loading) // 设置图片下载期间显示的图片
.showImageForEmptyUri(R.drawable.wutaicon) // 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.wutaicon) // 设置图片加载或解码过程中发生错误显示的图片
.cacheInMemory(true) // 设置下载的图片是否缓存在内存中
// .cacheOnDisk(true) // 设置下载的图片是否缓存在SD卡中
// .displayer(new RoundedBitmapDisplayer(20)) // 设置成圆角图片
.build(); // 构建完成
public static void showAlbumImage(ImageView imageView,String path){
mImageLoader.displayImage("file://" + path ,imageView,fileOptions);
}