高仿QQ空間發圖片的效果

項目需求只需要一張圖片,需要其他的可以自己改改;代碼地址在最下面



不好意思,在下午的測試中測到如果用戶沒有拍照,直接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卡垃圾過多}}




代碼地址







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章