Android watch girl version

I have written such an article before- jump to view it . Recently, I was bored and wanted to review it, but I found that I didn’t understand it... This is absolutely impossible. The original intention of writing a blog has not been achieved, and I can’t understand it, let alone share it. I gave it to someone else, so I wrote it again. I hope that when I look back someday, I can easily think of my thoughts at this time.
First of all, through this article, you can learn:
1. Interaction between native and H5
2. How to introduce web pages into APP through WebView
3. The specific practice of one-pixel keep-alive method

In order to fully understand the interaction process between native and H5, here is a switching effect
insert image description here
. Previous and next, the display belongs to the native range. The overall interface and switching background are part of H5. After clicking the display, return to the original page of the mobile phone, and the mobile phone can be normal Use (similar to one-pixel keep-alive usage), note: not compatible with mobile phones, different mobile phones may have different effects

insert image description here
First of all, two html interfaces and two activities are needed, one of which is the operation activity, and the other is the activity in the lower left corner. The one in the lower left corner imitates the one-pixel keep-alive method, except that one pixel is changed to the corresponding size and the layout is added.

First create an assets folder for storing html files
insert image description here

insert image description here
The contents of the two html files are as follows:

live2D

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>live2d模型</title>

    <style type="text/css">
		.rgba{
      
      
			background-color: rgba(0,0,0,1);
			background-position: center 0;
            background-size: cover;
            min-height: 100vh;
		}
    </style>
</head>

<body class="rgba">
<input type="button" value="切换背景" onclick="jsColor() " />
</body>
<!-- 导入模型的脚本文件 -->
<script src="https://eqcn.ajz.miesnfu.com/wp-content/plugins/wp-3d-pony/live2dw/lib/L2Dwidget.min.js"></script>

<script language="javascript">
   //人物集合
   var arr = ["https://unpkg.com/[email protected]/assets/chitose.model.json",
            "https://unpkg.com/[email protected]/assets/haruto.model.json",
            "https://unpkg.com/[email protected]/assets/hibiki.model.json",
            "https://unpkg.com/[email protected]/assets/hijiki.model.json",
            "https://unpkg.com/[email protected]/assets/izumi.model.json",
            "https://unpkg.com/[email protected]/assets/koharu.model.json",
            "https://unpkg.com/[email protected]/assets/miku.model.json",
            "https://unpkg.com/[email protected]/assets/ni-j.model.json",
            "https://unpkg.com/[email protected]/assets/shizuku.model.json",
            "https://unpkg.com/[email protected]/assets/tororo.model.json",
            "https://unpkg.com/[email protected]/assets/tsumiki.model.json",
            "https://unpkg.com/[email protected]/assets/unitychan.model.json",
            "https://unpkg.com/[email protected]/assets/z16.model.json",
            "https://unpkg.com/[email protected]/assets/nico.model.json",
            "https://unpkg.com/[email protected]/assets/nipsilon.model.json",
            "https://unpkg.com/[email protected]/assets/nito.model.json",
            "https://unpkg.com/[email protected]/assets/wanko.model.json"];
   //背景集合
   var color = ["https://c-ssl.duitang.com/uploads/item/202007/01/20200701073201_dMUFs.thumb.1000_0.gif",
               "http://img.bimg.126.net/photo/eqj93LhUGXGIJiJfOhQ4KA==/334110797356199467.jpg",
               "http://p3.itc.cn/q_70/images03/20200916/1d4adfc4ac6f4e7ca08f3c563bafdd0b.gif",
               "https://c-ssl.duitang.com/uploads/blog/202104/24/20210424120118_378cf.thumb.1000_0.gif",];

   var i = 0; //默认人物下标
   var j = 0; //默认背景下标

   //设置背景
   function jsColor(){
      
      
      if(j >= color.length){
      
      
          j = 0;
      }
      document.body.style.backgroundImage="URL("+color[j]+")";
      test.getBjIndex(j)
   	  j++;

   }

   //设置人物
   function jsBack(){
      
      
        if (i >0 ){
      
      
            i--;
        }else{
      
      
           //调用原生方法
           test.initJS();
        }
        setL2();
   }

    //设置人物
    function jsNext(){
      
      
        if (i < arr.length ){
      
      
            i++;
        }else{
      
      
           //调用原生方法
           test.initJS();
        }
        setL2();
   }

   //点击方法之后打开的
   function setL2(){
      
      

   test.getRwIndex(i)

   L2Dwidget.init({
      
      
        // 引用的模型
        "model": {
      
      
            jsonPath: arr[i], //设置人物
            "scale": 1
        },
        // 模型的样式,可以自行更改
        "display": {
      
      
            "position": "right",
            "width": 150,
            "height": 350,
            "hOffset": 50,
            "vOffset": 50
        },
        "mobile": {
      
      
            "show": true,
            "scale": 1
        },
        "react": {
      
      
            "opacityDefault": 1,
            "opacityOnHover":2
        }
    });

   }

   //进来之后默认打开的人物
    L2Dwidget.init({
      
      
        // 引用的模型
        "model": {
      
      
            jsonPath: arr[i],
            "scale": 1
        },
        // 模型的样式,可以自行更改
        "display": {
      
      
            "position": "right",
            "width": 150,
            "height": 350,
            "hOffset": 50,
            "vOffset": 50
        },
        "mobile": {
      
      
            "show": true,
            "scale": 1
        },
        "react": {
      
      
            "opacityDefault": 1,
            "opacityOnHover":2
        }
    });

