webview中图片的获取、保存、展示、缓存处理

来源:互联网 发布:郁冬 it 编辑:程序博客网 时间:2024/05/19 22:00

整体思路:在页面加载完成时获取webview页面的html源码,利用正则表达式获取html源码中的所有图片地址,获取到所有图片地址之后一切就变得简单了,监听图片的点击事件,从而实现图片的本地展示、保存以及滑动浏览问题

不善言辞 较为简单 直接上代码 亲测目前未出现bug(代码直接粘进项目即可使用,建议先拷贝出去再看)
最终效果图如下:
——–
截取后的图片展示

知识点:1、如何获取webview的源码    2、通过html源码获取img图片的地址    3、gilde的使用代码分析如下:-------1、自定义了MJavascriptInterface的类用来实现js调用本地的方法;并在WebViewClient中实现对WebView的监听管理。MJavascriptInterface代码如下--------------------------        `public class MJavascriptInterface {    private Context context;    private String[] imageUrls;    public MJavascriptInterface(Context context, String[] imageUrls) {        this.context = context;        this.imageUrls = imageUrls;    }    @android.webkit.JavascriptInterface    public void openImage(String img) {        Intent intent = new Intent();        intent.putExtra("imageUrls", imageUrls);        intent.putExtra("curImageUrl", img);        intent.setClass(context, PhotoBrowserActivity.class);        context.startActivity(intent);        for (int i = 0; i < imageUrls.length; i++) {            Log.e("图片地址" + i, imageUrls[i].toString());        }    }    @android.webkit.JavascriptInterface    public void getSource(String html) {        imageUrls = StringUtils.returnImageUrlsFromHtml(html);        Log.d("html=", html);    }2、 在MainActivity中 webView.setWebViewClient()的onPageFinished方法中设置addImageClickListener的监听方法——>当整个WebView页面加载完毕后,为每张图片设置监听事件——>这意味着,整个页面未加载完毕时,点击是无效的。addImageClickListener的代码实现也很简单,通过js找到相应的img标签,这样就知道是图片了,然后为这些图片设置点击监听事件——>每当点击时调用自定义的openImage(url)方法。这个openImage(url)方法与MJavascriptInterface中对应的方法交相辉映,这样就形成了js调用本地的方法。MainActivity中代码------------------  settings.setJavaScriptEnabled(true);   webView.loadUrl(url);   webView.addJavascriptInterface(new MJavascriptInterface(this,imageUrls), "imagelistener");  webView.setWebViewClient(new WebViewClient() {           @Override     public void onPageFinished(WebView view, String url) {         view.loadUrl("javascript:window.imagelistener.getSource('<head>'+" +                        "document.getElementsByTagName('html')[0].innerHTML+'</head>');");                super.onPageFinished(view, url);                addImageClickListener(view);//待网页加载完全后设置图片点击的监听方法            }        });    private void addImageClickListener(WebView webView) {        webView.loadUrl("javascript:(function(){" +                "var objs = document.getElementsByTagName(\"img\"); " +                "for(var i=0;i<objs.length;i++) " +                "{"                + " objs[i].onclick=function() " +                " { "                + "  window.imagelistener.openImage(this.src); " +//通过js代码找到标签为img的代码块,设置点击的监听方法与本地的openImage方法进行连接                " } " +                "}" +                "})()");    } 3、StringUtils工具类--利用正则表达式过滤出含有img标签的最终图片地址集    注意:正则表达式不是唯一 最好先打印出html源码格式 再确定正则表达式---------------------------------    public class StringUtils {    public static String [] returnImageUrlsFromHtml(String htmlCode) {        List<String> imageSrcList = new ArrayList<String>();        Pattern p = Pattern.compile("<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\f>]+\\b)[^>]*>", Pattern.CASE_INSENSITIVE);        Matcher m = p.matcher(htmlCode);        String quote = null;        String src = null;        while (m.find()) {            quote = m.group(1);            src = (quote == null || quote.trim().length() == 0) ? m.group(2).split("//s+")[0] : m.group(2);            imageSrcList.add(src);        }        return imageSrcList.toArray(new String[imageSrcList.size()]);    }4、PhotoBrowserActivity 主要用于处理图片的展示、保存、浏览,并且glide对图片的缓存进行了处理   代码如下--------------------------- public class PhotoBrowserActivity extends Activity implements View.OnClickListener {    private ImageView crossIv;    private ViewPager mPager;    private ImageView centerIv;    private TextView photoOrderTv;    private TextView saveTv;    private String curImageUrl = "";    private String[] imageUrls = new String[]{};    private int curPosition = -1;    private int[] initialedPositions = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_browser);        imageUrls = getIntent().getStringArrayExtra("imageUrls");        curImageUrl = getIntent().getStringExtra("curImageUrl");        initialedPositions = new int[imageUrls.length];        initInitialedPositions();        photoOrderTv = (TextView) findViewById(R.id.photoOrderTv);        saveTv = (TextView) findViewById(R.id.saveTv);        saveTv.setOnClickListener(this);        centerIv = (ImageView) findViewById(R.id.centerIv);        crossIv = (ImageView) findViewById(R.id.crossIv);        crossIv.setOnClickListener(this);        mPager = (ViewPager) findViewById(R.id.pager);        mPager.setPageMargin((int) (getResources().getDisplayMetrics().density * 15));        mPager.setAdapter(new PagerAdapter() {            @Override            public int getCount() {                return imageUrls.length;            }            @Override            public boolean isViewFromObject(View view, Object object) {                return view == object;            }            @Override            public Object instantiateItem(ViewGroup container, final int position) {                if (imageUrls[position] != null && !"".equals(imageUrls[position])) {                    final PhotoView view = new PhotoView(PhotoBrowserActivity.this);                    view.enable();                    view.setScaleType(ImageView.ScaleType.FIT_CENTER);                    Glide.with(PhotoBrowserActivity.this).load(imageUrls[position]).override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).fitCenter().crossFade().listener(new RequestListener<String, GlideDrawable>() {                        @Override                        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {                            if (position == curPosition) {                                hideLoadingAnimation();                            }                            showErrorLoading();                            return false;                        }                        @Override                        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {                            occupyOnePosition(position);                            if (position == curPosition) {                                hideLoadingAnimation();                            }                            return false;                        }                    }).into(view);                    container.addView(view);                    return view;                }                return null;            }            @Override            public void destroyItem(ViewGroup container, int position, Object object) {                releaseOnePosition(position);                container.removeView((View) object);            }        });        curPosition = returnClickedPosition() == -1 ? 0 : returnClickedPosition();        mPager.setCurrentItem(curPosition);        mPager.setTag(curPosition);        if (initialedPositions[curPosition] != curPosition) {//如果当前页面未加载完毕,则显示加载动画,反之相反;            showLoadingAnimation();        }        photoOrderTv.setText((curPosition + 1) + "/" + imageUrls.length);//设置页面的编号        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {            @Override            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {            }            @Override            public void onPageSelected(int position) {                if (initialedPositions[position] != position) {//如果当前页面未加载完毕,则显示加载动画,反之相反;                    showLoadingAnimation();                } else {                    hideLoadingAnimation();                }                curPosition = position;                photoOrderTv.setText((position + 1) + "/" + imageUrls.length);//设置页面的编号                mPager.setTag(position);//为当前view设置tag            }            @Override            public void onPageScrollStateChanged(int state) {            }        });    }    private int returnClickedPosition() {        if (imageUrls == null || curImageUrl == null) {            return -1;        }        for (int i = 0; i < imageUrls.length; i++) {            if (curImageUrl.equals(imageUrls[i])) {                return i;            }        }        return -1;    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.crossIv:                finish();                break;            case R.id.saveTv:                savePhotoToLocal();                break;            default:                break;        }    }    private void showLoadingAnimation() {        centerIv.setVisibility(View.VISIBLE);        centerIv.setImageResource(R.drawable.loading);        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(centerIv, "rotation", 0f, 360f);        objectAnimator.setDuration(2000);        objectAnimator.setRepeatCount(ValueAnimator.INFINITE);        objectAnimator.start();    }    private void hideLoadingAnimation() {        releaseResource();        centerIv.setVisibility(View.GONE);    }    private void showErrorLoading() {        centerIv.setVisibility(View.VISIBLE);        releaseResource();        centerIv.setImageResource(R.drawable.load_error);    }    private void releaseResource() {        if (centerIv.getAnimation() != null) {            centerIv.getAnimation().cancel();        }    }    private void occupyOnePosition(int position) {        initialedPositions[position] = position;    }    private void releaseOnePosition(int position) {        initialedPositions[position] = -1;    }    private void initInitialedPositions() {        for (int i = 0; i < initialedPositions.length; i++) {            initialedPositions[i] = -1;        }    }    private void savePhotoToLocal() {        ViewGroup containerTemp = (ViewGroup) mPager.findViewWithTag(mPager.getCurrentItem());        if (containerTemp == null) {            return;        }        PhotoView photoViewTemp = (PhotoView) containerTemp.getChildAt(0);        if (photoViewTemp != null) {            GlideBitmapDrawable glideBitmapDrawable = (GlideBitmapDrawable) photoViewTemp.getDrawable();            if (glideBitmapDrawable == null) {                return;            }            Bitmap bitmap = glideBitmapDrawable.getBitmap();            if (bitmap == null) {                return;            }            FileUtils.savePhoto(this, bitmap, new FileUtils.SaveResultCallback() {                @Override                public void onSavedSuccess() {                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            Toast.makeText(PhotoBrowserActivity.this, "保存成功", Toast.LENGTH_SHORT).show();                        }                    });                }                @Override                public void onSavedFailed() {                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            Toast.makeText(PhotoBrowserActivity.this, "保存失败", Toast.LENGTH_SHORT).show();                        }                    });                }            });        }    }    @Override    protected void onDestroy() {        releaseResource();        super.onDestroy();    }}5、PhotoBrowserActivity 中用到的FileUtils的代码如下----------------public class FileUtils {    public static void savePhoto(final Context context, final Bitmap bmp, final SaveResultCallback saveResultCallback) {        final File sdDir = getSDPath();        if (sdDir == null) {            Toast.makeText(context,"设备自带的存储不可用",Toast.LENGTH_LONG).show();            return;        }        new Thread(new Runnable() {            @Override            public void run() {                File appDir = new File(sdDir, "out_photo");                if (!appDir.exists()) {                    appDir.mkdir();                }                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置以当前时间格式为图片名称                String fileName = df.format(new Date()) + ".png";                File file = new File(appDir, fileName);                try {                    FileOutputStream fos = new FileOutputStream(file);                    bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);                    fos.flush();                    fos.close();                    saveResultCallback.onSavedSuccess();                } catch (FileNotFoundException e) {                    saveResultCallback.onSavedFailed();                    e.printStackTrace();                } catch (IOException e) {                    saveResultCallback.onSavedFailed();                    e.printStackTrace();                }                //保存图片后发送广播通知更新数据库                Uri uri = Uri.fromFile(file);                context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));            }        }).start();    }    public static File getSDPath() {        File sdDir = null;        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); //判断sd卡是否存在        if (sdCardExist) {            sdDir = Environment.getExternalStorageDirectory();//获取跟目录        }        return sdDir;    }    public interface SaveResultCallback {        void onSavedSuccess();        void onSavedFailed();    }}
0 0
原创粉丝点击