Android自定義組件獲取本地圖片和相機(jī)拍照?qǐng)D片
iOS中有封裝好的選擇圖片后長(zhǎng)按出現(xiàn)動(dòng)畫刪除效果,效果如下
而Android找了很久都沒有找到有這樣效果的第三方組件,最后懶得找了還是自己實(shí)現(xiàn)這效果吧
選擇圖片后還可對(duì)圖片進(jìn)行剪裁

當(dāng)然,代碼中還有很多不完善的地方,我接下來(lái)會(huì)繼續(xù)完善這個(gè)組件的
已經(jīng)上傳到開源社區(qū),歡迎大家來(lái)Star啊~
Demo源碼:傳送門
設(shè)計(jì)中的碰到的一些問題和解決思路
1.如何讓加號(hào)圖片顯示在GridView最后面
首先在調(diào)用GridAdapter構(gòu)造方法時(shí)就加載加號(hào)圖片
/**
* 圖片適配器
* @param context 上下文
* @param imagesum 最大可添加圖片數(shù)
*/
public GridAdapter(Context context, int imagesum) {
this.context = context;
this.imageSum = imagesum;
// 加號(hào)圖片
mAddBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_add_image);
}
然后在getCount()方法里對(duì)圖片數(shù)據(jù)集合加1,在該位置上添加加號(hào)圖片
@Override
public int getCount() {
// 數(shù)據(jù)集合加一,在該位置上添加加號(hào)
return imageItemData == null ? 0 : imageItemData.size() + 1;
}
最后在getView()方法中,每次顯示圖片時(shí)都對(duì)數(shù)據(jù)集合中的元素?cái)?shù)量進(jìn)行判斷,如果數(shù)據(jù)集合的數(shù)量大于position,則表示需要顯示加號(hào)圖片
if (imageItemData != null && imageItemData.size() > position) {
// 正常圖片
} else {
// 加號(hào)圖片
}
這樣就能保證加號(hào)圖片一直在GridView最后一個(gè)item上
2.如何顯示出刪除按鈕
在item布局時(shí),在圖片的右上角覆蓋一層刪除按鈕,在Adapter中對(duì)這個(gè)圖片的顯示和隱藏進(jìn)行處理
/** 判斷是否顯示清除按鈕 true=顯示 */
private boolean showImageClear = false;
//對(duì)外提供顯示和隱藏的方法
/**
* 設(shè)置圖片顯示狀態(tài)
* @param clear 圖片狀態(tài)
*/
public void setClearImgShow(boolean clear) {
showImageClear = clear;
}
/**
* 圖片顯示狀態(tài)
* @return 狀態(tài) true=顯示
*/
public boolean getClearImgShow() {
return showImageClear;
}
刪除按鈕默認(rèn)不顯示,當(dāng)用戶長(zhǎng)按圖片時(shí)就顯示出來(lái)
// 長(zhǎng)按顯示刪除按鈕
mGridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if (!(position == gridAdapter.imageItemData.size())) {
// 如果刪除按鈕已經(jīng)顯示了則不再設(shè)置
if (!gridAdapter.getClearImgShow()) {
gridAdapter.setClearImgShow(true);
gridAdapter.notifyDataSetChanged();
}
}
// 返回true,停止事件向下傳播
return true;
}
});
這里需要攔截長(zhǎng)按點(diǎn)擊事件,把返回值設(shè)置為true,因?yàn)槲覀冞€設(shè)置了點(diǎn)擊事件的監(jiān)聽,如果不攔截事件,那么長(zhǎng)按事件結(jié)束后還會(huì)同時(shí)執(zhí)行單擊事件
最后關(guān)鍵的一點(diǎn),在GridAdapter類中的getView方法里進(jìn)行控制,通過(guò)getClearImgShow方法獲取刪除圖片是否需要顯示,如果返回為true則顯示出來(lái),并獲取動(dòng)畫實(shí)例,讓圖片開始執(zhí)行動(dòng)畫效果
if (imageItemData != null && imageItemData.size() > position) {
// 正常顯示
// 判斷是否需要顯示刪除按鈕 ,為true則顯示,并執(zhí)行動(dòng)畫效果
if (getClearImgShow()) {
holder.imgclear.setVisibility(View.VISIBLE);
CustomRotateAnim anim = CustomRotateAnim.getCustomRotateAnim();
anim.setDuration(300);
anim.setRepeatCount(2);
anim.setInterpolator(new LinearInterpolator()); // 設(shè)置為勻速
holder.img.startAnimation(anim);
} else {
// 關(guān)閉動(dòng)畫,隱藏刪除按鈕
holder.img.clearAnimation();
holder.imgclear.setVisibility(View.GONE);
}
holder.img.setImageBitmap(PhotoBitmapUtil.getCompressPhoto(imageItemData.get(position)));
} else {
......省略......
}
3.如何設(shè)置當(dāng)圖片達(dá)到最大數(shù)時(shí),隱藏加號(hào)按鈕
在使用GridAdapter的時(shí)候,調(diào)用方需要傳入一個(gè)最大圖片數(shù):
gridAdapter = new GridAdapter(MainActivity.this, 8); mGridView.setAdapter(gridAdapter);
然后在GridAdapter中接收這個(gè)最大圖片數(shù),并在getView()方法中對(duì)加號(hào)圖片的顯示進(jìn)行管控
if (imageItemData != null && imageItemData.size() > position) {
// 顯示選擇的圖片
......省略......
} else {
// 顯示加號(hào)按鈕
// 圖片數(shù)達(dá)到最大限制時(shí)隱藏加號(hào)圖片
if (imageItemData.size() != imageSum) {
holder.imgclear.setVisibility(View.GONE); // 不顯示刪除按鈕
holder.img.clearAnimation(); // 去除動(dòng)畫
holder.img.setImageBitmap(mAddBitmap);
}
}
“gridAdapter.getCount() - 1”是因?yàn)槲覀冊(cè)谔砑蛹犹?hào)圖片時(shí)加了1,所以使用時(shí)需要減1
// 點(diǎn)擊圖片
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// 如果單擊時(shí)刪除按鈕處在顯示狀態(tài),則隱藏它
if (gridAdapter.getClearImgShow()) {
gridAdapter.setClearImgShow(false);
gridAdapter.notifyDataSetChanged();
} else {
if (gridAdapter.getCount() - 1 == position) {
// 判斷是否達(dá)到了可添加圖片最大數(shù)
if (!(gridAdapter.imageItemData.size() == gridAdapter.imageSum)) {
selectPhoto.showPopupSelect(mGridView);
}
} else {
popupViewGridPhoto(position);
}
}
}
});
4.如何降低圖片加載時(shí)的內(nèi)存消耗量
要在GridView中顯示那么多的圖片,肯定是需要多圖片進(jìn)行壓縮處理的,不然很容易出現(xiàn)OOM錯(cuò)誤
這里通過(guò)質(zhì)量壓縮,降低加載圖片的內(nèi)存大小
/**
* 把原圖按1/5的比例壓縮
*
* @param path 原圖的路徑
* @return 壓縮后的圖片
*/
public static Bitmap getCompressPhoto(String path) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 5; // 圖片的長(zhǎng)寬設(shè)置為原來(lái)的五分之一
Bitmap bmp = BitmapFactory.decodeFile(path, options);
options = null;
return bmp;
}
也可以通過(guò)其它的方式,可以參考這篇博客《Android避免內(nèi)存溢出(Out of Memory)方法總結(jié)》
5.如何防止部分手機(jī)拍照后圖片被旋轉(zhuǎn)的問題
在測(cè)試中,部分三星手機(jī)拍攝完照片后會(huì)把圖片旋轉(zhuǎn)90度,這個(gè)設(shè)計(jì)實(shí)在是坑,為此還得專門為了這個(gè)問題進(jìn)行處理,每次拍攝完照片后都要獲取圖片的旋轉(zhuǎn)角度,如果圖片被旋轉(zhuǎn)了的話就再旋轉(zhuǎn)回去
可以參考這篇博客
《Android 解決部分手機(jī)拍照后獲取的圖片被旋轉(zhuǎn)的問題》
6.如何讓圖片左右搖擺
想要實(shí)現(xiàn)圖片左右搖擺的效果,需要我們自定義Animation
可參看這篇博客
《Android 自定義Animation實(shí)現(xiàn)View搖擺效果》
這里就先介紹這么多,詳細(xì)的解釋代碼注釋中都有的,就不再多說(shuō)啦
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Android Activity與Service的交互方式
下面小編就為大家?guī)?lái)一篇淺談Android Activity與Service的交互方式。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
基于VSTS的Xamarin.Android持續(xù)集成步驟詳解
這篇文章主要介紹了基于VSTS的Xamarin.Android持續(xù)集成步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Android 開發(fā)之旅:詳解view的幾種布局方式及實(shí)踐
這篇文章主要介紹了Android 開發(fā)之旅:詳解view的幾種布局方式及實(shí)踐,具有一定的參考價(jià)值,有需要的可以了解一下。2016-12-12
Android自定義控件之圓形進(jìn)度條動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android自定義控件之圓形進(jìn)度條動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
windows10安裝adb/fastboot驅(qū)動(dòng)超詳細(xì)圖文教程
這篇文章主要介紹了windows10安裝adb/fastboot超詳細(xì)圖文教程,安裝方法也很簡(jiǎn)單,只要adb安裝成功,fastboot就安裝好了,文中給大家介紹了問題分析及解決方法,需要的朋友可以參考下2023-01-01
Android實(shí)現(xiàn)文字滾動(dòng)播放效果的代碼
這篇文章主要介紹了Android實(shí)現(xiàn)文字滾動(dòng)播放效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
android水平循環(huán)滾動(dòng)控件使用詳解
這篇文章主要為大家詳細(xì)介紹了android水平循環(huán)滾動(dòng)控件的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android編程ViewPager回彈效果實(shí)例分析
這篇文章主要介紹了Android編程ViewPager回彈效果,以實(shí)例形式較為詳細(xì)的分析了ViewPager回彈效果的相關(guān)使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10

