WebView的使用和第三方集成分享及图片的三级缓存

属性动画

  1. 动画: UI渐变, 变量值的变化
  2. ObjectAnimator : ofInt(“backgroundColor”,start,end);
  3. ValueAnimator:

    1. for(int i = start; i< end; i++) { a = i; }

      ValueAnimator animation=ValueAnimator.ofInt(start,end);
      animation.setDuration(DURATION);
      animation.addUpdateListener(new AnimatorUpdateListener() {
      
      @Override
      public void onAnimationUpdate(ValueAnimator animation)
      {
          int animationValue=(Integer) animation.getAnimatedValue();
          mHeaderlayout.setPadding(0, animationValue, 0, 0);
      }
      

      });
      animation.start();

刷新页面是使用ValueAnimator场景之一,以提高用户体验性。addUpdateListener这个方法不断更新高度,使其渐变收缩。从一开始的start到end。其他地方法就不介绍了,想了解的就去看看源码吧。

ListView页面数据点击已读的设置

实现条目点击的事件,把点击条目的唯一标识符id存储起来,通知listview适配器更新。

    listviewAdapter.notifyDataSetChanged();

在listview适配器中的getView()方法中判断当前position的id是否在存储的数据中(自定义区分的规则),若存在,设置文本字体为灰色,不存在则为黑色。

    //设置已读为灰色
    String itemId="#"+bean.id+"#";
    String readIds=GetDataShared.getString(mContext, KEY_READ_LIST);
    boolean isRead=!TextUtils.isEmpty(readIds)&& readIds.contains(itemId);
    holder.textlist.setTextColor(isRead ? Color.GRAY:Color.BLACK);

页面中webView的使用

    WebView listWeb=(WebView) findViewById(R.id.news_detial_wv);
    //根据url去加载数据
    listWeb.loadUrl(url);

    //设置webview参数
    WebSettings setting=listWeb.getSettings();//获取webview的设置

    //默认为false,不支持javascrip,设置为true可收缩
    setting.setJavaScriptEnabled(true);//设置js可用

    setting.setBuiltInZoomControls(true); //设置放大和缩小可见

    setting.setUseWideViewPort(true);//设置手势双击放大或缩小

改变webview中参数的大小:定义一个方法:mCurrentheckedItem为存储的值(0-4),要想做缓存就把mCurrentheckedItem的值存储起来,在每次初始化的时候先判断存储的值是否存在且不为空。

private void initTextSize()
{
    TextSize ts =null;
    switch(mCurrentheckedItem){
        case 0:
            ts=TextSize.LARGEST;
            break;
        case 1:
            ts=TextSize.LARGER;
            break;
        case 2:
            ts=TextSize.NORMAL;
            break;
        case 3:
            ts=TextSize.SMALLER;
            break;
        case 4:
            ts=TextSize.SMALLEST;
            break;
    }
    listWeb.getSettings().setTextSize(ts);
}

设置监听常用的两个API,第一个无法满足需求就可以使用第二个。

    //设置监听1,进度条的显示切换在这里监听
    listWeb.setWebViewClient(new WebViewClient(){
        @Override
        public void onPageFinished(WebView view, String url)
        {
            //数据加载完成时调用,隐藏进度条
            listPb.setVisibility(View.GONE);
        }
    });

    //监听2,进度条的更新要在这个api里监听
    listWeb.setWebChromeClient(new WebChromeClient(){
        @Override
        public void onProgressChanged(WebView view, int newProgress)
        {
            //更新进度条
            Log.i(TAG, newProgress+"");
        }
    });

自定义加载时环形进度条

把一个xml文件嵌套进进度条中:环形正向和反向同时转然后汇聚再分开,循环

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
        <rotate
            android:fromDegrees="-90"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="990" >
            <shape
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:innerRadius="20dp"
                android:shape="ring"
                android:thickness="5dp"
                android:useLevel="false" >
                <gradient
                    android:endColor="#88ffffff"
                    android:startColor="#88ff0000"
                    android:type="sweep"
                    android:useLevel="false" />
            </shape>
        </rotate>
    </item>
    <item>
        <rotate
            android:fromDegrees="990"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="-90" >
            <shape
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:innerRadius="20dp"
                android:shape="ring"
                android:thickness="5dp"
                android:useLevel="false" >
                <gradient
                    android:endColor="#88ffffff"
                    android:startColor="#88ff0000"
                    android:type="sweep"
                    android:useLevel="false" />
            </shape>
        </rotate>
    </item>

