zhanzicong 5 年之前
父節點
當前提交
0853190a68
共有 44 個文件被更改,包括 1491 次插入0 次删除
  1. 8 0
      webview查看原图与长按保存/.gitignore
  2. 1 0
      webview查看原图与长按保存/.idea/.name
  3. 22 0
      webview查看原图与长按保存/.idea/compiler.xml
  4. 3 0
      webview查看原图与长按保存/.idea/copyright/profiles_settings.xml
  5. 6 0
      webview查看原图与长按保存/.idea/encodings.xml
  6. 23 0
      webview查看原图与长按保存/.idea/gradle.xml
  7. 46 0
      webview查看原图与长按保存/.idea/misc.xml
  8. 9 0
      webview查看原图与长按保存/.idea/modules.xml
  9. 12 0
      webview查看原图与长按保存/.idea/runConfigurations.xml
  10. 1 0
      webview查看原图与长按保存/app/.gitignore
  11. 31 0
      webview查看原图与长按保存/app/build.gradle
  12. 17 0
      webview查看原图与长按保存/app/proguard-rules.pro
  13. 13 0
      webview查看原图与长按保存/app/src/androidTest/java/com/itant/weblongclick/ApplicationTest.java
  14. 29 0
      webview查看原图与长按保存/app/src/main/AndroidManifest.xml
  15. 86 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/ItemLongClickedPopWindow.java
  16. 185 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/MainActivity.java
  17. 46 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/ShowImgActivity.java
  18. 72 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/imagezoom/HackyViewPager.java
  19. 71 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/imagezoom/ImageFragment.java
  20. 33 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/imagezoom/ImageViewPagerAdapter.java
  21. 35 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/utils/SizeUtil.java
  22. 326 0
      webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/utils/StringUtils.java
  23. 11 0
      webview查看原图与长按保存/app/src/main/res/layout/activity_common_showimg.xml
  24. 14 0
      webview查看原图与长按保存/app/src/main/res/layout/activity_main.xml
  25. 11 0
      webview查看原图与长按保存/app/src/main/res/layout/fragment_image.xml
  26. 31 0
      webview查看原图与长按保存/app/src/main/res/layout/list_item_longclicked_img.xml
  27. 二進制
      webview查看原图与长按保存/app/src/main/res/mipmap-hdpi/ic_launcher.png
  28. 二進制
      webview查看原图与长按保存/app/src/main/res/mipmap-mdpi/ic_launcher.png
  29. 二進制
      webview查看原图与长按保存/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  30. 二進制
      webview查看原图与长按保存/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  31. 二進制
      webview查看原图与长按保存/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  32. 6 0
      webview查看原图与长按保存/app/src/main/res/values-w820dp/dimens.xml
  33. 6 0
      webview查看原图与长按保存/app/src/main/res/values/colors.xml
  34. 5 0
      webview查看原图与长按保存/app/src/main/res/values/dimens.xml
  35. 3 0
      webview查看原图与长按保存/app/src/main/res/values/strings.xml
  36. 16 0
      webview查看原图与长按保存/app/src/main/res/values/styles.xml
  37. 15 0
      webview查看原图与长按保存/app/src/test/java/com/itant/weblongclick/ExampleUnitTest.java
  38. 23 0
      webview查看原图与长按保存/build.gradle
  39. 18 0
      webview查看原图与长按保存/gradle.properties
  40. 二進制
      webview查看原图与长按保存/gradle/wrapper/gradle-wrapper.jar
  41. 6 0
      webview查看原图与长按保存/gradle/wrapper/gradle-wrapper.properties
  42. 160 0
      webview查看原图与长按保存/gradlew
  43. 90 0
      webview查看原图与长按保存/gradlew.bat
  44. 1 0
      webview查看原图与长按保存/settings.gradle

+ 8 - 0
webview查看原图与长按保存/.gitignore

@@ -0,0 +1,8 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures

+ 1 - 0
webview查看原图与长按保存/.idea/.name

@@ -0,0 +1 @@
+WebLongClick2

+ 22 - 0
webview查看原图与长按保存/.idea/compiler.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+      <entry name="!?*.aj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>

+ 3 - 0
webview查看原图与长按保存/.idea/copyright/profiles_settings.xml

@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="" />
+</component>

+ 6 - 0
webview查看原图与长按保存/.idea/encodings.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="PROJECT" charset="UTF-8" />
+  </component>
+</project>

