高仿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卡垃圾过多}}




代码地址







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