仿微信图片选择器

来源:互联网 发布:软件工程硕士排名 编辑:程序博客网 时间:2024/04/27 16:01

仿微信图片选择器

源码下载连接:

先上图,后上代码:

打开app后点击添加图片按钮:

获取选择的图片 并返回在gridview中:
这里写图片描述
实现该功能的重要组成部分有:利用gridview加载本地图片,gridView控件的使用,Intent之间数据的传递,和利用ContentProvider获取图片,和PopupWindow弹出页面的使用,利用Bitmap解决OOM问题。

下面开始贴出代码:
MainActivity文件的代码如下:
`import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.SimpleAdapter.ViewBinder;
import android.widget.Toast;

public class MainActivity extends Activity {

private ImageButton imageButton_poprecommend_back;private Button button_poprecommend_fabu;private EditText editText_poprecommend;private ImageButton imageButton_poprecommend_tianjia;private GridView gridView_poprecommend;private PopRecommend_ImageAdd_Adapter imageAdapter;private ArrayList<String> shuju = new ArrayList<String>();public static MainActivity activity;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    activity = this;    FindId();    Dianji();    shuju = new ArrayList<String>();    Intent intent = this.getIntent();    shuju = intent.getStringArrayListExtra("shuju");    if (shuju != null) {        imageAdapter = new PopRecommend_ImageAdd_Adapter(this, shuju);        gridView_poprecommend.setAdapter(imageAdapter);    }}private void FindId() {    imageButton_poprecommend_back = (ImageButton) findViewById(R.id.imagview_poprecommend_back);    button_poprecommend_fabu = (Button) findViewById(R.id.button_poprecommend_fabu);    editText_poprecommend = (EditText) findViewById(R.id.edittext_poprecommend);    imageButton_poprecommend_tianjia = (ImageButton) findViewById(R.id.iamgebutton_poprecommend_tianjiatupian);    gridView_poprecommend = (GridView)this.findViewById(R.id.gridview_poprecommend);}private void Dianji() {    imageButton_poprecommend_back.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            if (Activity_Image_Add.imageAdd!=null)                 Activity_Image_Add.imageAdd.finish();        }    });    button_poprecommend_fabu.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            if (Activity_Image_Add.imageAdd!=null)                Activity_Image_Add.imageAdd.finish();            if (editText_poprecommend.getText().toString().equals("")) {                Toast.makeText(getApplication(), "发布内容不能为空", Toast.LENGTH_SHORT).show();            } else                Toast.makeText(getApplication(), "发布成功", Toast.LENGTH_SHORT).show();        }    });    imageButton_poprecommend_tianjia.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Intent intent = new Intent(getApplication(), Activity_Image_Add.class);            startActivity(intent);        }    });}

}
`
Activity_Image_Add activity的页面代码:

package com.xiyouliwp.fangweixin;import java.io.File;import java.io.FilenameFilter;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.LinkedList;import java.util.List;import android.app.Activity;import android.app.ProgressDialog;import android.content.ContentResolver;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.graphics.Color;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.provider.MediaStore;import android.util.DisplayMetrics;import android.util.Log;import android.view.Gravity;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.GridView;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.PopupWindow;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;/** * 需求:IPet的图片选择器, * Created by lwp940118 on 2016/5/29. * 李文朋 */public class Activity_Image_Add extends Activity implements List_File_PopWind.OnImageDirSelected {    private ImageButton imageButton_ImageAdd_back;    private ImageButton imageButton_ImageAdd_finish;    private GridView gridView_ImageAdd;    int totalCount = 0;    /**     * 存储文件夹中的图片数量     */    private int mPicSize = 0;    /**     * 图片数量最多的文件夹     */    private File maxImageFile;    private RelativeLayout relativeLayout_popwind;    /**     * 所以图片     */    private List<String> mImags;    /**     * list存放扫描到的文件夹的信息     */    private List<ImageFolder> imageFolders = new ArrayList<ImageFolder>();    /**     * hashset  基于hashmap实现的,利用他可以防止一个文件夹  多次扫描     */    private HashSet<String> mImagePath = new HashSet<String>();    //弹出对话框  进度条    private ProgressDialog mprogressDialog;    private TextView textview_ChooseDir;    private TextView textview_ImageCount;    //定义屏幕的高度    private int screenHeight = 0;    /**     * 用户选择的图片,存储为图片的完整路径     */    public static List<String> mSelectedImage = new LinkedList<String>();    private ArrayList<String> shuju;    private MyAdapter myAdapter;    private List_File_PopWind popWind;    public static Activity_Image_Add imageAdd;    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            //加载的那个对话框  销毁            mprogressDialog.dismiss();            //view绑定数据            dateView();            //初始化Popwind            initPopWind();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_image_add);        DisplayMetrics displayMetrics = new DisplayMetrics();        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);        screenHeight = displayMetrics.heightPixels;        Log.e("screenHeight---->", "" + screenHeight);        imageAdd = this;        findId();        kongJianSheZhi();        getImages();        initEvent();    }    // 返回按键调用    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            if (MainActivity.activity!=null)                MainActivity.activity.finish();            shuju = new ArrayList<String>();            for (int i = 0; i < mSelectedImage.size(); i++)                shuju.add(mSelectedImage.get(i));            Intent intent = new Intent(getApplicationContext(),MainActivity.class);            intent.putStringArrayListExtra("shuju",shuju);            startActivity(intent);        }        return true;    }    /**     * 弹出popwind     */    private void initEvent() {        relativeLayout_popwind.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                popWind.setAnimationStyle(R.style.AnimBottom);                popWind.showAtLocation(Activity_Image_Add.this.findViewById(R.id.imagebutton_imageadd_back),                        Gravity.BOTTOM, 0, 0);                // 设置背景颜色变暗                WindowManager.LayoutParams lp = getWindow().getAttributes();                lp.alpha = 0.3f;                getWindow().setAttributes(lp);            }        });    }    /**     * 绑定view的数据     */    private void dateView() {        if (maxImageFile == null) {            Toast.makeText(getApplicationContext(), "没有扫描到图片", Toast.LENGTH_SHORT).show();            return;        }        //aslist  连接列表与数组,当一个更新时 另一个也自动更新但是没有add  和remove方法        mImags = Arrays.asList(maxImageFile.list());        myAdapter = new MyAdapter(getApplicationContext(), mImags, R.layout.item_gridview_imageadd,                maxImageFile.getAbsolutePath());        gridView_ImageAdd.setAdapter(myAdapter);        //显示多少张图片 在popwind中        textview_ImageCount.setText(totalCount + "张");    }    /**     * 初始化popwind的弹出界面     */    private void initPopWind() {        popWind = new List_File_PopWind(LinearLayout.LayoutParams.MATCH_PARENT, (int) (screenHeight                * 0.7), imageFolders, LayoutInflater.from(getApplicationContext())                .inflate(R.layout.list_dir, null));        popWind.setOnDismissListener(new PopupWindow.OnDismissListener() {            @Override            public void onDismiss() {                // 设置背景颜色变暗                WindowManager.LayoutParams lp = getWindow().getAttributes();                lp.alpha = 1.0f;                getWindow().setAttributes(lp);            }        });        //设置文件夹的回调        popWind.setOnImageDirSelected(this);    }    /**     * 利用contentProvider扫描手机中的图片,并获取jpn最多的那个文件夹     * ContentProvider  为Android四大组件,详情见我的博客     * Android四大组件介绍http://blog.csdn.net/qq_30000411/article/details/51355390     */    private void getImages() {        //判断Sd卡的状态 是否可用        if (!Environment.getExternalStorageState().equals(                Environment.MEDIA_MOUNTED)) {            Toast.makeText(getApplicationContext(), "没有找到SD", Toast.LENGTH_SHORT).show();        }        //显示进度条  加载中...        mprogressDialog = ProgressDialog.show(this, null, "图片读取中...");        new Thread(new Runnable() {            @Override            public void run() {                //读取第一张图片                String firstImagePath = null;                //EXTERNAL_CONTENT_URI多选                Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                //ContentResolver应用之间数据共享                ContentResolver mResolver = Activity_Image_Add.this.getContentResolver();                //数据查找,找出JPEG和png格式的图片,,,MediaStore为Android手机系统的多媒体数据库                Cursor mCursor = mResolver.query(mImageUri, null, MediaStore.Images.Media.MIME_TYPE + "=? or "                                + MediaStore.Images.Media.MIME_TYPE + "=?",                        new String[]{"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED);                //读取图片                while (mCursor.moveToNext()) {                    //定义图片的路径                    String imagePath = mCursor.getString(mCursor.getColumnIndex                            (MediaStore.Images.Media.DATA));                    //获取第一张图片的路径                    if (firstImagePath == null)                        firstImagePath = imagePath;                    //获取该图片的父路径名                    File parentFile = new File(imagePath).getParentFile();                    if (parentFile == null)                        continue;                    String folderPath = parentFile.getAbsolutePath();                    ImageFolder imageFolder = null;                    //利用hashset防止一个文件夹被多次扫描                    if (mImagePath.contains(folderPath)) {                        continue;                    } else {                        mImagePath.add(folderPath);                        //初始化  ImageFolder                        imageFolder = new ImageFolder();                        imageFolder.setFolderPath(folderPath);                        imageFolder.setFirstImagePath(imagePath);                    }                    int picSize = parentFile.list(new FilenameFilter() {                        @Override                        public boolean accept(File dir, String filename) {                            if (filename.endsWith(".png") || filename.endsWith(".jpg")                                    || filename.endsWith(".jpeg"))                                return true;                            return false;                        }                    }).length;                    totalCount += picSize;                    imageFolder.setImageCount(picSize);                    imageFolders.add(imageFolder);                    //更新最大数量文件夹                    if (picSize > mPicSize) {                        mPicSize = picSize;                        maxImageFile = parentFile;                    }                }                mCursor.close();                //扫描完成  hashset释放                mImagePath = null;                //通知  线程Handler  图片扫秒完成                handler.sendEmptyMessage(0x110);            }        }).start();    }    private void findId() {        gridView_ImageAdd = (GridView) findViewById(R.id.gridview_imageadd);        imageButton_ImageAdd_back = (ImageButton) findViewById(R.id.imagebutton_imageadd_back);        imageButton_ImageAdd_finish = (ImageButton) findViewById(R.id.imagebutton_imageadd_finish);        textview_ChooseDir = (TextView) findViewById(R.id.id_choose_dir);        textview_ImageCount = (TextView) findViewById(R.id.id_total_count);        relativeLayout_popwind = (RelativeLayout) findViewById(R.id.id_bottom_ly);    }    private void kongJianSheZhi() {        imageButton_ImageAdd_finish.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.e("完成--->","完成");                if (MainActivity.activity!=null)                    MainActivity.activity.finish();                shuju = new ArrayList<String>();                for (int i = 0; i < mSelectedImage.size(); i++)                    shuju.add(mSelectedImage.get(i));                Intent intent = new Intent(getApplicationContext(),MainActivity.class);                intent.putStringArrayListExtra("shuju",shuju);                startActivity(intent);            }        });        imageButton_ImageAdd_back.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                finish();            }        });    }    @Override    public void selected(ImageFolder floder) {        maxImageFile = new File(floder.getFolderPath());        mImags = Arrays.asList(maxImageFile.list(new FilenameFilter() {            @Override            public boolean accept(File dir, String filename) {                if (filename.endsWith(".jpg") || filename.endsWith(".png")                        || filename.endsWith(".jpeg"))                    return true;                return false;            }        }));        /**         * 可以看到文件夹的路径和图片的路径分开保存,极大的减少了内存的消耗;         */        myAdapter = new MyAdapter(getApplicationContext(), mImags,                R.layout.item_gridview_imageadd, maxImageFile.getAbsolutePath());        gridView_ImageAdd.setAdapter(myAdapter);        // mAdapter.notifyDataSetChanged();        textview_ImageCount.setText(floder.getImageCount() + "张");        textview_ChooseDir.setText(floder.getFolderName());        popWind.dismiss();    }    /**     * gridview的定义适配器     */    public class MyAdapter extends CommonAdapter<String> {        /**         * 文件夹路径         */        private String mDirPath;        public MyAdapter(Context context, List<String> mDatas, int itemLayoutId,                         String dirPath) {            super(context, mDatas, itemLayoutId);            this.mDirPath = dirPath;        }        @Override        public void convert(final ViewHolder helper, final String item) {            //设置no_pic            helper.setImageResource(R.id.id_item_image, R.drawable.pictures_no);            //设置no_selected            helper.setImageResource(R.id.id_item_select,                    R.drawable.picture_unselected);            //设置图片            helper.setImageByUrl(R.id.id_item_image, mDirPath + "/" + item);            final ImageView mImageView = helper.getView(R.id.id_item_image);            final ImageView mSelect = helper.getView(R.id.id_item_select);            mImageView.setColorFilter(null);            //设置ImageView的点击事件            mImageView.setOnClickListener(new View.OnClickListener() {                //选择,则将图片变暗,反之则反之                @Override                public void onClick(View v) {                    // 已经选择过该图片                    if (mSelectedImage.contains(mDirPath + "/" + item)) {                        mSelectedImage.remove(mDirPath + "/" + item);                        mSelect.setImageResource(R.drawable.picture_unselected);                        mImageView.setColorFilter(null);                    } else {// 未选择该图片                        mSelectedImage.add(mDirPath + "/" + item);                        mSelect.setImageResource(R.drawable.pictures_selected);                        mImageView.setColorFilter(Color.parseColor("#77000000"));                    }                }            });            /**             * 已经选择过的图片,显示出选择过的效果             */            if (mSelectedImage.contains(mDirPath + "/" + item)) {                mSelect.setImageResource(R.drawable.pictures_selected);                mImageView.setColorFilter(Color.parseColor("#77000000"));            }        }    }}

BitmapUtilities问价:用于缩小图片的尺寸,避免OOM问题出现

package com.xiyouliwp.fangweixin;/** * Created by lwp940118 on 2016/5/31. */import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;public class BitmapUtilities {    public BitmapUtilities() {        // TODO Auto-generated constructor stub    }    public static Bitmap getBitmapThumbnail(String path,int width,int height){        Bitmap bitmap = null;        //这里可以按比例缩小图片:        /*BitmapFactory.Options opts = new BitmapFactory.Options();        opts.inSampleSize = 4;//宽和高都是原来的1/4        bitmap = BitmapFactory.decodeFile(path, opts); */        /*进一步的,                如何设置恰当的inSampleSize是解决该问题的关键之一。BitmapFactory.Options提供了另一个成员inJustDecodeBounds。               设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。               有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。*/        BitmapFactory.Options opts = new BitmapFactory.Options();        opts.inJustDecodeBounds = true;        BitmapFactory.decodeFile(path, opts);        opts.inSampleSize = Math.max((int)(opts.outHeight / (float) height), (int)(opts.outWidth / (float) width));        opts.inJustDecodeBounds = false;        bitmap = BitmapFactory.decodeFile(path, opts);        return bitmap;    }    public static Bitmap getBitmapThumbnail(Bitmap bmp,int width,int height){        Bitmap bitmap = null;        if(bmp != null ){            int bmpWidth = bmp.getWidth();            int bmpHeight = bmp.getHeight();            if(width != 0 && height !=0){                Matrix matrix = new Matrix();                float scaleWidth = ((float) width / bmpWidth);                float scaleHeight = ((float) height / bmpHeight);                matrix.postScale(scaleWidth, scaleHeight);                bitmap = Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true);            }else{                bitmap = bmp;            }        }        return bitmap;    }}

CommonAdapter文件:超级适配器,也成通配器,可以使用gridview和listview共同使用:

package com.xiyouliwp.fangweixin;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;/** * 通配器,CommonAdapter通过封装BaseAdapter和RecyclerView.Adapter得到通用的、简单易用的Adapter。 * 作为ListView和GridView的通用适配器。 * 超级适配器 * @param <T> */public abstract class CommonAdapter<T> extends BaseAdapter {    protected LayoutInflater mInflater;    protected Context mContext;    protected List<T> mDatas;    protected final int mItemLayoutId;    public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId) {        this.mContext = context;        this.mInflater = LayoutInflater.from(mContext);        this.mDatas = mDatas;        this.mItemLayoutId = itemLayoutId;    }    @Override    public int getCount() {        return mDatas.size();    }    @Override    public T getItem(int position) {        return mDatas.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        final ViewHolder viewHolder = getViewHolder(position, convertView,                parent);        convert(viewHolder, getItem(position));        return viewHolder.getConvertView();    }    public abstract void convert(ViewHolder helper, T item);    private ViewHolder getViewHolder(int position, View convertView,                                     ViewGroup parent) {        return ViewHolder.get(mContext, convertView, parent, mItemLayoutId,                position);    }}

DiskLruCache文件:点击获取到的图片的path路径进行解析

package com.xiyouliwp.fangweixin;/** * Created by lwp940118 on 2016/5/31. */import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FilenameFilter;import java.io.IOException;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.Collections;import java.util.LinkedHashMap;import java.util.Map;import java.util.Map.Entry;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;public class DiskLruCache {    private static final String CACHE_FILENAME_PREFIX = "cache_";    private static final int MAX_REMOVALS = 4;    private static final int INITIAL_CAPACITY = 32;    private static final float LOAD_FACTOR = 0.75f;    private final File mCacheDir;    private int cacheSize = 0;    private int cacheByteSize = 0;    private final int maxCacheItemSize = 64; // 64 item default    private long maxCacheByteSize = 1024 * 1024 * 5; // 5MB default    private CompressFormat mCompressFormat = CompressFormat.JPEG;    private int mCompressQuality = 70;    private final int IO_BUFFER_SIZE = 4 * 1024;    private final Map<String, String> mLinkedHashMap = Collections.synchronizedMap(new LinkedHashMap<String, String>(INITIAL_CAPACITY, LOAD_FACTOR, true));    /**     * A filename filter to use to identify the cache filenames which have CACHE_FILENAME_PREFIX prepended.     */    private static final FilenameFilter cacheFileFilter = new FilenameFilter() {        @Override        public boolean accept(File dir, String filename) {            return filename.startsWith(CACHE_FILENAME_PREFIX);        }    };    /**     * Used to fetch an instance of DiskLruCache.     *     * @param context     * @param cacheDir     * @param maxByteSize     * @return     */    public static DiskLruCache openCache(Context context, File cacheDir, long maxByteSize) {        if (!cacheDir.exists()) {            cacheDir.mkdir();        }        if (cacheDir.isDirectory() && cacheDir.canWrite()) {            return new DiskLruCache(cacheDir, maxByteSize);        }        return null;    }    /**     * @param cacheDir     * @param maxByteSize     */    private DiskLruCache(File cacheDir, long maxByteSize) {        mCacheDir = cacheDir;        maxCacheByteSize = maxByteSize;    }    /**     * Add a bitmap to the disk cache.     *     * @param key  A unique identifier for the bitmap.     * @param data The bitmap to store.     */    public void put(String key, Bitmap data) {        synchronized (mLinkedHashMap) {            if (mLinkedHashMap.get(key) == null) {                try {                    final String file = createFilePath(mCacheDir, key);                    if (writeBitmapToFile(data, file)) {                        put(key, file);                        flushCache();                    }                } catch (final FileNotFoundException e) {                } catch (final IOException e) {                }            }        }    }    private void put(String key, String file) {        mLinkedHashMap.put(key, file);        cacheSize = mLinkedHashMap.size();        cacheByteSize += new File(file).length();    }    /**     * Flush the cache, removing oldest entries if the total size is over the specified cache size. Note that this isn't keeping track of stale files in the cache directory that     * aren't in the HashMap. If the images and keys in the disk cache change often then they probably won't ever be removed.     */    private void flushCache() {        Entry<String, String> eldestEntry;        File eldestFile;        long eldestFileSize;        int count = 0;        while (count < MAX_REMOVALS && (cacheSize > maxCacheItemSize || cacheByteSize > maxCacheByteSize)) {            eldestEntry = mLinkedHashMap.entrySet().iterator().next();            eldestFile = new File(eldestEntry.getValue());            eldestFileSize = eldestFile.length();            mLinkedHashMap.remove(eldestEntry.getKey());            eldestFile.delete();            cacheSize = mLinkedHashMap.size();            cacheByteSize -= eldestFileSize;            count++;        }    }    /**     * Get an image from the disk cache.     *     * @param key The unique identifier for the bitmap     * @return The bitmap or null if not found     */    public Bitmap get(String key) {        synchronized (mLinkedHashMap) {            try {                final String file = mLinkedHashMap.get(key);                if (file != null) {                    return BitmapFactory.decodeFile(file);                } else {                    final String existingFile = createFilePath(mCacheDir, key);                    if (new File(existingFile).exists()) {                        put(key, existingFile);                        return BitmapFactory.decodeFile(existingFile);                    }                }            } catch (OutOfMemoryError e) {            }            return null;        }    }    /**     * Checks if a specific key exist in the cache.     *     * @param key The unique identifier for the bitmap     * @return true if found, false otherwise     */    public boolean containsKey(String key) {        // See if the key is in our HashMap        if (mLinkedHashMap.containsKey(key)) {            return true;        }        // Now check if there's an actual file that exists based on the key        final String existingFile = createFilePath(mCacheDir, key);        if (new File(existingFile).exists()) {            // File found, add it to the HashMap for future use            put(key, existingFile);            return true;        }        return false;    }    /**     * Removes all disk cache entries from this instance cache dir     */    public void clearCache() {        DiskLruCache.clearCache(mCacheDir);    }    /**     * Removes all disk cache entries from the application cache directory in the uniqueName sub-directory.     *     * @param context    The context to use     * @param uniqueName A unique cache directory name to append to the app cache directory     */    public static void clearCache(Context context, String uniqueName) {        File cacheDir = getDiskCacheDir(context, uniqueName);        clearCache(cacheDir);    }    /**     * Removes all disk cache entries from the given directory. This should not be called directly, call {@link DiskLruCache#clearCache(Context, String)} or     * {@link DiskLruCache#clearCache()} instead.     *     * @param cacheDir The directory to remove the cache files from     */    private static void clearCache(File cacheDir) {        final File[] files = cacheDir.listFiles(cacheFileFilter);        for (int i = 0; i < files.length; i++) {            files[i].delete();        }    }    /**     * Get a usable cache directory (external if available, internal otherwise).     *     * @param context    The context to use     * @param uniqueName A unique directory name to append to the cache dir     * @return The cache dir     */    public static File getDiskCacheDir(Context context, String uniqueName) {        // Check if media is mounted or storage is built-in, if so, try and use external cache dir        // otherwise use internal cache dir        final String cachePath = context.getCacheDir().getPath();        return new File(cachePath + File.separator + uniqueName);    }    /**     * Creates a constant cache file path given a target cache directory and an image key.     *     * @param cacheDir     * @param key     * @return     */    public static String createFilePath(File cacheDir, String key) {        try {            // Use URLEncoder to ensure we have a valid filename, a tad hacky but it will do for            // this example            return cacheDir.getAbsolutePath() + File.separator + CACHE_FILENAME_PREFIX + URLEncoder.encode(key.replace("*", ""), "UTF-8");        } catch (final UnsupportedEncodingException e) {        }        return null;    }    /**     * Create a constant cache file path using the current cache directory and an image key.     *     * @param key     * @return     */    public String createFilePath(String key) {        return createFilePath(mCacheDir, key);    }    /**     * Sets the target compression format and quality for images written to the disk cache.     *     * @param compressFormat     * @param quality     */    public void setCompressParams(CompressFormat compressFormat, int quality) {        mCompressFormat = compressFormat;        mCompressQuality = quality;    }    /**     * Writes a bitmap to a file. Call {@link DiskLruCache#setCompressParams(CompressFormat, int)} first to set the target bitmap compression and format.     *     * @param bitmap     * @param file     * @return     */    private boolean writeBitmapToFile(Bitmap bitmap, String file) throws IOException, FileNotFoundException {        OutputStream out = null;        try {            out = new BufferedOutputStream(new FileOutputStream(file), IO_BUFFER_SIZE);            return bitmap.compress(mCompressFormat, mCompressQuality, out);        } finally {            if (out != null) {                out.close();            }        }    }}

ImageFolder文件:图片的信息的定义:

package com.xiyouliwp.fangweixin;/** * 需求:对手机中的图片进行扫描,直接显示在gridview上,并且在扫描结束后得到一个list,,list里面存的是所有包含 * 图片的文件夹 * Created by lwp940118 on 2016/5/29. * 李文朋 */public class ImageFolder {    //文件夹的路径    private String folderPath;    //第一张图片的文件夹路径    private String firstImagePath;    //文件夹名称    private String folderName;    //图片的数量    private int imageCount = 0;    public int getImageCount() {        return imageCount;    }    public String getFirstImagePath() {        return firstImagePath;    }    public String getFolderName() {        return folderName;    }    public String getFolderPath() {        return folderPath;    }    public void setFirstImagePath(String firstImagePath) {        this.firstImagePath = firstImagePath;    }    public void setFolderPath(String folderPath) {        this.folderPath = folderPath;        //判断字符/它第一次出现的位置        int start = this.folderPath.lastIndexOf("/");        //得到从/第一次出现的位置开始  到该字符串结束的子串为folderName        this.folderName = this.folderPath.substring(start);    }    public void setImageCount(int imageCount) {        this.imageCount = imageCount;    }}

ImageLoade文件:缓存图片,使grideview运行流畅

package com.xiyouliwp.fangweixin;import java.lang.reflect.Field;import java.util.LinkedList;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v4.util.LruCache;import android.util.DisplayMetrics;import android.util.Log;import android.view.ViewGroup.LayoutParams;import android.widget.ImageView;public class ImageLoade {    /**     * 图片缓存的核心类     */    private LruCache<String, Bitmap> mLruCache;    /**     * 线程池     */    private ExecutorService mThreadPool;    /**     * 线程池的线程数量,默认为1     */    private int mThreadCount = 1;    /**     * 队列的调度方式     */    private Type mType = Type.LIFO;    /**     * 任务队列     */    private LinkedList<Runnable> mTasks;    /**     * 轮询的线程     */    private Thread mPoolThread;    private Handler mPoolThreadHander;    /**     * 运行在UI线程的handler,用于给ImageView设置图片     */    private Handler mHandler;    /**     * 引入一个值为1的信号量,防止mPoolThreadHander未初始化完成     */    private volatile Semaphore mSemaphore = new Semaphore(0);    /**     * 引入一个值为1的信号量,由于线程池内部也有一个阻塞线程,防止加入任务的速度过快,使LIFO效果不明显     */    private volatile Semaphore mPoolSemaphore;    private static ImageLoade mInstance;    /**     * 队列的调度方式     *     * @author zhy     */    public enum Type {        FIFO, LIFO    }    /**     * 单例获得该实例对象     *     * @return     */    public static ImageLoade getInstance() {        if (mInstance == null) {            synchronized (ImageLoade.class) {                if (mInstance == null) {                    mInstance = new ImageLoade(1, Type.LIFO);                }            }        }        return mInstance;    }    private ImageLoade(int threadCount, Type type) {        init(threadCount, type);    }    private void init(int threadCount, Type type) {        // loop thread        mPoolThread = new Thread() {            @Override            public void run() {                Looper.prepare();                mPoolThreadHander = new Handler() {                    @Override                    public void handleMessage(Message msg) {                        mThreadPool.execute(getTask());                        try {                            mPoolSemaphore.acquire();                        } catch (InterruptedException e) {                        }                    }                };                // 释放一个信号量                mSemaphore.release();                Looper.loop();            }        };        mPoolThread.start();        // 获取应用程序最大可用内存        int maxMemory = (int) Runtime.getRuntime().maxMemory();        int cacheSize = maxMemory / 8;        mLruCache = new LruCache<String, Bitmap>(cacheSize) {            @Override            protected int sizeOf(String key, Bitmap value) {                return value.getRowBytes() * value.getHeight();            }            ;        };        mThreadPool = Executors.newFixedThreadPool(threadCount);        mPoolSemaphore = new Semaphore(threadCount);        mTasks = new LinkedList<Runnable>();        mType = type == null ? Type.LIFO : type;    }    /**     * 加载图片     *     * @param path     * @param imageView     */    public void loadImage(final String path, final ImageView imageView) {        // set tag        imageView.setTag(path);        // UI线程        if (mHandler == null) {            mHandler = new Handler() {                @Override                public void handleMessage(Message msg) {                    ImgBeanHolder holder = (ImgBeanHolder) msg.obj;                    ImageView imageView = holder.imageView;                    Bitmap bm = holder.bitmap;                    String path = holder.path;                    if (imageView.getTag().toString().equals(path)) {                        imageView.setImageBitmap(bm);                    }                }            };        }        Bitmap bm = getBitmapFromLruCache(path);        if (bm != null) {            ImgBeanHolder holder = new ImgBeanHolder();            holder.bitmap = bm;            holder.imageView = imageView;            holder.path = path;            Message message = Message.obtain();            message.obj = holder;            mHandler.sendMessage(message);        } else {            addTask(new Runnable() {                @Override                public void run() {                    ImageSize imageSize = getImageViewWidth(imageView);                    int reqWidth = imageSize.width;                    int reqHeight = imageSize.height;                    Bitmap bm = decodeSampledBitmapFromResource(path, reqWidth,                            reqHeight);                    addBitmapToLruCache(path, bm);                    ImgBeanHolder holder = new ImgBeanHolder();                    holder.bitmap = getBitmapFromLruCache(path);                    holder.imageView = imageView;                    holder.path = path;                    Message message = Message.obtain();                    message.obj = holder;                    // Log.e("TAG", "mHandler.sendMessage(message);");                    mHandler.sendMessage(message);                    mPoolSemaphore.release();                }            });        }    }    /**     * 添加一个任务     *     * @param runnable     */    private synchronized void addTask(Runnable runnable) {        try {            // 请求信号量,防止mPoolThreadHander为null            if (mPoolThreadHander == null)                mSemaphore.acquire();        } catch (InterruptedException e) {        }        mTasks.add(runnable);        mPoolThreadHander.sendEmptyMessage(0x110);    }    /**     * 取出一个任务     *     * @return     */    private synchronized Runnable getTask() {        if (mType == Type.FIFO) {            return mTasks.removeFirst();        } else if (mType == Type.LIFO) {            return mTasks.removeLast();        }        return null;    }    /**     * 单例获得该实例对象     *     * @return     */    public static ImageLoade getInstance(int threadCount, Type type) {        if (mInstance == null) {            synchronized (ImageLoade.class) {                if (mInstance == null) {                    mInstance = new ImageLoade(threadCount, type);                }            }        }        return mInstance;    }    /**     * 根据ImageView获得适当的压缩的宽和高     *     * @param imageView     * @return     */    private ImageSize getImageViewWidth(ImageView imageView) {        ImageSize imageSize = new ImageSize();        final DisplayMetrics displayMetrics = imageView.getContext()                .getResources().getDisplayMetrics();        final LayoutParams params = imageView.getLayoutParams();        int width = params.width == LayoutParams.WRAP_CONTENT ? 0 : imageView                .getWidth(); // Get actual image width        if (width <= 0)            width = params.width; // Get layout width parameter        if (width <= 0)            width = getImageViewFieldValue(imageView, "mMaxWidth"); // Check        // maxWidth        // parameter        if (width <= 0)            width = displayMetrics.widthPixels;        int height = params.height == LayoutParams.WRAP_CONTENT ? 0 : imageView                .getHeight(); // Get actual image height        if (height <= 0)            height = params.height; // Get layout height parameter        if (height <= 0)            height = getImageViewFieldValue(imageView, "mMaxHeight"); // Check        // maxHeight        // parameter        if (height <= 0)            height = displayMetrics.heightPixels;        imageSize.width = width;        imageSize.height = height;        return imageSize;    }    /**     * 从LruCache中获取一张图片,如果不存在就返回null。     */    private Bitmap getBitmapFromLruCache(String key) {        return mLruCache.get(key);    }    /**     * 往LruCache中添加一张图片     *     * @param key     * @param bitmap     */    private void addBitmapToLruCache(String key, Bitmap bitmap) {        if (getBitmapFromLruCache(key) == null) {            if (bitmap != null)                mLruCache.put(key, bitmap);        }    }    /**     * 计算inSampleSize,用于压缩图片     *     * @param options     * @param reqWidth     * @param reqHeight     * @return     */    private int calculateInSampleSize(BitmapFactory.Options options,                                      int reqWidth, int reqHeight) {        // 源图片的宽度        int width = options.outWidth;        int height = options.outHeight;        int inSampleSize = 1;        if (width > reqWidth && height > reqHeight) {            // 计算出实际宽度和目标宽度的比率            int widthRatio = Math.round((float) width / (float) reqWidth);            int heightRatio = Math.round((float) width / (float) reqWidth);            inSampleSize = Math.max(widthRatio, heightRatio);        }        return inSampleSize;    }    /**     * 根据计算的inSampleSize,得到压缩后图片     *     * @param pathName     * @param reqWidth     * @param reqHeight     * @return     */    private Bitmap decodeSampledBitmapFromResource(String pathName,                                                   int reqWidth, int reqHeight) {        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小        final BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(pathName, options);        // 调用上面定义的方法计算inSampleSize值        options.inSampleSize = calculateInSampleSize(options, reqWidth,                reqHeight);        // 使用获取到的inSampleSize值再次解析图片        options.inJustDecodeBounds = false;        Bitmap bitmap = BitmapFactory.decodeFile(pathName, options);        return bitmap;    }    private class ImgBeanHolder {        Bitmap bitmap;        ImageView imageView;        String path;    }    private class ImageSize {        int width;        int height;    }    /**     * 反射获得ImageView设置的最大宽度和高度     *     * @param object     * @param fieldName     * @return     */    private static int getImageViewFieldValue(Object object, String fieldName) {        int value = 0;        try {            Field field = ImageView.class.getDeclaredField(fieldName);            field.setAccessible(true);            int fieldValue = (Integer) field.get(object);            if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE) {                value = fieldValue;                Log.e("TAG", value + "");            }        } catch (Exception e) {        }        return value;    }}

ImageShowManager文件:图片的一些信息及其缓存情况的设置

package com.xiyouliwp.fangweixin;/** * Created by lwp940118 on 2016/5/31. */import java.io.File;import android.app.ActivityManager;import android.app.Application;import android.content.Context;import android.graphics.Bitmap;import android.os.Looper;import android.support.v4.util.LruCache;public class ImageShowManager {    private static ImageShowManager imageManager;    private static Application myApp;    private LruCache<String, Bitmap> mMemoryCache;    private DiskLruCache mDiskCache;    // 硬盘缓存区域的大小,可以提升之前浏览过的图片的显示速度    private static final int DISK_CACHE_SIZE = 1024 * 1024 * 20;    // 硬盘缓存区域的文件名称    private static final String DISK_CACHE_SUBDIR = "thumbnails";    public static final int bitmap_width = 100;    public static final int bitmap_height = 100;    public static ImageShowManager from(Context context) {        // 如果不在ui线程中,则抛出异常        if (Looper.myLooper() != Looper.getMainLooper()) {            throw new RuntimeException("Cannot instantiate outside UI thread.");        }        if (myApp == null) {            myApp = (Application) context.getApplicationContext();        }        if (imageManager == null) {            imageManager = new ImageShowManager(myApp);        }        //        return imageManager;    }    /**     * 私有的构造器为了保持单例模式     */    private ImageShowManager(Context context) {        /********** 初始化内存缓冲区 ******/        int memClass = ((ActivityManager) context                .getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();        memClass = memClass > 32 ? 32 : memClass;        // 使用可用内存的1/8作为图片缓存        final int cacheSize = 1024 * 1024 * memClass / 8;        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {            @Override            protected int sizeOf(String key, Bitmap bitmap) {                return bitmap.getRowBytes() * bitmap.getHeight();            }        };        /********* 初始化硬盘缓冲区 *********/        File cacheDir = DiskLruCache                .getDiskCacheDir(context, DISK_CACHE_SUBDIR);        mDiskCache = DiskLruCache.openCache(context, cacheDir, DISK_CACHE_SIZE);    }    /**     * 将图片保存至本地缓存     * @param key     * @param value     */    public void putBitmapToDisk(String key,Bitmap value){        mDiskCache.put(key, value);    }    /**     * 从硬盘缓存中读取图像     * @param url     * @return     */    public Bitmap getBitmapFormDisk(String url){        return mDiskCache.get(url);    }    /**     * 从内存缓存区中获取bitmap,根据特定的url     * @param url     * @return     */    public Bitmap getBitmapFromMemory(String url){        return mMemoryCache.get(url);    }    /**     * 将新的图片添加至内存缓存区     * @param key     * @param value     */    public void putBitmapToMemery(String key,Bitmap value){        mMemoryCache.put(key, value);    }}

List_File_PopWind文件:弹出窗口的设置及其定义:

package com.xiyouliwp.fangweixin;import java.util.List;import android.content.Context;import android.graphics.drawable.BitmapDrawable;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.AdapterView;import android.widget.ListView;import android.widget.PopupWindow;/** * Created by lwp940118 on 2016/5/29. */public class List_File_PopWind extends        BasePopupWindowForListView<ImageFolder>{    private ListView mListDir;    public List_File_PopWind(int width, int height,                                   List<ImageFolder> datas, View convertView) {        super(convertView, width, height, true, datas);    }    @Override    public void initViews() {        mListDir = (ListView) findViewById(R.id.listviwe_dir);        mListDir.setAdapter(new CommonAdapter<ImageFolder>(context, mDatas,                R.layout.list_dir_item) {            @Override            public void convert(ViewHolder helper, ImageFolder item) {                helper.setText(R.id.id_dir_item_name, item.getFolderName());                helper.setImageByUrl(R.id.id_dir_item_image,                        item.getFirstImagePath());                helper.setText(R.id.id_dir_item_count, item.getImageCount() + "张");            }        });    }    public interface OnImageDirSelected {        void selected(ImageFolder floder);    }    private OnImageDirSelected mImageDirSelected;    public void setOnImageDirSelected(OnImageDirSelected mImageDirSelected) {        this.mImageDirSelected = mImageDirSelected;    }    @Override    public void initEvents() {        mListDir.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view,                                    int position, long id) {                if (mImageDirSelected != null) {                    mImageDirSelected.selected(mDatas.get(position));                }            }        });    }    @Override    public void init() {    }    @Override    protected void beforeInitWeNeedSomeParams(Object... params) {    }}abstract class BasePopupWindowForListView<T> extends PopupWindow {    /**     * 布局文件的最外层View     */    protected View mContentView;    protected Context context;    /**     * ListView的数据集     */    protected List<T> mDatas;    public BasePopupWindowForListView(View contentView, int width, int height,                                      boolean focusable) {        this(contentView, width, height, focusable, null);    }    public BasePopupWindowForListView(View contentView, int width, int height,                                      boolean focusable, List<T> mDatas) {        this(contentView, width, height, focusable, mDatas, new Object[0]);    }    public BasePopupWindowForListView(View contentView, int width, int height,                                      boolean focusable, List<T> mDatas, Object... params) {        super(contentView, width, height, focusable);        this.mContentView = contentView;        context = contentView.getContext();        if (mDatas != null)            this.mDatas = mDatas;        if (params != null && params.length > 0) {            beforeInitWeNeedSomeParams(params);        }        setBackgroundDrawable(new BitmapDrawable());        setTouchable(true);        setOutsideTouchable(true);        setTouchInterceptor(new OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {                    dismiss();                    return true;                }                return false;            }        });        initViews();        initEvents();        init();    }    protected abstract void beforeInitWeNeedSomeParams(Object... params);    public abstract void initViews();    public abstract void initEvents();    public abstract void init();    public View findViewById(int id) {        return mContentView.findViewById(id);    }    protected static int dpToPx(Context context, int dp) {        return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f);    }}

PopRecommend_ImageAdd_Adapter文件:返回时存放选择图片的gridview的适配器

package com.xiyouliwp.fangweixin;import java.lang.ref.WeakReference;import java.util.ArrayList;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.os.AsyncTask;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;/** * Created by lwp940118 on 2016/5/31. */public class PopRecommend_ImageAdd_Adapter extends BaseAdapter {    private Activity uiActivity;    private ArrayList<String> paths;    private int size;    private ImageShowManager imageManager;    private LayoutInflater li;    public PopRecommend_ImageAdd_Adapter(Activity a, ArrayList<String> paths) {        this.uiActivity = a;        this.paths = paths;        size = paths.size();        imageManager = ImageShowManager.from(uiActivity);        li = LayoutInflater.from(uiActivity);    }    @Override    public int getCount() {        // TODO Auto-generated method stub        return size;    }    @Override    public Object getItem(int position) {        // TODO Auto-generated method stub        return null;    }    @Override    public long getItemId(int position) {        // TODO Auto-generated method stub        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        SurfaceHolder surfaceHolder = new SurfaceHolder();        if (convertView != null) {            surfaceHolder = (SurfaceHolder) convertView.getTag();        } else {            convertView = li.inflate(R.layout.item_gridview_poprecommend, null);            surfaceHolder.iv = (ImageView) convertView                    .findViewById(R.id.imageView1);        }        convertView.setTag(surfaceHolder);        String path = paths.get(position);        // 首先检测是否已经有线程在加载同样的资源(如果则取消较早的),避免出现重复加载        if (cancelPotentialLoad(path, surfaceHolder.iv)) {            AsyncLoadImageTask task = new AsyncLoadImageTask(surfaceHolder.iv);            surfaceHolder.iv.setImageDrawable(new LoadingDrawable(task));            task.execute(path);        }        return convertView;    }    static class SurfaceHolder {        ImageView iv;    }    /**     * 判断当前的imageview是否在加载相同的资源     *     * @param url     * @param imageview     * @return     */    private boolean cancelPotentialLoad(String url, ImageView imageview) {        AsyncLoadImageTask loadImageTask = getAsyncLoadImageTask(imageview);        if (loadImageTask != null) {            String bitmapUrl = loadImageTask.url;            if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {                loadImageTask.cancel(true);            } else {                // 相同的url已经在加载中.                return false;            }        }        return true;    }    /**     * 负责加载图片的异步线程     *     * @author Administrator     */    class AsyncLoadImageTask extends AsyncTask<String, Void, Bitmap> {        private final WeakReference<ImageView> imageViewReference;        private String url = null;        public AsyncLoadImageTask(ImageView imageview) {            super();            imageViewReference = new WeakReference<ImageView>(imageview);        }        @Override        protected Bitmap doInBackground(String... params) {            /**             * 具体的获取bitmap的部分,流程: 从内存缓冲区获取,如果没有向硬盘缓冲区获取,如果没有从sd卡/网络获取             */            Bitmap bitmap = null;            this.url = params[0];            // 从内存缓存区域读取            bitmap = imageManager.getBitmapFromMemory(url);            if (bitmap != null) {                Log.d("dqq", "return by 内存");                return bitmap;            }            // 从硬盘缓存区域中读取            bitmap = imageManager.getBitmapFormDisk(url);            if (bitmap != null) {                imageManager.putBitmapToMemery(url, bitmap);                Log.d("dqq", "return by 硬盘");                return bitmap;            }            // 没有缓存则从原始位置读取            bitmap = BitmapUtilities.getBitmapThumbnail(url,                    ImageShowManager.bitmap_width,                    ImageShowManager.bitmap_height);            imageManager.putBitmapToMemery(url, bitmap);            imageManager.putBitmapToDisk(url, bitmap);            Log.d("dqq", "return by 原始读取");            return bitmap;        }        @Override        protected void onPostExecute(Bitmap resultBitmap) {            if (isCancelled()) {                // 被取消了                resultBitmap = null;            }            if (imageViewReference != null) {                ImageView imageview = imageViewReference.get();                AsyncLoadImageTask loadImageTask = getAsyncLoadImageTask(imageview);                if (this == loadImageTask) {                    imageview.setImageDrawable(null);                    imageview.setImageBitmap(resultBitmap);                }            }            super.onPostExecute(resultBitmap);        }    }    /**     * 根据imageview,获得正在为此imageview异步加载数据的函数     *     * @param imageview     * @return     */    private AsyncLoadImageTask getAsyncLoadImageTask(ImageView imageview) {        if (imageview != null) {            Drawable drawable = imageview.getDrawable();            if (drawable instanceof LoadingDrawable) {                LoadingDrawable loadedDrawable = (LoadingDrawable) drawable;                return loadedDrawable.getLoadImageTask();            }        }        return null;    }    /**     * 记录imageview对应的加载任务,并且设置默认的drawable     *     * @author Administrator     */    public static class LoadingDrawable extends ColorDrawable {        // 引用与drawable相关联的的加载线程        private final WeakReference<AsyncLoadImageTask> loadImageTaskReference;        public LoadingDrawable(AsyncLoadImageTask loadImageTask) {            super(Color.BLUE);            loadImageTaskReference = new WeakReference<AsyncLoadImageTask>(                    loadImageTask);        }        public AsyncLoadImageTask getLoadImageTask() {            return loadImageTaskReference.get();        }    }}

ViewHolde文件:从sd卡中读取图片时gridview和listview的优化:

package com.xiyouliwp.fangweixin;/** * Created by lwp940118 on 2016/5/29. */import android.content.Context;import android.graphics.Bitmap;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;public class ViewHolder {    private final SparseArray<View> mViews;    private int mPosition;    private View mConvertView;    private ViewHolder(Context context, ViewGroup parent, int layoutId,                       int position) {        this.mPosition = position;        this.mViews = new SparseArray<View>();        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,                false);        // setTag        mConvertView.setTag(this);    }    /**     * 拿到一个ViewHolder对象     */    public static ViewHolder get(Context context, View convertView,                                 ViewGroup parent, int layoutId, int position) {        ViewHolder holder = null;        if (convertView == null) {            holder = new ViewHolder(context, parent, layoutId, position);        } else {            holder = (ViewHolder) convertView.getTag();            holder.mPosition = position;        }        return holder;    }    public View getConvertView() {        return mConvertView;    }    /**     * 通过控件的Id获取对于的控件,如果没有则加入views     *     * @return     */    public <T extends View> T getView(int viewId) {        View view = mViews.get(viewId);        if (view == null) {            view = mConvertView.findViewById(viewId);            mViews.put(viewId, view);        }        return (T) view;    }    /**     * 为TextView设置字符串     *     * @return     */    public ViewHolder setText(int viewId, String text) {        TextView view = getView(viewId);        view.setText(text);        return this;    }    /**     * 为ImageView设置图片     *     * @return     */    public ViewHolder setImageResource(int viewId, int drawableId) {        ImageView view = getView(viewId);        view.setImageResource(drawableId);        return this;    }    /**     * 为ImageView设置图片     */    public ViewHolder setImageBitmap(int viewId, Bitmap bm) {        ImageView view = getView(viewId);        view.setImageBitmap(bm);        return this;    }    /**     * 为ImageView设置图片     */    public ViewHolder setImageByUrl(int viewId, String url) {        ImageLoade.getInstance(3, ImageLoade.Type.LIFO).loadImage(url, (ImageView) getView(viewId));        return this;    }    public int getPosition() {        return mPosition;    }}

push_bottom_in.xml push_bottom_out.xml文件:定义弹出窗口的划入划出方式:

<?xml version="1.0" encoding="utf-8"?><!-- 上下滑入式 --><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="200"        android:fromYDelta="100%p"        android:toYDelta="0"        />    <alpha        android:fromAlpha="0.0"        android:toAlpha="1.0"        android:duration="200"        /></set>
<?xml version="1.0" encoding="utf-8"?><!-- 上下滑入式 --><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="200"        android:fromYDelta="0"        android:toYDelta="50%p" />    <alpha        android:fromAlpha="1.0"        android:toAlpha="0.0"        android:duration="200"        /></set>

mybutton.xml按钮形状设置:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" >    <item>        <shape            android:shape="rectangle"            >            <corners                android:radius="8dp"/>            <solid                android:color="#ffffff"/>        </shape>    </item>    <item        android:bottom="1dp"        android:left="1dp"        android:right="1dp"        android:top="1dp">        <shape android:shape="rectangle" >            <corners android:radius="8dp" />            <solid android:color="#ddf0ed" />        </shape>    </item></layer-list>

myedittext.xml 输入框的边框设置

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle" >    <!--     <gradient            android:angle="45"            android:endColor="#CCCCCC"            android:startColor="#CCCCCC" /> -->    <padding        android:bottom="7dp"        android:left="7dp"        android:right="7dp"        android:top="7dp" />    <!-- 设置圆角矩形 -->    <corners android:radius="6dp" />    <stroke        android:width="5px"        android:color="#1199EF" />    <solid android:color="#CCCCCC" /></shape>

下面给出demo中使用的布局文件
activity_image_add.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp"        android:orientation="horizontal"        android:background="#ddf0ed">        <ImageButton            android:id="@+id/imagebutton_imageadd_back"            android:layout_width="25dp"            android:layout_height="25dp"            android:layout_gravity="center"            android:layout_marginLeft="15dp"            android:background="@drawable/share_search_back"            />        <TextView            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"/>        <TextView            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:text="iPet选择图片"            android:gravity="center"            android:textSize="20dp"/>        <TextView            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"/>        <ImageButton            android:id="@+id/imagebutton_imageadd_finish"            android:layout_width="28dp"            android:layout_height="28dp"            android:layout_gravity="center"            android:layout_marginRight="15dp"            android:background="@drawable/finish"/>    </LinearLayout>    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="match_parent">        <GridView            android:id="@+id/gridview_imageadd"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:cacheColorHint="@android:color/transparent"            android:clipChildren="true"            android:gravity="center"            android:horizontalSpacing="3dip"            android:listSelector="@android:color/transparent"            android:numColumns="3"            android:stretchMode="columnWidth"            android:verticalSpacing="3dip">        </GridView>        <RelativeLayout            android:id="@+id/id_bottom_ly"            android:layout_width="match_parent"            android:layout_height="50dip"            android:layout_alignParentBottom="true"            android:background="#e0000000"            android:clickable="true">            <TextView                android:id="@+id/id_choose_dir"                android:layout_width="wrap_content"                android:layout_height="match_parent"                android:layout_alignParentLeft="true"                android:layout_centerVertical="true"                android:gravity="center_vertical"                android:paddingLeft="10dip"                android:text="所有图片"                android:textColor="@android:color/white" />            <TextView                android:id="@+id/id_total_count"                android:layout_width="50dip"                android:layout_height="match_parent"                android:layout_alignParentRight="true"                android:layout_centerVertical="true"                android:gravity="center"                android:text="0张"                android:textColor="@android:color/white" />        </RelativeLayout>    </RelativeLayout></LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:id="@+id/linearlayout_pop_recommend"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView            android:layout_width="match_parent"            android:layout_height="20dp" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="60dp"            android:background="#ddf0ed"            android:orientation="horizontal">            <TextView                android:id="@+id/textview_recommend_list"                android:layout_width="wrap_content"                android:layout_height="match_parent"                android:layout_marginLeft="15dp"                android:gravity="left|center"                android:text="动态发布:"                android:textColor="#fb0b0b0b"                android:textSize="20dp" />            <TextView                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1" />            <ImageButton                android:id="@+id/imagview_poprecommend_back"                android:layout_width="30dp"                android:layout_height="30dp"                android:layout_gravity="center"                android:layout_marginRight="15dp"                android:background="@drawable/quxiao" />        </LinearLayout>        <EditText            android:id="@+id/edittext_poprecommend"            android:layout_width="match_parent"            android:layout_height="150dp"            android:background="@drawable/myedittext" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="70dp"            android:orientation="horizontal">            <TextView                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1" />            <LinearLayout                android:layout_width="40dp"                android:layout_height="40dp"                android:layout_gravity="center"                android:background="#ddf0ed">                <ImageButton                    android:id="@+id/iamgebutton_poprecommend_tianjiatupian"                    android:layout_width="40dp"                    android:layout_height="40dp"                    android:layout_gravity="center"                    android:background="@drawable/tianjiatupian" />            </LinearLayout>            <TextView                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="5" />            <Button                android:id="@+id/button_poprecommend_fabu"                android:layout_width="70dp"                android:layout_height="40dp"                android:layout_gravity="center"                android:background="@drawable/mybutton"                android:text="发布"                android:textSize="20dp" />            <TextView                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1" />        </LinearLayout>    </LinearLayout>    <GridView        android:id="@+id/gridview_poprecommend"        android:layout_width="match_parent"        android:layout_height="150dp"        android:cacheColorHint="@android:color/transparent"        android:clipChildren="true"        android:gravity="center"        android:horizontalSpacing="3dip"        android:listSelector="@android:color/transparent"        android:numColumns="4"        android:stretchMode="columnWidth"        android:verticalSpacing="3dip">    </GridView>    <TextView        android:layout_width="match_parent"        android:layout_height="20dp"/></LinearLayout>

item_gridview_imageadd.xml

<?xml version="1.0" encoding="UTF-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <ImageView        android:id="@+id/id_item_image"        android:layout_width="fill_parent"        android:layout_height="100dp"        android:background="@drawable/pictures_no"        android:scaleType="centerCrop" />    <ImageButton        android:id="@+id/id_item_select"        android:clickable="false"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_alignParentTop="true"        android:layout_marginRight="3dp"        android:layout_marginTop="3dp"        android:background="@null"        android:src="@drawable/pictures_selected" /></RelativeLayout>

item_gridview_poprecommend.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <RelativeLayout        android:layout_width="80dp"        android:layout_height="80dp"        android:layout_gravity="center"        android:orientation="vertical" >        <ImageView            android:id="@+id/imageView1"            android:layout_width="100dp"            android:layout_height="100dp"            android:layout_margin="10dp"            android:scaleType="centerInside"             android:background="@drawable/pictures_no"/>    </RelativeLayout></LinearLayout>

list_dir_item.xml

<?xml version="1.0" encoding="UTF-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:padding="5dp" >    <ImageView        android:id="@+id/id_dir_item_image"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_alignParentLeft="true"        android:layout_centerVertical="true"        android:background="@drawable/pic_dir"        android:paddingBottom="17dp"        android:paddingLeft="12dp"        android:paddingRight="12dp"        android:paddingTop="9dp"        android:scaleType="fitXY"        android:src="@drawable/ic_launcher" />    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:layout_marginLeft="10dp"        android:layout_toRightOf="@id/id_dir_item_image"        android:orientation="vertical" >        <TextView            android:id="@+id/id_dir_item_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="所有图片"            android:textSize="10sp" />        <TextView            android:id="@+id/id_dir_item_count"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:text="4723张"            android:textColor="#444"            android:textSize="8sp" />    </LinearLayout>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"        android:layout_marginRight="20dp"        android:src="@drawable/dir_choose" /></RelativeLayout>

list_dir.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <ListView        android:id="@+id/listviwe_dir"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:divider="#EEE3D9"        android:dividerHeight="1px" >    </ListView></LinearLayout>

本demo参考博文有:
http://blog.csdn.net/lmj623565791/article/details/39943731/
还有一些小的问题是从网上百度的 忘记地址了,总之谢谢他们

最后别忘了给整个demo加入权限设置:

<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
0 0
原创粉丝点击