美文网首页
Android DialogFragment加载WebView在

Android DialogFragment加载WebView在

作者: 坑逼的严 | 来源:发表于2021-01-19 11:02 被阅读0次

项目上有个奇葩需求,一个网页的扭蛋游戏,需要半屏展示,并且需要最小化。
1、半屏展示可以用dialogfragment,加载webview,把加载的webview设置半屏的高度就行。当然,webview,最好以java代码创建,再add到布局里面,不然会内存泄漏。

class HalfSizeWebViewFragment : DialogFragment() {
    var activity: YYSGroupKRoomActivity? = null
    private val mWebView by lazy {
        RoundWebView(Sheng.getInstance())
    }
    private val window by lazy {
        dialog!!.window
    }
    private var http:String? = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, R.style.Theme_AppCompat_Dialog)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_half_size_web_view, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        http = arguments?.getString("http")
        initWebView()
        initView()
        showH5(http)
    }

    @SuppressLint("NewApi")
    private fun initView() {
        mNullView?.setOnClickListener {
            dismissAllowingStateLoss()
        }
    }

    override fun onStart() {
        super.onStart()
        if(dialog !=null) {
            window!!.setGravity(Gravity.BOTTOM)
            window.setWindowAnimations(R.style.luck_box_dialog_theme)
            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            val params: WindowManager.LayoutParams = window.attributes
            params.dimAmount = 0.0f
            params.flags = params.flags or WindowManager.LayoutParams.FLAG_DIM_BEHIND
            window.attributes = params
        }
    }

    private fun initWebView() {
        mWebView.settings.javaScriptEnabled = true
        if(activity!=null){
            mWebView.webViewClient = MyWebViewClient(this)
        }
        mWebView.settings.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
        mWebView.settings.textZoom = 100
        //设置支持脚本
        mWebView.settings.javaScriptEnabled = true
        //设置支持DOM Storage
        mWebView.settings.domStorageEnabled = true
        ////解决图片不显示
        mWebView.settings.blockNetworkImage = false
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //解决引用http地址的图片不显示
            mWebView.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        }
        //       加快HTML网页装载完成的速度   故在WebView初始化时设置如下代码:
        mWebView.settings.loadsImagesAutomatically = Build.VERSION.SDK_INT >= 19

        // 修改ua使得web端正确判断
        mWebView.settings.userAgentString = "mchangapp/android"
        //设置webview支持插件
        // mWebView.getSettings().setPluginsEnabled(true);

        mWebView.settings.cacheMode = WebSettings.LOAD_NO_CACHE

        // 将一个对象起一个别名传入,在JS代码中用这个别名代替这个对象,可以调用这个对象的一些方法
        mWebView.addJavascriptInterface(WebJSInterface(this, mUser), "webJsInstence")
        mWebViewBox?.let {
            it.addView(mWebView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
        }
        mWebView.setRadius(resources.getDimension(R.dimen.dp_15), resources.getDimension(R.dimen.dp_15), 0f, 0f)
    }

    override fun onDestroy() {
        try {
            // 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再
            val parent = mWebView.parent
            if (parent != null) {
                (parent as ViewGroup).removeView(mWebView)
            }
            mWebView.stopLoading()
            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
            mWebView.settings.javaScriptEnabled = false
            mWebView.clearHistory()
            mWebView.clearView()
            mWebView.removeAllViews()
            mWebView.destroy()
        }catch (e: java.lang.Exception){
            e.printStackTrace()
        }
        super.onDestroy()
    }

    public fun hide(){
        dialog.hide()
    }

删除了业务代码

2、webview的圆角

public class RoundWebView extends WebView {
    private Path mPath;
    private Paint mPaint;
    private RectF mRectF;
    private final float[] mRadius = new float[8];

    public RoundWebView(@NonNull Context context) {
        this(context, null);
    }

    public RoundWebView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundWebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPath = new Path();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mRectF = new RectF();
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void draw(Canvas canvas) {
        int scrollX = this.getScrollX();
        int scrollY = this.getScrollY();
        mRectF.set(0, scrollY, scrollX + getWidth(), scrollY + getHeight());

        canvas.save();
        canvas.clipPath(genPath());
        super.draw(canvas);
        canvas.restore();
    }

