将Android弹出菜单定位到Web视图中的html元素

时间:2016-11-26 20:09:28

标签: android android-webview popupmenu

我的Android应用中有一些带有一些按钮的网页视图。当使用按下其中一个按钮时,我想呈现一个定位到该HTML按钮的PopupMenu。

我使用addJavascriptInterface从Web视图回传到java代码,我还发送HTML元素相对于Web视图左上角的位置。

现在我想将PopupMenu定位在这个位置。我有什么选择? PopupMenu易于使用,但似乎不容易定位。 PopupWindows很容易定位,但却很难用作菜单。

我还创建了一个覆盖Web视图中位置的临时视图,并从此位置创建了PopupMenu。视图位于正确的位置,但PopupMenu仍然显示在活动的左上角。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

如果有人想知道,这是一个粗略的工作解决方案。页面中的元素左边距为30%。将内容滚动到视图后,您点按txt中的WebView div元素,PopupWindow将显示元素相对于WebView的位置。< / p>

的src /主/ your.package / MainActivity.java:

这会将javascript界面​​附加到名为“Android”的WebView。

public class MainActivity extends AppCompatActivity {

    private WebView webview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webview = (WebView) findViewById(R.id.webview);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.addJavascriptInterface(new MyJavaScriptInterface(this), "Android");

        try {
            String content = new Scanner(getAssets().open("sample.html")).useDelimiter("\\A").next();
            webview.loadData(content, "text/html", null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void managePopup(int px, int py) {
        View view = MainActivity.this.getLayoutInflater().inflate(R.layout.view_popup, null);
        PopupWindow popup = new PopupWindow(view,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        popup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        popup.setOutsideTouchable(true);
        popup.showAsDropDown(webview, px, -webview.getHeight() + py);
    }

    private class MyJavaScriptInterface {
        private Context ctx;

        public MyJavaScriptInterface(Context ctx) {
            this.ctx = ctx;
        }

        @JavascriptInterface
        public void showMenu(int x, int y) {
            final int px = (int) (x * ctx.getResources().getDisplayMetrics().density);
            final int py = (int) (y * ctx.getResources().getDisplayMetrics().density);

            Handler mainHandler = new Handler(Looper.getMainLooper());
            Runnable myRunnable = new Runnable() {
                @Override
                public void run() {
                    managePopup(px, py);
                }
            };
            mainHandler.post(myRunnable);
        }
    }
}

的src /主/资产/ sample.html:

以下是一些从资源目录加载到WebView的示例HTML。它在div上有一个点击监听器。

<html>
<style>
#txt {
    margin-left: 30%;
    margin-top: 400px;
    margin-bottom: 1000px;
    border: 1px red solid;
    display: inline-block;
}
</style>
<body>
    <div id="txt">some text</div>
    <script>
        var element = document.getElementById("txt");
        element.addEventListener('click', function (event) {
            var rect = element.getBoundingClientRect();
            Android.showMenu(rect.left, rect.top + rect.height);
        });
    </script>
</body>
</html>

的src /主/ RES /布局/ view_popup.xml:

这是一个示例菜单。我在这个示例中没有使用PopupMenu,而是更喜欢PopupWindow#showAsDropDown(View,int,int)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#000">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#FFF"
        android:text="Menu Item 1" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#FFF"
        android:text="Menu Item 2" />

</LinearLayout>

结果:

以下是它的GIF:

visual demo of the code above

答案 1 :(得分:1)

如果任何人都可以使用它,我有一些功能可以在我拥有的库fork中解决,它可以使用jquery和提供的标准ID,类和标记属性here来提取屏幕矩形。由于该库的主要重点不是解决此问题,所以请随意进行分叉或复制和粘贴。

getWebJQueryRects-根据jquery字符串列表返回矩形列表

getWebIDRects-与上面相同,但使用document.getElementById

getWebTagRects-与上面相同,但使用document.getElementsByTagName

getWebClassRects-与上面相同,但使用document.getElementsByClassName

返回的矩形在屏幕上以像素为单位表示坐标。在张贴者场景中,可用于查找屏幕位置上的按钮。

答案 2 :(得分:0)

通过在视图OnLayoutChangeListener回调中创建和显示PopupMenu来解决。