关于android:Android入门教程-WebView-二

34次阅读

共计 5299 个字符,预计需要花费 14 分钟才能阅读完成。

自定义长按文字弹出的菜单

长按 WebView 中的文字,会有抉择光标,并且弹出一个小菜单。个别菜单里会有「复制」,「搜寻」等等选项。

这个菜单能够由开发者自定义。让弹出的菜单显示其余选项。比方弹出「复制」「翻译」。

个别步骤:

  • 设计监听器
  • 自定义 WebView,复写办法
  • 定义 Js 接口

须要新建 2 个 Java 文件,WebChooseActionListenerCustomClickWebView

定义监听器

监听器 WebChooseActionListener,用来传输用户的抉择。

public interface WebChooseActionListener {

    /**
     * @param itemTitle 选项的题目
     * @param txt       选中的文字
     */
    void onChosen(String itemTitle, String txt);
}

txt是用户在 WebView 上选中的文字。如何获取到选中的文字呢?本例中用 js 办法来获取。

自定义 WebView

js 和 Java 的交互

定义 CustomJsInterface (本例中把它放在了 CustomClickWebView 里),其中给 chooseAction 增加注解 @JavascriptInterface,将其定义为沟通的桥梁。js 中会调用这个 chooseAction 办法。

为了获取用户在 WebView 上选中的文字,须要执行 js 代码,参考 exeSelectTextJs 办法。js 代码中的RFJSInterface,和 Java 中addJavascriptInterface 传入的名字必须统一。

addJavascriptInterface(new CustomJsInterface(this), "RFJSInterface");

js 代码中 "RFJSInterface.chooseAction(txt,title);" 就是在调用 Java 中定义的办法。

管制菜单

想要管制 WebView 中弹出的菜单,须要复写 startActionMode 办法,把默认的菜单替换成自定义的菜单。调用 Menu.add() 办法增加选项。

自定义的菜单选项,从里面传进来。

@Override
public ActionMode startActionMode(ActionMode.Callback callback) {ActionMode actionMode = super.startActionMode(callback);
    return resolveActionMode(actionMode);
}

@Override
public ActionMode startActionMode(ActionMode.Callback callback, int type) {ActionMode actionMode = super.startActionMode(callback, type);
    return resolveActionMode(actionMode);
}

private ActionMode resolveActionMode(ActionMode actionMode) {if (actionMode != null) {final Menu menu = actionMode.getMenu();
        mCurActionMode = actionMode;
        menu.clear();
        for (int i = 0; i < mMenuItemNameList.size(); i++) {menu.add(mMenuItemNameList.get(i));
        }
        for (int i = 0; i < menu.size(); i++) {MenuItem menuItem = menu.getItem(i);
            menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {exeSelectTextJs((String) item.getTitle());
                    releaseAction();
                    return true;
                }
            });
        }
    }
    mCurActionMode = actionMode;
    return actionMode;
}

CustomClickWebView 代码:

import android.content.Context;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import java.util.ArrayList;
import java.util.List;

public class CustomClickWebView extends WebView {
    private ActionMode mCurActionMode;
    private List<String> mMenuItemNameList = new ArrayList<>();
    private WebChooseActionListener mWebChooseActionListener;

    public CustomClickWebView(Context context) {super(context);
    }

    public CustomClickWebView(Context context, AttributeSet attrs) {super(context, attrs);
    }

    public CustomClickWebView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback) {ActionMode actionMode = super.startActionMode(callback);
        return resolveActionMode(actionMode);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type) {ActionMode actionMode = super.startActionMode(callback, type);
        return resolveActionMode(actionMode);
    }

    private ActionMode resolveActionMode(ActionMode actionMode) {if (actionMode != null) {final Menu menu = actionMode.getMenu();
            mCurActionMode = actionMode;
            menu.clear();
            for (int i = 0; i < mMenuItemNameList.size(); i++) {menu.add(mMenuItemNameList.get(i));
            }
            for (int i = 0; i < menu.size(); i++) {MenuItem menuItem = menu.getItem(i);
                menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {exeSelectTextJs((String) item.getTitle());
                        releaseAction();
                        return true;
                    }
                });
            }
        }
        mCurActionMode = actionMode;
        return actionMode;
    }

    private void releaseAction() {if (mCurActionMode != null) {mCurActionMode.finish();
            mCurActionMode = null;
        }
    }

    private void exeSelectTextJs(String title) {String js = "(function getSelectedText() {" +
                "var txt;" +
                "var title = \"" + title + "\";"+"if (window.getSelection) {"+"txt = window.getSelection().toString();"+"} else if (window.document.getSelection) {"+"txt = window.document.getSelection().toString();"+"} else if (window.document.selection) {"+"txt = window.document.selection.createRange().text;"+"}"+"RFJSInterface.chooseAction(txt,title);"+"})()";
        evaluateJavascript("javascript:" + js, null);
    }

    /**
     * 在内部调用
     */
    public void linkJSInterface() {addJavascriptInterface(new CustomJsInterface(this), "RFJSInterface");
    }

    /**
     * @param actionList 弹出菜单
     */
    public void setActionList(List<String> actionList) {mMenuItemNameList = actionList;}

    public void setActionSelectListener(WebChooseActionListener webChooseActionListener) {this.mWebChooseActionListener = webChooseActionListener;}

    /**
     * 暗藏隐没 Action
     */
    public void dismissAction() {releaseAction();
    }

    /**
     * js 选中的回掉接口
     */
    private class CustomJsInterface {

        CustomClickWebView webView;

        CustomJsInterface(CustomClickWebView c) {webView = c;}

        /**
         * @param value 选中的文字
         * @param title 菜单题目
         */
        @JavascriptInterface
        public void chooseAction(final String value, final String title) {if (mWebChooseActionListener != null) {mWebChooseActionListener.onChosen(title, value);
            }
        }
    }
}

应用

layout 中应用这个 CustomClickWebView

<com.rustfisher.tutorial2020.web.longmenu.CustomClickWebView
    android:id="@+id/web1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Activity 中进行初始化配置

mWv1.getSettings().setJavaScriptEnabled(true);   // 容许应用 js
mWv1.setActionList(Arrays.asList("复制", "翻译"));// 自定义菜单选项
mWv1.getSettings().setBlockNetworkImage(false);
mWv1.linkJSInterface(); // 把 js 接口增加进去

// 设置监听器,获取点击到的菜单和选中的文字
mWv1.setActionSelectListener(new WebChooseActionListener() {
    @Override
    public void onChosen(String title, String selectText) {Toast.makeText(getApplicationContext(), "(" + title + ") ->" + selectText, Toast.LENGTH_SHORT).show();}
});

(重写 startActionMode 的做法在 x5 WebView 上并不起作用。)

【Android 零根底入门教程视频参考】

正文完
 0