TabLayout实现选项卡 & 图片 三级缓存 & 请求图片框架—Android项目实战—新闻APP06


不否认努力,继续加油!
学习整理重点、盲区,笔记如下:干干巴巴,麻麻赖赖,一点都不圆润……

day06

内容

1. TabLayout 替换ViewPagerIndicator

  1. TabLayout的使用

    a. 添加依赖;写布局;实例化 三连;

    b. 和 TabLayout 关联;注意此时设置监听的方法;并设置 Tab 是可以滚动的,否则可能出现不现实的内容的情况;

    tabLayout.setupWithViewPager(viewPager);
    //注意以后监听页面的变化 ,TabPageIndicator监听页面的变化
    viewPager.addOnPageChangeListener(new MyOnPageChangeListener());
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    
  2. TabLayout设置指针颜色和高度文字颜色;

    a. 在布局中添加 样式 style="@style/MyCustomTabLayout"

    b. 写 style 样式

    <style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
    		<item name="tabMaxWidth">72dp</item>
           	<item name="tabMinWidth">72dp</item>
            <item name="tabIndicatorColor">#ff0000</item>
            <item name="tabIndicatorHeight">2dp</item>
            <item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item>
            <item name="tabSelectedTextColor">@android:color/holo_red_light</item>
    </style>
    <style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
        	<item name="android:textSize">16sp</item>
          	<item name="android:textColor">@android:color/black</item>
           	<item name="textAllCaps">false</item>
    
    </style>
    

    c. TabLayout 自定义样式

    注意可以在选项卡中设置背景图片;下图的红点就是图片,可以自定义进行设置;
    在这里插入图片描述

    设置样式:detailpager.setAdapter(adapter);

    关联ViewPager;否则TabPageIndicator 不能显示 tabLayout.setupWithViewPager(vp_news_menu_detailpager);

    设置页面的监听需要用TabPageIndicator

       for (int i = 0; i < tabpageindicator.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(getTabView(i));
        }
    

    setupWithViewPager必须在ViewPager.setAdapter()之后调用

    在适配器中添加getTabView()方法

    public View getTabView(int position){
            View view = LayoutInflater.from(context).inflate(R.layout.tab_item, null);
            TextView ……
            return view;
    }
    
  3. 解决兼容问题
    a. 由于清单文件中,activity 用到了 ViewPagerIndicator 的主题,将其父主题改成; parent="Theme.AppCompat.Light.NoActionBar">

    b. ViewPagerIndicater_library库中增加 V7 包;implementation 'com.android.support:appcompat-v7:28.0.0'

2. 图片 三级缓存 -网络缓存

  1. 三级缓存的原理
    好处:可以尽量避免内存溢出,提高程序执行效率,省流量,提供用户体验

    读取速度:

    • 内存缓存: 最快
    • 本地缓存: 其次
    • 网络缓存: 速度最慢
      -

    三级缓存设计步骤:

    • 从内存中取图片
    • 从本地文件中取图片;向内存中保持一份
    • 请求网络图片,获取图片,显示到控件上;向内存存一份;向本地文件中存一份
  2. 缓存工具类的创建

    a. 图片缓存工具类中调用,从网络加载图片的方法;

    b. 在需要缓存图片的页面中,修改自定义的 adapter,在 getView() 方法中,获取缓存中的图片,如果获取到的 bitmap 不等于 null,那么内容来自内存或者本地取到;否则从网络请求

  3. 发送到主线程显示

    在缓存工具类中,初始化 handler,不论是否有缓存图片;都发送handler;

    在显示页面,直接将图片设置到对应的 View 中显示;

  4. 线程池类Executors的使用

    public static ExecutorService newCachedThreadPool();创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。如果现在线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

    public static ExecutorService newFixedThreadPool(int nThreads);创建一个可重用固定线程数的线程池,

