項目需求只需要一張圖片,需要其他的可以自己改改;代碼地址在最下面
不好意思,在下午的測試中測到如果用戶沒有拍照,直接finish掉會空指針異常,現在已解決
@Override
protected void onDestroy() {
super.onDestroy();
if (!isImageView) {
mFile.delete();
}
}
在onDestroy()方法中這樣去判斷,現在已經改正,疏忽大意了.代碼地址就不變了,我不知道怎麼重新上傳。。。
項目需求是這個效果,搜到的Demo對比一下也不太滿意,乾脆自己寫一個
分析起來很簡單,一個GridView和EditText組成,爲了保持那個圖標一直都是最後一個所以在Adapter的getCount那裏把size+1;
package com.example.y.demo;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* Created by y on 2016/3/16.
*/
public class Adapter extends BaseAdapter {
private ArrayList<Bitmap> list;
private Context context;
public Adapter(Context context, ArrayList<Bitmap> list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size() + 1;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.item, null);
ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
if (position < list.size()) {
iv.setImageBitmap(list.get(position));
} else if (position == list.size()) {
iv.setImageResource(R.mipmap.photo);
}
return convertView;
}
}
佈局就是兩個控件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.y.demo.MainActivity">
<EditText
android:id="@+id/et_feedback"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="20dp"
android:background="@mipmap/bg_edit_feedback"
android:gravity="left"
android:hint="照片只可以上傳一張"
android:minHeight="200dp"
android:padding="10dp"
android:textColorHint="#a8a8a8"
android:textSize="14sp" />
<GridView
android:id="@+id/gv_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/et_feedback"
android:layout_marginTop="-70dp"
android:background="@null"
android:listSelector="@android:color/transparent"
android:numColumns="4" />
</RelativeLayout>
這裏要注意以下,加了GridView我的EditText總是自動獲取焦點自動彈出鍵盤,在manifests.xml的那個activity下加一句
android:windowSoftInputMode="stateHidden"
一共有好幾個屬性,有興趣的可以自己去查下資料
記得一定要添加權限
<!--在SDCard中創建與刪除文件權限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard寫入數據權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 從SDCard讀取數據權限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Activity的註釋比較詳細,就不細說了
package com.example.y.demo;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private Uri imageUri;
private boolean isImageView = true;
private String path;
private ArrayList<Bitmap> list;
private Adapter adapter;
private GridView gridView;
private static final int RESULT_OPENCAMERA_LOAD_IMAGE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<>();
adapter = new Adapter(getApplicationContext(), list);
gridView = (GridView) findViewById(R.id.gv_photo);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (isImageView && position == adapter.getCount() - 1) {
openCamera();
} else if (position == adapter.getCount() - 1) {
Toast.makeText(getApplicationContext(), "抱歉,只能選擇一張照片", Toast.LENGTH_LONG).show();
}
}
});
}
private void openCamera() {
//建議一些緩存的東西都這樣弄,放在Android/data文件夾下的包名,這樣你的軟件卸載了,緩存也會被一起卸載。
path = getExternalFilesDir(Environment.DIRECTORY_DCIM).getPath() + File.separator + "temp.png";
File mFile = new File(path);
try {
if (mFile.exists()) {
mFile.delete();
}
mFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
imageUri = Uri.fromFile(mFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//這個屬性可以拿到正常拍照的圖,否則得到的圖和打了馬賽克的動作片沒區別
startActivityForResult(intent, RESULT_OPENCAMERA_LOAD_IMAGE);//想在onActivityResult裏面得到返回的數據,只能startActivityForResult
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
return;
}
switch (requestCode) {
case RESULT_OPENCAMERA_LOAD_IMAGE:
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
list.add(saveFile(bitmap, path));//之所以用同一個路徑是方便,直接覆蓋原圖,避免原圖好幾M,而讓SD卡垃圾過多,看需求而定
adapter.notifyDataSetChanged();
isImageView = false;
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
/**
* 壓縮圖片的方法
*
* @param bm
* @param fileName
* @return
* @throws Exception
*/
public Bitmap saveFile(Bitmap bm, String fileName) throws Exception {
File dirFile = new File(fileName);
if (dirFile.exists()) {
dirFile.delete();
}
File myCaptureFile = new File(fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.JPEG, 50, bos);//壓縮圖片,成像基本沒變
bos.flush();
bos.close();
return bm;
//這樣壓縮的圖片親測從2M被壓倒了300K,而且清晰度沒怎麼變
}
@Override
protected void onDestroy() {
super.onDestroy();
if (!isImageView) {
mFile.delete();
}
}//一般只用一次的圖片,比如換頭像之類的一定要在onDestroy方法中刪除文件。避免SD卡垃圾過多}}