ViewPager,TabLayout与三级缓存

时间:2023-01-10 05:25:35

主要需要添加四种依赖

compile 'com.android.support:support-v4:23.4.0' //TabLayout的依赖
compile 'com.android.support:design:23.4.0'
compile 'com.squareup.okhttp3:okhttp:3.3.1'
compile 'com.jakewharton:disklrucache:2.0.2' //磁盘缓存的依赖

当想要用非原声系统的控件,主要在父容器中注册(这里的ViewPage,TabLayout都是):

xmlns:app="http://schemas.android.com/apk/res-auto">


TabLayout布局中可以设置选择时的文字颜色与滑动模式

app:tabSelectedTextColor="#f00"
app:tabMode="scrollable"

ViewPager是适配器视图控件,所以需要设置适配器(结合Fragment的使用,则使用FragmentPageAdapter,其中的FragmentList是存放Fragment的自定义集合)

class MyPagerAdapter extends FragmentPagerAdapter{
@Override
public Fragment getItem(int position){
return FragmentList.get(position);
}
@Override
public int getCount(){
return FragmentList.size();
}

想要ViewPager和TabLayout联动使用,就必须先给Viewpager设置标题内容,这些标题内容后面能在TabLayout中显示(此方法也是在上述适配中的重写方法)

@Override
public CharSequence getPageTitle(int position){
return titles[position];
}
private String[] titles = {"头条","社会","国内","国际","军事","体育","娱乐","科技","原创"};

设置ViewPager与TabLayout关联

tabLayout.setupWithViewPager(viewPager);

图片三级缓存的使用:

首先需要把图片先存放在手机运行时内存中

//创建一个缓存对象,参数是给予缓存的空间大小,通常以字节为单位,这里给10M缓存空间
private static LruCache<String ,Bitmap> cache = new LruCache<String ,Bitmap>(10*1024*1024){
@Override
protected int sizeOf(String key, Bitmap value){
return value.getByteCount();//返回以字节为单位
}
};

当第一次下载图片成功后,把图片存入缓存中:

 把图片放入缓存中:

cache.put(url,bitmap);//写入缓存(运行时内存)

图片存入缓存中后,再把图片存入磁盘内存中:

在存入磁盘内存中之前,需要上下文对象和初始化缓存地址,而可以选择用一个继承Application的类中传出上下文对象:

public class MyApp extends Application{
private static Application mApp;

@Override
public void onCreate(){
super.onCreate();
mApp = this;//把上下文赋值给mApp
}

public static Application getInstance(){
return mApp;//这样本应用中只要需要上下文对象的,调用此方法即可获得时
}
}

注意写完此类后,此时还应该在清单中注册上,不然获取对象时会是空指针

<application
android:name=".MyApp"

初始化缓存地址:

//初始化缓存地址
public static File getDiskCacheDir(Context context, String uniqueName){
String cachePath;
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()){
cachePath = context.getExternalCacheDir().getPath();
}else{
cachePath = context.getCacheDir().getPath();
}
File file = new File(cachePath + File.separator + uniqueName);
file.mkdirs();
return file;
}

把图片存入磁盘内存中:

private static DiskLruCache discache;

static {
//在启动时就获得缓存地址
//参数一是上下文,参数二是处理存储文件的字符串
File file = getDiskCacheDir(MyApp.getInstance(),"imgs");
try{
//参数一是flie文件,参数二是版本号,参数三是用于此缓存的最大字节数,参数四是分配的容量
discache = DiskLruCache.open(file,1,1,50*1024*1024);
DiskLruCache.Editor edit = discache.edit(encrptMD5(url));//获取一个可以向本地写入文件的edit
OutputStream os = edit.newOutputStream(0);//因为一个key对应一个文件,所以这个地方一定是0
bitmap.compress(Bitmap.CompressFormat.JPEG,100,os);//把bitmap存到SD卡中去,
edit.commit();//提交


每次下载图片前,先判断缓存中是否存在,没有再去磁盘内存中寻找,找不到则再开启线程去下载

从缓存中读取图片:

cache.get(url)

从磁盘存储中读取图片:

Bitmap bitmap;
if((bitmap = cache.get(url)) == null){
DiskLruCache.Snapshot snapshot = null;
try{
snapshot = discache.get(encrptMD5(url)); //指定字符串对应的快照
if(snapshot != null){
//SD卡中存在
InputStream is = snapshot.getInputStream(0);
bitmap = BitmapFactory.decodeStream(is);
if(bitmap != null){
//如果bitmap是从SD卡中取出来的,那 cache.put(url,bitmap);那么再次放回到缓存中取
cache.put(url,bitmap);
}
return bitmap;

最后需要还需要注册相关的权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>