</script>

</html>


live2D_title

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>live2d模型</title>

    <style type="text/css">
		.rgba{
      
      
			background-color: rgba(0,0,0,1);
			background-position: center 0;
            background-size: cover;
            min-height: 100vh;
		}
    </style>
</head>

<body class="rgba">
</body>
<!-- 导入模型的脚本文件 -->
<script src="https://eqcn.ajz.miesnfu.com/wp-content/plugins/wp-3d-pony/live2dw/lib/L2Dwidget.min.js"></script>

<script language="javascript">
   //人物集合
   var arr = ["https://unpkg.com/[email protected]/assets/chitose.model.json",
            "https://unpkg.com/[email protected]/assets/haruto.model.json",
            "https://unpkg.com/[email protected]/assets/hibiki.model.json",
            "https://unpkg.com/[email protected]/assets/hijiki.model.json",
            "https://unpkg.com/[email protected]/assets/izumi.model.json",
            "https://unpkg.com/[email protected]/assets/koharu.model.json",
            "https://unpkg.com/[email protected]/assets/miku.model.json",
            "https://unpkg.com/[email protected]/assets/ni-j.model.json",
            "https://unpkg.com/[email protected]/assets/shizuku.model.json",
            "https://unpkg.com/[email protected]/assets/tororo.model.json",
            "https://unpkg.com/[email protected]/assets/tsumiki.model.json",
            "https://unpkg.com/[email protected]/assets/unitychan.model.json",
            "https://unpkg.com/[email protected]/assets/z16.model.json",
            "https://unpkg.com/[email protected]/assets/nico.model.json",
            "https://unpkg.com/[email protected]/assets/nipsilon.model.json",
            "https://unpkg.com/[email protected]/assets/nito.model.json",
            "https://unpkg.com/[email protected]/assets/wanko.model.json"];
   //背景集合
   var color = ["https://c-ssl.duitang.com/uploads/item/202007/01/20200701073201_dMUFs.thumb.1000_0.gif",
               "http://img.bimg.126.net/photo/eqj93LhUGXGIJiJfOhQ4KA==/334110797356199467.jpg",
               "http://p3.itc.cn/q_70/images03/20200916/1d4adfc4ac6f4e7ca08f3c563bafdd0b.gif",
               "https://c-ssl.duitang.com/uploads/blog/202104/24/20210424120118_378cf.thumb.1000_0.gif",];


   //点击方法之后打开的
   function setL2(i,j){
      
      

   //设置背景
   document.body.style.backgroundImage="URL("+color[i]+")";

   //进来之后默认打开的人物
    L2Dwidget.init({
      
      
        // 引用的模型
        "model": {
      
      
            jsonPath: arr[j],
            "scale": 1
        },
        // 模型的样式,可以自行更改
        "display": {
      
      
            "position": "left,bottom",
            "width": 23,
            "height": 60,
            "hOffset": 0,
            "vOffset": 0
        },
        "mobile": {
      
      
            "show": true,
            "scale": 1
        },
        "react": {
      
      
            "opacityDefault": 1,
            "opacityOnHover":2
        }
    });

   }



