App活动弹出框

作者: 刀放下好好说话 | 来源:发表于2018-10-15 16:49 被阅读239次

一、关于手淘的弹出层技术

犹记得做项目的时候,老板说要实现一个新注册用户进入app弹出赠送优惠券的项目。很简单,dialog就能实现对吧。但是,优惠券到底做成什么样的还不清楚,而项目这周上线。也就是说只能预埋页面。那就不好做了,上线了dialog是没办法替换的啊。

老板说那就做成H5的页面,随时可以替换。这个简单,在首页的布局上藏一个WebView,请求到H5地址的时候load(String url)。项目按时上线了。

过了些日子,需求要在商家详情页面弹出一些优惠信息。于是拷贝代码,在详情页面再藏一个WebView,原代码改改...

又过些日子,需求又加了,优惠券页面把过期的优惠券弹出来提示一下用户。再藏一个WebView,原代码改改...

这个时候需要改动的地方太多了,对原代码的入侵也多,webview本身问题就多,每改动一个,其它地方就要拷贝拷贝。

但是用过手淘app的都知道,在任何地方都可能会弹出一个活动框,应该不会像我这样每一个地方都加webview。问了一下技术主管,提到了H5的poplayer,不知道他从哪听来的。

百度了很久才找到一篇大致相关的文章 客户端还可以这么玩?

这个文章阅读数还不到300,发布时间也就在16年8月份。可以说这个技术真的没什么人关心呐,因为像手淘这样临时业务多的app也很少。

二、仿手淘的poplayer

怎样才能优雅的实现这种效果呢?透明的activity + webview。

这应该是最简单的办法了,而且代码侵入性极小。

public class PopLayerActivity extends Activity {

    private WebView webView;

    public static void start(Context mContext, String url) {
        Intent intent = new Intent(mContext, PopLayerActivity.class);
        intent.putExtra("pop_url", url);
        mContext.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        webView = new WebView(this);
        webView.setBackgroundColor(0); // 设置背景色
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        webView.setLayoutParams(params);
        initWebSetting(webView.getSettings());
        webView.setWebChromeClient(new WebChromeClient());
        webView.setWebViewClient(new MyWebviewClient());

        setContentView(webView);

        Intent intent = getIntent();
        if(intent != null && intent.hasExtra("pop_url")){
            String pop_url = intent.getStringExtra("pop_url");
            webView.loadUrl(pop_url);
        }
    }

    public class MyWebviewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.endsWith(".apk")){
                String reg = ".*(https://.*\\.apk).*";
                Pattern pattern = Pattern.compile(reg);
                Matcher matcher = pattern.matcher(url);
                if(matcher.find()){
                    String group = matcher.group(1);
                    openByBrowser(group);
                }
                return true;
            } else if (!url.startsWith("http")) {
                openByBrowser(url);
                return true;
            }
            return super.shouldOverrideUrlLoading(view, url);
        }

        /**
         * 通过浏览器打开一个url
         * @param url
         */
        private void openByBrowser(String url) {
            try {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.setData(Uri.parse(url));
                startActivity(intent);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 配置webview
     *
     * @param webSettings
     */
    private void initWebSetting(WebSettings webSettings) {
        /**支持Js**/
        webSettings.setJavaScriptEnabled(true);

        /**设置自适应屏幕,两者合用**/
        //将图片调整到适合webview的大小
        webSettings.setUseWideViewPort(true);
        // 缩放至屏幕的大小
        webSettings.setLoadWithOverviewMode(true);

        /**缩放操作**/
        // 是否支持画面缩放,默认不支持  易导致闪退问题
//        webSettings.setBuiltInZoomControls(true);
//        webSettings.setSupportZoom(true);
        // 是否显示缩放图标,默认显示
        webSettings.setDisplayZoomControls(false);
        // 设置网页内容自适应屏幕大小
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

        /**设置允许JS弹窗**/
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setDomStorageEnabled(true);

        /**关闭webview中缓存**/
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        /**设置可以访问文件 **/
        webSettings.setAllowFileAccess(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            webSettings.setAllowFileAccessFromFileURLs(true);
            webSettings.setAllowUniversalAccessFromFileURLs(true);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webSettings.setPluginState(WebSettings.PluginState.ON);
    }

    @Override
    public void onPause() {
        super.onPause();
        if(webView != null){
            webView.onPause();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if(webView != null){
            webView.onResume();
        }
    }

    @Override
    public void onDestroy() {
        if(webView != null){
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }
}

整个activity的代码就是一个webview,因为一般的弹框只涉及到下载和跳转,所以只监听了.apk的后缀和非http或https的前缀,有什么其他需要监听的自行添加。

三、透明化的activity

如果不设置透明的activity,效果就是跳转一个页面。设置透明有两个地方,第一,activity

    <style name="PopLayerTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowAnimationStyle">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowFullscreen">false</item>
        <item name="windowNoTitle">true</item>
    </style>

写在样式里效果最好,不要全屏,否则会有布局闪动的bug。

第二,webview

    webView.setBackgroundColor(0); // 设置背景色

给webview设置背景色透明。

四、效果

poplayer.gif

相关文章

  • App活动弹出框

    一、关于手淘的弹出层技术 犹记得做项目的时候,老板说要实现一个新注册用户进入app弹出赠送优惠券的项目。很简单,d...

  • iOS多个弹框按顺序依次弹出

    前言 现在APP在首页会有多个弹框按照顺序依次弹出的功能,比如强制更新、比如弹出消息推送的活动弹框、比如弹出搜索弹...

  • 关于appium操作APP的弹出框的问题

    关于appium处理APP的弹出框的问题 弹出框通过appium的定位是定位不到的,所以不能执行对应的操作,这时候...

  • APP弹出框的类型

    app弹出框常见有四种类型,其中toast、snackbar属于非模态弹窗;dialog、actionbar属于模...

  • vue-弹出框组件

    创建一个公用的弹出框组件,包括消息弹出框,确认弹出框,自定义内容弹出框 一、创建 1、创建一个基础弹出框:dial...

  • App Store引导用户评价优化

    具体什么时候弹出,用什么文案你自己根据自己app的情况考虑,我就不说了。 上面弹出框点【好评】,跳转到app st...

  • uni-app subNVues的使用

    在首页要弹出一个弹框,弹出的弹框无法遮住顶部导航栏和底部tabbar,uni-app官方给出了两种解决方法,plu...

  • 记录遇到的一些难缠的bug

    1、内存泄漏 出现场景: 在app启动首页检测网络权限,没打开网络权限使用自定义弹框弹出提示,自定义弹框的弹出需要...

  • vue实现点击除自身等指定元素外关闭弹出框

    需求: 点击某元素可以关闭打开弹出框,点击弹出框外可以关闭弹出框,点击框内不处理

  • 安卓弹出框顶部距离过大(点击弹出框外围时,弹出框未消失)

    问题描述 当点击弹出框外面一圈时,弹出框未消失. 离开弹出框比较远时,才消失. 原因分析 弹出框默认外围有一圈透明...

网友评论

本文标题:App活动弹出框

本文链接:https://www.haomeiwen.com/subject/yuafzftx.html