@@ -25,7 +25,7 @@ android { | |||
compileSdkVersion 28 | |||
defaultConfig { | |||
minSdkVersion 16 | |||
minSdkVersion 21 | |||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |||
} | |||
lintOptions { | |||
@@ -36,3 +36,8 @@ android { | |||
} | |||
} | |||
dependencies { | |||
implementation 'androidx.appcompat:appcompat:1.2.0' | |||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | |||
} |
@@ -1,3 +1,13 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
package="cn.zhios.zhiying_base_widget"> | |||
</manifest> | |||
package="cn.zhios.zhiying_base_widget"> | |||
<application> | |||
<activity | |||
android:name=".WebViewActivity" | |||
android:usesCleartextTraffic="true" | |||
android:hardwareAccelerated="true" | |||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"></activity> | |||
</application> | |||
</manifest> |
@@ -0,0 +1,541 @@ | |||
package cn.zhios.zhiying_base_widget; | |||
import androidx.annotation.NonNull; | |||
import androidx.annotation.RequiresApi; | |||
import androidx.appcompat.app.AppCompatActivity; | |||
import androidx.core.app.ActivityCompat; | |||
import androidx.core.content.ContextCompat; | |||
import android.Manifest; | |||
import android.app.Activity; | |||
import android.content.ComponentName; | |||
import android.content.Context; | |||
import android.content.Intent; | |||
import android.content.pm.PackageInfo; | |||
import android.content.pm.PackageManager; | |||
import android.graphics.Color; | |||
import android.graphics.drawable.ColorDrawable; | |||
import android.net.Uri; | |||
import android.os.Build; | |||
import android.os.Bundle; | |||
import android.util.Log; | |||
import android.view.KeyEvent; | |||
import android.view.MotionEvent; | |||
import android.view.View; | |||
import android.view.WindowManager; | |||
import android.webkit.GeolocationPermissions; | |||
import android.webkit.WebChromeClient; | |||
import android.webkit.WebSettings; | |||
import android.webkit.WebView; | |||
import android.webkit.WebViewClient; | |||
import android.widget.ImageView; | |||
import android.widget.ProgressBar; | |||
import android.widget.TextView; | |||
import android.widget.Toast; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.logging.Logger; | |||
public class WebViewActivity extends AppCompatActivity { | |||
WebView webview; | |||
ImageView back; | |||
ImageView refresh; | |||
ProgressBar progressBar; | |||
TextView tvTitle; | |||
Boolean isRequestPre = false; | |||
String url; | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.activity_web_view); | |||
getWindow().setStatusBarColor(Color.TRANSPARENT); | |||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); | |||
url = getIntent().getStringExtra("url"); | |||
Log.d("请求连接:", url); | |||
webview = findViewById(R.id.web); | |||
back = findViewById(R.id.iv_back); | |||
refresh = findViewById(R.id.iv_refresh); | |||
progressBar = findViewById(R.id.pg_bar); | |||
tvTitle = findViewById(R.id.tv_title); | |||
back.setOnClickListener( | |||
new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
if (webview.canGoBack()) { | |||
webview.goBack(); | |||
} else { | |||
isRequestPre = false; | |||
finish(); | |||
} | |||
} | |||
} | |||
); | |||
refresh.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
webview.reload(); | |||
} | |||
}); | |||
WebSettings settings = webview.getSettings(); | |||
settings.setJavaScriptEnabled(true);//启用js | |||
settings.setJavaScriptCanOpenWindowsAutomatically(true);//js和android交互 | |||
// String cacheDirPath = PathCommonDefines.WEBVIEW_CACHE; | |||
// | |||
// settings.setAppCachePath(cacheDirPath); //设置缓存的指定路径 | |||
settings.setAllowFileAccess(true); // 允许访问文件 | |||
settings.setAppCacheEnabled(true); //设置H5的缓存打开,默认关闭 | |||
settings.setUseWideViewPort(true);//设置webview自适应屏幕大小 | |||
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);//设置,可能的话使所有列的宽度不超过屏幕宽度 | |||
settings.setLoadWithOverviewMode(true);//设置webview自适应屏幕大小 | |||
settings.setDomStorageEnabled(true);//设置可以使用localStorage | |||
settings.setSupportZoom(false);//关闭zoom按钮 | |||
settings.setBuiltInZoomControls(false);//关闭zoom | |||
settings.setGeolocationEnabled(true); | |||
webview.setVerticalScrollBarEnabled(false); | |||
// | |||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { | |||
// webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null); | |||
// | |||
// } | |||
webview.setWebViewClient(new WebViewClient() { | |||
@Override | |||
public boolean shouldOverrideUrlLoading(WebView view, String url) { | |||
Log.d("WEB重定向", url); | |||
if (WebViewActivity.this.isFinishing()) { | |||
return true; | |||
} | |||
Intent intent2 = new Intent(); | |||
intent2.putExtra("url", url); | |||
WebViewActivity.this.setResult(20210501, intent2); | |||
if (url.startsWith("http://") || url.startsWith("https://")) { | |||
} else { | |||
try { | |||
/** | |||
* 统一的scheme协议打开第三方app,若出错说明没有安装该app | |||
* 捕获到错误后不继续加载该url以免加载出错 | |||
*/ | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||
startActivity(intent); | |||
return true; | |||
} catch (Exception e) { | |||
} | |||
} | |||
if (url.startsWith("tel:")) { | |||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); | |||
return true; | |||
} | |||
if (url.startsWith("bdnetdisk:")) { | |||
return true; | |||
} | |||
if (url.contains("vipshop://")) {//打开唯品会 | |||
if (isAvilible(WebViewActivity.this, "com.achievo.vipshop")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装唯品会app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("androidamap://")) { | |||
if (isAvilible(WebViewActivity.this, "com.autonavi.minimap")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
startActivity(intent); | |||
return true; | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装高德地图app", Toast.LENGTH_SHORT).show(); | |||
} | |||
} | |||
if (url.contains("didapinche://")) { | |||
if (isAvilible(WebViewActivity.this, "com.didapinche.booking")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装滴答出行app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("tmast://")) { | |||
try { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
startActivity(intent); | |||
} catch (Exception e) { | |||
Toast.makeText(WebViewActivity.this, "请先安装应用宝app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.startsWith("http://ditu.amap.com") || | |||
url.startsWith("https://ditu.amap.com")) { | |||
return true; | |||
} | |||
//品牌店家点击商品,请求接口进行相应的跳转 | |||
if (url.contains("h5.m.taobao.com/awp/core/detail") || url.contains("detail.m.tmall.com/item.htm") | |||
|| url.contains("item.m.jd.com/product") || (url.contains("item.m.jd.com/ware/view.action") | |||
|| url.contains("wareId=") || url.contains("h5.m.taobao.com/trip/travel-detail/index/index.htm")) | |||
|| url.contains("detail.tmall.hk/hk") || url.contains("vip.com/product") | |||
|| url.contains("suning.com/product") || url.contains("kaola.com/product") | |||
|| url.contains("yangkeduo.com/goods")) { | |||
} | |||
if (url.contains("tbopen://") || url.contains("tmall://") || url.contains("taobaotravel://")) { | |||
return true; | |||
} | |||
if (url.contains("openapp.jdmobile:")) { | |||
//打开京东app | |||
if (isAvilible(WebViewActivity.this, "com.jingdong.app.mall")) { | |||
} | |||
return true; | |||
} | |||
if (url.contains("pinduoduo://com.xunmeng.pinduoduo")) { | |||
if (isAvilible(WebViewActivity.this, "com.xunmeng.pinduoduo")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装拼多多app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("imeituan://")) {//打开美团 | |||
if (isAvilible(WebViewActivity.this, "com.sankuai.meituan")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装美团app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("suning://")) { | |||
if (isAvilible(WebViewActivity.this, "com.suning.mobile.ebuy")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装苏宁app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("kaola://")) { | |||
if (isAvilible(WebViewActivity.this, "com.kaola")) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装考拉app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("dianping://")) { | |||
return true; | |||
} | |||
if (url.contains("aliim:")) { | |||
return true; | |||
} | |||
if (url.contains("?mod=appapi&act=miandan_course&ctrl=close")) { | |||
finish(); | |||
return true; | |||
} | |||
if (url.contains("vipma.net/quickapp.html?")) { | |||
return true; | |||
} | |||
if (url.contains("cxcwallet://")) { | |||
if (isAvilible(WebViewActivity.this, "com.cxcblock.wallet")) {//传入指定应用包名 | |||
Intent intent = new Intent(); | |||
intent.setData(Uri.parse(url)); | |||
startActivity(intent); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装CXCapp", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
// 如下方案可在非微信内部WebView的H5页面中调出微信支付 | |||
if (url.startsWith("weixin://wap/pay?")) { | |||
try { | |||
Intent intent = new Intent(); | |||
intent.setAction(Intent.ACTION_VIEW); | |||
intent.setData(Uri.parse(url)); | |||
startActivity(intent); | |||
return true; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
Toast.makeText(WebViewActivity.this, "请先安装微信app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.startsWith("weixin://")) { | |||
try { | |||
Intent intent = new Intent(); | |||
intent.setAction(Intent.ACTION_VIEW); | |||
intent.setData(Uri.parse(url)); | |||
startActivity(intent); | |||
return true; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
Toast.makeText(WebViewActivity.this, "请先安装微信app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.endsWith("native://wechat")) { | |||
Intent intent = new Intent(); | |||
ComponentName cmp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"); | |||
intent.setAction(Intent.ACTION_MAIN); | |||
intent.addCategory(Intent.CATEGORY_LAUNCHER); | |||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||
intent.setComponent(cmp); | |||
startActivity(intent); | |||
return true; | |||
} | |||
// if (url.contains("navite://save#")) { | |||
// String[] split = url.split("navite://save#"); | |||
// SDFileHelper sdFileHelper = new SDFileHelper(mActivity); | |||
// sdFileHelper.setOnDownloadFinishListener(new SDFileHelper.OnDownloadFinishListener() { | |||
// @Override | |||
// public void onDownloadFinish(String filePath) { | |||
// ToastUtils.showShort("图片已保存到内存卡根目录" + AppUtil.getAppName() + "文件夹中"); | |||
// } | |||
// }); | |||
// sdFileHelper.savePicture("we_chat_qr_code" + ".jpg", split[1], true); | |||
// return true; | |||
// } | |||
//不拦截的话绑定淘宝关系id的时候会因为下面login.m.taobao.com的拦截而唤醒手淘授权之后导致不能切换帐号 | |||
// if (url.contains("client_id") && url.contains("login.m.taobao.com/logout.htm?")) { | |||
// view.loadUrl(url); | |||
// return true; | |||
// } | |||
if (url.contains("client_id")) { | |||
view.loadUrl(url); | |||
return true; | |||
} | |||
// if (url.contains("login.m.taobao.com")) { | |||
// AliLoginMethodUtil.AliLoginMethod(new AliLoginMethodUtil.AliLoginListener() { | |||
// @Override | |||
// public void loginSuccess(String s, String s1, Session session) { | |||
// | |||
// } | |||
// | |||
// @Override | |||
// public void LoginFail(int i, String s) { | |||
// | |||
// } | |||
// }); | |||
// return true; | |||
// } | |||
if (url.contains("alipays://platformapi")) { | |||
if (checkAliPayInstalled()) { | |||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||
startActivity(intent); | |||
// finish(); | |||
} else { | |||
Toast.makeText(WebViewActivity.this, "请先安装支付宝app", Toast.LENGTH_SHORT).show(); | |||
} | |||
return true; | |||
} | |||
if (url.contains("intent://go/ju/webview?")) { | |||
return true; | |||
} | |||
if (url.contains("deterorder")) { | |||
webview.loadUrl(url); | |||
return true; | |||
} | |||
if (getIntent().getBooleanExtra("isSearchEnter", false) && url.contains("sku=")) { | |||
} | |||
return !(url.startsWith("http://") || url.startsWith("https://")); | |||
} | |||
@Override | |||
public void onLoadResource(WebView view, String url) { | |||
} | |||
@Override | |||
public void onPageFinished(WebView view, String url) { | |||
} | |||
}); | |||
webview.setWebChromeClient(new WebChromeClient() { | |||
@Override | |||
synchronized public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { | |||
callback.invoke(origin, true, false); | |||
// if (!isRequestPre) { | |||
// isRequestPre = true; | |||
// quanxian(WebViewActivity.this); | |||
// } | |||
} | |||
@Override | |||
public void onProgressChanged(WebView view, int newProgress) { | |||
super.onProgressChanged(view, newProgress); | |||
progressBar.setProgress(newProgress); | |||
if (newProgress == 100) { | |||
progressBar.setVisibility(View.GONE); | |||
} else { | |||
progressBar.setVisibility(View.VISIBLE); | |||
} | |||
} | |||
@Override | |||
public void onReceivedTitle(WebView view, String title) { | |||
super.onReceivedTitle(view, title); | |||
if (title != null && title.length() != 0) { | |||
tvTitle.setText(title); | |||
} else { | |||
tvTitle.setText(url); | |||
} | |||
} | |||
}); | |||
webview.loadUrl(url); | |||
} | |||
/** | |||
* 检测是否安装支付宝app | |||
* | |||
* @return | |||
*/ | |||
public boolean checkAliPayInstalled() { | |||
Uri uri = Uri.parse("alipays://platformapi/startApp"); | |||
Intent intent = new Intent(Intent.ACTION_VIEW, uri); | |||
ComponentName componentName = intent.resolveActivity(getPackageManager()); | |||
return componentName != null; | |||
} | |||
/** | |||
* 检查手机上是否安装了指定的软件 | |||
* | |||
* @param context | |||
* @param packageName:应用包名 | |||
* @return | |||
*/ | |||
private boolean isAvilible(Context context, String packageName) { | |||
//获取packagemanager | |||
final PackageManager packageManager = context.getPackageManager(); | |||
//获取所有已安装程序的包信息 | |||
List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0); | |||
//用于存储所有已安装程序的包名 | |||
List<String> packageNames = new ArrayList<String>(); | |||
//从pinfo中将包名字逐一取出,压入pName list中 | |||
if (packageInfos != null) { | |||
for (int i = 0; i < packageInfos.size(); i++) { | |||
String packName = packageInfos.get(i).packageName; | |||
packageNames.add(packName); | |||
} | |||
} | |||
//判断packageNames中是否有目标程序的包名,有TRUE,没有FALSE | |||
return packageNames.contains(packageName); | |||
} | |||
/** | |||
* 检查是否安装手机淘宝 | |||
* | |||
* @param context | |||
* @return | |||
*/ | |||
public static boolean isInstallTaoBao(Context context) { | |||
PackageInfo packageInfo = null; | |||
try { | |||
packageInfo = context.getPackageManager().getPackageInfo("com.taobao.taobao", 0); | |||
} catch (Exception e) { | |||
packageInfo = null; | |||
e.printStackTrace(); | |||
} | |||
if (packageInfo == null) { | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
} | |||
///检查并请求定位权限 | |||
public void quanxian(final Activity context) { | |||
Log.d("权限请求", "------------"); | |||
try { | |||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |||
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { | |||
Log.d("权限请求", "无定位权限------------"); | |||
ActivityCompat.requestPermissions(context, | |||
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 20210422); | |||
} | |||
} | |||
} catch (SecurityException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
@Override | |||
public boolean onKeyDown(int keyCode, KeyEvent event) { | |||
if (keyCode == KeyEvent.KEYCODE_BACK) { | |||
if (webview.canGoBack()) { | |||
webview.goBack(); | |||
return true; | |||
} | |||
isRequestPre = true; | |||
} | |||
return super.onKeyDown(keyCode, event); | |||
} | |||
@Override | |||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | |||
if (requestCode == 20210422) { | |||
Log.d("权限请求", "定位权限回调------------"); | |||
webview.clearCache(true); | |||
webview.loadUrl(url); | |||
return; | |||
} | |||
super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |||
} | |||
@Override | |||
protected void onDestroy() { | |||
super.onDestroy(); | |||
webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); | |||
webview.destroy(); | |||
} | |||
} |
@@ -1,45 +1,90 @@ | |||
package cn.zhios.zhiying_base_widget; | |||
import android.app.Activity; | |||
import android.content.Intent; | |||
import androidx.annotation.NonNull; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import io.flutter.embedding.engine.plugins.FlutterPlugin; | |||
import io.flutter.embedding.engine.plugins.activity.ActivityAware; | |||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; | |||
import io.flutter.plugin.common.MethodCall; | |||
import io.flutter.plugin.common.MethodChannel; | |||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; | |||
import io.flutter.plugin.common.MethodChannel.Result; | |||
import io.flutter.plugin.common.PluginRegistry; | |||
import io.flutter.plugin.common.PluginRegistry.Registrar; | |||
/** ZhiyingBaseWidgetPlugin */ | |||
public class ZhiyingBaseWidgetPlugin implements FlutterPlugin, MethodCallHandler { | |||
@Override | |||
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { | |||
final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "zhiying_base_widget"); | |||
channel.setMethodCallHandler(new ZhiyingBaseWidgetPlugin()); | |||
} | |||
// This static function is optional and equivalent to onAttachedToEngine. It supports the old | |||
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting | |||
// plugin registration via this function while apps migrate to use the new Android APIs | |||
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration. | |||
// | |||
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep | |||
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called | |||
// depending on the user's project. onAttachedToEngine or registerWith must both be defined | |||
// in the same class. | |||
public static void registerWith(Registrar registrar) { | |||
final MethodChannel channel = new MethodChannel(registrar.messenger(), "zhiying_base_widget"); | |||
channel.setMethodCallHandler(new ZhiyingBaseWidgetPlugin()); | |||
} | |||
@Override | |||
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { | |||
if (call.method.equals("getPlatformVersion")) { | |||
result.success("Android " + android.os.Build.VERSION.RELEASE); | |||
} else { | |||
result.notImplemented(); | |||
} | |||
} | |||
@Override | |||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { | |||
} | |||
/** | |||
* ZhiyingBaseWidgetPlugin | |||
*/ | |||
public class ZhiyingBaseWidgetPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener { | |||
private Activity activity; | |||
private ActivityPluginBinding binding; | |||
private MethodChannel channel; | |||
@Override | |||
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { | |||
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "zhiying_base_widget"); | |||
channel.setMethodCallHandler(this); | |||
} | |||
@Override | |||
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { | |||
if (call.method.equals("getPlatformVersion")) { | |||
result.success("Android " + android.os.Build.VERSION.RELEASE); | |||
} else if (call.method.equals("loadUrl")) { | |||
String url = (String) ((Map<String, Object>) call.arguments).get("url"); | |||
Intent intent = new Intent(activity, WebViewActivity.class); | |||
intent.putExtra("url", url); | |||
activity.startActivityForResult(intent, 20210501); | |||
} else { | |||
result.notImplemented(); | |||
} | |||
} | |||
@Override | |||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { | |||
} | |||
@Override | |||
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { | |||
activity = binding.getActivity(); | |||
binding.addActivityResultListener(this); | |||
} | |||
@Override | |||
public void onDetachedFromActivityForConfigChanges() { | |||
if (binding != null) { | |||
binding.removeActivityResultListener(this); | |||
} | |||
} | |||
@Override | |||
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { | |||
} | |||
@Override | |||
public void onDetachedFromActivity() { | |||
} | |||
@Override | |||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) { | |||
if (requestCode == 20210501 && resultCode == 20210501) { | |||
HashMap<String, Object> map = new HashMap<>(); | |||
map.put("url", data.getStringExtra("url")); | |||
channel.invokeMethod("reload", map); | |||
return true; | |||
} | |||
return false; | |||
} | |||
} |
@@ -0,0 +1,5 @@ | |||
<vector android:height="24dp" android:tint="#636363" | |||
android:viewportHeight="24" android:viewportWidth="24" | |||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<path android:fillColor="@android:color/white" android:pathData="M15.41,16.59L10.83,12l4.58,-4.59L14,6l-6,6 6,6 1.41,-1.41z"/> | |||
</vector> |
@@ -0,0 +1,5 @@ | |||
<vector android:height="24dp" android:tint="#636363" | |||
android:viewportHeight="24" android:viewportWidth="24" | |||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<path android:fillColor="@android:color/white" android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/> | |||
</vector> |
@@ -0,0 +1,67 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<RelativeLayout 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" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:background="#FFFFFF" | |||
tools:context=".WebViewActivity"> | |||
<LinearLayout | |||
android:id="@+id/ly_ll" | |||
android:orientation="vertical" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content"> | |||
<RelativeLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="48dp"> | |||
<ImageView | |||
android:id="@+id/iv_back" | |||
android:layout_width="32dp" | |||
android:layout_height="32dp" | |||
android:layout_alignParentLeft="true" | |||
android:layout_marginLeft="10dp" | |||
android:layout_centerVertical="true" | |||
android:clickable="true" | |||
android:focusable="true" | |||
android:background="@drawable/ic_baseline_keyboard_arrow_left_24" | |||
/> | |||
<TextView | |||
android:id="@+id/tv_title" | |||
android:maxLines="1" | |||
android:maxWidth="200dp" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_centerHorizontal="true" | |||
android:layout_centerVertical="true" | |||
android:text="" | |||
android:textColor="#FF333333" | |||
android:textStyle="bold" | |||
android:textSize="17sp" /> | |||
<ImageView | |||
android:id="@+id/iv_refresh" | |||
android:layout_width="24dp" | |||
android:layout_height="24dp" | |||
android:layout_alignParentRight="true" | |||
android:layout_marginRight="16dp" | |||
android:layout_centerVertical="true" | |||
android:background="@drawable/ic_baseline_refresh_24" | |||
/> | |||
</RelativeLayout> | |||
<ProgressBar | |||
android:id="@+id/pg_bar" | |||
android:layout_width="match_parent" | |||
android:layout_height="2dp" | |||
style="?android:progressBarStyleHorizontal" | |||
/> | |||
</LinearLayout> | |||
<WebView | |||
android:id="@+id/web" | |||
android:focusable="true" | |||
android:layout_below="@id/ly_ll" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent"/> | |||
</RelativeLayout> |
@@ -0,0 +1 @@ | |||
<resources></resources> |
@@ -36,7 +36,7 @@ dev_dependencies: | |||
path: ../../zhiying_acquisition | |||
zhiying_shopping_mall: | |||
git: | |||
ref: 0.0.4 | |||
ref: 0.0.5 | |||
url: 'http://192.168.0.138:3000/FnuoOS_ZhiYing/zhiying_shopping_mall.git' | |||
zhiying_credit_card: | |||
path: ../../zhiying_credit_card | |||
@@ -11,6 +11,7 @@ import 'bloc/about_us_event.dart'; | |||
import 'bloc/about_us_state.dart'; | |||
import 'package:zhiying_comm/util/shared_prefe_util.dart'; | |||
import 'package:zhiying_comm/util/global_config.dart'; | |||
/// | |||
/// 关于我们 | |||
/// | |||
@@ -36,7 +37,7 @@ class _AboutUsPageContainer extends StatefulWidget { | |||
class __AboutUsPageContainerState extends State<_AboutUsPageContainer> { | |||
/// 检查更新 | |||
void _onClickCheckUpdate() async{ | |||
void _onClickCheckUpdate() async { | |||
Logger.log('点击了更新'); | |||
AppUpdateUtil.updateApp(context, needToast: true, mustShowDialog: true); | |||
} | |||
@@ -52,17 +53,18 @@ class __AboutUsPageContainerState extends State<_AboutUsPageContainer> { | |||
_onClickCheckUpdate(); | |||
} else if (model.type == 'comment') { | |||
_onClickEvaluation(); | |||
} | |||
} else if (model.type == "") { | |||
} else if (model.type == "") {} | |||
} | |||
bool _isiOSReview = false; | |||
@override | |||
void initState() { | |||
_settingIosReview(); | |||
super.initState(); | |||
} | |||
void _settingIosReview() async { | |||
String is_ios_review = await SharedPreferencesUtil.getStringValue(GlobalConfig.IS_IOS_REVIEW, defaultVal: '0'); | |||
setState(() { | |||
@@ -151,12 +153,12 @@ class __AboutUsPageContainerState extends State<_AboutUsPageContainer> { | |||
/// 更新,评价 | |||
_isiOSReview ? Container() : _buildListWidget(model), | |||
_buildAgreement(model) | |||
], | |||
), | |||
); | |||
} | |||
/// 列表 | |||
Widget _buildListWidget(AboutUsModel model) { | |||
List<Widget> widgets = []; | |||
@@ -165,7 +167,7 @@ class __AboutUsPageContainerState extends State<_AboutUsPageContainer> { | |||
widgets.add(Container()); | |||
} else { | |||
model.settings.forEach((element) { | |||
if(element.type == 'comment'){ | |||
if (element.type == 'comment') { | |||
return; | |||
} | |||
widgets.add(GestureDetector( | |||
@@ -228,4 +230,46 @@ class __AboutUsPageContainerState extends State<_AboutUsPageContainer> { | |||
elevation: 0, | |||
); | |||
} | |||
_buildAgreement(AboutUsModel model) { | |||
List<Widget> widgets = []; | |||
int length = model?.articles?.length ?? 0; | |||
if (length == 0) { | |||
widgets.add(Container()); | |||
} else { | |||
model.articles.forEach((element) { | |||
widgets.add(GestureDetector( | |||
onTap: () => _onClickAgreementItem(element), | |||
behavior: HitTestBehavior.opaque, | |||
child: Container( | |||
margin: const EdgeInsets.symmetric(vertical: 15), | |||
child: Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Text( | |||
element?.title ?? '', | |||
style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 13, fontWeight: FontWeight.bold), | |||
), | |||
Icon( | |||
Icons.arrow_forward_ios, | |||
color: HexColor.fromHex('#999999'), | |||
size: 14, | |||
) | |||
], | |||
), | |||
), | |||
)); | |||
}); | |||
return Column( | |||
children: widgets, | |||
); | |||
} | |||
} | |||
_onClickAgreementItem(Articles element) { | |||
if (element.link != null) { | |||
RouterUtil.openWebview(element.link, context); | |||
} | |||
} | |||
} |
@@ -9,25 +9,25 @@ class AboutUsModel { | |||
String appVersionColor; | |||
List<String> dataKeys; | |||
List<Settings> settings; | |||
List<Articles> articles; | |||
String bottomName; | |||
String bottomNameColor; | |||
String appVerison; | |||
AboutUsModel({ | |||
this.appBarName, | |||
this.appBarNameColor, | |||
this.appBarBgColor, | |||
this.bgColor, | |||
this.settingsBgColor, | |||
this.appLogo, | |||
this.appVersionText, | |||
this.appVersionColor, | |||
this.dataKeys, | |||
this.settings, | |||
this.bottomName, | |||
this.bottomNameColor, | |||
this.appVerison, | |||
}); | |||
AboutUsModel( | |||
{this.appBarName, | |||
this.appBarNameColor, | |||
this.appBarBgColor, | |||
this.bgColor, | |||
this.settingsBgColor, | |||
this.appLogo, | |||
this.appVersionText, | |||
this.appVersionColor, | |||
this.dataKeys, | |||
this.settings, | |||
this.articles, | |||
this.bottomName, | |||
this.bottomNameColor}); | |||
AboutUsModel.fromJson(Map<String, dynamic> json) { | |||
appBarName = json['app_bar_name']; | |||
@@ -38,7 +38,6 @@ class AboutUsModel { | |||
appLogo = json['app_logo']; | |||
appVersionText = json['app_version_text']; | |||
appVersionColor = json['app_version_color']; | |||
appVerison = json['appVerison']; | |||
dataKeys = json['data_keys'].cast<String>(); | |||
if (json['settings'] != null) { | |||
settings = new List<Settings>(); | |||
@@ -46,6 +45,12 @@ class AboutUsModel { | |||
settings.add(new Settings.fromJson(v)); | |||
}); | |||
} | |||
if (json['articles'] != null) { | |||
articles = new List<Articles>(); | |||
json['articles'].forEach((v) { | |||
articles.add(new Articles.fromJson(v)); | |||
}); | |||
} | |||
bottomName = json['bottom_name']; | |||
bottomNameColor = json['bottom_name_color']; | |||
} | |||
@@ -64,16 +69,18 @@ class AboutUsModel { | |||
if (this.settings != null) { | |||
data['settings'] = this.settings.map((v) => v.toJson()).toList(); | |||
} | |||
if (this.articles != null) { | |||
data['articles'] = this.articles.map((v) => v.toJson()).toList(); | |||
} | |||
data['bottom_name'] = this.bottomName; | |||
data['bottom_name_color'] = this.bottomNameColor; | |||
data['appVerison'] = this.appVerison; | |||
return data; | |||
} | |||
} | |||
class Settings { | |||
List<String> dataKeys; | |||
String type; | |||
List<String> dataKeys; | |||
String name; | |||
String subName; | |||
String nameColor; | |||
@@ -82,12 +89,21 @@ class Settings { | |||
String descColor; | |||
String skipIdentifier; | |||
Settings({this.dataKeys, this.name, this.subName, this.nameColor, this.subNameColor, this.descText, this.descColor, this.skipIdentifier}); | |||
Settings( | |||
{this.type, | |||
this.dataKeys, | |||
this.name, | |||
this.subName, | |||
this.nameColor, | |||
this.subNameColor, | |||
this.descText, | |||
this.descColor, | |||
this.skipIdentifier}); | |||
Settings.fromJson(Map<String, dynamic> json) { | |||
type = json['type']; | |||
dataKeys = json['data_keys'].cast<String>(); | |||
name = json['name']; | |||
type = json['type']; | |||
subName = json['sub_name']; | |||
nameColor = json['name_color']; | |||
subNameColor = json['sub_name_color']; | |||
@@ -98,8 +114,8 @@ class Settings { | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type'] = this.type; | |||
data['data_keys'] = this.dataKeys; | |||
data['type'] = this.type; | |||
data['name'] = this.name; | |||
data['sub_name'] = this.subName; | |||
data['name_color'] = this.nameColor; | |||
@@ -110,3 +126,25 @@ class Settings { | |||
return data; | |||
} | |||
} | |||
class Articles { | |||
String type; | |||
String title; | |||
String link; | |||
Articles({this.type, this.title, this.link}); | |||
Articles.fromJson(Map<String, dynamic> json) { | |||
type = json['type']; | |||
title = json['title']; | |||
link = json['link']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type'] = this.type; | |||
data['title'] = this.title; | |||
data['link'] = this.link; | |||
return data; | |||
} | |||
} |
@@ -1,8 +1,10 @@ | |||
import 'dart:async'; | |||
import 'dart:io'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter_user_agent/flutter_user_agent.dart'; | |||
import 'package:jdsdk/jdsdk.dart'; | |||
import 'package:permission_handler/permission_handler.dart'; | |||
import 'package:sharesdk_plugin/sharesdk_interface.dart'; | |||
import 'package:sharesdk_plugin/sharesdk_register.dart'; | |||
import 'package:zhiying_base_widget/models/app_config_model.dart'; | |||
@@ -131,7 +133,8 @@ class BaseWidgetRegister { | |||
register.setupWechat(config.keys?.weixin?.appId ?? '', config.keys?.weixin?.secret ?? '', config.keys?.weixin?.universalLink ?? ''); | |||
register.setupSinaWeibo(config.keys?.weibo?.appkey ?? '', config.keys?.weibo?.secret ?? '', config.keys?.weibo?.redirectUrl ?? '', config.keys?.weibo?.universalLink ?? 'templink'); | |||
register.setupSinaWeibo( | |||
config.keys?.weibo?.appkey ?? '', config.keys?.weibo?.secret ?? '', config.keys?.weibo?.redirectUrl ?? '', config.keys?.weibo?.universalLink ?? 'templink'); | |||
register.setupQQ(config.keys?.qq?.appId ?? '', config.keys?.qq?.appkey ?? ''); | |||
@@ -201,6 +204,17 @@ class BaseWidgetRegister { | |||
Application.addMethod(() async { | |||
// return Future.delayed(Duration(seconds: 1)); | |||
}); | |||
Application.addStringParamsMethod( | |||
type: "openUrl", | |||
method: (data) async { | |||
if (!EmptyUtil.isEmpty(data)) { | |||
if (!await Permission.location.isGranted) { | |||
await showDialog(context: navigatorKey.currentState.overlay.context, child: NotificationSettingDialogNew([NotificationSettingDialogNew.locationPermissModel])); | |||
} | |||
ZhiyingBaseWidget.loadUrl(data['url']); | |||
} | |||
}); | |||
} | |||
// 注册页面 | |||
@@ -3,6 +3,7 @@ import 'dart:convert'; | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:tab_indicator_styler/tab_indicator_styler.dart'; | |||
import 'package:zhiying_base_widget/dialog/loading/loading.dart'; | |||
import 'package:zhiying_base_widget/dialog/tip_dialog/tip_dialog.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/model/wallet_detail_model.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_bloc.dart'; | |||
@@ -70,6 +71,7 @@ class _WalletDetailState extends State<WalletDetail> with TickerProviderStateMix | |||
///骨架图 | |||
return WalletDetailSkeleton(); | |||
} | |||
Loading.dismiss(); | |||
return Container( | |||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 7.5, bottom: 7.5), | |||
@@ -98,6 +100,7 @@ class _WalletDetailState extends State<WalletDetail> with TickerProviderStateMix | |||
indicatorSize: TabBarIndicatorSize.label, | |||
onTap: (index) { | |||
///变更平台 | |||
Loading.show(context); | |||
changeProvider(_model.providers[index].type); | |||
}, | |||
tabs: _buildTabs()), | |||
@@ -212,6 +215,7 @@ class _WalletDetailState extends State<WalletDetail> with TickerProviderStateMix | |||
), | |||
), | |||
onTap: () { | |||
Loading.show(context); | |||
_bloc.selectDay = item.type; | |||
_bloc.loadData(_bloc.currentType, _bloc.selectDay); | |||
}, | |||
@@ -1,6 +1,7 @@ | |||
import 'dart:async'; | |||
import 'dart:convert'; | |||
import 'package:zhiying_base_widget/dialog/loading/loading.dart'; | |||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
@@ -42,7 +43,11 @@ class WalletDetailBloc extends BlocBase { | |||
currentWalletDetailDataModel = listDataModel[0]; | |||
refresh(); | |||
} | |||
}); | |||
Loading.dismiss(); | |||
}, onError: (e) { | |||
Fluttertoast.showToast(msg: "加载数据出了小差"); | |||
Loading.dismiss(); | |||
}, timeOut: 60000); | |||
} | |||
///刷新页面 | |||
@@ -1,5 +1,7 @@ | |||
library zhiying_base_widget; | |||
import 'package:flutter/services.dart'; | |||
export 'dialog/loading/loading.dart'; | |||
export 'package:flutter_swiper/flutter_swiper.dart'; | |||
export 'package:zhiying_base_widget/pages/main_page/model/background_model.dart'; | |||
@@ -11,3 +13,27 @@ export 'package:amap_flutter_location/amap_flutter_location.dart'; | |||
export 'package:amap_flutter_location/amap_location_option.dart'; | |||
export 'package:tab_indicator_styler/tab_indicator_styler.dart'; | |||
export 'package:zhiying_base_widget/dialog/global_dialog/notification_setting_dialog/notification_setting_dialog.dart'; | |||
class ZhiyingBaseWidget { | |||
static const MethodChannel _channel = const MethodChannel('zhiying_base_widget'); | |||
///监听重定向的方法 | |||
static addListener(Function(String) reload) { | |||
_channel.setMethodCallHandler((call) { | |||
if (call.method == "reload") { | |||
reload(call.arguments['url']); | |||
} | |||
return null; | |||
}); | |||
} | |||
///打开原生webView | |||
static loadUrl(String url) async { | |||
await _channel.invokeMethod("loadUrl", {"url": url}); | |||
} | |||
static Future<String> get platformVersion async { | |||
final String version = await _channel.invokeMethod('getPlatformVersion'); | |||
return version; | |||
} | |||
} |