</script>

</html>


Secondly, bind the WebView to the interface in the Activity.
How to introduce the webpage into the APP through the WebView
insert image description here

  1. Among them mDataBind.mWebView.loadUrl("file:///android_asset/live2D.html")is to add html to WebView, pay attention to the path file:///android_asset/ If there are other sub-paths, similarly write down, android_asset is the folder where html was created just now

  2. mDataBind.mWebView.addJavascriptInterface(this, "test")This method is to associate the entire Activity with the JS of the interface, and then test in the HTML corresponding to the WebView represents the Activity, which is used for Js to call the native method

  3. Don't forget to set the WebView to support JS, otherwise the whole method will be invalid

Interact with H5 natively, and introduce it in detail with this code

1. Call H5 natively (no parameters)

native

insert image description here
2.H5 call native in H5 (no parameter)
insert image description here

In native,
insert image description here
don’t forget to add annotations, otherwise you won’t find the corresponding method (Koltin and Java should be noted)

@SuppressLint("JavascriptInterface")
@JavascriptInterface

Does the test here in H5
insert image description here
look familiar? This is the one set by the addJavascriptInterface method, and it can be called directly.

3. Call H5 natively (with parameters)

In the original version,
insert image description here
you can see that the difference with no parameter is that the corresponding parameter is added in the brackets. If there are multiple parameters, don’t forget to add a comma.

In H5,
insert image description here
you can see that JS parameters can be defined directly, and then used directly. Don’t forget the comma for multiple parameters.

4. H5 calls the native method (with parameters)

Native in
insert image description here
H5

insert image description here

One-pixel keep-alive method in practice

Why do I want to talk about this here? I think this part is more interesting. After all, it has a glorious history. It can also be seen from the first screenshot that the overall Activity is a small piece. It is also a small piece in the previous article, but it is In a counterfeit way, the overall APP is inoperable, but this time it is operable

In the core code part
insert image description here
, I wrote a one-pixel demo separately, and found that the APP does have one pixel, but the phone cannot perform other operations.

 //全屏不可触摸
 window.setFlags(
 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
        )
//取消全屏不可触摸 
//window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

Finally, let me talk about the overall idea :

  1. In html, put different viewer resources and backgrounds in different collections, and switch by calling the H5 method natively
  2. After switching, call the native method through H5 to pass the current subscript to the native
  3. Get the subscript natively, click on the pixel activity that jumps to the display and pass the subscript to it
  4. Pixel Activity gets the subscript, and passes the subscript to H5 for display by natively calling the H5 method

All code posted:

1. Network permissions

<uses-permission android:name="android.permission.INTERNET" />

2. Use dataBinding

 dataBinding {
    
    
        enabled = true
    }

3. Overall directory
insert image description here
MainActivity

class MainActivity : AppCompatActivity() {
    
    

    lateinit var mDataBind: ActivityMainBinding

    var bjIndex = "0"
    var rwIndex = "0"

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        mDataBind = DataBindingUtil.setContentView(this,R.layout.activity_main)
        initBar()
        initWeb()
        initEvent()
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun initBar(){
    
    
        this.window.statusBarColor = this.resources.getColor(R.color.white)
        this.window.decorView.systemUiVisibility = SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    }

    @SuppressLint("SetJavaScriptEnabled", "JavascriptInterface")
    private fun initWeb(){
    
    
        mDataBind.mWebView.webChromeClient = WebChromeClient()
        mDataBind.mWebView.settings.javaScriptEnabled = true
        mDataBind.mWebView.settings.domStorageEnabled = true
        mDataBind.mWebView.settings.javaScriptCanOpenWindowsAutomatically = true
        //mDataBind.mWebView.setBackgroundColor(0);//设置背景色
        //mDataBind.mWebView.background.alpha = 0;//设置填充透明度(布局中一定要设置background,不然getbackground会是null)
        mDataBind.mWebView.addJavascriptInterface(this, "test")
        mDataBind.mWebView.loadUrl("file:///android_asset/live2D.html")

    }

