最近因為公司需求需要做一個自定義的相冊,因為手機自帶的相冊沒有這種可以選取多張圖片的功能,先上gif圖,看效果(功能可以看出來,不知道為什么gif這么稀爛。。。)
GIF.gif
簡單功能都實現(xiàn)了,主要點是對圖片的查詢,然后設置了兩個popupWindow來顯示小相冊和點擊放大的效果,比較簡單。(代碼里面會有一些簡單的工具類,看名字可以看出來是干什么的)
查詢手機中的圖片路徑
步驟:
1.查詢圖片的path
2.由圖片path獲取其他信息(該圖片所在文件夾的路徑,文件夾的名字,文 件夾下的圖片個數(shù))
3.定義一個圖片Model,來保存及對圖片信息的傳遞,以便展示出來
4.通過文件夾的list()方法,可以獲取每一個小相冊下的圖片文件
上代碼。。。
//獲取圖片的路徑和父路徑 及 圖片size
private void getImages() {
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
ViewKit.shortToast("檢測到?jīng)]有內(nèi)存卡");
return;
}
showLoading();
new Thread(new Runnable() {
@Override
public void run() {
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver mContentResolver = GalleryActivity.this.getContentResolver();
Cursor mCursor = mContentResolver.query(mImageUri, null,
MediaStore.Images.Media.MIME_TYPE + "=? or "+
MediaStore.Images.Media.MIME_TYPE + "=? or "+
MediaStore.Images.Media.MIME_TYPE + "=?",
new String[]{"image/jpeg", "image/png","image/jpg"},
MediaStore.Images.Media.DATE_TAKEN +" DESC");//獲取圖片的cursor,按照時間倒序(發(fā)現(xiàn)沒卵用)
while (mCursor.moveToNext()) {
String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));// 1.獲取圖片的路徑
File parentFile = new File(path).getParentFile();
if (parentFile == null)
continue;//不獲取sd卡根目錄下的圖片
String parentPath = parentFile.getAbsolutePath();//2.獲取圖片的文件夾信息
String parentName = parentFile.getName();
ImageFloder imageFloder ;//自定義一個model,來保存圖片的信息
//這個操作,可以提高查詢的效率,將查詢的每一個圖片的文件夾的路徑保存到集合中,
//如果存在,就直接查詢下一個,避免對每一個文件夾進行查詢操作
if (mDirPaths.contains(parentPath)) {
continue;
} else {
mDirPaths.add(parentPath);//將父路徑添加到集合中
imageFloder = new ImageFloder();
imageFloder.setFirstImagePath(path);
imageFloder.setDir(parentPath);
imageFloder.setName(parentName);
}
List<String> strings = null;
try {
strings = Arrays.asList(parentFile.list(getFileterImage()));
} catch (Exception e) {
e.printStackTrace();
}
int picSize = strings.size();//獲取每個文件夾下的圖片個數(shù)
imageFloder.setCount(picSize);//傳入每個相冊的圖片個數(shù)
mImageFloders.add(imageFloder);//添加每一個相冊
//獲取圖片最多的文件夾信息(父目錄對象和個數(shù),使得剛開始顯示的是最多圖片的相冊
if (picSize > mPicsSize) {
mPicsSize = picSize;
mImgDir = parentFile;
}
}
mCursor.close();
mDirPaths = null;
mHandler.sendEmptyMessage(1);
}
}).start();
}
這是Model類,貼出來,方便觀看
public class ImageFloder {
private int count;//文件夾下的圖片個數(shù)
private String firstImagePath;//第一張圖片的路徑 傳這個給小相冊圖片顯示
private String dir;//文件夾路徑
private String name;//文件夾的名字
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getFirstImagePath() {
return firstImagePath;
}
public void setFirstImagePath(String firstImagePath) {
this.firstImagePath = firstImagePath;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
還記得上面的handler操作嗎,查詢圖片是一個耗時的操作,為了更新ui,也為了方便觀看,就使用了handler的方式,這樣代碼也比較整潔,下面這個小代碼,就是接下來的步驟了
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
setAdapterData();//設置圖片的顯示
cancelLoading();//取消加載框
initListDirPopupWindw();//初始化小相冊的popupWindow
initChekcBox();//初始化checkbox集合,防止checkBox的錯亂
}
};
設置適配器(采用的RecycleVIew,自己做的封裝)
//設置適配器數(shù)據(jù)
private void setAdapterData() {
if (mImgDir == null) {
ViewKit.shortToast("沒有查詢到圖片");
return;
}
tv_pop_gallery.setText(mImgDir.getName());
try {
mImgs = Arrays.asList(mImgDir.list(getFileterImage()));//獲取文件夾下的圖片集合
}catch (Exception e){
e.printStackTrace();
}
//查詢出來的圖片是正序的,為了讓圖片按照時間倒序顯示,對其倒序操作
Collections.sort(mImgs, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
return -1;
}
});
mAdapter = new GalleryAdapter(gallery_recycleView, mImgs, R.layout.item_gallery_camera);
gallery_recycleView.setLayoutManager(new GridLayoutManager(this, 3));
gallery_recycleView.addItemDecoration(new DividerGridItemDecoration(this));
gallery_recycleView.setAdapter(mAdapter);
}
適配器:
//適配器
private class GalleryAdapter extends BaseRecyclerAdapter<String> {
List<String> datas;
String picPath;
ImageView iv_gallery;
CheckBox cb_gallery;
public GalleryAdapter(RecyclerView v, List<String> datas, int itemLayoutId) {
super(v, datas, itemLayoutId);
this.datas = datas;
}
@Override
public void convert(final RecyclerHolder holder, String item, final int position) {
iv_gallery = holder.getView(R.id.iv_gallery);
cb_gallery = holder.getView(R.id.cb_gallery);
iv_gallery.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, DensityKit.getScreenW() / 3));
picPath = mImgDir.getAbsolutePath() + "/" + datas.get(position);
BitmapKit.loadLocalImage(iv_gallery, picPath);//這里采用的是Glide為ImageVIew加載圖片,很方便,這里對Glide進行了工具類的封裝
//顯示大圖
iv_gallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initBigPicPopupWindw(mImgDir.getAbsolutePath() + "/" + datas.get(position));
}
});
//checkBox
cb_gallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox checkBox = (CheckBox) v;
if (realCount >= 9 && !selectList.get(position)) {
ViewKit.shortToast("最多可以選擇9張圖片");
selectList.put(position, false);
} else{
selectList.put(position, !selectList.get(position));
}
for (Map.Entry<Integer, Boolean> entry : selectList.entrySet()) {
entry.getKey();
Boolean value = entry.getValue();
if (value) {
checkCount++;
}
}
tv_count_gallery.setText("(" + checkCount + ")");
tv_confirm_gallery.setVisibility(checkCount>0?View.VISIBLE:View.GONE);
realCount = checkCount;
checkCount = 0;
checkBox.setChecked(selectList.get(position));
}
});
if(selectList!=null)
cb_gallery.setChecked(selectList.get(position));
}
}
}
左側(cè)popupWindow小相冊的定義
//設置相冊PopupWindow
private void initListDirPopupWindw() {
mListImageDirPopupWindow = new ListImageDirPopupWindow(this, mImageFloders);
mListImageDirPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
setToRightDrawable(R.drawable.arrow_bottom);
}
});
mListImageDirPopupWindow.setOnImageDirSelected(new ListImageDirPopupWindow.OnImageDirSelected() {
//點擊item之后的回調(diào)
@Override
public void selected(ImageFloder floder) {
mListImageDirPopupWindow.showAtDropDownCenter(tv_confirm_gallery);
setToRightDrawable(R.drawable.arrow_bottom);
realCount = 0;
tv_pop_gallery.setText(floder.getName());
tv_count_gallery.setText("(0)");
tv_confirm_gallery.setVisibility(View.GONE);
File file = new File(floder.getDir());
List<String> picFileList = null;
try {
picFileList = Arrays.asList(file.list(getFileterImage()));
} catch (Exception e) {
e.printStackTrace();
}
Collections.sort(picFileList, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
return -1;
}
});
//重新設置數(shù)據(jù)和checkBox初始化
mImgDir = file;
mImgs = picFileList;
initChekcBox();
mAdapter = new GalleryAdapter(gallery_recycleView, picFileList, R.layout.item_gallery_camera);
gallery_recycleView.setAdapter(mAdapter);
}
});
}
相冊PopupWIndow的代碼:
public class ListImageDirPopupWindow extends PopupWindow {
RecyclerView recycl_camera_list;
public ListImageDirPopupWindow(Context context, List<ImageFloder> mImageFloders) {
View conentView = LayoutInflater.from(context).inflate(R.layout.view_dir_camera, null);
recycl_camera_list = (RecyclerView) conentView.findViewById(R.id.recycl_camera_list);
setContentView(conentView);
ListAdapter listAdapter = new ListAdapter(recycl_camera_list, mImageFloders, R.layout.item_list_camera);
recycl_camera_list.setLayoutManager(new LinearLayoutManager(context));//設置垂直
recycl_camera_list.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
recycl_camera_list.setAdapter(listAdapter);
listAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, Object data, int position) {
if (data instanceof ImageFloder) {
ImageFloder imageFloder = (ImageFloder) data;
onImageDirSelected.selected(imageFloder);
}
}
});
setAnimationStyle(R.style.popup_camera);
setFocusable(true);
setTouchable(true);
setOutsideTouchable(true);
ColorDrawable background = new ColorDrawable(0xffffff);
setBackgroundDrawable(background);
setWidth((int) (DensityKit.getScreenW()/2));
setHeight(DensityKit.getScreenH()/3);
}
class ListAdapter extends BaseRecyclerAdapter<ImageFloder> {
public ListAdapter(RecyclerView v, List<ImageFloder> datas, int itemLayoutId) {
super(v, datas, itemLayoutId);
}
@Override
public void convert(RecyclerHolder holder, final ImageFloder imageFloder, int position) {
ImageView iv_first_image = holder.getView(R.id.iv_first_image);
TextView tv_count_list = holder.getView(R.id.tv_count_list);
TextView tv_name_list = holder.getView(R.id.tv_name_list);
BitmapKit.loadLocalImage(iv_first_image, imageFloder.getFirstImagePath());
tv_count_list.setText("(" + imageFloder.getCount() + ")");
tv_name_list.setText(imageFloder.getName());
}
}
public void showAtDropDownCenter(View parent) {
if (!isShowing()) {
setAnimationStyle(R.style.popup_camera);
int[] location = new int[2];
parent.getLocationOnScreen(location);//獲取以屏幕為原點的位置
showAtLocation(parent,Gravity.TOP|Gravity.LEFT,0,location[1]-getHeight());
// showAtLocation(parent,Gravity.TOP,(location[0]-getWidth())/2, location[1]-getHeight());
// showAtLocation(parent, Gravity.NO_GRAVITY, location[0], location[1]-getHeight()); 三種方式都可以 原理是一樣的
} else {
dismiss();
}
}
//點擊之后的接口回調(diào)
private OnImageDirSelected onImageDirSelected;
public void setOnImageDirSelected(OnImageDirSelected onImageDirSelected) {
this.onImageDirSelected = onImageDirSelected;
}
public interface OnImageDirSelected {
void selected(ImageFloder floder);
}
}
雜⑦雜⑧的代碼,懶的搞了,都貼出來(都有小注釋)
//設置大圖片的PopupWindow
private void initBigPicPopupWindw(String path) {
BigImagePopup bigImagePopup = new BigImagePopup(this);
bigImagePopup.setUrl(path);
bigImagePopup.showAtDropDownCenter(tv_confirm_gallery);
}
//導航欄點擊事件
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.tv_pop_gallery) {
setToRightDrawable(R.drawable.arrow_up);
mListImageDirPopupWindow.showAtDropDownCenter(tv_confirm_gallery);
} else if (i == R.id.tv_confirm_gallery) {
ArrayList<String> pathList = new ArrayList<>();
for (Map.Entry<Integer, Boolean> entry : selectList.entrySet()) {
Boolean isChecked = entry.getValue();
if (isChecked) {
Integer position = entry.getKey();
String checkPath = mImgDir.getAbsolutePath() + "/" + mImgs.get(position);
pathList.add(checkPath);
}
}
backUrl(pathList);
}
}
//intent
public static Intent createIntent(Context context) {
Intent intent = new Intent(context, GalleryActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
return intent;
}
//返回的圖片路徑集合
private void backUrl(ArrayList<String> pathList) {
Intent intent = new Intent();
intent.putStringArrayListExtra("imageUrl", pathList);
setResult(RESULT_OK, intent);
finish();
}
// 初始化 設置所有checkbox都為未選擇
private void initChekcBox() {
selectList = new HashMap<Integer, Boolean>();
if (mImgs != null && mImgs.size() > 0) {
for (int i = 0; i < mImgs.size(); i++) {
selectList.put(i, false);
}
}
}
//動態(tài)改變text的toRightDrawable
private void setToRightDrawable(int drawalbeId){
Drawable drawable= getResources().getDrawable(drawalbeId);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
tv_pop_gallery.setCompoundDrawables(null,null,drawable,null);
}
//設置popWindow的背景----不要設置 會透視。。。
public void setBg_popup() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1.0f;
getWindow().setAttributes(lp);
}
//圖片篩選器,過濾無效圖片
private FilenameFilter getFileterImage(){
FilenameFilter filenameFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if (filename.endsWith(".jpg")
|| filename.endsWith(".png")
|| filename.endsWith(".jpeg"))
return true;
return false;
}
};
return filenameFilter;
}
點擊放大的popupWIndow
public class BigImagePopup extends PopupWindow {
ImageView iv_big_picture;
public BigImagePopup(Activity context) {
View conentView = LayoutInflater.from(context).inflate(R.layout.view_bigpic, null);
setContentView(conentView);
LinearLayout linearLayout = (LinearLayout) conentView.findViewById(R.id.ll_picture);
iv_big_picture = (ImageView) conentView.findViewById(R.id.iv_big_picture);
linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
iv_big_picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
setAnimationStyle(R.style.big_popup_camera);
setFocusable(true);
setTouchable(true);
setOutsideTouchable(true);
ColorDrawable background = new ColorDrawable(0xffffff);
setBackgroundDrawable(background);
setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
setHeight(LinearLayout.LayoutParams.MATCH_PARENT);
}
public void setUrl(String url){
BitmapKit.loadLocalImage(iv_big_picture, url);
}
public void showAtDropDownCenter(View parent) {
if (!isShowing()) {
setAnimationStyle(R.style.big_popup_camera);
showAtLocation(parent, Gravity.BOTTOM, 0, 0);
} else {
dismiss();
}
}
}
寫個這樣的博客都這么累。。。。。