1 . 如何显示一个很大的图,高清加载巨图方案
首先不压缩,按照原图尺寸加载,那么屏幕肯定是不够大的,并且考虑到内存的情况,不可能一次性整图加载到内存中,所以肯定是局部加载,那么就需要用到一个类:
BitmapRegionDecoder
其次,既然屏幕显示不完,那么最起码要添加一个上下左右拖动的手势,让用户可以拖动查看。
BitmapRegionDecoder主要用于显示图片的某一块矩形区域,如果你需要显示某个图片的指定区域,那么这个类非常合适。
对于该类的用法,非常简单,既然是显示图片的某一块区域,那么至少只需要一个方法去设置图片;一个方法传入显示的区域即可;详见:
BitmapRegionDecoder提供了一系列的newInstance方法来构造对象,支持传入文件路径,文件描述符,文件的inputstrem等。
例如:
BitmapRegionDecoder bitmapRegionDecoder =
BitmapRegionDecoder.newInstance(inputStream, false);
上述解决了传入我们需要处理的图片,那么接下来就是显示指定的区域。
bitmapRegionDecoder.decodeRegion(rect, options);
参数一很明显是一个rect,参数二是BitmapFactory.Options,你可以控制图片的inSampleSize,inPreferredConfig等。
那么下面看一个超级简单的例子:
package com.zhy.blogcodes.largeImage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import com.zhy.blogcodes.R;
import java.io.IOException;
import java.io.InputStream;
public class LargeImageViewActivity extends AppCompatActivity
{
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_large_image_view);
mImageView = (ImageView) findViewById(R.id.id_imageview);
try
{
InputStream inputStream = getAssets().open(tangyan.jpg);
//获得图片的宽、高
BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
tmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, tmpOptions);
int width = tmpOptions.outWidth;
int height = tmpOptions.outHeight;
//设置显示图片的中心区域
BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = bitmapRegionDecoder.decodeRegion(new Rect(width / 2 - 100, height / 2 - 100, width / 2 + 100, height / 2 + 100), options);
mImageView.setImageBitmap(bitmap);
} catch (IOException e)
{
e.printStackTrace();
}
}
}
2 .安卓的数据缓存方案
首先数据分为两种:和应用相关的数据;和应用无关的数据。这里分别介绍:
1、应用无关的数据是那些用户比较关心的数据,不管您的应用在不在用户设备上,这些数据用户都希望保留,这些数据包含:用相机拍摄的照片、用浏览器(下载工具)下载的文件、用户制作的个性铃声等。假设您开发了一个照相应用(例如: 360相机),用户用您的应用拍摄并处理过的照片就属于应用无关的数据,如果用户把您的应用给卸载了,用户还是会期望仍然保留他们拍摄并处理过的照片。这里的照片按照Android官方的建议应该保存到 DIRECTORY_PICTURES 目录中,该目录通过Environment.getExternalStoragePublicDirectory(String type)来获取,您可以在该目录下创建一个以您的程序命名的目录来保存数据。
2、应用相关的数据: 这种数据只和您的应用相关,如果您的应用被用户删除了这些数据也没有理由还存在用户设备中。这种数据包含:数据库文件、属性配置文件、应用的缓存文件等。这里我们只讨论在API 8(Android 2.2)中新引入了一种保存到外部存储空间的伪私有数据API,通过函数getExternalFilesDir() 来获取该路径,同样可以设置获取各种类型数据的参数,例如 DIRECTORY_MUSIC 和 DIRECTORY_RINGTONES (如果参数为null则返回您应用数据的跟目录)。比如一个应用的包名为 org.goodev.test 的应用,通过函数getExternalFilesDir(Environment.DIRECTORY_MOVIES)获取到的文件路径为 /storage/sdcard0/Android/data/org.goodev.test/files/Movies。
关于app图片存储问题
方案:
暂时方案:
1、 与用户有关的数据按照上面所说的,存在程序安装文件夹下的一个目录中。
2、 与用户无关的数据,统一存在手机外存储卡上,如果手机没有装外存储卡,则提示没插存储卡,图片不能缓存。
LruCache介绍
核心的类是LruCache (此类在android-support-v4的包中提供) 。这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。
LruCache使用 下面我们就来写一个简单的demo来学习LruCache,效果也是每次请求一次第二次直接从缓存中提取出来不用再次请求网络 ## 标题 ##
private LruCache<integer, string=""> mJsonCache; /** * 缓存json数据 */
private LruCache<integer, bitmap=""> mBitmapCache; /** * 缓存图片信息 */
public Util() {
mJsonCache = new LruCache<integer, string="">(1 * 1024 * 1024);
mBitmapCache = new LruCache<integer, bitmap="">(2 * 1024 * 1024);
}
/** * 添加进入缓存列表 * * @param key * @param value */
public void addJsonLruCache(Integer key, String value)
{
mJsonCache.put(key, value);
}
public void addBitmapLruCache(Integer key, Bitmap value)
{
mBitmapCache.put(key, value);
}
/** * 从缓存列表中拿出来 * * @param key * @return */
public String getJsonLruCache(Integer key)
{
return mJsonCache.get(key);
}
public Bitmap getBitmapLruCache(Integer key)
{
return mBitmapCache.get(key);
}