+ 23 - 0
webview查看原图与长按保存/.idea/gradle.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+          </set>
+        </option>
+        <option name="myModules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 46 - 0
webview查看原图与长按保存/.idea/misc.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="NullableNotNullManager">
+    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
+    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
+    <option name="myNullables">
+      <value>
+        <list size="4">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+        </list>
+      </value>
+    </option>
+    <option name="myNotNulls">
+      <value>
+        <list size="4">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+        </list>
+      </value>
+    </option>
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>

+ 9 - 0
webview查看原图与长按保存/.idea/modules.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/WebLongClick2.iml" filepath="$PROJECT_DIR$/WebLongClick2.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
+    </modules>
+  </component>
+</project>

+ 12 - 0
webview查看原图与长按保存/.idea/runConfigurations.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>

+ 1 - 0
webview查看原图与长按保存/app/.gitignore

@@ -0,0 +1 @@
+/build

+ 31 - 0
webview查看原图与长按保存/app/build.gradle

@@ -0,0 +1,31 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 25
+    buildToolsVersion "25.0.0"
+
+    defaultConfig {
+        applicationId "com.itant.weblongclick"
+        minSdkVersion 15
+        targetSdkVersion 25
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    testCompile 'junit:junit:4.12'
+    compile 'com.android.support:appcompat-v7:25.1.0'
+
+    // 图片查看
+    compile 'com.commit451:PhotoView:1.2.4'
+    // 图片加载框架
+    compile 'com.github.bumptech.glide:glide:3.7.0'
+}

+ 17 - 0
webview查看原图与长按保存/app/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\assdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 13 - 0
webview查看原图与长按保存/app/src/androidTest/java/com/itant/weblongclick/ApplicationTest.java

@@ -0,0 +1,13 @@
+package com.itant.weblongclick;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+    public ApplicationTest() {
+        super(Application.class);
+    }
+}

+ 29 - 0
webview查看原图与长按保存/app/src/main/AndroidManifest.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.itant.weblongclick">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <!-- 照片涉及到文件读写 -->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity android:name=".MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".ShowImgActivity"
+            android:theme="@style/NotitleTheme"/>
+    </application>
+
+</manifest>

+ 86 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/ItemLongClickedPopWindow.java

@@ -0,0 +1,86 @@
+package com.itant.weblongclick;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.PopupWindow;
+
+/**
+ * author:Geoffery Sun
+ * time:2016/12/25 16:27
+ * desc:
+ * version:0.0.1
+ */
+public class ItemLongClickedPopWindow extends PopupWindow {
+    /**
+     * 书签条目弹出菜单 * @value * {@value} *
+     */
+    public static final int FAVORITES_ITEM_POPUPWINDOW = 0;
+    /**
+     * 书签页面弹出菜单 * @value * {@value} *
+     */
+    public static final int FAVORITES_VIEW_POPUPWINDOW = 1;
+    /**
+     * 历史条目弹出菜单 * @value * {@value} *
+     */
+    public static final int HISTORY_ITEM_POPUPWINDOW = 3;
+    /**
+     * 历史页面弹出菜单 * @value * {@value} *
+     */
+    public static final int HISTORY_VIEW_POPUPWINDOW = 4;
+    /**
+     * 图片项目弹出菜单 * @value * {@value} *
+     */
+    public static final int IMAGE_VIEW_POPUPWINDOW = 5;
+    /**
+     * 超链接项目弹出菜单 * @value * {@value} *
+     */
+    public static final int ACHOR_VIEW_POPUPWINDOW = 6;
+    private LayoutInflater itemLongClickedPopWindowInflater;
+    private View itemLongClickedPopWindowView;
+    private Context context;
+    private int type;
+
+    /**
+     * 构造函数 * @param context 上下文 * @param width 宽度 * @param height 高度 *
+     */
+    public ItemLongClickedPopWindow(Context context, int type, int width, int height) {
+        super(context);
+        this.context = context;
+        this.type = type;
+        //创建
+        this.initTab();
+        //设置默认选项
+        setWidth(width);
+        setHeight(height);
+        setContentView(this.itemLongClickedPopWindowView);
+        setOutsideTouchable(true);
+        setFocusable(true);
+    }
+
+    //实例化
+    private void initTab() {
+        this.itemLongClickedPopWindowInflater = LayoutInflater.from(this.context);
+        switch (type) {
+//            case FAVORITES_ITEM_POPUPWINDOW:
+//                this.itemLongClickedPopWindowView = this.itemLongClickedPopWindowInflater.inflate(R.layout.list_item_longclicked_favorites, null);
+//                break;
+//            case FAVORITES_VIEW_POPUPWINDOW: //对于书签内容弹出菜单,未作处理
+//                break;
+//            case HISTORY_ITEM_POPUPWINDOW:
+//                this.itemLongClickedPopWindowView = this.itemLongClickedPopWindowInflater.inflate(R.layout.list_item_longclicked_history, null);
+//                break;
+//            case HISTORY_VIEW_POPUPWINDOW: //对于历史内容弹出菜单,未作处理
+//                break;
+//            case ACHOR_VIEW_POPUPWINDOW: //超链接
+//               break;
+            case IMAGE_VIEW_POPUPWINDOW: //图片
+                this.itemLongClickedPopWindowView = this.itemLongClickedPopWindowInflater.inflate(R.layout.list_item_longclicked_img, null);
+                break;
+        }
+    }
+
+    public View getView(int id) {
+        return this.itemLongClickedPopWindowView.findViewById(id);
+    }
+}