3. 三级缓存完成

  1. 本地缓存

    a. 本地缓存工具类:

    public class LocalCacheUtils {
      private final String CACHE_DIR = "/mnt/sdcard/beijingnews";
      /**
       * 根据Url存储当前图片
       */
      public void putBitmap2Local(String imageUrl,Bitmap mp){
         try {
           String fileName = MD5Encoder.encode(imageUrl);
           ///mnt/sdcard/atguigu_beijingnews/slsllsllksklklkkl
           File file = new File(CACHE_DIR, fileName);
           //创建目录
           File parentFile = file.getParentFile();
           if(!parentFile.exists()){
              parentFile.mkdirs();
           }
           
           //存图片
           FileOutputStream stream = new FileOutputStream(file);
           mp.compress(CompressFormat.JPEG, 100, stream);
           
         } catch (Exception e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
         }   
      }
     
      /**
       * 根据Url从本地取出图片
       */
      public Bitmap getBitmapFromLocal(String imageUrl) {
         try {
           String fileName = MD5Encoder.encode(imageUrl);
           ///mnt/sdcard/atguigu_beijingnews/slsllsllksklklkkl
           File file = new File(CACHE_DIR, fileName);
           if(file.exists()){
              //文件存在,有缓存,读取出来,并返回
              FileInputStream is = new FileInputStream(file);
              Bitmap bm = BitmapFactory.decodeStream(is);
              return bm;
           }
         } catch (Exception e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
         }
         return null;
      }
    }
    

    b. 请求数据,在图片缓存工具类中,网络请求图片前,先检测本地是否有缓存;有的话直接获取;没有的话从网络请求,并在请求得到后将图片缓存到本地;

  2. 内存缓存

    a. 内存缓存工具类:

    public class MemoryCacheUtils { 
      private LruCache<String, Bitmap> lruCache;
      public MemoryCacheUtils(){
         //虚拟机内存的八分之一来缓存图片
              int maxMemorySize = (int) Runtime.getRuntime().maxMemory()/8;
              lruCache = new LruCache<String, Bitmap>(maxMemorySize){
     
                @Override
                protected int sizeOf(String key, Bitmap value) {
                   return value.getRowBytes() * value.getHeight();
                }
              };
      }
      /**
       * 根据Url保存图片在内存中
       */
      public void putBitmap2Memory(String imageUrl,Bitmap bm){
         lruCache.put(imageUrl, bm);
      }
      /**
       * 根据Url取出imp
       */
      public Bitmap getBitmapFromMemory(String imageUrl){
         return lruCache.get(imageUrl);
      }
    }
    

    b. 在图片缓存工具类中,先根据Url到内存中获取,如没有根据Url本地去获取,有的话直接获取;没有的话从网络请求,并在请求得到后将在内存、本地中各保存一份;

4. 软件数据缓存-文件方式缓存文本

  1. 向SharedPreferences 中存储字符串

    public static void putString(Context context, String key, String value) {
    
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            try {
                String fileName = MD5Encoder.encode(key);
                String dir = Environment.getExternalStorageDirectory()+"/beijiengnews";
                Log.e("putString","dir=="+dir);
                File file = new File(dir,fileName);
                File parentfile = file.getParentFile();
                if(!parentfile.exists()){
                    parentfile.mkdirs();
                }
                if(!file.exists()){
                    file.createNewFile();
                }
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(value.getBytes());
                fos.flush();
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            SharedPreferences sp = context.getSharedPreferences("atguigu", Context.MODE_PRIVATE);
            sp.edit().putString(key, value).commit();
        }
    }
    
  2. 从SharedPreferences 中获取存储的字符串

    public static String getString(Context context, String key, String defult) {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            String result = "";
            try {
                String fileName = MD5Encoder.encode(key);
                String dir = Environment.getExternalStorageDirectory()+"/beijiengnews";
                Log.e("putString","dir=="+dir);
                File file = new File(dir,fileName);
                if(file.exists()){
                    FileInputStream fis = new FileInputStream(file);
                    byte[] buffer = new byte[1024];
                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    int length = -1;
                    while((length =fis.read(buffer))!= -1){
                        stream.write(buffer,0,length);
                    }
                    result = stream.toString();
                    stream.close();
                    fis.close();;
                    return  result;
                }else{
                    return  "";
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        } else {
            SharedPreferences sp = context.getSharedPreferences("atguigu", Context.MODE_PRIVATE);
            return sp.getString(key, defult);
        }
    }
    

5. 极光消息 推送

通过案例,将极光推送集成到项目中

6. 请求图片框架

  1. Picasso
    没错是这个老爷子;2333
    PPicasso的使用很简单,根据文档案例操作就可以了;在这里插入图片描述

  2. Glide

    同样可以用来加载图片,并且方法更多,体积相对来说大了一丢丢;

    缓存图片的速度比较快,它也可以有效的防止OOM错误,可以 加载gif图片

    不过图片质量来言Picasso更高一些,具体细节不进行赘述;

盲区

  1. 声明:本博客根据尚硅谷项目实战: 北京新闻.学习整理;

其他笔记

新闻APP其他笔记

  1. day01
    第一天的学习笔记: 新闻APP01.
  2. day02
    第二天的学习笔记: 新闻APP02.
  3. day03
    第三天的学习笔记: 新闻APP03.
  4. day04
    第四天的学习笔记: 新闻APP04.
  5. day05
    第五天的学习笔记: 新闻APP05.
  6. day06
    第六天的学习笔记:新闻APP06.
  7. day07
    第七天的学习笔记:新闻APP07.

购物商城APP学习笔记

购物商城APP学习笔记:购物商城

猜你喜欢

转载自blog.csdn.net/liusaisaiV1/article/details/106093538
今日推荐