场景

项目中的广告详情页面是个webView加载的富文本,包含图片,需要点击查看大图,长按识别二维码功能。

实现

  • webView基础设置
        val webView = fragment.binding.webViewwebView.settings.javaScriptEnabled = truewebView.settings.builtInZoomControls = falsewebView.settings.displayZoomControls = truewebView.settings.setSupportZoom(false)//不支持缩放功能webView.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY //取消滚动条白边效果webView.webChromeClient = WebChromeClient()webView.webViewClient = MyWebViewClient()webView.addJavascriptInterface(MJavascriptInterface(fragment.activity,fragment),"imagelistener")webView.settings.defaultTextEncodingName = "UTF-8"webView.settings.blockNetworkImage = falseif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {webView.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW  //注意安卓5.0以上的权限}if (detail.content.checkNotNull()) {val css = "<style>*{padding: 0;margin: 0}#webview_content_wrapper{margin: 10px 15px 0 15px;}; p{color: #333333;line-height: 2em;font-size:14px;opacity: 1;}; img {margin-top: 13px;margin-bottom: 15px;width: 100%;}</style>"val html = css + "<body><div id='webview_content_wrapper'>" + detail.content + "</div></body>"webView.loadDataWithBaseURL(null, ImageUtil.getNewContent(html), "text/html", "UTF-8", null)}webView.setOnLongClickListener(object : View.OnLongClickListener {override fun onLongClick(v: View?): Boolean {val result =webView.hitTestResultif (!result.checkNotNull()) {return false}val type = result.typewhen (type) {// 超链接WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE,/*带有链接的图片类型*/WebView.HitTestResult.IMAGE_TYPE -> {// 处理长按图片的菜单项val coverUrl = result.extraif (URLUtil.isValidUrl(coverUrl) || coverUrl.startsWith("data:image")) {UiUtils.webViewLongClick(fragment, webView.context, coverUrl)return true}}}return false}})
  • webViewLongClick