+ 185 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/MainActivity.java

@@ -0,0 +1,185 @@
+package com.itant.weblongclick;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.widget.Toast;
+
+import com.itant.weblongclick.utils.SizeUtil;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Date;
+
+
+public class MainActivity extends AppCompatActivity {
+    private String mUrl = "http://zhan.renren.com/hdwallpapers?from=template&checked=true";
+    private Context mContext;
+    private WebView mWebView;
+    // 长按查看图片
+    private ItemLongClickedPopWindow itemLongClickedPopWindow;
+    // 手指触发屏幕的坐标
+    private int downX, downY;
+    // 需要保存图片的路径
+    private String saveImgUrl = "";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        mContext = this;
+
+        mWebView = (WebView) findViewById(R.id.webview);
+
+        WebSettings webSettings = mWebView.getSettings();
+        webSettings.setJavaScriptEnabled(true);
+        webSettings.setSupportZoom(false);
+        webSettings.setAppCacheEnabled(true);
+        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+        webSettings.setAllowFileAccess(true);// 设置允许访问文件数据
+        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
+        webSettings.setDomStorageEnabled(true);
+        webSettings.setDatabaseEnabled(true);
+        webSettings.setGeolocationEnabled(true);
+
+        mWebView.setOnTouchListener(listener);
+
+        mWebView.setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                WebView.HitTestResult result = ((WebView)v).getHitTestResult();
+                if (null == result)
+                    return false;
+                int type = result.getType();
+                if (type == WebView.HitTestResult.UNKNOWN_TYPE)
+                    return false;
+                if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
+
+                }
+
+                itemLongClickedPopWindow = new ItemLongClickedPopWindow(MainActivity.this,
+                        ItemLongClickedPopWindow.IMAGE_VIEW_POPUPWINDOW,
+                        SizeUtil.dp2px(mContext, 120), SizeUtil.dp2px(mContext, 90));
+
+                switch (type) {
+                    case WebView.HitTestResult.PHONE_TYPE: // 处理拨号
+                        break;
+                    case WebView.HitTestResult.EMAIL_TYPE: // 处理Email
+                        break;
+                    case WebView.HitTestResult.GEO_TYPE: // TODO
+                        break;
+                    case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超链接
+                        break;
+                    case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
+                        break;
+                    case WebView.HitTestResult.IMAGE_TYPE: // 处理长按图片的菜单项
+                        // 获取图片的路径
+                        saveImgUrl = result.getExtra();
+                        //通过GestureDetector获取按下的位置,来定位PopWindow显示的位置
+                        itemLongClickedPopWindow.showAtLocation(v, Gravity.TOP| Gravity.LEFT, downX, downY + 10);
+                        break;
+                    default:
+                        break;
+                }
+
+                itemLongClickedPopWindow.getView(R.id.item_longclicked_viewImage)
+                        .setOnClickListener(new View.OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+                                itemLongClickedPopWindow.dismiss();
+                                Intent intent = new Intent(mContext, ShowImgActivity.class);
+                                intent.putExtra("info", saveImgUrl);
+                                startActivity(intent);
+                            }
+                        });
+                itemLongClickedPopWindow.getView(R.id.item_longclicked_saveImage)
+                        .setOnClickListener(new View.OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+                                itemLongClickedPopWindow.dismiss();
+                                new SaveImage().execute(); // Android 4.0以后要使用线程来访问网络
+                            }
+                        });
+                return true;
+            }
+        });
+
+        // 加载页面
+        mWebView.loadUrl(mUrl);
+    }
+
+    View.OnTouchListener listener = new View.OnTouchListener() {
+
+        @Override
+        public boolean onTouch(View arg0, MotionEvent arg1) {
+            downX = (int) arg1.getX();
+            downY = (int) arg1.getY();
+            return false;
+        }
+    };
+
+    /***
+     * 功能:用线程保存图片
+     *
+     * @author wangyp
+     */
+    private class SaveImage extends AsyncTask<String, Void, String> {
+        @Override
+        protected String doInBackground(String... params) {
+            String result = "";
+            try {
+                String sdcard = Environment.getExternalStorageDirectory().toString();
+                File file = new File(sdcard + "/Download");
+                if (!file.exists()) {
+                    file.mkdirs();
+                }
+                int idx = saveImgUrl.lastIndexOf(".");
+                String ext = saveImgUrl.substring(idx);
+                file = new File(sdcard + "/Download/" + new Date().getTime() + ext);
+                InputStream inputStream = null;
+                URL url = new URL(saveImgUrl);
+                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+                conn.setRequestMethod("GET");
+                conn.setConnectTimeout(20000);
+                if (conn.getResponseCode() == 200) {
+                    inputStream = conn.getInputStream();
+                }
+                byte[] buffer = new byte[4096];
+                int len = 0;
+                FileOutputStream outStream = new FileOutputStream(file);
+                while ((len = inputStream.read(buffer)) != -1) {
+                    outStream.write(buffer, 0, len);
+                }
+                outStream.close();
+                result = "图片已保存至:" + file.getAbsolutePath();
+
+                Intent localIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
+                final Uri localUri = Uri.fromFile(file);
+                localIntent.setData(localUri);
+                sendBroadcast(localIntent);
+            } catch (Exception e) {
+                result = "保存失败!" + e.getLocalizedMessage();
+            }
+            return result;
+        }
+
+        @Override
+        protected void onPostExecute(String result) {
+            Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
+        }
+    }
+}

