package com.salama.android.webviewutil;
import java.util.concurrent.ConcurrentHashMap;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.salama.android.support.ServiceSupportApplication;
import com.salama.android.util.SSLog;
import com.salama.android.webcore.BaseViewController;
import com.salama.android.webcore.LocalWebView;
import com.salama.android.webcore.LocalWebViewFragment;
@SuppressLint("ValidFragment")
public class CommonWebViewController extends BaseWebViewController {
private final static String LOG_TAG = "CommonWebViewController";
private ConcurrentHashMap<String, String> _viewEventNameToJSCallBackMapping = new ConcurrentHashMap<String, String>();
private ConcurrentHashMap<String, Long> _localPageLastCreateTimeMapping = new ConcurrentHashMap<String, Long>();
protected String _title = "";
protected RelativeLayout _contentLayout = null;
protected TitleBar _titleBarLayout = null;
protected LocalWebView _webView = null;
//Title bar setting -----------------------------------
protected TitleBarSetting _titleBarSetting = new TitleBarSetting();
protected static boolean _defaultTitleBarHidden = false;
/**
* 标题栏是否隐藏的默认设置(全局)
* @return
*/
public static boolean isDefaultTitleBarHidden() {
return _defaultTitleBarHidden;
}
/**
* 标题栏是否隐藏的默认设置(全局)
* @param defaultTitleBarHidden
*/
public static void setDefaultTitleBarHidden(boolean defaultTitleBarHidden) {
_defaultTitleBarHidden = defaultTitleBarHidden;
}
public void setNavigationBarHidden(boolean hidden) {
_titleBarSetting.setHidden(hidden);
}
/**
* 取得标题栏设置
* @return 标题栏设置
*/
public TitleBarSetting getTitleBarSetting() {
return _titleBarSetting;
}
/**
* 设置标题栏设置
* @param titleBarSetting 标题栏设置
*/
public void setTitleBarSetting(final TitleBarSetting titleBarSetting) {
_titleBarSetting = titleBarSetting;
if(_titleBarLayout != null && getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
_titleBarLayout.loadSetting(getActivity(), titleBarSetting);
} catch(Throwable e) {
Log.e(LOG_TAG, "setTitleBarSetting()", e);
}
}
});
}
}
/**
* 装载标题栏设置
*/
public void loadTitleBarSetting() {
if(_titleBarLayout != null && getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
_titleBarLayout.loadSetting(getActivity(), _titleBarSetting);
} catch(Throwable e) {
Log.e(LOG_TAG, "loadTitleBarSetting()", e);
}
}
});
}
}
/**
* 取得标题栏Layout
* @return 标题栏Layout
*/
public TitleBar getTitleBarLayout() {
return _titleBarLayout;
}
/**
* 取得标题栏Layout
*/
public LocalWebView getWebView() {
return _webView;
}
/**
* 取得内容Layout
* @return
*/
public RelativeLayout getContentLayout() {
return _contentLayout;
}
/**
* 取得标题
* @return 标题
*/
public String getTitle() {
return _title;
}
/**
* 设置标题
* @param title
*/
public void setTitle(String title) {
_title = title;
_titleBarSetting.setCenterViewTitle(title);
if(_titleBarLayout != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
_titleBarLayout.setTitle(_title);
} catch(Throwable e) {
Log.e(LOG_TAG, "setTitle()", e);
}
}
});
}
}
public CommonWebViewController() {
this(null);
}
public CommonWebViewController(String viewServiceClassName) {
super(viewServiceClassName);
_titleBarSetting.setHidden(_defaultTitleBarHidden);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(container != null) {
_viewContainerId = container.getId();
Log.d("CommonWebViewFragment", "container != null :" + _viewContainerId);
}
//Layout ------------------------------------------
_contentLayout = new RelativeLayout(getActivity());
RelativeLayout.LayoutParams contentLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
_contentLayout.setLayoutParams(contentLayoutParams);
//title bar layout
_titleBarLayout = createTitleBarLayout();
if(_titleBarLayout != null) {
_contentLayout.addView(_titleBarLayout);
//_titleBarLayout.setTitle(_title);
}
//WebView
_webView = createWebView();
if(_webView != null) {
setWebView(_webView);
if(_titleBarLayout != null) {
((RelativeLayout.LayoutParams) _webView.getLayoutParams()).
addRule(RelativeLayout.BELOW, _titleBarLayout.getId());
}
_contentLayout.addView(_webView);
_webView.loadLocalPage(getLocalPage());
loadWebViewSettings();
}
//Handle event
if(getThisViewService() != null) {
getThisViewService().viewDidLoad();
}
handleViewEvent("viewDidLoad");
return _contentLayout;
}
@Override
public void onDestroyView() {
//JsCallBack
if(getThisViewService() != null) {
getThisViewService().viewWillUnload();
}
handleViewEvent("viewWillUnload");
super.onDestroyView();
//Handle event
if(getThisViewService() != null) {
getThisViewService().viewDidUnload();
}
handleViewEvent("viewDidUnload");
}
@Override
public void onResume() {
//Handle event
if(getThisViewService() != null) {
getThisViewService().viewWillAppear();
}
handleViewEvent("viewWillAppear");
super.onResume();
//Handle event
if(getThisViewService() != null) {
getThisViewService().viewDidAppear();
}
handleViewEvent("viewDidAppear");
}
@Override
public void onPause() {
//Handle event
if(getThisViewService() != null) {
getThisViewService().viewWillDisappear();
}
handleViewEvent("viewWillDisappear");
super.onPause();
//Handle event
if(getThisViewService() != null) {
getThisViewService().viewDidDisappear();
}
handleViewEvent("viewDidDisappear");
}
protected void handleViewEvent(String eventName) {
//JsCallBack
String jsCallBack = _viewEventNameToJSCallBackMapping.get(eventName);
if(jsCallBack != null) {
callJavaScript(jsCallBack, null);
}
}
protected TitleBar createTitleBarLayout() {
if(_titleBarSetting.isHidden()) {
return null;
}
//Title bar layout --------------------------
TitleBar titleBarLayout = new TitleBar(getActivity());
titleBarLayout.setId(ServiceSupportApplication.singleton().newViewId());
titleBarLayout.loadSetting(getActivity(), _titleBarSetting);
return titleBarLayout;
}
protected LocalWebView createWebView() {
LocalWebView webView = new LocalWebView(this, getActivity());
webView.setId(ServiceSupportApplication.singleton().newViewId());
RelativeLayout.LayoutParams webViewLayoutPrams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
webView.setLayoutParams(webViewLayoutPrams);
return webView;
}
/************************************* Interfaces Below -------> ***************************/
/******* These methods below are designed to be compatible to the javascript in salamNativeService.
* The code style is like IOS, because the first version of Salama Hybrid SDK is written in IOS.
**&**************************************************************************************************/
/********** Navigation Bar ***********/
/**
* 设置导航栏颜色
* @param red 红(0-1.0)
* @param green 绿(0-1.0)
* @param blue 蓝(0-1.0)
* @param alpha alpha(0-1.0)
*/
public void setNavigationBarTintColor(float red, float green, float blue, float alpha) {
final int iRed = (int)(red * 255);
final int iGreen = (int)(green * 255);
final int iBlue = (int)(blue * 255);
final int iAlpha = (int)(alpha * 255);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
_titleBarSetting.setBackgroundTColor(TitleBar.toIntColor(iRed, iGreen, iBlue, iAlpha));
if(_titleBarLayout != null) {
_titleBarLayout.setBackGroundTInt255Color(iRed, iGreen, iBlue, iAlpha);
}
} catch(Throwable e) {
Log.e(LOG_TAG, "setNavigationBarTintColor()", e);
}
}
});
}
/**
* 将jsCallBack同画面事件绑定
* @param eventName 画面事件名
* 支持的事件名: viewDidLoad,viewDidUnload, viewWillUnload, viewWillAppear, viewWillDisappear, viewDidAppear, viewDidDisappear
* @param jsCallBack JavaScript回调函数
*/
public void registerJSCallBackToViewEvent(String eventName, String jsCallBack) {
if(eventName == null || eventName.length() == 0
|| jsCallBack == null || jsCallBack.length() == 0) {
return;
}
if(!_viewEventNameToJSCallBackMapping.containsKey(eventName)) {
_viewEventNameToJSCallBackMapping.put(eventName, jsCallBack);
SSLog.d("CommonWebViewFragment",
"registerJSCallBackToViewEvent() eventName:" + eventName
+ " jsCallBack:" + jsCallBack);
}
}
/**
* 创建页面View
* @param pageName 页面名
* @return 页面View
*/
public CommonWebViewController createPageView(String pageName) {
if(isCreateLocalPageTwiceInvoked(pageName)) {
return null;
}
CommonWebViewController vc = new CommonWebViewController();
vc.setLocalPage(pageName);
vc.setViewContainerId(_viewContainerId);
//vc.setRootViewControllerId(getRootViewControllerId());
vc.setTitleBarSetting(_titleBarSetting);
return vc;
}
/**
* 创建页面View
* @param pageName 页面名
* @param commonWebViewControllerClassName 页面View类型名
* @return 页面View
*/
public CommonWebViewController createPageView(String pageName, String commonWebViewControllerClassName) {
if(isCreateLocalPageTwiceInvoked(pageName)) {
return null;
}
try {
Class<?> cls = ServiceSupportApplication.singleton().findClass(commonWebViewControllerClassName);
CommonWebViewController vc = (CommonWebViewController) cls.newInstance();
vc.setLocalPage(pageName);
vc.setViewContainerId(_viewContainerId);
//vc.setRootViewControllerId(getRootViewControllerId());
vc.setTitleBarSetting(_titleBarSetting);
return vc;
} catch(Throwable e) {
Log.e(LOG_TAG, "createPageView()", e);
return null;
}
}
/**
* 创建页面View
* @param pageName 页面名
* @param commonWebViewControllerClassName 页面View类型名
* @param viewServiceClassName Class name of thisViewService
* @return 页面View
*/
public CommonWebViewController createPageView(String pageName, String commonWebViewControllerClassName,
String viewServiceClassName) {
if(isCreateLocalPageTwiceInvoked(pageName)) {
return null;
}
try {
Class<?> cls = ServiceSupportApplication.singleton().findClass(commonWebViewControllerClassName);
CommonWebViewController vc = (CommonWebViewController) cls.
getConstructor(String.class).newInstance(viewServiceClassName);
vc.setLocalPage(pageName);
vc.setViewContainerId(_viewContainerId);
//vc.setRootViewControllerId(getRootViewControllerId());
vc.setTitleBarSetting(_titleBarSetting);
return vc;
} catch(Throwable e) {
Log.e(LOG_TAG, "createPageView()", e);
return null;
}
}
/**
* push方式显示页面View
* @param pageView 页面View
* @param setIntoNavigationAsRoot Not be used. It is to be compatible with javascript invoking
* which supports IOS, Android, Windows Phone.
*/
public void pushPageView(final BaseViewController viewController, final boolean setIntoNavigationAsRoot) {
/*
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
if(viewController == null) {
Log.i("CommonWebViewController", "viewController is null");
}
viewController.setViewContainerId(_viewContainerId);
//viewController.setRootViewControllerId(getRootViewControllerId());
FragmentTransaction trans = getActivity().getSupportFragmentManager().beginTransaction();
trans.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
//trans.add(_viewContainerId, pageView, pageView.getLocalPage());
if(LocalWebViewFragment.class.isAssignableFrom(viewController.getClass())) {
trans.add(_viewContainerId, viewController, ((LocalWebViewFragment)viewController).getLocalPage());
} else {
trans.add(_viewContainerId, viewController, viewController.getClass().getName());
}
trans.addToBackStack(null);
int backStackEntryId = trans.commit();
viewController.setBackStackEntryId(backStackEntryId);
} catch(Throwable e) {
Log.e("CommonWebViewController", "pushPageView()", e);
}
}
});
*/
pushView(viewController);
}
/**
* push方式显示页面View
* @param pageName 页面View
*/
public void pushPage(final String pageName) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
pushPageView(createPageView(pageName), false);
}
});
}
/**
* 返回至指定页面
* @param pageName 页面名
*/
public void popToPage(final String pageName) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
getActivity().getSupportFragmentManager().popBackStack(pageName, 0);
} catch(Throwable e) {
Log.e(LOG_TAG, "popToRoot()", e);
}
}
});
}
/**
* present方式显示页面
* @param pageView 页面View
* @param setIntoNavigationAsRoot 该参数为保持和iOS版兼容,Android中不使用
*/
public void presentPageView(final BaseViewController viewController, final boolean setIntoNavigationAsRoot) {
/*
viewController.setViewContainerId(_viewContainerId);
//viewController.setRootViewControllerId(getRootViewControllerId());
FragmentTransaction trans = getActivity().getSupportFragmentManager().beginTransaction();
trans.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
if(LocalWebViewFragment.class.isAssignableFrom(viewController.getClass())) {
trans.add(_viewContainerId, viewController, ((LocalWebViewFragment)viewController).getLocalPage());
} else {
trans.add(_viewContainerId, viewController, viewController.getClass().getName());
}
trans.addToBackStack(null);
trans.commit();
*/
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
Intent intent = new Intent(getActivity(), BaseViewControllerActivity.class);
String vcSessionKey = "PresentBaseViewController." + System.currentTimeMillis();
ServiceSupportApplication.singleton().setSessionValue(vcSessionKey, viewController);
intent.putExtra("baseViewControllerSessionKey", vcSessionKey);
getActivity().startActivity(intent);
} catch(Throwable e) {
Log.e(LOG_TAG, "presentPageView()", e);
}
}
});
}
/**
* present方式显示页面
* @param pageName 页面名
* @param setIntoNavigationAsRoot 该参数为保持和iOS版兼容,Android中不使用
*/
public void presentPage(String pageName, boolean setIntoNavigationAsRoot) {
presentPageView(createPageView(pageName), false);
}
/**
* 关闭present方式显示的画面(为了和IOS版兼容,保留参数animated)
*/
public void dismissSelf(boolean animated) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
try {
//getActivity().getSupportFragmentManager().popBackStack();
getActivity().finish();
} catch(Throwable e) {
Log.e(LOG_TAG, "dismissSelf()", e);
}
}
});
}
public void enableScrollBar() {
getWebView().setScrollbarFadingEnabled(false);
getWebView().setVerticalScrollBarEnabled(true);
}
public void disableScrollBar() {
getWebView().setScrollbarFadingEnabled(true);
getWebView().setVerticalScrollBarEnabled(false);
}
private final static long CREATE_PAGE_LIMIT_INTERVAL_MS = 700;
/**
* 在部分Android版本的WebView中存在一次click事件被提交2次的bug,此方法用于解决这个问题。
* @param pageName
* @return
*/
private boolean isCreateLocalPageTwiceInvoked(String pageName) {
Long currentTime = Long.valueOf(System.currentTimeMillis());
Long lastTime = _localPageLastCreateTimeMapping.get(pageName);
boolean isTwiceInvoked = false;
if(lastTime != null
&& (currentTime.longValue() - lastTime.longValue()) <= CREATE_PAGE_LIMIT_INTERVAL_MS) {
SSLog.d(LOG_TAG, "isCreateLocalPageTwiceInvoked() true");
isTwiceInvoked = true;
}
_localPageLastCreateTimeMapping.put(pageName, currentTime);
return isTwiceInvoked;
}
/************************************* Interfaces above <-------- **************************/
}