android上方导航条跳转页面,《成为大前端》系列 7. 多页面、页面跳转和Navigation模块...
介紹
開(kāi)發(fā)過(guò)移動(dòng) Web 頁(yè)面的同學(xué)都知道,單個(gè)頁(yè)面由客戶端的 UI 所承載,頁(yè)面間的跳轉(zhuǎn)也
不再是使用 window 和 location,也不是使用 a 標(biāo)簽,而且調(diào)用 Native 寫(xiě)好的 bridge
進(jìn)行跳轉(zhuǎn)創(chuàng)建一個(gè)新的 WebView 來(lái)打開(kāi)新頁(yè)面。
這種行為我們定義為頁(yè)面跳轉(zhuǎn),也可以稱(chēng)為導(dǎo)航(Navigation)
JS 端
新增頁(yè)面
root.html:app 打開(kāi)的第一個(gè)頁(yè)面
page_1.html: 從 root 跳轉(zhuǎn)到的頁(yè)面
page_2.html:從 page_1 跳轉(zhuǎn)到的頁(yè)面
三個(gè)頁(yè)面的主要代碼分別為:
root.html
switch (button.innerText) {
case "Navigation.open":
JSBridge.Navigation.open({
page: "page_1.html"
});
break;
}
}
root.html
Navigation.open
復(fù)制代碼
page_1.html
switch (button.innerText) {
case "Navigation.open":
JSBridge.Navigation.open({
page: "page_2.html"
});
break;
case "Navigation.close":
JSBridge.Navigation.close();
}
}
page_1.html
Navigation.open
Navigation.close
復(fù)制代碼
page_2.html
switch (button.innerText) {
case "Navigation.close":
JSBridge.Navigation.close();
}
}
page_2.html
Navigation.close
復(fù)制代碼
JS 接口
定義我們頁(yè)面之間,跳轉(zhuǎn)的接口為:
JSBridge.Navigation.open({
page: "page_1.html"
});
復(fù)制代碼
關(guān)閉當(dāng)前頁(yè)面,回到上一個(gè)頁(yè)面:
JSBridge.Navigation.close();
復(fù)制代碼
jsbridge.js 實(shí)現(xiàn)
JSBridge.Navigation = {};
JSBridge.Navigation.open = function(params, callback){
// 復(fù)制一份參數(shù)用于修改
params = JSON.parse(JSON.stringify(params));
let path = location.pathname;
// 如果是當(dāng)前頁(yè)面是根路徑
if (!path) {
params.url = location.protocol + "//" + location.host + "/" + params.page;
}
// 否則拼成相對(duì)路徑
else {
params.url =
location.protocol +
"//" +
location.host +
path.substr(0, path.lastIndexOf("/") + 1) +
params.page;
}
callNative("Navigation.open", params, callback);
};
JSBridge.Navigation.close = function(callback){
callNative("Navigation.close", {}, callback);
};
復(fù)制代碼
iOS跳轉(zhuǎn) - present和dismiss實(shí)現(xiàn)
WebViewController添加url變量
class WebViewController ...{
var url: String? = nil
func getLoadUrl() -> String {
return url ?? "about:blank"
}
}
復(fù)制代碼
如果外部創(chuàng)建WebViewController時(shí)傳遞了url參數(shù),則WebView加載這個(gè)url
JSBridgeNavigation
class JSBridgeNavigation : BridgeModuelBase{
weak var viewController: WebViewController?
init(viewController: WebViewController) {
self.viewController = viewController
}
override func callFunc(_ funcName: String, callbackId: String, arg: [String : Any?]) {
switch funcName {
case "open": open(callbackId: callbackId, arg: arg)
case "close": close(callbackId: callbackId, arg: arg)
default: break
}
}
private func open(callbackId: String, arg: [String : Any?]) {
guard let vc = self.viewController else { return }
guard let url = arg["url"] as? String else { return }
let newVC = WebViewController()
newVC.url = url
vc.present(newVC, animated: true, completion: nil)
}
private func close(callbackId: String, arg: [String : Any?]) {
viewController?.dismiss(animated: true, completion: nil)
}
}
復(fù)制代碼
WebViewBridge
func initModules() {
...
moduleDict["Navigation"] = JSBridgeNavigation(viewController: viewController!)
}
復(fù)制代碼
ViewController
將鏈接改為root
class ViewController : WebViewController{
override func getLoadUrl() -> String {
return "http://192.168.31.101:8000/root.html"
}
}
復(fù)制代碼
Android 跳轉(zhuǎn) - WebActivity 實(shí)現(xiàn)
實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn),我們可以利用 Intent 調(diào)到 WebActivity,向 WebActivity 傳遞參數(shù) url
WebActivity
將 WebActivity 改為 open 而不是 abstract
將 abstract 的 getLoadUrl 改為從 Intent 獲取 url
open class WebActivity ...{
...
open fun getLoadUrl(): String {
// 從intent中獲取url
return intent.getStringExtra("url") ?: "about:blank"
}
...
}
復(fù)制代碼
注冊(cè) WebActivity
...
復(fù)制代碼
JSBridgeNavigation
class JSBridgeNavigation(val activity: WebActivity, webView: WebView) : BridgeModuleBase(webView) {
override fun callFunc(func: String, callbackId: String, arg: JSONObject) {
when (func) {
"open" -> open(callbackId, arg)
"close" -> close(callbackId, arg)
}
}
private fun open(callbackId: String, arg: JSONObject) {
val intent = Intent(activity, WebActivity::class.java)
intent.putExtra("url", arg.getString("url"))
activity.startActivity(intent)
}
private fun close(callbackId: String, arg: JSONObject) {
activity.finish()
}
}
復(fù)制代碼
WebViewBridge
init {
...
bridgeModuleMap["Navigation"] = JSBridgeNavigation(activity, webView)
}
復(fù)制代碼
MainActivity
將鏈接改為 root
class MainActivity : WebActivity() {
override fun getLoadUrl(): String {
return "http://192.168.31.101:8000/root.html"
}
}
復(fù)制代碼
iOS - UINavigationController 實(shí)現(xiàn)跳轉(zhuǎn)
iOS 系統(tǒng)除了 present 和 dismiss 可以實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn),還可以使用 UINavigationController 實(shí)現(xiàn),這種
實(shí)現(xiàn)方式會(huì)為頁(yè)面增加頂部的導(dǎo)航條
自定義啟動(dòng)的 RootViewController
1. 刪除 Scene 相關(guān)的代碼和配置
SceneDelegate.swift
Main.storyboard
刪除 Info.plist 中的 Application Scene Manifest
2. 收到初始化 Window 和 RootViewController
AppDelegate.swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{
// 定義window變量
@objc open var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 初始化話window
self.window = UIWindow(frame: UIScreen.main.bounds)
// 1. 初始化一個(gè)導(dǎo)航控制器
// 2. rootViewController設(shè)置為ViewController
// 3. 給window賦值rootViewController
self.window?.rootViewController = UINavigationController(rootViewController: ViewController())
// 顯示window
self.window?.makeKeyAndVisible()
return true
}
}
復(fù)制代碼
JSBridgeNavigation 修改
class JSBridgeNavigation : BridgeModuelBase{
weak var viewController: WebViewController?
init(viewController: WebViewController) {
self.viewController = viewController
}
override func callFunc(_ funcName: String, callbackId: String, arg: [String : Any?]) {
switch funcName {
case "open": open(callbackId: callbackId, arg: arg)
case "close": close(callbackId: callbackId, arg: arg)
case "push": push(callbackId: callbackId, arg: arg)
default: break
}
}
private func open(callbackId: String, arg: [String : Any?]) {
guard let vc = self.viewController else { return }
guard let url = arg["url"] as? String else { return }
let newVC = WebViewController()
newVC.url = url
vc.present(newVC, animated: true, completion: nil)
}
private func close(callbackId: String, arg: [String : Any?]) {
guard let vc = self.viewController else { return }
// 關(guān)閉時(shí)兼容兩種打開(kāi)方式
// 1. 如果是push過(guò)來(lái)的
if vc.navigationController != nil && vc.navigationController!.viewControllers.count > 1 {
vc.navigationController?.popViewController(animated: true)
}
// 2. 如果是present過(guò)來(lái)的
else if vc.isBeingPresented || vc.presentingViewController != nil {
vc.dismiss(animated: true, completion: nil)
}
}
// push的實(shí)現(xiàn)
private func push(callbackId: String, arg: [String : Any?]) {
guard let vc = self.viewController else { return }
guard let navVC = vc.navigationController else { return }
guard let url = arg["url"] as? String else { return }
let newVC = WebViewController()
newVC.url = url
navVC.pushViewController(newVC, animated: true)
}
}
復(fù)制代碼
運(yùn)行效果
運(yùn)行后多了導(dǎo)航條,點(diǎn)擊 Navigation.push 跳轉(zhuǎn)到頁(yè)面可以看出和之前 open 打開(kāi)的不一樣,有返回按鈕
JS端為iOS添加Navigation.push跳轉(zhuǎn)
function resolveNavParams(params){
params = JSON.parse(JSON.stringify(params));
let path = location.pathname;
if (!path) {
params.url = location.protocol + "//" + location.host + "/" + params.page;
} else {
params.url =
location.protocol +
"//" +
location.host +
path.substr(0, path.lastIndexOf("/") + 1) +
params.page;
}
return params;
}
JSBridge.Navigation = {};
JSBridge.Navigation.open = function(params, callback){
callNative("Navigation.open", resolveNavParams(params), callback);
};
JSBridge.Navigation.close = function(callback){
callNative("Navigation.close", {}, callback);
};
JSBridge.Navigation.push = function(params, callback){
// 如果是android還是走open,因?yàn)榘沧康奶D(zhuǎn)沒(méi)有push類(lèi)型
// 當(dāng)然如果想實(shí)現(xiàn)push這樣從左到右的動(dòng)畫(huà)也可以,這里暫不實(shí)現(xiàn)
if (window.androidBridge) {
JSBridge.Navigation.open(params, callback)
} else {
callNative("Navigation.push", resolveNavParams(params), callback);
}
};
復(fù)制代碼
結(jié)語(yǔ)
到這里,我們完成的 H5 頁(yè)面直接的跳轉(zhuǎn)功能
總結(jié)
以上是生活随笔為你收集整理的android上方导航条跳转页面,《成为大前端》系列 7. 多页面、页面跳转和Navigation模块...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 你将要去那里是哪首歌啊?
- 下一篇: 怎么在html中写当前时间,当前时间(J