+ 46 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/ShowImgActivity.java

@@ -0,0 +1,46 @@
+package com.itant.weblongclick;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import com.itant.weblongclick.imagezoom.HackyViewPager;
+import com.itant.weblongclick.imagezoom.ImageViewPagerAdapter;
+import com.itant.weblongclick.utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * author:Geoffery Sun
+ * time:2016/12/25 18:37
+ * desc:
+ * version:0.0.1
+ */
+public class ShowImgActivity extends AppCompatActivity {
+    ImageViewPagerAdapter adapter;
+    HackyViewPager pager;
+    private List<String> mList = new ArrayList<>();
+    String mInfo = "";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_common_showimg);
+
+        Bundle bundle = getIntent().getExtras();
+        if (bundle != null) {
+            if (bundle.containsKey("info")) {
+                mInfo = bundle.getString("info");
+            }
+        }
+
+        if (StringUtils.isEmpty(mInfo)) {
+            finish();
+        } else {
+            pager = (HackyViewPager) findViewById(R.id.pager);
+            mList.add(mInfo);
+            adapter = new ImageViewPagerAdapter(getSupportFragmentManager(), mList);
+            pager.setAdapter(adapter);
+        }
+    }
+}

+ 72 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/imagezoom/HackyViewPager.java

@@ -0,0 +1,72 @@
+package com.itant.weblongclick.imagezoom;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/**
+ * Found at http://stackoverflow.com/questions/7814017/is-it-possible-to-disable-scrolling-on-a-viewpager.
+ * Convenient way to temporarily disable ViewPager navigation while interacting with ImageView.
+ * 
+ * Julia Zudikova
+ */
+
+/**
+ * Hacky fix for Issue #4 and
+ * http://code.google.com/p/android/issues/detail?id=18990
+ * <p/>
+ * ScaleGestureDetector seems to mess up the touch events, which means that
+ * ViewGroups which make use of onInterceptTouchEvent throw a lot of
+ * IllegalArgumentException: pointerIndex out of range.
+ * <p/>
+ * There's not much I can do in my code for now, but we can mask the result by
+ * just catching the problem and ignoring it.
+ *
+ * @author Chris Banes
+ */
+public class HackyViewPager extends ViewPager {
+
+	private boolean isLocked;
+	
+    public HackyViewPager(Context context) {
+        super(context);
+        isLocked = false;
+    }
+
+    public HackyViewPager(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        isLocked = false;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+    	if (!isLocked) {
+	        try {
+	            return super.onInterceptTouchEvent(ev);
+	        } catch (IllegalArgumentException e) {
+	            e.printStackTrace();
+	            return false;
+	        }
+    	}
+    	return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        return !isLocked && super.onTouchEvent(event);
+    }
+    
+	public void toggleLock() {
+		isLocked = !isLocked;
+	}
+
+	public void setLocked(boolean isLocked) {
+		this.isLocked = isLocked;
+	}
+
+	public boolean isLocked() {
+		return isLocked;
+	}
+	
+}