    private Path genPath() {
        mPath.reset();
        mPath.addRoundRect(mRectF, mRadius, Path.Direction.CW);
        return mPath;
    }

    public void setRadius(float topLeft, float topRight, float bottomRight, float bottomLeft) {
        mRadius[0] = topLeft;
        mRadius[1] = topLeft;
        mRadius[2] = topRight;
        mRadius[3] = topRight;
        mRadius[4] = bottomRight;
        mRadius[5] = bottomRight;
        mRadius[6] = bottomLeft;
        mRadius[7] = bottomLeft;
        invalidate();
    }
}

然后使用它

HalfSizeWebViewFragment mHalfSizeWebViewFragment = HalfSizeWebViewFragment.newInstance(mBean.getActionUrl());
mHalfSizeWebViewFragment.show(transaction, mHalfSizeWebViewFragment.getTag());

当我们调用HalfSizeWebViewFragment 里面的hide后,fragment会最小化,但是我们的自动扭蛋游戏变慢了,原本4秒一次,变成了5分钟。我们也没有对webview进行resumeTimers和pauseTimers的操作,那为什么这样呢?

造成这个的原因是webview没有在前台展示,系统会降低webview对cpu的使用频率。所以,解决办法就是,hide后将webview放入一个可见的布局中,show的时候再放回到Fragment里面,我这里是选择了悬浮窗。

public class HideWebViewService extends GroupRoomService {

    private WindowManager mWindowManager;
    private View mRootView;
    private static FrameLayout mHideWebView;

    public HideWebViewService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        try {
            if (mWindowManager != null && mRootView != null) {
                mWindowManager.removeView(mRootView);
            }
            if(mHideWebView!=null){
                mHideWebView.removeAllViews();
            }
        } catch (Exception e) {
            Log.i("exist", "destory");
        }
        super.onDestroy();
    }

    public static void addHideWebView(RoundWebView webView) {
        try {
            if(webView!=null){
                ViewParent parent = webView.getParent();
                ((ViewGroup) parent).removeView(webView);
                mHideWebView.addView(webView,new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int command = super.onStartCommand(intent, flags, startId);
        return command;
    }

    public void showHideView(){
        try {
            mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
            mRootView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.view_flow_window3, null);
            mHideWebView = mRootView.findViewById(R.id.hide_web_views);
            WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
            //小于的时候不能接收点击事件,所以用申请权限的方式开启 TYPE_PHONE
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0
                mParams.type = TYPE_APPLICATION_OVERLAY;
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0
                mParams.type = TYPE_PHONE;
            } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) {//4.3以下toast没有触摸事件
                mParams.type = TYPE_PHONE;
            } else {
                if (PermissionUtils.isMiPhone()) {//小米手机
                    mParams.type = TYPE_PHONE;
                } else {
                    mParams.type = TYPE_TOAST;
                }
            }
            mParams.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
            mParams.format = PixelFormat.RGBA_8888;
            mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            int width = 1;//设置大小
            int height = 1;
            mParams.width = width;
            mParams.height = height;
//        mParams.x = (int) mCurrentX;
//        mParams.y = (int) mCurrentY;
            mParams.x = MATCH_PARENT;
            mParams.y = WRAP_CONTENT;

            mWindowManager.addView(mRootView, mParams);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMoonEvent(MessageEvent messageEvent) {
        //判断消息类型
        switch (messageEvent.getState()) {
            case MessageEvent.STATE_TYPE_SHOW_HIDE_WINDOW://更新悬浮窗信息
                showHideView();
                break;
        }
    }
}

悬浮窗一定要经过用户授权后才能设置布局,所以我这里再用户点击hide时请求权限,有权限了才通过EventBus初始化悬浮窗的布局。这里我们把宽高都设为1,这样就能最小化。当hide时调用addHideWebView,将webview放入进来就行啦。

相关文章

网友评论

      本文标题:Android DialogFragment加载WebView在

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