当下主流 APP , Hybrid app 中需要熟练掌握的交互知识(二)

如果感觉略有用处,点赞支持下作者。上一篇将关于 WebView 的设置仔细的捋了一遍,我们通过 WebViewController 这个类完成了所有 WebView 的设置,并且在布局的时候,只需在布局文件中引入这个类的完整包名,前提是这个类要继承于 WebView,就可以完成所有 WebView 的设置,具体可参考上一篇 当下主流 APP,Hybrid app 中需要熟练掌握的交互知识(一) 其实有人就说到了,现在有现成的框架可,那我的出发点是从自己动手开始,再去接触框架,这个系列我们一步步来!

那么本篇将就以下几点展开:

  • 页面布局相同情况下Activity 的 共用问题。

  • 在原生与网页混合的开发状态下,如何确定页面跳转以及参数传递。

  • 根据服务端发送的 Js 接口名去做具体实现

Activity 共用

这是当下很多 WebApp 都在使用的一个套路,除了避免了创建多个 Activity 后影响性能之外,还可以保持项目「友好」的结构!这样的处理大多适应于这样的场景:

  • 页面布局上方只有一个 ToolBar 或者 ActionBar 等等的标题栏

  • 下方则是一个 WebView 用于呈现网页内容

  • 如此则可以将共同的属性提取出来,WebView 则不用管,都是一致的东西。ToolBar 上无论是标题还是按钮的设置,当点击了某处后我们会进入我们在本地实现的网页接口,具体的原理请看下面的详细解释!

一 、建立共用的 Activity:

我们将之命名为 NewWebViewActivity

//获取到消息处理类传过来的 url 网址
String url = getIntent().getStringExtra("url");
//获取到消息处理类传过来的动画操作
int anim = getIntent().getIntExtra("animation", 0);
if (url == null) {
   finish();
}else if (url.equals(Constants.urlHostBase + Constants.urlLogIn)){
   baseWebView.loadUrl(url);
   topToolbar.setVisibility(View.GONE);
} else {
   baseWebView.loadUrl(url);
   //用动画文件判断新开页面
   if (anim == R.anim.slide_right_out) {  //当所有的新开页面 是从右往左打开时(表示新开页面)
        //添加返回按钮
        backImageView.setImageResource(R.drawable.returns);
        //变为显示状态
        backImageView.setVisibility(View.VISIBLE);
        //返回键点击事件
        backImageView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               finish(); //关闭页面
               //设置页面退出动画为从左往右退出
               overridePendingTransition(R.anim.none, R.anim.slide_right_out);
           }
         });
    }
}

可以看到,并没有多少逻辑。我们这样就可以所有新开的页面添加一个返回键了,前提是有一个消息处理的类来完成打开页面的 url 参数设置,以及动画参数设置,其实实现起来也是很简单!往下看

二 、建立共用的 Activity 的布局:

我们紧接着需要将我们这个 Activity 布局:



    
    
    
    
    
    
    
    
    
    
    
    

布局文件很简单,我们将标题栏上正中标题,左上角关闭页面的图片点击按钮,右上角的文字提交按钮以及图片点击按钮都放在了布局中,那接下来就是如何去控制他们的显示时机,以及按下后的反馈了!

建立好了这个用于展示我们所有网页的共用 Activity 后,就是我们本篇的核心类了,敲黑板!!

核心类 HtmlMessageForLocal

在开始之前我们先将思路捋清楚

  • 处理所有网页的接口实现,以及跳转操作和添加标题栏上的按钮添加。

  • 此类用于接收我们点击或打开 WebView 服务端暴漏给我们的接口,我们负责具体实现!

  • 将我们实现的方法上加上 @JavascriptInterface 注解

  • 此注解表明所有服务端 Js 接口,都会进入我们自定义的这个方法里找同名方法,直接执行里面的逻辑!

好了,通过以上说明相信明眼的你可以发现,这是一个网页与我们本地的交互的核心类,所有的交互逻辑实现都需要在这里进行!

接下来我们分层进行,一层层,一个个方法的具体实现步骤,来剖析整个过程。

一 、判断接口名执行具体的方法:

@JavascriptInterface
public void callHandler(final String methodName, final String data, final String callbackName) {
    Log.e(TAG, "Method:" + methodName);
    if (methodName.equals("openAttendanceFromJS")) {
       openAttendanceFromJS(data);      // 打开新窗口
    }
}

这里只是起到了判断作用,特定的方法执行特定的操作,就比如上面这个方法,只负责用户点击了 WebView 去打开新的 WebView 的所有操作。

如何判断

/**
 * Js 与 Native(android 原生交互)
 * Native 调用 JS 方法
 * @param methodName Js 方法名
 * @param data 需要用到的数据 比如图片资源需要传递的数据 以下代码的实体类为 RightInfo
 我们需要声明一个实体类 用到什么数据资源就传给这个参数 
 * @param callbackName 回调的方法名 这里具体用不到
 */
@JavascriptInterface
public void callHandler(final String methodName, final String data, final String callbackName) {
    Log.e(TAG, "Method:" + methodName);
    if (methodName.equals("openAttendanceFromJS")) {
       openAttendanceFromJS(data);      // 打开新窗口
    } else if (methodName.equals("addRightBarButtonItemFromJS")) {
       addRightBarButtonItemFromJS(data);// 添加右上角按钮
    }

/**
 * 打开新窗口
 * @param url
 */
protected void openAttendanceFromJS(String url) {
    Log.i("js", url);
    // TODO Auto-generated method stub
    Intent intent = new Intent(ActivityCollector.getTopActivity(), NewWebViewActivity.class);
    intent.putExtra("url", url);
    intent.putExtra("animation", R.anim.slide_right_out);
    intent.putExtra("animation", R.anim.slide_right_in);
    ActivityCollector.getTopActivity().startActivity(intent);
}

/**
 * 设置右上角图片按钮
 * @param data
 */
protected void addRightBarButtonItemFromJS(String data) {
    topRightImage.setBackgroundResource(imageId);  //找到图片按钮资源
    topRightImage.setVisibility(View.VISIBLE);     //设置为可见状态
    topRightImage.setOnClickListener(new View.OnClickListener() {  //此按钮点击事件
        @Override
        public void onClick(View v) {
            Activity activity = ActivityCollector.getTopActivity();//获取到栈顶 Activity
            activity.runOnUiThread(new Runnable() {  //强制运行到主线程
                @Override
                public void run() {
                    //找到共用打的 WebView                       
                    ActivityCollector.getTopActivity().findViewById(R.id.base_web_view);
                    activity.overridePendingTransition(R.anim.push_bottom_out, R.anim.push_bottom_in);
                    //找到对应 web url网址
                    baseWebView.loadUrl("javascript:" + rightInfo.funcName);
                }
            });
        }
    });
}

在这里用两个方法举例,重要的步骤在这里都呈现了出来,根据我们服务端和 Android 端的需求做相应逻辑和方法的叠加就可以了!

总结

此次在这里将 Js 与 Native 的交互做了一个简单总结记录,整理了通用流程和思想,下个系列将使用当下比较流行的 Hybrid APP 框架来实现一个总体的处理流程。

你可能感兴趣的:(当下主流 APP , Hybrid app 中需要熟练掌握的交互知识(二))