+ 71 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/imagezoom/ImageFragment.java

@@ -0,0 +1,71 @@
+package com.itant.weblongclick.imagezoom;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.bumptech.glide.Glide;
+import com.itant.weblongclick.R;
+
+import uk.co.senab.photoview.PhotoView;
+
+public class ImageFragment extends Fragment {
+
+
+    private static final String IMAGE_URL = "image";
+    PhotoView image;
+    private String imageUrl;
+
+    public ImageFragment() {
+        // Required empty public constructor
+    }
+
+    public static ImageFragment newInstance(String param1) {
+        ImageFragment fragment = new ImageFragment();
+        Bundle args = new Bundle();
+        args.putString(IMAGE_URL, param1);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (getArguments() != null) {
+            imageUrl = getArguments().getString(IMAGE_URL);
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.fragment_image, container, false);
+        image = (PhotoView) view.findViewById(R.id.image);
+        Glide.with(getContext()).load(imageUrl).into(image);
+        return view;
+    }
+
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+    }
+
+//    public interface OnFragmentInteractionListener {
+//        // TODO: Update argument type and name
+//        void onFragmentInteraction(Uri uri);
+//    }
+}

+ 33 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/imagezoom/ImageViewPagerAdapter.java

@@ -0,0 +1,33 @@
+package com.itant.weblongclick.imagezoom;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+
+import java.util.List;
+
+/**
+ * Created by csonezp on 15-12-28.
+ */
+public class ImageViewPagerAdapter extends FragmentStatePagerAdapter {
+    private static final String IMAGE_URL = "image";
+
+    List<String> mDatas;
+
+    public ImageViewPagerAdapter(FragmentManager fm, List data) {
+        super(fm);
+        mDatas = data;
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        String url = mDatas.get(position);
+        Fragment fragment = ImageFragment.newInstance(url);
+        return fragment;
+    }
+
+    @Override
+    public int getCount() {
+        return mDatas.size();
+    }
+}

+ 35 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/utils/SizeUtil.java

@@ -0,0 +1,35 @@
+package com.itant.weblongclick.utils;
+
+import android.content.Context;
+import android.util.TypedValue;
+
+/**
+ * 尺寸转换工具类
+ * Created by Brioal on 2016/7/21.
+ */
+
+public class SizeUtil {
+    //dp转px
+    public static int dp2px(Context ctx, int dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+                ctx.getResources().getDisplayMetrics());
+    }
+
+    //px转dp
+    public static int px2dp(Context ctx, int px) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,
+                ctx.getResources().getDisplayMetrics());
+    }
+
+    //sp转px
+    public static int sp2px(Context ctx, int sp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
+                ctx.getResources().getDisplayMetrics());
+    }
+
+    //px转sp
+    public static int px2sp(Context ctx, int px) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,
+                ctx.getResources().getDisplayMetrics());
+    }
+}

+ 326 - 0
webview查看原图与长按保存/app/src/main/java/com/itant/weblongclick/utils/StringUtils.java