</layer-list>

在Probress中设置应用:设置属性indeterminateDrawable,在这里引用布局

    <ProgressBar 
        android:id="@+id/news_detial_pb"
        android:layout_gravity="center"
        android:indeterminateDrawable="@drawable/loadingpb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

一键分享,使用第三方分享SDK,现在有大量的平台提供分享,这里以Mob为例说明一下使用的方法。

1、首先在mob官网注册一个账号。创建应用, 获取ShareSDK的AppKey

2、 下载SDK,点击下载之后如下图所以,点击下载SDK的下载页,展开平台可以选择其他的第三方平台;demo也是这里下载;

3、 快速集成(具体参考mob官方Android集成文档)、

(1)、使用快速工具进行集成

(2)、配置AndroidManifest.xml 添加权限、添加activity信息、替换mob后台申请的Appkey与各个平台申请的key

4、添加分享代码

private void showShare() {
 ShareSDK.initSDK(this);
 OnekeyShare oks = new OnekeyShare();
 //关闭sso授权
 oks.disableSSOWhenAuthorize(); 

// 分享时Notification的图标和文字  2.5.9以后的版本不调用此方法
 //oks.setNotification(R.drawable.ic_launcher, getString(R.string.app_name));
 // title标题,印象笔记、邮箱、信息、微信、人人网和QQ空间使用
 oks.setTitle(getString(R.string.share));
 // titleUrl是标题的网络链接,仅在人人网和QQ空间使用
 oks.setTitleUrl("http://sharesdk.cn");
 // text是分享文本,所有平台都需要这个字段
 oks.setText("我是分享文本");
 // imagePath是图片的本地路径,Linked-In以外的平台都支持此参数
 //oks.setImagePath("/sdcard/test.jpg");//确保SDcard下面存在此张图片
 // url仅在微信(包括好友和朋友圈)中使用
 oks.setUrl("http://sharesdk.cn");
 // comment是我对这条分享的评论,仅在人人网和QQ空间使用
 oks.setComment("我是测试评论文本");
 // site是分享此内容的网站名称,仅在QQ空间使用
 oks.setSite(getString(R.string.app_name));
 // siteUrl是分享此内容的网站地址,仅在QQ空间使用
 oks.setSiteUrl("http://sharesdk.cn");

// 启动分享GUI
 oks.show(this);
 }

这里就可以使用分享东西到多社交平台了。

ShareSDK集成的主要步骤
  1. 注册账号
  2. 创建应用
  3. 下载sdk
  4. SDK 导入配置
  5. 代码配置

图片的三级缓存## 图片的三级缓存

  1. 引用

    1. 强引用: 应用程序崩溃时都不会回收,成员变量
    2. 软引用: 当应用程序内存不足的时候,系统会回收(JVM) SoftReference
    3. 弱引用:当jvm的回收机制运行时,就回收
    4. 虚引用:应用场景很少
  2. 3.0: bitmap缓存时,用软引用

  3. LruCache: Lru less recently use

首先是页面要显示图片,到内存中取图片数据,发现内存中没有,之后到本地中查询,有数据就存到内存中,页面从内存中取出数据显示;若本地也没有数据,就到网络取数据,取出数据就存到本地中,再存到内存中,最后显示出来。这就是三级缓存的大概步骤。下面来看看图片流程:

下面就来看看代码如何实现这些步骤

package com.cca.zhihui.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.widget.ImageView;

/**
 * 
 * @包名:com.cca.zhihui.utils
 * @类名:CacheHelper
 * @时间:下午11:07:15
 * @author Administrator
 * 
 * @描述:三级缓存的实现原理
 */
public class ImageHelper
{
    public static LruCache<String, Bitmap>  mCaches = null;
    // private Map<String ,SoftReference<Bitmap>>

    private static String                           mCacheDir; //系统缓存目录

    private static Handler mHandler;            //handler机制