/*网页长按弹窗(识别二维码,下载图片)*/@JvmStaticfun webViewLongClick(fragment: BaseFragment, context: Context, coverUrl: String) {openSelect(fragment, context, coverUrl)}/*网页长按弹窗(识别二维码,下载图片)*/private fun openSelect(fragment: BaseFragment, context: Context, coverUrl: String) {val dialog = BottomSheetDialog(context)val layoutView = LayoutInflater.from(context).inflate(R.layout.dialog_select_qrcode_down_img, null)layoutView.findViewById<TextView>(R.id.tv_qrcode).setOnClickListener {//图片urlGlide.with(context.applicationContext).asBitmap().load(coverUrl).into(object : SimpleTarget<Bitmap>() {override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {CodeUtils.analyzeBitmap(resource, object : CodeUtils.AnalyzeCallback {override fun onAnalyzeSuccess(mBitmap: Bitmap, result: String) {fragment.start(WebFragment.newInstance("", result))}override fun onAnalyzeFailed() {"未识别到二维码".toast()}})dialog.dismiss()}})}layoutView.findViewById<TextView>(R.id.tv_download).setOnClickListener {if (coverUrl.startsWith("data:image")) {var fileName: String? = nullif (MimeTypeMap.getFileExtensionFromUrl(coverUrl) == "") {fileName = System.currentTimeMillis().toString() + ".jpg"} else {fileName = System.currentTimeMillis().toString() + "." + MimeTypeMap.getFileExtensionFromUrl(coverUrl)}val file = BitmapUtils.saveBitmapFile(AndroidtoJs.stringToBitmap(coverUrl), DownLoadImageRunnable.SAVE_DOWNLOAD_IMAGE_PATH + fileName)if (file.checkNotNull()) {"已保存".toast()} else {"保存失败".toast()}} else {ImageUtil.downLoadImg(context, coverUrl)}dialog.dismiss()}dialog.setContentView(layoutView)dialog.show()}
  • 弹窗布局dialog_select_qrcode_down_img.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/white"android:orientation="vertical"><TextViewandroid:id="@+id/tv_qrcode"android:layout_width="match_parent"android:layout_height="wrap_content"android:includeFontPadding="false"android:padding="15dp"android:text="识别二维码"android:textColor="@color/color_333333"android:textSize="@dimen/sp_14" /><Viewandroid:layout_width="match_parent"android:layout_height="@dimen/dp_1"android:layout_marginLeft="@dimen/dp_15"android:layout_marginRight="@dimen/dp_15"android:background="@color/color_f5f5f5" /><TextViewandroid:id="@+id/tv_download"android:layout_width="match_parent"android:layout_height="wrap_content"android:includeFontPadding="false"android:padding="15dp"android:textColor="@color/color_333333"android:textSize="@dimen/sp_14"android:text="下载图片" />
</LinearLayout>
  • MyWebViewClient

import android.graphics.Bitmap;
import android.webkit.WebView;
import android.webkit.WebViewClient;/*** Created by Administrator on 2017/2/10.*/public class MyWebViewClient extends WebViewClient {@Overridepublic void onPageFinished(WebView view, String url) {view.getSettings().setJavaScriptEnabled(true);super.onPageFinished(view, url);addImageClickListener(view);//待网页加载完全后设置图片点击的监听方法}@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {view.getSettings().setJavaScriptEnabled(true);super.onPageStarted(view, url, favicon);}private void addImageClickListener(WebView webView) {webView.loadUrl("javascript:(function(){" + "var objs = document.getElementsByTagName(\"img\");" +" " + " var array=new Array(); " +" for(var j=0;j<objs.length;j++){ " + "array[j]=objs[j].src;" + " }  " +"for(var i=0;i<objs.length;i++)  " + "{" + "  objs[i].onclick=function()  " + "  {  " + "   " +" window.imagelistener.openImage(this.src,array);  " + "  }  " + "}" + "})()");}
}
  • MJavascriptInterface

import android.app.Activity;
import android.widget.ImageView;import com.xlj.app.global.base.BaseFragment;
import com.xlj.app.widget.ninegrid.ImageInfo;import java.util.ArrayList;public class MJavascriptInterface {private Activity context;private BaseFragment fragment;private static final String TAG = "SIMON";ArrayList<String> images = new ArrayList<>();public MJavascriptInterface(Activity context, BaseFragment fragment) {this.context = context;this.fragment = fragment;}@android.webkit.JavascriptInterface //必须添加public void openImage(String img, String[] array) {int index = 0;ArrayList<ImageInfo> imageInfo = new ArrayList<>();for (int i = 0; i < array.length; i++) {ImageInfo imInfo = new ImageInfo();imInfo.thumbnailUrl = array[i];imInfo.bigImageUrl = array[i];imageInfo.add(imInfo);if (array[i].equals(img)) {index = printArray(array, img);}}ImageView imageView = new ImageView(context);fragment.previewPhoto(imageView, imageInfo, index, false, true,true);}//遍历数组private int printArray(String[] array, String value) {for (int i = 0; i < array.length; i++) {if (array[i].equals(value)) {return i;}}return -1;//当if条件不成立时,默认返回一个负数值-1}
}
  • 大图查看
//图片预览fun previewPhoto(clickImageView: ImageView, imageInfo: List<ImageInfo>, index: Int, finishAnimator: Boolean = true, isShowShare: Boolean = false,isSeeCode:Boolean=false) {if (imageInfo.isNotEmpty()) {val info: ImageInfo = imageInfo[0]imageInfo.forEach {it.imageViewWidth = clickImageView.widthit.imageViewHeight = clickImageView.heightval points = IntArray(2)clickImageView.getLocationInWindow(points)info.imageViewX = points[0]info.imageViewY = points[1] - StatusBarUtil.getStatusBarHeight(activity)}val intent = Intent(context, ImagePreviewActivity::class.java)val bundle = Bundle()bundle.putSerializable(ImagePreviewActivity.IMAGE_INFO, imageInfo as Serializable)bundle.putInt(ImagePreviewActivity.CURRENT_ITEM, index)bundle.putBoolean(ImagePreviewActivity.FINISH_ANIMATION, finishAnimator)bundle.putBoolean(ImagePreviewActivity.IS_SHOW_SHARE, isShowShare)bundle.putBoolean(ImagePreviewActivity.IS_SEE_CODE, isSeeCode)intent.putExtras(bundle)context!!.startActivity(intent)activity!!.overridePendingTransition(0, 0)}}
  • 下面是图片预览的activity -----ImagePreviewActivity

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;import com.bigkoo.alertview.AlertView;
import com.bigkoo.alertview.OnItemClickListener;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.dtr.zxing.utils.CodeUtils;
import com.kaopiz.kprogresshud.KProgressHUD;
import com.tencent.qcloud.tim.uikit.component.photoview.downloadimg.ImageUtil;
import com.tencent.qcloud.tim.uikit.utils.ToastUtil;
import com.umeng.analytics.MobclickAgent;
import com.umeng.socialize.UMShareAPI;
import com.xlj.app.R;
import com.xlj.app.global.Constant;
import com.xlj.app.mvvm.main.activity.WebActivity;
import com.xlj.app.mvvm.main.fragment.WebFragment;
import com.xlj.app.utils.EventBusUtils;
import com.xlj.app.utils.Toast.ToastUtils;
import com.xlj.app.widget.ninegrid.ImageInfo;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;public class ImagePreviewActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {public static final String IMAGE_INFO = "IMAGE_INFO";public static final String CURRENT_ITEM = "CURRENT_ITEM";public static final String FINISH_ANIMATION = "FINISH_ANIMATION";public static final String IS_SHOW_SHARE = "IS_SHOW_SHARE";//是否有 识别二维码public static final String IS_SEE_CODE = "IS_SEE_CODE";public static final int ANIMATE_DURATION = 200;private RelativeLayout rootView;private ImagePreviewAdapter imagePreviewAdapter;private List<ImageInfo> imageInfo;private int currentItem;private int imageHeight;private int imageWidth;private int screenWidth;private int screenHeight;private boolean isUseFinishAnimator, isShowShare, isSeeCode;private KProgressHUD loading;private String bigImageUrl;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_preview);loading = KProgressHUD.create(ImagePreviewActivity.this).setStyle(KProgressHUD.Style.SPIN_INDETERMINATE).setWindowColor(ImagePreviewActivity.this.getResources().getColor(R.color.color_trans)).setCancellable(false);ViewPager viewPager = findViewById(R.id.viewPager);final TextView tv_pager = findViewById(R.id.tv_pager);ImageView imgShare = findViewById(R.id.img_share);rootView = findViewById(R.id.rootView);DisplayMetrics metric = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metric);screenWidth = metric.widthPixels;screenHeight = metric.heightPixels;Intent intent = getIntent();imageInfo = (List<ImageInfo>) intent.getSerializableExtra(IMAGE_INFO);currentItem = intent.getIntExtra(CURRENT_ITEM, 0);isUseFinishAnimator = intent.getBooleanExtra(FINISH_ANIMATION, true);isShowShare = intent.getBooleanExtra(IS_SHOW_SHARE, false);//是否有弹窗菜单(转发。保存)isSeeCode = intent.getBooleanExtra(IS_SEE_CODE, false);//是否有弹窗菜单(转发。保存)imgShare.setVisibility(isShowShare ? View.VISIBLE : View.GONE);imagePreviewAdapter = new ImagePreviewAdapter(this, imageInfo);imagePreviewAdapter.setIsShowOrginal(isShowShare);imagePreviewAdapter.setSeeCode(isSeeCode);viewPager.setAdapter(imagePreviewAdapter);viewPager.setCurrentItem(currentItem);viewPager.getViewTreeObserver().addOnPreDrawListener(this);viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {@Overridepublic void onPageSelected(int position) {currentItem = position;tv_pager.setText(String.format(getString(R.string.select), currentItem + 1, imageInfo.size()));}});tv_pager.setText(String.format(getString(R.string.select), currentItem + 1, imageInfo.size()));bigImageUrl = imageInfo.get(currentItem).thumbnailUrl;imgShare.setOnClickListener(v -> {if (bigImageUrl != null && !"".equals(bigImageUrl)) {menuPop(v, bigImageUrl);}
//            DialogUtils.umShare(ImagePreviewActivity.this,imgShare.getContext(),bigImageUrl,"分享到", loading);
/*            new Thread(() -> ImageUtil.url2Bitmap(ImagePreviewActivity.this, bigImageUrl, new ImageUtil.GetCallBackInterface<Bitmap>() {@Overridepublic void onSuccess(Bitmap bitmap) {//点击分享if (bitmap != null) {runOnUiThread(() -> DialogUtils.shareWeChatDialog(ImagePreviewActivity.this, bitmap, "分享到").show());}}@Overridepublic void onFail(String s) {}})).start();*/});}private void menuPop(View v, String bigImageUrl) {if (isSeeCode) {showSeeCodeDialog(v);return;}new AlertView("操作", null, "取消", null, new String[]{"转发", "保存"}, v.getContext(), AlertView.Style.ActionSheet, new OnItemClickListener() {@Overridepublic void onItemClick(Object o, int position) {if (position == -1) return;if (position == 0) {//转发if (currentItem == -1) return;EventBusUtils.forwordImgMessage(currentItem);onBackPressed();} else {if (bigImageUrl.contains("http")) {ImageUtil.downLoadImg(ImagePreviewActivity.this, bigImageUrl);} else {try {FileInputStream fis = new FileInputStream(bigImageUrl);Bitmap bitmap = BitmapFactory.decodeStream(fis);boolean succ = ImageUtil.saveImageToGallery(ImagePreviewActivity.this, bitmap);String tip = "";if (succ) {tip = "已保存到相册";} else {tip = "保存失败";}ToastUtil.toastShortMessage(tip);} catch (FileNotFoundException e) {e.printStackTrace();}}}}}).setCancelable(true).show();}private void showSeeCodeDialog(View v) {new AlertView("操作", null, "取消", null, new String[]{"识别二维码", "保存"}, v.getContext(), AlertView.Style.ActionSheet, new OnItemClickListener() {@Overridepublic void onItemClick(Object o, int position) {if (position == -1) return;if (position == 0) {// 识别二维码Glide.with(v.getContext()).asBitmap().load(bigImageUrl).into(new SimpleTarget<Bitmap>() {@Overridepublic void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {CodeUtils.analyzeBitmap(resource, new CodeUtils.AnalyzeCallback() {@Overridepublic void onAnalyzeSuccess(Bitmap mBitmap, String result) {WebActivity.Companion.start(v.getContext(),result,"");}@Overridepublic void onAnalyzeFailed() {ToastUtils.showShortToast(v.getContext(), "未识别到二维码");}});}});} else {if (bigImageUrl.contains("http")) {ImageUtil.downLoadImg(ImagePreviewActivity.this, bigImageUrl);} else {try {FileInputStream fis = new FileInputStream(bigImageUrl);Bitmap bitmap = BitmapFactory.decodeStream(fis);boolean succ = ImageUtil.saveImageToGallery(ImagePreviewActivity.this, bitmap);String tip = "";if (succ) {tip = "已保存到相册";} else {tip = "保存失败";}ToastUtil.toastShortMessage(tip);} catch (FileNotFoundException e) {e.printStackTrace();}}}}}).setCancelable(true).show();}@Overridepublic void onBackPressed() {finishActivityAnim();}/*** 绘制前开始动画*/@Overridepublic boolean onPreDraw() {rootView.getViewTreeObserver().removeOnPreDrawListener(this);final View view = imagePreviewAdapter.getPrimaryItem();final ImageView imageView = imagePreviewAdapter.getPrimaryImageView();computeImageWidthAndHeight(imageView);final ImageInfo imageData = imageInfo.get(currentItem);final float vx = imageData.imageViewWidth * 1.0f / imageWidth;final float vy = imageData.imageViewHeight * 1.0f / imageHeight;ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f);valueAnimator.addUpdateListener(animation -> {long duration = animation.getDuration();long playTime = animation.getCurrentPlayTime();float fraction = duration > 0 ? (float) playTime / duration : 1f;if (fraction > 1) {fraction = 1;}view.setTranslationX(evaluateInt(fraction, imageData.imageViewX + imageData.imageViewWidth / 2 - imageView.getWidth() / 2, 0));view.setTranslationY(evaluateInt(fraction, imageData.imageViewY + imageData.imageViewHeight / 2 - imageView.getHeight() / 2, 0));view.setScaleX(evaluateFloat(fraction, vx, 1));view.setScaleY(evaluateFloat(fraction, vy, 1));view.setAlpha(fraction);rootView.setBackgroundColor(evaluateArgb(fraction, Color.TRANSPARENT, Color.BLACK));});addIntoListener(valueAnimator);valueAnimator.setDuration(ANIMATE_DURATION);valueAnimator.start();return true;}@Overrideprotected void onResume() {super.onResume();MobclickAgent.onPageStart(this.getClass().getSimpleName());MobclickAgent.onResume(this);if (loading.isShowing()) {loading.dismiss();}}@Overrideprotected void onPause() {super.onPause();MobclickAgent.onPageEnd(this.getClass().getSimpleName());MobclickAgent.onPause(this);}public void longClick(View v) {if (!isShowShare) return;//if (bigImageUrl != null && !"".equals(bigImageUrl)) {menuPop(v, bigImageUrl);}}/*** activity的退场动画*/public void finishActivityAnim() {if (!isUseFinishAnimator) {finish();overridePendingTransition(0, 0);} else {final View view = imagePreviewAdapter.getPrimaryItem();final ImageView imageView = imagePreviewAdapter.getPrimaryImageView();computeImageWidthAndHeight(imageView);final ImageInfo imageData = imageInfo.get(currentItem);final float vx = imageData.imageViewWidth * 1.0f / imageWidth;final float vy = imageData.imageViewHeight * 1.0f / imageHeight;final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f);valueAnimator.addUpdateListener(animation -> {long duration = animation.getDuration();long playTime = animation.getCurrentPlayTime();float fraction = duration > 0 ? (float) playTime / duration : 1f;if (fraction > 1) {fraction = 1;}view.setTranslationX(evaluateInt(fraction, 0, imageData.imageViewX + imageData.imageViewWidth / 2 - imageView.getWidth() / 2));view.setTranslationY(evaluateInt(fraction, 0, imageData.imageViewY + imageData.imageViewHeight / 2 - imageView.getHeight() / 2));view.setScaleX(evaluateFloat(fraction, 1, vx));view.setScaleY(evaluateFloat(fraction, 1, vy));view.setAlpha(1 - fraction);rootView.setBackgroundColor(evaluateArgb(fraction, Color.BLACK, Color.TRANSPARENT));});addOutListener(valueAnimator);valueAnimator.setDuration(ANIMATE_DURATION);valueAnimator.start();}}/*** 计算图片的宽高*/private void computeImageWidthAndHeight(ImageView imageView) {// 获取真实大小Drawable drawable = imageView.getDrawable();int intrinsicHeight = drawable.getIntrinsicHeight();int intrinsicWidth = drawable.getIntrinsicWidth();// 计算出与屏幕的比例,用于比较以宽的比例为准还是高的比例为准,因为很多时候不是高度没充满,就是宽度没充满float h = screenHeight * 1.0f / intrinsicHeight;float w = screenWidth * 1.0f / intrinsicWidth;if (h > w) h = w;else w = h;// 得出当宽高至少有一个充满的时候图片对应的宽高imageHeight = (int) (intrinsicHeight * h);imageWidth = (int) (intrinsicWidth * w);}/*** 进场动画过程监听*/private void addIntoListener(ValueAnimator valueAnimator) {valueAnimator.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {rootView.setBackgroundColor(0x0);}@Overridepublic void onAnimationEnd(Animator animation) {}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});}/*** 退场动画过程监听*/private void addOutListener(ValueAnimator valueAnimator) {valueAnimator.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {rootView.setBackgroundColor(0x0);}@Overridepublic void onAnimationEnd(Animator animation) {finish();overridePendingTransition(0, 0);}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});}/*** Integer 估值器*/public Integer evaluateInt(float fraction, Integer startValue, Integer endValue) {int startInt = startValue;return (int) (startInt + fraction * (endValue - startInt));}/*** Float 估值器*/public Float evaluateFloat(float fraction, Number startValue, Number endValue) {float startFloat = startValue.floatValue();return startFloat + fraction * (endValue.floatValue() - startFloat);}/*** Argb 估值器*/public int evaluateArgb(float fraction, int startValue, int endValue) {int startA = (startValue >> 24) & 0xff;int startR = (startValue >> 16) & 0xff;int startG = (startValue >> 8) & 0xff;int startB = startValue & 0xff;int endA = (endValue >> 24) & 0xff;int endR = (endValue >> 16) & 0xff;int endG = (endValue >> 8) & 0xff;int endB = endValue & 0xff;return (startA + (int) (fraction * (endA - startA))) << 24| (startR + (int) (fraction * (endR - startR))) << 16| (startG + (int) (fraction * (endG - startG))) << 8| (startB + (int) (fraction * (endB - startB)));}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);}}
  • 预览的xml文件activity_preview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/rootView"android:layout_width="match_parent"android:layout_height="match_parent"><com.xlj.app.widget.ninegrid.preview.HackyViewPagerandroid:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="match_parent" /><TextViewandroid:id="@+id/tv_pager"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="20dp"android:text="1/4"android:textColor="#ffffff"android:textSize="20sp" /><ImageViewandroid:id="@+id/img_share"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_margin="10dp"android:padding="5dp"android:src="@drawable/ic_pic_more" />
</RelativeLayout>
  • 用到了一个自定义的HackyViewPager

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;/** 修复图片在ViewPager控件中缩放报错的BUG */
public class HackyViewPager extends ViewPager {public HackyViewPager(Context context) {super(context);}public HackyViewPager(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onTouchEvent(MotionEvent ev) {try {return super.onTouchEvent(ev);} catch (IllegalArgumentException ex) {ex.printStackTrace();}return false;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {try {return super.onInterceptTouchEvent(ev);} catch (IllegalArgumentException ex) {ex.printStackTrace();}return false;}
}

参考链接

  • Android 实现WebView点击图片查看大图列表及图片保存
  • webview 获取html中所有的图片资源并给图片添加点击事件
  • android 获取webview中所有的图片
  • Android-通过WebView获取html内容

[Android]网页内图片点击查看大图/识别二维码/下载相关推荐

  1. 用uni.previewImage({}) 来直接做图片的预览和识别二维码

    需求: 客户要求用户不用截图保存,通过直接用手机识别二维码关注,所以,这就需要我们进行图片的预览即可以解决. <image src="https://lr-huayoushi.oss- ...

  2. 微信小程序webview识别二维码长按点击识别二维码

    场景:微信小程序,使用webview控件.需求:点击图片后长按图片出现"识别二维码" 1.JS代码: <script src="http://res.wx.qq.c ...

  3. Android利用zxing生成二维码,识别二维码,中间填充图片超详细、超简易教程

    gayhub上的zxing可用于生成二维码,识别二维码 gayhub地址:https://github.com/zxing/zxing 此文只是简易教程,文末附有完整代码和demo下载地址,进入正题: ...

  4. 微信内扫描识别二维码打开网页的时候打开外部默认浏览器打开链接

    很多朋友问我怎么解决微信内点击链接或扫描二维码可以直接跳出微信在外部浏览器打开网页链接,其实这并不难,只要我们实现微信跳转功能即可.下面给大家介绍这个功能 功能目的 生成微信跳转链接,实现微信内置浏览 ...

  5. 微信小程序点击按钮弹窗生成二维码图片+长按识别

    框架:uni-app 库:Painter ui框架:uView 1.X <u-modal class="show-close" v-model="showClose ...

  6. 移动端(ios and android)长按识别二维码(含js与原生互调)

    这篇文章就整理下移动端长按识别二维码的实现吧!实现方式可以分为三种 一.长按原生控件,直接获取控件中的图片数据(src或background) 二.长按原生控件,截图识别 三.长按web中的图片,ap ...

  7. 小程序内识别二维码调查

    1.添加image标签的show-menu-by-longpress属性,可以长按识别名片/前往群聊/打开小程序.需要是小程序的二维码或者公众号的二维码,因为我们的二维码是一个第三方网站的,所以长按后 ...

  8. Android 扫描、生成、识别二维码、条码 一库搞定

    他来了,他来了,他带着YXing走来了. YXing 集成了CameraX + zxing, 简洁调用,功能完善,自定义扫码界面,再也不用像以前一样cv一堆冗余的Camera代码进项目了. 怎么集成: ...

  9. 微信长按图片无法弹出识别二维码选项解决方案

    1.首先页面中有两个二维码的兄弟别忙活了,一个页面中只可以识别其中一个二维码,两个的话需提示用户双击放大二维码进行二维码识别. 2.网页内有一张图片进行二维码识别时长按没有反应(长按图片无法弹出识别二 ...

  10. 树莓派python识别二维码_Zbar树莓派二维码(QR)识别(基于图片)

    注意:如果二维码太小的话,zbar是很难识别的,这也是我在公司解决的问题(不然随便调用下zbar就解决问题了,图像算法工程师就没有存在的必要了,下文虽然是一个通用的解决方案,但对一般识别应用场景来说是 ...

最新文章

  1. 微生物所科学家建成小鼠肠道微生物资源库
  2. 设计模式工作笔记-简单工厂场景与实现(针对接口编程的设计思想)
  3. export default 打包_贵阳【打包扣】价格
  4. PHP通过字符串调用函数
  5. 3.1EDA和数据描述: 探索性数据分析
  6. 推荐一个好用的百度文库在线免费下载文档网站
  7. 精通Javascript之引用
  8. 乘法鉴相器的matlab仿真,Matlab中基于dq变换的锁相环仿真研究
  9. 大学生活这样过,等着 Offer 飞来找 | 程序员有话说
  10. win10如何同时安装并使用多个版本的jdk
  11. 导线中电流分布和集肤深度
  12. 继承----有关虚函数和虚拟继承
  13. Centos7:网络设置+搜狗输入法安装
  14. ERP系统在元器件贸易企业中的应用
  15. 查看Android手机上的CellID等信息
  16. 计算机发展历史介绍英文版,计算机发展历史英文PPT The history of computer
  17. Spring MVC 请求处理过程。你这样回答保证通过面试!
  18. sdl+ffmpeg视频播放器
  19. 虚拟机下安装linux mysql weblogic过程
  20. 有关学习参与度的计算

热门文章

  1. 365天深度学习训练营-第P3周:天气识别
  2. 短视频运营的目标:引流并转化客户
  3. 结巴分词--关键词抽取
  4. 电脑上怎么看主板型号
  5. Let us learn English confidently
  6. 拳皇世界6月13服务器维护,拳皇世界闪退怎么办 对症下药马上好
  7. 北京高考零分作文(结尾太搞了)终于懂了什么叫笑喷了
  8. 我平时的一个学习方法
  9. 记录在训练深度学习算法过程中遇到的问题及解决办法。持续更新中....
  10. android维持登录状态