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
- webview中图片的获取、保存、展示、缓存处理
- WebView缓存图片的获取
- 从WebView缓存中获取网页图片
- Android中图片的展示之Webview居中显示图片
- WebView的缓存处理(中)
- Android 从WebView缓存中获取网页图片
- Android 从WebView缓存中获取网页图片
- Android 从WebView缓存中获取网页图片
- 获取网络图片缓存并展示
- android 从webview中读取缓存的图片
- webjs--获取上传图片的缓存路径展示在页面上
- Android中WebView的缓存
- Android中WebView的缓存
- Android 的WebView长按保存图片
- Android 的WebView长按保存图片
- Cocos2d-x 获取网络图片缓存并展示
- 关于启动页面动态获取网络的图片url进行展示的处理
- 将字符串的图片展示到webview上
- RAID 级别
- 算法训练 未名湖边的烦恼
- 算分作业3
- 浅谈JavaScript new对象的四个过程
- json 解析jsonArray
- webview中图片的获取、保存、展示、缓存处理
- jvm类加载过程
- 性能测试实施那些事
- 告警日志文件,查看控制文件,联机重做日志文件,数据文件和临时文件的名称跟大小
- 三方图表库hellocharts使用简单例子归纳(感觉比MpAndroidchart好用)
- FFT 【JSOI2012】bzoj4332 分零食
- 字符集所需要的比特数
- Xshell常用命令
- 密码MD5加密