    private fun initEvent(){
    
    
        mDataBind.tvBack.setOnClickListener {
    
    
            mDataBind.mWebView.loadUrl("javascript:jsBack()");
        }
        mDataBind.tvNext.setOnClickListener {
    
    
            mDataBind.mWebView.loadUrl("javascript:jsNext()");
        }
        mDataBind.tvSelect.setOnClickListener {
    
    
            val it = Intent(this@MainActivity, ShowActivity::class.java)
            it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            it.putExtra("BJ_KEY",bjIndex)
            it.putExtra("RW_KEY",rwIndex)
            startActivity(it)
            finish()
        }

    }

    @SuppressLint("JavascriptInterface")
    @JavascriptInterface
    fun initWVBack(){
    
    
        Toast.makeText(this,"设置背景",Toast.LENGTH_SHORT).show()
    }

    @SuppressLint("JavascriptInterface")
    @JavascriptInterface
    fun initJS(){
    
    
        Toast.makeText(this,"没了..",Toast.LENGTH_SHORT).show()
    }

    @SuppressLint("JavascriptInterface")
    @JavascriptInterface
    fun getBjIndex(s: String){
    
    
         this.bjIndex = s
    }

    @SuppressLint("JavascriptInterface")
    @JavascriptInterface
    fun getRwIndex(s: String){
    
    
          this.rwIndex = s
    }
}

ShowActivity

class ShowActivity : AppCompatActivity() {
    
    

    lateinit var mDataBind: ActivityShowBinding

    var bjKey = "BJ_KEY"
    var rwKey = "RW_KEY"

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        //一像素的时候不需要setContentView方法
        mDataBind = DataBindingUtil.setContentView(this,R.layout.activity_show);
        val window = window
        //一像素保护法通用默认是左上
        window.setGravity(Gravity.LEFT or Gravity.BOTTOM)
        val params = window.attributes
        params.x = 0
        params.y = 0
        //一像素的时候这里都是1
        params.height = 400
        params.width = 200
        window.attributes = params
//        @SuppressLint("UseCompatLoadingForDrawables") val drawable =
//            this.resources.getDrawable(R.drawable.ic_launcher_background)
//        window.setBackgroundDrawable(drawable)
        //全屏不可触摸
        window.setFlags(
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
        )
        //取消全屏不可触摸
        //window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

        //获取数据
        val i = intent.getStringExtra(bjKey)
        val j = intent.getStringExtra(rwKey)
        initWeb(i,j)
    }

    @SuppressLint("JavascriptInterface")
    private fun initWeb(i: String?,j: String?){
    
    
        mDataBind.mWebView.webChromeClient = WebChromeClient()
        mDataBind.mWebView.settings.javaScriptEnabled = true
        mDataBind.mWebView.settings.domStorageEnabled = true
        mDataBind.mWebView.settings.javaScriptCanOpenWindowsAutomatically = true
        //mDataBind.mWebView.setBackgroundColor(0);//设置背景色
        //mDataBind.mWebView.background.alpha = 0;//设置填充透明度(布局中一定要设置background,不然getbackground会是null)
        mDataBind.mWebView.addJavascriptInterface(this, "test")
        mDataBind.mWebView.loadUrl("file:///android_asset/live2D_title.html")
        Handler().postDelayed(Runnable {
    
    
            //2秒之后在这进行操作
            mDataBind.mWebView.loadUrl("javascript:setL2($i,$j)");
        }, 2000)


    }

}

activity_main

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <WebView
            android:id="@+id/mWebView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="48dp">

            <TextView
                android:id="@+id/tvBack"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:gravity="center"
                android:textStyle="bold"
                android:textColor="@color/black"
                android:text="上一个"/>

            <TextView
                android:id="@+id/tvSelect"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:gravity="center"
                android:textStyle="bold"
                android:textColor="@color/black"
                android:layout_centerInParent="true"
                android:text="展示"/>

            <TextView
                android:id="@+id/tvNext"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:gravity="center"
                android:textStyle="bold"
                android:textColor="@color/black"
                android:layout_alignParentRight="true"
                android:text="下一个"/>

        </RelativeLayout>

    </LinearLayout>
</layout>

activity_show

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <LinearLayout
        android:layout_width="200px"
        android:layout_height="300px"
        android:orientation="vertical"
        tools:context=".ShowActivity">


        <WebView
            android:id="@+id/mWebView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>
</layout>

Guess you like

Origin blog.csdn.net/As_thin/article/details/124582469