@@ -0,0 +1,326 @@
+package com.itant.weblongclick.utils;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * <pre>
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2016/8/16
+ *     desc  : 字符串相关工具类
+ * </pre>
+ */
+public class StringUtils {
+
+    private StringUtils() {
+        throw new UnsupportedOperationException("u can't fuck me...");
+    }
+
+    /**
+     * 判断字符串是否为null或长度为0
+     *
+     * @param s 待校验字符串
+     * @return {@code true}: 空<br> {@code false}: 不为空
+     */
+    public static boolean isEmpty(CharSequence s) {
+        return s == null || s.length() == 0;
+    }
+
+    /**
+     * 判断字符串是否为null或全为空格
+     *
+     * @param s 待校验字符串
+     * @return {@code true}: null或全空格<br> {@code false}: 不为null且不全空格
+     */
+    public static boolean isSpace(String s) {
+        return (s == null || s.trim().length() == 0);
+    }
+
+    /**
+     * null转为长度为0的字符串
+     *
+     * @param s 待转字符串
+     * @return s为null转为长度为0字符串,否则不改变
+     */
+    public static String null2Length0(String s) {
+        return s == null ? "" : s;
+    }
+
+    /**
+     * 返回字符串长度
+     *
+     * @param s 字符串
+     * @return null返回0,其他返回自身长度
+     */
+    public static int length(CharSequence s) {
+        return s == null ? 0 : s.length();
+    }
+
+    /**
+     * 首字母大写
+     *
+     * @param s 待转字符串
+     * @return 首字母大写字符串
+     */
+    public static String upperFirstLetter(String s) {
+        if (isEmpty(s) || !Character.isLowerCase(s.charAt(0))) {
+            return s;
+        }
+        return String.valueOf((char) (s.charAt(0) - 32)) + s.substring(1);
+    }
+
+    /**
+     * 首字母小写
+     *
+     * @param s 待转字符串
+     * @return 首字母小写字符串
+     */
+    public static String lowerFirstLetter(String s) {
+        if (isEmpty(s) || !Character.isUpperCase(s.charAt(0))) {
+            return s;
+        }
+        return String.valueOf((char) (s.charAt(0) + 32)) + s.substring(1);
+    }
+
+    /**
+     * 反转字符串
+     *
+     * @param s 待反转字符串
+     * @return 反转字符串
+     */
+    public static String reverse(String s) {
+        int len = length(s);
+        if (len <= 1) return s;
+        int mid = len >> 1;
+        char[] chars = s.toCharArray();
+        char c;
+        for (int i = 0; i < mid; ++i) {
+            c = chars[i];
+            chars[i] = chars[len - i - 1];
+            chars[len - i - 1] = c;
+        }
+        return new String(chars);
+    }
+
+    /**
+     * 转化为半角字符
+     *
+     * @param s 待转字符串
+     * @return 半角字符串
+     */
+    public static String toDBC(String s) {
+        if (isEmpty(s)) {
+            return s;
+        }
+        char[] chars = s.toCharArray();
+        for (int i = 0, len = chars.length; i < len; i++) {
+            if (chars[i] == 12288) {
+                chars[i] = ' ';
+            } else if (65281 <= chars[i] && chars[i] <= 65374) {
+                chars[i] = (char) (chars[i] - 65248);
+            } else {
+                chars[i] = chars[i];
+            }
+        }
+        return new String(chars);
+    }
+
+    /**
+     * 转化为全角字符
+     *
+     * @param s 待转字符串
+     * @return 全角字符串
+     */
+    public static String toSBC(String s) {
+        if (isEmpty(s)) {
+            return s;
+        }
+        char[] chars = s.toCharArray();
+        for (int i = 0, len = chars.length; i < len; i++) {
+            if (chars[i] == ' ') {
+                chars[i] = (char) 12288;
+            } else if (33 <= chars[i] && chars[i] <= 126) {
+                chars[i] = (char) (chars[i] + 65248);
+            } else {
+                chars[i] = chars[i];
+            }
+        }
+        return new String(chars);
+    }
+
+    private static int[] pyValue = new int[]{-20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242,
+            -20230, -20051, -20036, -20032,
+            -20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751,
+            -19746, -19741, -19739, -19728,
+            -19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281,
+            -19275, -19270, -19263, -19261,
+            -19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, -19006,
+            -19003, -18996, -18977, -18961,
+            -18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, -18697, -18696,
+            -18526, -18518, -18501, -18490,
+            -18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, -18201, -18184, -18183,
+            -18181, -18012, -17997, -17988,
+            -17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, -17752, -17733, -17730, -17721,
+            -17703, -17701, -17697, -17692,
+            -17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, -17427, -17417, -17202, -17185, -16983,
+            -16970, -16942, -16915, -16733,
+            -16708, -16706, -16689, -16664, -16657, -16647, -16474, -16470, -16465, -16459, -16452, -16448, -16433,
+            -16429, -16427, -16423, -16419,
+            -16412, -16407, -16403, -16401, -16393, -16220, -16216, -16212, -16205, -16202, -16187, -16180, -16171,
+            -16169, -16158, -16155, -15959,
+            -15958, -15944, -15933, -15920, -15915, -15903, -15889, -15878, -15707, -15701, -15681, -15667, -15661,
+            -15659, -15652, -15640, -15631,
+            -15625, -15454, -15448, -15436, -15435, -15419, -15416, -15408, -15394, -15385, -15377, -15375, -15369,
+            -15363, -15362, -15183, -15180,
+            -15165, -15158, -15153, -15150, -15149, -15144, -15143, -15141, -15140, -15139, -15128, -15121, -15119,
+            -15117, -15110, -15109, -14941,
+            -14937, -14933, -14930, -14929, -14928, -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889,
+            -14882, -14873, -14871, -14857,
+            -14678, -14674, -14670, -14668, -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384,
+            -14379, -14368, -14355, -14353,
+            -14345, -14170, -14159, -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112,
+            -14109, -14099, -14097, -14094,
+            -14092, -14090, -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878,
+            -13870, -13859, -13847, -13831,
+            -13658, -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359,
+            -13356, -13343, -13340, -13329,
+            -13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060,
+            -12888, -12875, -12871, -12860,
+            -12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, -12556,
+            -12359, -12346, -12320, -12300,
+            -12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, -11798, -11781,
+            -11604, -11589, -11536, -11358,
+            -11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, -11041, -11038, -11024,
+            -11020, -11019, -11018, -11014,
+            -10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, -10533, -10519, -10331, -10329,
+            -10328, -10322, -10315, -10309,
+            -10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, -10254};
+
+    private static String[] pyStr = new String[]{"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao",
+            "bei", "ben", "beng", "bi", "bian",
+            "biao", "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai",
+            "chan", "chang", "chao", "che",
+            "chen", "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci",
+            "cong", "cou", "cu", "cuan",
+            "cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die",
+            "ding", "diu", "dong", "dou", "du",
+            "duan", "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou",
+            "fu", "ga", "gai", "gan", "gang",
+            "gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun",
+            "guo", "ha", "hai", "han", "hang",
+            "hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun",
+            "huo", "ji", "jia", "jian",
+            "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan",
+            "kang", "kao", "ke", "ken",
+            "keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan",
+            "lang", "lao", "le", "lei", "leng",
+            "li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan",
+            "lue", "lun", "luo", "ma", "mai",
+            "man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu",
+            "mo", "mou", "mu", "na", "nai",
+            "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", "ning",
+            "niu", "nong", "nu", "nv", "nuan",
+            "nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", "pian", "piao",
+            "pie", "pin", "ping", "po", "pu",
+            "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", "quan", "que", "qun",
+            "ran", "rang", "rao", "re",
+            "ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao",
+            "se", "sen", "seng", "sha",
+            "shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan",
+            "shuang", "shui", "shun",
+            "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te",
+            "teng", "ti", "tian", "tiao",
+            "tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", "wang", "wei",
+            "wen", "weng", "wo", "wu", "xi",
+            "xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya",
+            "yan", "yang", "yao", "ye", "yi",
+            "yin", "ying", "yo", "yong", "you", "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze",
+            "zei", "zen", "zeng", "zha",
+            "zhai", "zhan", "zhang", "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai",
+            "zhuan", "zhuang", "zhui",
+            "zhun", "zhuo", "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo"};
+
+    /**
+     * 单个汉字转成ASCII码
+     *
+     * @param s 单个汉字字符串
+     * @return 如果字符串长度是1返回的是对应的ascii码,否则返回-1
+     */
+    private static int oneCn2ASCII(String s) {
+        if (s.length() != 1) return -1;
+        int ascii = 0;
+        try {
+            byte[] bytes = s.getBytes("GB2312");
+            if (bytes.length == 1) {
+                ascii = bytes[0];
+            } else if (bytes.length == 2) {
+                int highByte = 256 + bytes[0];
+                int lowByte = 256 + bytes[1];
+                ascii = (256 * highByte + lowByte) - 256 * 256;
+            } else {
+                throw new IllegalArgumentException("Illegal resource string");
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return ascii;
+    }
+
+    /**
+     * 单个汉字转成拼音
+     *
+     * @param s 单个汉字字符串
+     * @return 如果字符串长度是1返回的是对应的拼音,否则返回{@code null}
+     */
+    private static String oneCn2PY(String s) {
+        int ascii = oneCn2ASCII(s);
+        if (ascii == -1) return null;
+        String ret = null;
+        if (0 <= ascii && ascii <= 127) {
+            ret = String.valueOf((char) ascii);
+        } else {
+            for (int i = pyValue.length - 1; i >= 0; i--) {
+                if (pyValue[i] <= ascii) {
+                    ret = pyStr[i];
+                    break;
+                }
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * 获得第一个汉字首字母
+     *
+     * @param s 单个汉字字符串
+     * @return 拼音
+     */
+    public static String getPYFirstLetter(String s) {
+        if (isSpace(s)) return "";
+        String first, py;
+        first = s.substring(0, 1);
+        py = oneCn2PY(first);
+        if (py == null) return null;
+        return py.substring(0, 1);
+    }
+
+    /**
+     * 中文转拼音
+     *
+     * @param s 汉字字符串
+     * @return 拼音
+     */
+    public static String cn2PY(String s) {
+        String hz, py;
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < s.length(); i++) {
+            hz = s.substring(i, i + 1);
+            py = oneCn2PY(hz);
+            if (py == null) {
+                py = "?";
+            }
+            sb.append(py);
+        }
+        return sb.toString();
+    }
+}

+ 11 - 0
webview查看原图与长按保存/app/src/main/res/layout/activity_common_showimg.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+    <com.itant.weblongclick.imagezoom.HackyViewPager
+        android:id="@+id/pager"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
+</RelativeLayout>

+ 14 - 0
webview查看原图与长按保存/app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/activity_main"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="sun.geofferysun.weblongclick.MainActivity">
+
+    <WebView
+        android:id="@+id/webview"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</RelativeLayout>

+ 11 - 0
webview查看原图与长按保存/app/src/main/res/layout/fragment_image.xml

@@ -0,0 +1,11 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent">
+
+    <uk.co.senab.photoview.PhotoView
+        android:id="@+id/image"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        />
+
+</FrameLayout>

+ 31 - 0
webview查看原图与长按保存/app/src/main/res/layout/list_item_longclicked_img.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:layout_margin="5dp"
+              android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/item_longclicked_viewImage"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:gravity="center"
+        android:text="查看图片"
+        android:textColor="@android:color/white"
+        android:textSize="16sp"/>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#cccccc"/>
+
+    <TextView
+        android:id="@+id/item_longclicked_saveImage"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:gravity="center"
+        android:text="保存图片"
+        android:textColor="@android:color/white"
+        android:textSize="16sp"/>
+
+</LinearLayout>

二進制
webview查看原图与长按保存/app/src/main/res/mipmap-hdpi/ic_launcher.png


二進制
webview查看原图与长按保存/app/src/main/res/mipmap-mdpi/ic_launcher.png


二進制
webview查看原图与长按保存/app/src/main/res/mipmap-xhdpi/ic_launcher.png


二進制
webview查看原图与长按保存/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


二進制
webview查看原图与长按保存/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 6 - 0
webview查看原图与长按保存/app/src/main/res/values-w820dp/dimens.xml

@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>

+ 6 - 0
webview查看原图与长按保存/app/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>

+ 5 - 0
webview查看原图与长按保存/app/src/main/res/values/dimens.xml

@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>

+ 3 - 0
webview查看原图与长按保存/app/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">WebLongClick</string>
+</resources>

+ 16 - 0
webview查看原图与长按保存/app/src/main/res/values/styles.xml

@@ -0,0 +1,16 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+    <style name="NotitleTheme" parent="Theme.AppCompat.NoActionBar">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+    </style>
+
+</resources>

+ 15 - 0
webview查看原图与长按保存/app/src/test/java/com/itant/weblongclick/ExampleUnitTest.java

@@ -0,0 +1,15 @@
+package com.itant.weblongclick;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * To work on unit tests, switch the Test Artifact in the Build Variants view.
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() throws Exception {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 23 - 0
webview查看原图与长按保存/build.gradle

@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:2.1.2'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 18 - 0
webview查看原图与长按保存/gradle.properties

@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true

二進制
webview查看原图与长按保存/gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
webview查看原图与长按保存/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Mon Dec 28 10:00:20 PST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

+ 160 - 0
webview查看原图与长按保存/gradlew

@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
webview查看原图与长按保存/gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
webview查看原图与长按保存/settings.gradle

@@ -0,0 +1 @@
+include ':app'