项目实战:新闻APPday06学习笔记
不否认努力,继续加油!
学习整理重点、盲区,笔记如下:干干巴巴,麻麻赖赖,一点都不圆润……
day06
内容
1. TabLayout 替换ViewPagerIndicator
-
TabLayout的使用
a. 添加依赖;写布局;实例化 三连;
b. 和 TabLayout 关联;注意此时设置监听的方法;并设置 Tab 是可以滚动的,否则可能出现不现实的内容的情况;
tabLayout.setupWithViewPager(viewPager); //注意以后监听页面的变化 ,TabPageIndicator监听页面的变化 viewPager.addOnPageChangeListener(new MyOnPageChangeListener()); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
-
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; }
-
解决兼容问题
a. 由于清单文件中,activity 用到了 ViewPagerIndicator 的主题,将其父主题改成;parent="Theme.AppCompat.Light.NoActionBar">
;b. ViewPagerIndicater_library库中增加 V7 包;
implementation 'com.android.support:appcompat-v7:28.0.0'
2. 图片 三级缓存 -网络缓存
-
三级缓存的原理
好处:可以尽量避免内存溢出,提高程序执行效率,省流量,提供用户体验读取速度:
- 内存缓存: 最快
- 本地缓存: 其次
- 网络缓存: 速度最慢
-
三级缓存设计步骤:
- 从内存中取图片
- 从本地文件中取图片;向内存中保持一份
- 请求网络图片,获取图片,显示到控件上;向内存存一份;向本地文件中存一份
-
缓存工具类的创建
a. 图片缓存工具类中调用,从网络加载图片的方法;
b. 在需要缓存图片的页面中,修改自定义的 adapter,在 getView() 方法中,获取缓存中的图片,如果获取到的 bitmap 不等于 null,那么内容来自内存或者本地取到;否则从网络请求
-
发送到主线程显示
在缓存工具类中,初始化 handler,不论是否有缓存图片;都发送handler;
在显示页面,直接将图片设置到对应的 View 中显示;
-
线程池类Executors的使用
public static ExecutorService newCachedThreadPool();
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。如果现在线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。public static ExecutorService newFixedThreadPool(int nThreads);
创建一个可重用固定线程数的线程池,
3. 三级缓存完成
-
本地缓存
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. 请求数据,在图片缓存工具类中,网络请求图片前,先检测本地是否有缓存;有的话直接获取;没有的话从网络请求,并在请求得到后将图片缓存到本地;
-
内存缓存
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. 软件数据缓存-文件方式缓存文本
-
向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(); } }
-
从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. 请求图片框架
-
Picasso
没错是这个老爷子;2333
PPicasso的使用很简单,根据文档案例操作就可以了; -
Glide
同样可以用来加载图片,并且方法更多,体积相对来说大了一丢丢;
缓存图片的速度比较快,它也可以有效的防止OOM错误,可以 加载gif图片;
不过图片质量来言Picasso更高一些,具体细节不进行赘述;
盲区
- 声明:本博客根据尚硅谷项目实战: 北京新闻.学习整理;
其他笔记
新闻APP其他笔记
- day01
第一天的学习笔记: 新闻APP01. - day02
第二天的学习笔记: 新闻APP02. - day03
第三天的学习笔记: 新闻APP03. - day04
第四天的学习笔记: 新闻APP04. - day05
第五天的学习笔记: 新闻APP05. - day06
第六天的学习笔记:新闻APP06. - day07
第七天的学习笔记:新闻APP07.
购物商城APP学习笔记
购物商城APP学习笔记:购物商城