Android 圖片選擇詳解及實(shí)例代碼
Android 圖片選擇
可以達(dá)到的效果:
1.第一個(gè)圖片的位置放照相機(jī),點(diǎn)擊打開(kāi)照相機(jī)
2.其余的是顯示全部存儲(chǔ)的圖片,點(diǎn)擊一次是查看大圖,長(zhǎng)按則是每張圖片出現(xiàn)一個(gè)checkBox,可以進(jìn)行選擇
下面是實(shí)例效果圖
MainActivity 類
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 類
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類
//也可以用 extends 來(lái)限制一個(gè)泛型的父類 //在類的后面定義一個(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 類
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>
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Android開(kāi)發(fā)者常見(jiàn)的UI組件總結(jié)大全
Android開(kāi)發(fā)中UI組件是構(gòu)建用戶界面的基本元素,下面這篇文章主要給大家介紹了關(guān)于Android開(kāi)發(fā)者常見(jiàn)的UI組件總結(jié)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04Android獲取系統(tǒng)儲(chǔ)存以及內(nèi)存信息的方法(一)
這篇文章主要為大家詳細(xì)介紹了Android獲取系統(tǒng)儲(chǔ)存以及內(nèi)存信息的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Android編程實(shí)現(xiàn)仿iphone抖動(dòng)效果的方法(附源碼)
這篇文章主要介紹了Android編程實(shí)現(xiàn)仿iphone抖動(dòng)效果的方法,結(jié)合實(shí)例形式分析了仿iphone抖動(dòng)效果的頁(yè)面布局及功能實(shí)現(xiàn)技巧,并附帶實(shí)例源碼供讀者下載,需要的朋友可以參考下2015-11-11android自定義View實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
這篇文章主要為大家詳細(xì)介紹了android自定義View實(shí)現(xiàn)簡(jiǎn)單五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Android 自定義View實(shí)現(xiàn)計(jì)時(shí)文字詳解
這篇文章主要為大家介紹了Android 自定義View實(shí)現(xiàn)計(jì)時(shí)文字詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Kotlin基礎(chǔ)學(xué)習(xí)之lambda中return語(yǔ)句詳解
這篇文章主要給大家介紹了關(guān)于Kotlin基礎(chǔ)學(xué)習(xí)之lambda中return語(yǔ)句的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或使用Kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07android實(shí)現(xiàn)okHttp的get和post請(qǐng)求的簡(jiǎn)單封裝與使用
這篇文章主要介紹了android實(shí)現(xiàn)okHttp的get和post請(qǐng)求的簡(jiǎn)單封裝與使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05