詳解android寫(xiě)一個(gè)選擇圖片的示例代碼
可以達(dá)到的效果
- 第一個(gè)圖片的位置放照相機(jī),點(diǎn)擊打開(kāi)照相機(jī)
- 其余的是顯示全部存儲(chǔ)的圖片,點(diǎn)擊一次是查看大圖,長(zhǎng)按則是每張圖片出現(xiàn)一個(gè)checkBox,可以進(jìn)行選擇
下面是實(shí)例效果圖

MainActivity 類(lèi)
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, ImageAdapter.OnImageCheckListener, View.OnClickListener {
private static final int CAMERA_CODE = 12;
List<File> fileList = new ArrayList<>();
ImageAdapter adapter;
GridView gvImage;
TextView tvFinish;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//彈出對(duì)話框,加載數(shù)據(jù)
loadData();
}
private void initView() {
gvImage = (GridView) findViewById(R.id.gv_image);
tvFinish = (TextView) findViewById(R.id.tv_finish);
adapter = new ImageAdapter(this, fileList);
adapter.setOnImageCheckListener(this);
gvImage.setAdapter(adapter);
gvImage.setOnItemClickListener(this);
gvImage.setOnItemLongClickListener(this);
tvFinish.setOnClickListener(this);
}
private ProgressDialog showProgressDialog() {
//彈出對(duì)話框
ProgressDialog dialog = new ProgressDialog(this);
dialog.setTitle("提示");
dialog.setMessage("正在加載圖片,請(qǐng)稍等。。。");
dialog.show();
return dialog;
}
private void loadData() {
final ProgressDialog dialog = showProgressDialog();
//開(kāi)啟線程
new Thread() {
@Override
public void run() {
super.run();
//遞歸
//從sd卡中獲取所有圖片
getFile(Environment.getExternalStorageDirectory());
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.dismiss();
adapter.notifyDataSetChanged();
}
});
}
}.start();
}
public void getFile(File dir) {
//1. 獲取子目錄
File[] files = dir.listFiles();
if (files == null)
return;
//集合或者數(shù)組去點(diǎn)for
for (File file : files) {
if (file.isDirectory())
getFile(file);
else {
//加載圖片
if (file.getName().endsWith(".png") || file.getName().endsWith(".jpg")) {
fileList.add(file);
}
}
}
}
File cameraFile;
//點(diǎn)擊
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
//getAbsolutePath返回的路徑是沒(méi)有"/"
cameraFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/" + System.currentTimeMillis() + ".png");
//打開(kāi)照相機(jī)
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//照相機(jī)需要帶數(shù)據(jù)
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
startActivityForResult(intent, CAMERA_CODE);
} else {
//打開(kāi)大圖
File file = fileList.get(position - 1);
//帶數(shù)據(jù)跳轉(zhuǎn)到現(xiàn)實(shí)大圖
Intent intent = new Intent(this, ShowBigImage.class);
intent.putExtra("file", file);
startActivity(intent);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e("TAG", resultCode + "---------------------");
if (requestCode == CAMERA_CODE && resultCode == RESULT_OK) {
Log.e("TAG", (cameraFile.exists()) + "");
fileList.add(0, cameraFile);
adapter.notifyDataSetChanged();
}
}
//長(zhǎng)按
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0)
return false;
else {
adapter.open(position);
}
return true;
}
@Override
public void onImageCheck(boolean b) {
//b代表 適配器中 有沒(méi)有勾選的值
tvFinish.setEnabled(b);
}
@Override
public void onClick(View v) {
//需要知道有哪些數(shù)據(jù)被選中
//不能使用泛型,ArrayList才實(shí)現(xiàn)了序列化,List沒(méi)有實(shí)現(xiàn)
ArrayList<File> resultList = new ArrayList<>();
//通過(guò)適配器中的 為true的 選中的項(xiàng)來(lái)加載file
SparseBooleanArray booleanArray = adapter.getBooleanArray();
for (int i = 0; i < booleanArray.size(); i++) {
boolean isCheck = booleanArray.get(booleanArray.keyAt(i));
if (isCheck) {
int position = booleanArray.keyAt(i);
resultList.add(fileList.get(position - 1));
}
}
Intent intent = new Intent();
intent.putExtra("list", resultList);
//返回?cái)?shù)據(jù)
setResult(RESULT_OK, intent);
finish();
}
}
ImageAdapter 類(lèi)
public class ImageAdapter extends ListItemAdapter<File> {
private boolean select = false;
public void open(int posisiont) {
select = true;
booleanArray.put(posisiont, true);
if (onImageCheckListener != null)
onImageCheckListener.onImageCheck(true);
this.notifyDataSetChanged();
}
public void close() {
select = false;
booleanArray.clear();
notifyDataSetChanged();
}
//position
//HashMap<Integer, Boolean> map = new HashMap<>();
private SparseBooleanArray booleanArray = new SparseBooleanArray();
public SparseBooleanArray getBooleanArray() {
return booleanArray;
}
public ImageAdapter(Context context, List<File> list) {
super(context, list);
}
@Override
public int getCount() {
//多出來(lái)的就是照相機(jī)
return super.getCount() + 1;
}
// @Override
// public View getView(int position, View convertView, ViewGroup parent) {
// if (convertView == null) {
// ImageView iv = new ImageView(mContext);
// iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
// iv.setBackgroundColor(Color.argb(0xFF, 0x07, 0x05, 0x18));
// int width = mContext.getResources().getDisplayMetrics().widthPixels / 3 - 2;
// GridView.LayoutParams params = new GridView.LayoutParams(width, width);
// iv.setPadding(2, 2, 2, 2);
// iv.setLayoutParams(params);
// convertView = iv;
// }
// ImageView iv = (ImageView) convertView;
// if (position == 0) {
// //照相機(jī)
// iv.setImageResource(R.mipmap.camera);
// } else {
// iv.setImageURI(Uri.fromFile(getItem(position - 1)));
// }
// return convertView;
// }
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_image, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position == 0) {
holder.image.setImageResource(R.mipmap.camera);
holder.checkBox.setVisibility(View.GONE);
} else {
holder.image.setImageURI(Uri.fromFile(getItem(position - 1)));
if (select) {
holder.checkBox.setVisibility(View.VISIBLE);
//當(dāng)前的需不需要勾選呢
//null
Boolean b = booleanArray.get(position);
if (b == null || b == false) {
holder.checkBox.setChecked(false);
} else {
holder.checkBox.setChecked(true);
}
//item點(diǎn)擊和布局沖突
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Boolean b = booleanArray.get(position);
if (b == null || b == false)
b = true;
else
b = false;
booleanArray.put(position, b);
//判斷所有的boolean,如果已經(jīng)沒(méi)有一個(gè)true 關(guān)閉
for (int i = 0; i < booleanArray.size(); i++) { //4-true 0==false
//兩個(gè)值 key -- > 3 4
// 0 1 2 3 4 5
boolean isChecked = booleanArray.get(booleanArray.keyAt(i));
Log.e("TAG", "----" + isChecked);
Log.e("TAG", booleanArray.toString());
if (isChecked) {
//有被勾選的值
if (onImageCheckListener != null)
onImageCheckListener.onImageCheck(true);
return;
}
}
if (onImageCheckListener != null)
onImageCheckListener.onImageCheck(false);
//沒(méi)有被勾選的值了
//關(guān)閉
close();
}
});
} else {
holder.checkBox.setVisibility(View.GONE);
}
//不能使用onCheck
// holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// @Override
// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// booleanArray.put(position, isChecked);
// }
// });
}
return convertView;
}
//回調(diào)方法。
//寫(xiě)在需要執(zhí)行方法的地方
//他實(shí)現(xiàn) 在需要返回的地方
public interface OnImageCheckListener {
public void onImageCheck(boolean b);
}
private OnImageCheckListener onImageCheckListener;
//alt+insert
public void setOnImageCheckListener(OnImageCheckListener onImageCheckListener) {
this.onImageCheckListener = onImageCheckListener;
}
class ViewHolder {
ImageView image;
CheckBox checkBox;
public ViewHolder(View convertView) {
image = (ImageView) convertView.findViewById(R.id.iv_image);
int width = mContext.getResources().getDisplayMetrics().widthPixels / 3 - 2;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, width);
image.setLayoutParams(params);
checkBox = (CheckBox) convertView.findViewById(R.id.cb_check);
}
}
}
ListItemAdapter類(lèi)
//也可以用 extends 來(lái)限制一個(gè)泛型的父類(lèi)
//在類(lèi)的后面定義一個(gè)泛型
public abstract class ListItemAdapter<T> extends BaseAdapter {
protected Context mContext;
protected List<T> mList;
//必須要有上下文,數(shù)據(jù)
//List<File> List<String>
public ListItemAdapter(Context context, List<T> list) {
mContext = context;
mList = list;
}
//適配器去加載一個(gè)List
public void setList(List<T> list) {
this.mList = list;
notifyDataSetChanged();
}
@Override
public int getCount() {
return mList == null ? 0 : mList.size();
}
@Override
public T getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
ShowBigImage 類(lèi)
public class ShowBigImage extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ImageView iv = new ImageView(this);
File file = (File) getIntent().getSerializableExtra("file");
iv.setImageURI(Uri.fromFile(file));
setContentView(iv);
}
}
main_xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.imageselector.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="選取圖片"
android:textColor="@android:color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:enabled="false"
android:text="完成"
android:textColor="@color/textenable" />
</RelativeLayout>
<GridView
android:id="@+id/gv_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="2dp"
android:numColumns="3"
android:verticalSpacing="2dp" />
</LinearLayout>
item_image.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#03030a">
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:scaleType="centerCrop"
android:src="@mipmap/camera" />
<CheckBox
android:id="@+id/cb_check"
android:button="@null"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/cb_selector"
android:layout_alignParentRight="true"
android:layout_margin="10dp"
/>
</RelativeLayout>
res下color文件夾下的textenable.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_enabled="true" /> <item android:color="@android:color/darker_gray" android:state_enabled="false" /> </selector>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android xml實(shí)現(xiàn)animation的4種動(dòng)畫(huà)效果實(shí)例代碼
在Android應(yīng)用程序,使用動(dòng)畫(huà)效果,能帶給用戶更好的感覺(jué),做動(dòng)畫(huà)可以通過(guò)XML或Android代碼來(lái)實(shí)現(xiàn)。本文給大家介紹Android xml實(shí)現(xiàn)animation的4種動(dòng)畫(huà)效果實(shí)例代碼,一起看看吧2016-05-05
Android中ProgressBar用法簡(jiǎn)單實(shí)例
這篇文章主要介紹了Android中ProgressBar用法,以簡(jiǎn)單實(shí)例形式分析了Android中ProgressBar進(jìn)度條控件的功能與布局相關(guān)技巧,需要的朋友可以參考下2016-01-01
Android中HttpURLConnection與HttpClient的使用與封裝
這篇文章主要介紹了Android中HttpURLConnection與HttpClient的使用以及封裝方法,感興趣的小伙伴們可以參考一下2016-03-03
基于Android實(shí)現(xiàn)定時(shí)刷新功能
定時(shí)刷新是一種常見(jiàn)的應(yīng)用需求,例如自動(dòng)加載新數(shù)據(jù)、定時(shí)更新 UI、動(dòng)畫(huà)循環(huán)播放、實(shí)時(shí)監(jiān)控等場(chǎng)景中都需要定時(shí)刷新頁(yè)面,Android 平臺(tái)提供了多種實(shí)現(xiàn)定時(shí)刷新的方式,本文將結(jié)合實(shí)例詳細(xì)講解如何實(shí)現(xiàn)定時(shí)刷新功能,需要的朋友可以參考下2025-04-04
Andorid基于ZXing實(shí)現(xiàn)二維碼生成與掃描的示例代碼
ZXing是一個(gè)開(kāi)源的條碼和二維碼掃描庫(kù),它可以用于Android開(kāi)發(fā)中,通過(guò)ZXing庫(kù)可以實(shí)現(xiàn)Android設(shè)備上的條碼和二維碼掃描功能,開(kāi)發(fā)者可以輕松地在Android應(yīng)用中集成條碼和二維碼掃描功能,本文主要給大家介紹了Andorid?ZXing實(shí)現(xiàn)二維碼,感興趣的朋友可以參考下2023-08-08
Android實(shí)現(xiàn)獲取聯(lián)系人電話號(hào)碼功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)獲取聯(lián)系人電話號(hào)碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android開(kāi)發(fā)之自定義CheckBox
本文通過(guò)實(shí)例代碼演示如何在Android中如何自定義CheckBox,實(shí)現(xiàn)的效果很好,有需要的可以參考借鑒。2016-08-08
Android使用Activity實(shí)現(xiàn)簡(jiǎn)單的可輸入對(duì)話框
大家在做彈出對(duì)話框效果的時(shí)候最容易想到的是用Dialog顯示,但其實(shí)彈出對(duì)話框的實(shí)現(xiàn)效果有兩種:Dialog和Activity,那么下面這篇文章就來(lái)給大家介紹了關(guān)于Android使用Activity如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的可輸入對(duì)話框的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-10-10