    private ExecutorService mPool;      //线程管理者
    private static Map<ImageView,Future<?>> mFuture;
    public ImageHelper(Context context) {
        if (mCaches == null)
        {
            // lru最大占用的应用的内存
            int maxSize = (int) (Runtime.getRuntime().freeMemory() / 4);
            mCaches = new LruCache<String, Bitmap>(maxSize) {
                @Override
                protected int sizeOf(String key, Bitmap value)
                {
                    return value.getByteCount();
                    // 低版本:value.getRowBytes() * value.getHeight()
                }
            };

        }
        mCacheDir = getCacheDir(context);
        if(mHandler==null){
            mHandler=new ImagHandler();
        }
        //线程管理
        if(mPool==null){
            mPool=Executors.newFixedThreadPool(3);//只允许开3个子线程
        }
        if(mFuture==null){
            mFuture=new LinkedHashMap<ImageView, Future<?>>();//需要连续的内存地址
        }
    }

    //方法图片显示
    public void display(ImageView view, String url)
    {
        // 1、到内存中取数据
        Bitmap bitmap = mCaches.get(url);
        if (bitmap != null)
        {
            // 内存中有数据
            view.setImageBitmap(bitmap);
            return;
        }
        // 内存中没有数据
        // 2、到本地中取数据
        bitmap = getBitmapFromLocal(url);
        if (bitmap != null)
        {
            // 本地中有数据
            view.setImageBitmap(bitmap);
            return;
        }
        // 本地也没有数据
        getBitmapFromNet(view, url);
    }

    private void getBitmapFromNet(ImageView view, String url)
    {
        // 去网络获取数据
        //new Thread(new ImageRequestTask(view, url)).start();
        //判断是否有已经在执行的
        Future<?> future=mFuture.get(view);
        if(future!=null && future.isDone() && !future.isCancelled()){
            //正在执行
            future.cancel(true);
            future=null;
        }
        future=mPool.submit(new ImageRequestTask(view, url));
        mFuture.put(view, future);
    }

    //从本地获取图片资源
    private Bitmap getBitmapFromLocal(String url)
    {
        // 首先找到文件
        String name;
        try
        {
            name = MD5Encoder.encode(url);
            File file = new File(mCacheDir, url);//mCacheDir、缓存目录
            if (file.exists())
            {
                // 解析文件为bitmap
                Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

                // 存到内存中
                mCaches.put(url, bitmap);
                return bitmap;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    //获取两种存储缓存的目录
    private String getCacheDir(Context context)
    {
        // 如果有sdcard就用Android/data/appname
        if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState())
        {
            // 有sd卡
            File sdDir = Environment.getExternalStorageDirectory();
            File dir = new File(sdDir, "/Android/data/" + context.getPackageName() + "/bitmap/");
            if (!dir.exists())
            {
                dir.mkdirs();
            }
            return dir.getAbsolutePath();
        }
        else
        {
            return context.getCacheDir().getAbsolutePath();
        }

    }

    //异步加载图片数据
    class ImageRequestTask implements Runnable
    {

        private String      url;
        private ImageView   view;

        public ImageRequestTask(ImageView iv, String url) {
            this.url = url;
            this.view = iv;
        }

        @Override
        public void run()
        {
            try
            {
                // 去网络获取数据
                HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
                conn.setConnectTimeout(5000);// 连接超时
                conn.setReadTimeout(5000);// 读取超时
                conn.connect();// 开启连接
                int code = conn.getResponseCode();
                if (code == 200)
                {
                    // 访问网络成功
                    // 获取流,将流解析成bitmap
                    InputStream in = conn.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(in);

                    // 存到本地
                    writeLocal(bitmap, url);
                    // 存到内存
                    mCaches.put(url, bitmap);

                    //主线程中刷新图片
                    Message msg=Message.obtain();
                    msg.obj=new Object[]{view,url};
                    mHandler.sendMessage(msg);

                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    class ImagHandler extends Handler{
        @Override
        public void handleMessage(Message msg)
        {
            Object[] objs=(Object[]) msg.obj;
            ImageView view=(ImageView) objs[0];
            String url=(String) objs[1];
            //设置UI显示
            display(view, url);
        }
    }

    //把图片数据写进本地
    public void writeLocal(Bitmap bitmap, String url)
    {
        String name;
        FileOutputStream fos=null;
        try
        {
            name = MD5Encoder.encode(url);
            File file = new File(mCacheDir, name);

            fos = new FileOutputStream(file);

            //压缩图片写进本地,jpeg格式,质量为100
            bitmap.compress(CompressFormat.JPEG, 100, fos);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (fos != null){
                try
                {
                    fos.close();
                    fos=null;
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值