@@ -34,7 +34,7 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" | |||||
android { | android { | ||||
compileSdkVersion 28 | compileSdkVersion 29 | ||||
lintOptions { | lintOptions { | ||||
disable 'InvalidPackage' | disable 'InvalidPackage' | ||||
@@ -44,7 +44,7 @@ android { | |||||
defaultConfig { | defaultConfig { | ||||
applicationId "cn.zhios.zhiying" | applicationId "cn.zhios.zhiying" | ||||
minSdkVersion 21 | minSdkVersion 21 | ||||
targetSdkVersion 28 | targetSdkVersion 29 | ||||
versionCode 1 | versionCode 1 | ||||
versionName "1.0" | versionName "1.0" | ||||
aaptOptions.cruncherEnabled = false | aaptOptions.cruncherEnabled = false | ||||
@@ -157,9 +157,33 @@ flutter { | |||||
} | } | ||||
dependencies { | dependencies { | ||||
implementation 'androidx.appcompat:appcompat:1.2.0' | |||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.2' | |||||
testImplementation 'junit:junit:4.12' | testImplementation 'junit:junit:4.12' | ||||
androidTestImplementation 'androidx.test:runner:1.1.1' | androidTestImplementation 'androidx.test:runner:1.1.1' | ||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' | ||||
//登陆 | |||||
implementation 'com.ali.auth.sdk:alibabauth_core:2.0.0.11@aar' | |||||
implementation 'com.ali.auth.sdk:alibabauth_ui:2.0.0.11@aar' | |||||
implementation 'com.ali.auth.sdk:alibabauth_ext:2.0.0.11@aar' | |||||
//安全组件 | |||||
implementation 'com.taobao.android:securityguardaar3:5.4.171@aar' | |||||
implementation 'com.taobao.android:securitybodyaar3:5.4.99@aar' | |||||
implementation 'com.taobao.android:avmpaar3:5.4.36@aar' | |||||
implementation 'com.taobao.android:sgmiddletieraar3:5.4.9@aar' | |||||
//Mtop | |||||
implementation 'com.taobao.android:mtopsdk_allinone_open:3.1.2.5@jar' | |||||
//applink | |||||
implementation 'com.alibaba.sdk.android:alibc_link_partner:4.1.15@aar' | |||||
//ut | |||||
implementation 'com.taobao.android:utdid4all:1.5.2' | |||||
implementation 'com.alibaba.mtl:app-monitor-sdk:2.6.4.5_for_bc' | |||||
// 电商基础组件 | |||||
implementation 'com.alibaba.sdk.android:AlibcTradeCommon:4.0.0.16@aar' | |||||
implementation 'com.alibaba.sdk.android:AlibcTradeBiz:4.0.0.16@aar' | |||||
implementation 'com.alibaba.sdk.android:nb_trade:4.0.0.16@aar' | |||||
implementation 'com.alibaba:fastjson:1.2.41@jar' | |||||
} | } | ||||
@@ -1,40 +1,51 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
xmlns:tools="http://schemas.android.com/tools" | xmlns:tools="http://schemas.android.com/tools" | ||||
package="cn.zhios.zhiying_base_widget_example"> | package="cn.zhios.zhiying_base_widget_example"> | ||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that | <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||||
calls FlutterMain.startInitialization(this); in its onCreate method. | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||||
In most cases you can leave this as-is, but you if you want to provide | <uses-permission android:name="android.permission.INTERNET" /> | ||||
additional functionality it is fine to subclass or reimplement | |||||
FlutterApplication and put your custom class here. --> | |||||
<application | <application | ||||
android:name="io.flutter.app.FlutterApplication" | android:name="io.flutter.app.FlutterApplication" | ||||
android:label="@string/app_name" | |||||
android:icon="@mipmap/ic_launcher" | android:icon="@mipmap/ic_launcher" | ||||
android:label="@string/app_name" | |||||
android:usesCleartextTraffic="true" | android:usesCleartextTraffic="true" | ||||
tools:replace="android:name"> | tools:replace="android:name"> | ||||
<activity android:name=".WebActivity"></activity> | |||||
<activity | |||||
android:name=".TestActivity" | |||||
android:theme="@style/Theme.AppCompat.NoActionBar"> | |||||
<!-- <intent-filter>--> | |||||
<!-- <action android:name="android.intent.action.MAIN" />--> | |||||
<!-- <category android:name="android.intent.category.LAUNCHER" />--> | |||||
<!-- </intent-filter>--> | |||||
</activity> | |||||
<activity | <activity | ||||
android:name=".MainActivity" | android:name=".MainActivity" | ||||
android:launchMode="singleTop" | |||||
android:theme="@style/LaunchTheme" | |||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | ||||
android:hardwareAccelerated="true" | android:hardwareAccelerated="true" | ||||
android:launchMode="singleTop" | |||||
android:theme="@style/LaunchTheme" | |||||
android:usesCleartextTraffic="true" | |||||
android:windowSoftInputMode="adjustResize"> | android:windowSoftInputMode="adjustResize"> | ||||
<intent-filter> | <intent-filter> | ||||
<action android:name="android.intent.action.MAIN" /> | <action android:name="android.intent.action.MAIN" /> | ||||
<category android:name="android.intent.category.LAUNCHER" /> | <category android:name="android.intent.category.LAUNCHER" /> | ||||
</intent-filter> | </intent-filter> | ||||
</activity> | </activity> | ||||
<!-- Don't delete the meta-data below. | <!-- | ||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> | Don't delete the meta-data below. | ||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java | |||||
--> | |||||
<meta-data | <meta-data | ||||
android:name="flutterEmbedding" | android:name="flutterEmbedding" | ||||
android:value="2" /> | android:value="2" /> | ||||
</application> | </application> | ||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | </manifest> | ||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |||||
<uses-permission android:name="android.permission.INTERNET"/> | |||||
</manifest> |
@@ -38,7 +38,8 @@ public class MainActivity extends FlutterActivity implements ZhiyingFlutterCommN | |||||
@Override | @Override | ||||
public Map getSetting() { | public Map getSetting() { | ||||
Map map = new HashMap(); | Map map = new HashMap(); | ||||
map.put("domain", "http://inapi.izhyin.cn"); //"http://120.76.175.204:8989"); | //map.put("domain", "http://inapi.izhyin.cn"); //"http://120.76.175.204:8989"); | ||||
map.put("domain", "http://192.168.0.113:5000"); | |||||
map.put("master_id", "123456"); | map.put("master_id", "123456"); | ||||
map.put("secret_key", "123456"); | map.put("secret_key", "123456"); | ||||
// map.put("token", "123465"); | // map.put("token", "123465"); | ||||
@@ -0,0 +1,108 @@ | |||||
package cn.zhios.zhiying_base_widget_example; | |||||
import androidx.appcompat.app.AppCompatActivity; | |||||
import android.app.Activity; | |||||
import android.content.Intent; | |||||
import android.os.Bundle; | |||||
import android.util.Log; | |||||
import android.view.View; | |||||
import android.webkit.WebChromeClient; | |||||
import android.webkit.WebView; | |||||
import android.webkit.WebViewClient; | |||||
import android.widget.TextView; | |||||
import android.widget.Toast; | |||||
import com.alibaba.baichuan.android.trade.AlibcTrade; | |||||
import com.alibaba.baichuan.android.trade.AlibcTradeSDK; | |||||
import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback; | |||||
import com.alibaba.baichuan.android.trade.callback.AlibcTradeInitCallback; | |||||
import com.alibaba.baichuan.android.trade.model.AlibcShowParams; | |||||
import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult; | |||||
import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams; | |||||
import com.alibaba.baichuan.trade.biz.login.AlibcLogin; | |||||
import com.alibaba.baichuan.trade.biz.login.AlibcLoginCallback; | |||||
import com.alibaba.baichuan.trade.common.utils.AlibcLogger; | |||||
import java.util.HashMap; | |||||
public class TestActivity extends Activity { | |||||
@Override | |||||
protected void onCreate(Bundle savedInstanceState) { | |||||
super.onCreate(savedInstanceState); | |||||
setContentView(R.layout.activity_test); | |||||
TextView aliBcTV = findViewById(R.id.tv_aliBc); | |||||
AlibcTradeSDK.asyncInit(this.getApplication(), new AlibcTradeInitCallback() { | |||||
@Override | |||||
public void onSuccess() { | |||||
Toast.makeText(TestActivity.this, "阿里百川注册成功", Toast.LENGTH_LONG).show(); | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
Toast.makeText(TestActivity.this, "阿里百川注册失败" + s, Toast.LENGTH_LONG).show(); | |||||
} | |||||
}); | |||||
aliBcTV.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) { | |||||
AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { | |||||
@Override | |||||
public void onSuccess(int i, String s, String s1) { | |||||
Toast.makeText(TestActivity.this, "授权成功" + s, Toast.LENGTH_LONG).show(); | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
Toast.makeText(TestActivity.this, "登陆失败" + s, Toast.LENGTH_LONG).show(); | |||||
} | |||||
}); | |||||
} | |||||
}); | |||||
findViewById(R.id.tv_open_detail).setOnClickListener(new View.OnClickListener() { | |||||
AlibcShowParams showParams = new AlibcShowParams(); | |||||
@Override | |||||
public void onClick(View v) { | |||||
// // 以显示传入url的方式打开页面(第二个参数是套件名称) | |||||
// AlibcTrade.openByUrl(TestActivity.this, "", "http://www.izhim.com/comm/tb_callback.php?_ctrl=domain&domain_state=MTI2&domain_return_url=aHR0cDovLzE5Mi4xNjguMC4xMTM6NTAwMC9hcGkvdjEvdGFvYmFvL2F1dGgvY2FsbGJhY2s%2FdGltZT0xNjAyNDk4MjA3", new WebView(TestActivity.this), | |||||
// new WebViewClient(), new WebChromeClient(), showParams, | |||||
// new AlibcTaokeParams("","",""), new HashMap<String,String>(), new AlibcTradeCallback() { | |||||
// @Override | |||||
// public void onTradeSuccess(AlibcTradeResult tradeResult) { | |||||
// AlibcLogger.i("", "request success"); | |||||
// } | |||||
// @Override | |||||
// public void onFailure(int code, String msg) { | |||||
// AlibcLogger.e("", "code=" + code + ", msg=" + msg); | |||||
// if (code == -1) { | |||||
// Toast.makeText(TestActivity.this, msg, Toast.LENGTH_SHORT).show(); | |||||
// } | |||||
// } | |||||
// }); | |||||
if (!AlibcLogin.getInstance().isLogin()) { | |||||
AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { | |||||
@Override | |||||
public void onSuccess(int i, String s, String s1) { | |||||
startActivity(new Intent(TestActivity.this,WebActivity.class)); | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
Log.d("阿里百川授权失败",s); | |||||
} | |||||
}); | |||||
} else { | |||||
startActivity(new Intent(TestActivity.this,WebActivity.class)); | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,521 @@ | |||||
package cn.zhios.zhiying_base_widget_example; | |||||
import android.annotation.SuppressLint; | |||||
import android.app.Activity; | |||||
import android.content.ComponentName; | |||||
import android.content.Intent; | |||||
import android.graphics.Bitmap; | |||||
import android.net.Uri; | |||||
import android.net.http.SslError; | |||||
import android.os.Bundle; | |||||
import android.util.Log; | |||||
import android.util.Patterns; | |||||
import android.view.View; | |||||
import android.webkit.GeolocationPermissions; | |||||
import android.webkit.JavascriptInterface; | |||||
import android.webkit.SslErrorHandler; | |||||
import android.webkit.ValueCallback; | |||||
import android.webkit.WebChromeClient; | |||||
import android.webkit.WebResourceError; | |||||
import android.webkit.WebResourceRequest; | |||||
import android.webkit.WebSettings; | |||||
import android.webkit.WebView; | |||||
import android.webkit.WebViewClient; | |||||
import android.widget.Toast; | |||||
import com.alibaba.baichuan.android.trade.AlibcTrade; | |||||
import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback; | |||||
import com.alibaba.baichuan.android.trade.model.AlibcShowParams; | |||||
import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult; | |||||
import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams; | |||||
import com.alibaba.baichuan.trade.biz.login.AlibcLogin; | |||||
import com.alibaba.baichuan.trade.biz.login.AlibcLoginCallback; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
public class WebActivity extends Activity { | |||||
WebView mainWeb; | |||||
@Override | |||||
protected void onCreate(Bundle savedInstanceState) { | |||||
super.onCreate(savedInstanceState); | |||||
setContentView(R.layout.activity_web_bc); | |||||
mainWeb = findViewById(R.id.webview_main); | |||||
mainWeb.getSettings().setJavaScriptEnabled(true); | |||||
mainWeb.getSettings().setDomStorageEnabled(true); | |||||
mainWeb.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); | |||||
mainWeb.getSettings().setLoadWithOverviewMode(true); | |||||
mainWeb.getSettings().setAllowFileAccess(true); | |||||
mainWeb.getSettings().setDatabaseEnabled(true); | |||||
MyWebClient myWebClient = new MyWebClient(); | |||||
MyWebChromeClient myWebChromeClient = new MyWebChromeClient(); | |||||
mainWeb.setWebViewClient(myWebClient); | |||||
mainWeb.setWebChromeClient(myWebChromeClient); | |||||
Map<String, String> exParams = new HashMap<>();//yhhpass参数 | |||||
// AlibcTaokeParams alibcTaokeParams = new AlibcTaokeParams("", "", ""); | |||||
// alibcTaokeParams.pid = SPUtils.getPrefString(mActivity, Pkey.pid, ""); | |||||
// alibcTaokeParams.adzoneid = SPUtils.getPrefString(mActivity, Pkey.APP_adzoneId, ""); | |||||
// alibcTaokeParams.extraParams = new HashMap<>(); | |||||
// alibcTaokeParams.extraParams.put("taokeAppkey", SPUtils.getPrefString(mActivity, Pkey.APP_alliance_appkey, "")); | |||||
AlibcShowParams showParams = new AlibcShowParams(); | |||||
showParams.setBackUrl("alisdk://"); | |||||
AlibcTrade.openByUrl(WebActivity.this, "", "http://www.izhim.com/comm/tb_callback.php?_ctrl=domain&domain_state=MTI2&domain_return_url=aHR0cDovLzE5Mi4xNjguMC4xMTM6NTAwMC9hcGkvdjEvdGFvYmFvL2F1dGgvY2FsbGJhY2s%2FdGltZT0xNjAyNDk4MjA3", | |||||
mainWeb, new MyBaichuanWebClient(), new MyWebChromeClient(), showParams, | |||||
new AlibcTaokeParams("", "", ""), exParams, new AlibcTradeCallback() { | |||||
@Override | |||||
public void onTradeSuccess(AlibcTradeResult alibcTradeResult) { | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
} | |||||
}); | |||||
} | |||||
//用于百川授权的简化的WebClient | |||||
@SuppressLint("AddJavascriptInterface") | |||||
private class MyBaichuanWebClient extends WebViewClient { | |||||
@SuppressLint("AddJavascriptInterface") | |||||
@Override | |||||
public boolean shouldOverrideUrlLoading(WebView view, final String url) { | |||||
Log.d("百川拦截", url); | |||||
//绑定会员关系时获取网页内容关闭网页 | |||||
if (url.contains("comm/tbredirect.php") && !url.contains("oauth.m.taobao.com") && url.contains("track_id")) { | |||||
Log.d("百川系时获取网页内容关闭网页", url); | |||||
mainWeb.addJavascriptInterface(new InJavaScriptLocalObj(), "java_obj"); | |||||
} | |||||
if (url.contains("oauth.taobao.com/authorize") || url.contains("oauth.m.taobao.com/authorize")) { | |||||
//渠道授权改动测试 | |||||
Log.d("百川渠道授权改动测试", url); | |||||
Map<String, String> exParams = new HashMap<>();//yhhpass参数 | |||||
AlibcShowParams showParams = new AlibcShowParams(); | |||||
showParams.setBackUrl("alisdk://"); | |||||
AlibcTrade.openByUrl(WebActivity.this, "", url, | |||||
mainWeb, new MyBaichuanWebClient(), new MyWebChromeClient(), showParams, | |||||
new AlibcTaokeParams("", "", ""), exParams, new AlibcTradeCallback() { | |||||
@Override | |||||
public void onTradeSuccess(AlibcTradeResult alibcTradeResult) { | |||||
Log.d("cg", alibcTradeResult.toString()); | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
Log.d("sb", s); | |||||
} | |||||
}); | |||||
} | |||||
return super.shouldOverrideUrlLoading(view, url); | |||||
} | |||||
@Override | |||||
public void onPageStarted(WebView view, String url, Bitmap favicon) { | |||||
// WebLoad.setVisibility(View.GONE); | |||||
mainWeb.setVisibility(View.GONE); | |||||
//开始加载设置为透明 | |||||
super.onPageStarted(view, url, favicon); | |||||
} | |||||
@Override | |||||
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { | |||||
super.onReceivedError(view, request, error); | |||||
} | |||||
@Override | |||||
public void onPageFinished(WebView view, String url) { | |||||
// WebLoad.setVisibility(View.GONE); | |||||
mainWeb.setVisibility(View.VISIBLE); | |||||
// 获取页面内容 | |||||
view.loadUrl("javascript:window.java_obj.showSource(" | |||||
+ "document.documentElement.innerText);"); | |||||
// 获取解析<meta name="share-description" content="获取到的值"> | |||||
view.loadUrl("javascript:window.java_obj.showDescription(" | |||||
+ "document.querySelector('meta[name=\"share-description\"]').getAttribute('content')" | |||||
+ ");"); | |||||
// quanyikaText(); | |||||
super.onPageFinished(view, url); | |||||
} | |||||
//处理 [Android]用WebView访问证书有问题的SSL网页 | |||||
//http://blog.sina.com.cn/s/blog_4cd978f90102vrxk.html | |||||
@Override | |||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { | |||||
handler.proceed(); | |||||
} | |||||
} | |||||
/** | |||||
* 绑定渠道 | |||||
*/ | |||||
private final class InJavaScriptLocalObj { | |||||
@JavascriptInterface | |||||
public void showSource(final String html) { | |||||
//获取网页内容,用于判断是否成功绑定关系id | |||||
try { | |||||
if (html.contains("成功")) {//成功 | |||||
Toast.makeText(WebActivity.this, "授权成功", Toast.LENGTH_SHORT).show(); | |||||
finish(); | |||||
} else {//失败 | |||||
mainWeb.setAlpha(0); | |||||
} | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
@JavascriptInterface | |||||
public void showDescription(String str) { | |||||
} | |||||
} | |||||
public class MyWebChromeClient extends WebChromeClient { | |||||
private CustomViewCallback mCustomViewCallback; | |||||
// 横屏时,显示视频的view | |||||
private View mCustomView; | |||||
// 点击全屏按钮时,调用的方法 | |||||
@Override | |||||
public void onShowCustomView(View view, CustomViewCallback callback) { | |||||
super.onShowCustomView(view, callback); | |||||
//isFullPlayVedio = true; | |||||
//如果view 已经存在,则隐藏 | |||||
if (mCustomView != null) { | |||||
callback.onCustomViewHidden(); | |||||
return; | |||||
} | |||||
mCustomView = view; | |||||
mCustomView.setVisibility(View.VISIBLE); | |||||
mCustomViewCallback = callback; | |||||
} | |||||
// 取消全屏调用的方法 | |||||
@Override | |||||
public void onHideCustomView() { | |||||
super.onHideCustomView(); | |||||
if (mCustomView == null) { | |||||
return; | |||||
} | |||||
mCustomView.setVisibility(View.GONE); | |||||
mCustomView = null; | |||||
try { | |||||
mCustomViewCallback.onCustomViewHidden(); | |||||
} catch (Exception e) { | |||||
} | |||||
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏 | |||||
} | |||||
@Override | |||||
public void onProgressChanged(WebView view, int newProgress) { | |||||
} | |||||
@Override | |||||
public void onReceivedTitle(WebView view, String title) { | |||||
super.onReceivedTitle(view, title); | |||||
// Logger.wtf("我的url" + view.getUrl()); | |||||
String url = view.getUrl(); | |||||
if (Patterns.WEB_URL.matcher(title).matches()) { | |||||
//网址不显示为标题 | |||||
} else { | |||||
//不是网址 | |||||
if (!url.contains("api.ejiayou.com/pages/platform/soulList/index.html")) { | |||||
} | |||||
} | |||||
} | |||||
@Override | |||||
public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) { | |||||
super.onGeolocationPermissionsShowPrompt(origin, callback); | |||||
} | |||||
// For Android 3.0+ | |||||
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { | |||||
} | |||||
// For Android < 3.0 | |||||
public void openFileChooser(ValueCallback<Uri> uploadMsg) { | |||||
openFileChooser(uploadMsg, ""); | |||||
} | |||||
// For Android > 4.1.1 | |||||
public void openFileChooser(ValueCallback<Uri> uploadMsg, | |||||
String acceptType, String capture) { | |||||
openFileChooser(uploadMsg, acceptType); | |||||
} | |||||
// For Android > 5.0 | |||||
@Override | |||||
public boolean onShowFileChooser(WebView webView, | |||||
ValueCallback<Uri[]> filePathCallback, | |||||
FileChooserParams fileChooserParams) { | |||||
return true; | |||||
} | |||||
} | |||||
@SuppressLint("AddJavascriptInterface") | |||||
private class MyWebClient extends WebViewClient { | |||||
@SuppressLint("AddJavascriptInterface") | |||||
@Override | |||||
public boolean shouldOverrideUrlLoading(WebView view, final String url) { | |||||
if (url.startsWith("tel:")) { | |||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); | |||||
return true; | |||||
} | |||||
if (url.startsWith("bdnetdisk:")) { | |||||
return true; | |||||
} | |||||
if (url.contains("tmast://")) { | |||||
try { | |||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |||||
startActivity(intent); | |||||
} catch (Exception e) { | |||||
} | |||||
return true; | |||||
} | |||||
if (url.startsWith("http://ditu.amap.com") || | |||||
url.startsWith("https://ditu.amap.com")) { | |||||
return true; | |||||
} | |||||
if (url.contains("oauth.taobao.com/authorize") || url.contains("oauth.m.taobao.com/authorize")) { | |||||
// mainWeb.addJavascriptInterface(new InJavaScriptLocadeUpgralObj(), "java_obj"); | |||||
Map<String, String> exParams = new HashMap<>();//yhhpass参数 | |||||
// AlibcTaokeParams alibcTaokeParams = new AlibcTaokeParams("", "", ""); | |||||
// alibcTaokeParams.pid = SPUtils.getPrefString(mActivity, Pkey.pid, ""); | |||||
// alibcTaokeParams.adzoneid = SPUtils.getPrefString(mActivity, Pkey.APP_adzoneId, ""); | |||||
// alibcTaokeParams.extraParams = new HashMap<>(); | |||||
// alibcTaokeParams.extraParams.put("taokeAppkey", SPUtils.getPrefString(mActivity, Pkey.APP_alliance_appkey, "")); | |||||
AlibcShowParams showParams = new AlibcShowParams(); | |||||
showParams.setBackUrl("alisdk://"); | |||||
AlibcTrade.openByUrl(WebActivity.this, "", url, mainWeb, new MyBaichuanWebClient(), new MyWebChromeClient(), showParams, | |||||
new AlibcTaokeParams("", "", ""), exParams, new AlibcTradeCallback() { | |||||
@Override | |||||
public void onTradeSuccess(AlibcTradeResult alibcTradeResult) { | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
} | |||||
}); | |||||
} | |||||
if (url.contains("tbopen://") || url.contains("tmall://") || url.contains("taobaotravel://")) { | |||||
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; | |||||
} | |||||
// 如下方案可在非微信内部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(); | |||||
} | |||||
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(); | |||||
} | |||||
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#")) { | |||||
} | |||||
//不拦截的话绑定淘宝关系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")) { | |||||
// if (!AlibcLogin.getInstance().isLogin()) { | |||||
// AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { | |||||
//// @Override | |||||
//// public void onSuccess(int i) { | |||||
//// } | |||||
// | |||||
// @Override | |||||
// public void onSuccess(int i, String s, String s1) { | |||||
// | |||||
// } | |||||
// | |||||
// @Override | |||||
// public void onFailure(int i, String s) { | |||||
// } | |||||
// }); | |||||
// } | |||||
// return true; | |||||
// } | |||||
if (url.contains("maliprod.alipay.com") && !url.contains("confirmGoods.do")) { | |||||
AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { | |||||
@Override | |||||
public void onSuccess(int i, String s, String s1) { | |||||
} | |||||
@Override | |||||
public void onFailure(int i, String s) { | |||||
} | |||||
}); | |||||
} | |||||
if (url.contains("intent://go/ju/webview?")) { | |||||
return true; | |||||
} | |||||
// if (url.contains("s.click.taobao.com")) { | |||||
// Logger.wtf(SPUtils.getPrefString(WebActivity.this, Pkey.IS_OPEN_TAOBAO, "")); | |||||
// if (SPUtils.getPrefString(WebActivity.this, Pkey.IS_OPEN_TAOBAO, "").equals("shoutao")) { | |||||
// if (!Token.isLogin()) { | |||||
// if (isFirst2Login) { | |||||
// ActivityJump.toLogin(WebActivity.this); | |||||
// } | |||||
// isFirst2Login = false; | |||||
// finish(); | |||||
// } else { | |||||
// if (isInstallTaoBao(WebActivity.this)) { | |||||
// jump2TaoBao(url); | |||||
// finish(); | |||||
// } else { | |||||
// view.loadUrl(url); | |||||
// } | |||||
// } | |||||
// return true; | |||||
// } | |||||
// } | |||||
// if (url.contains("kingcard.dgunicom.com") && url.contains("newMsg") && url.contains("fill.html")) { | |||||
// getItf(url); | |||||
// } | |||||
// else { | |||||
// Logger.wtf("123"); | |||||
// mainWeb.loadUrl(url); | |||||
// } | |||||
return super.shouldOverrideUrlLoading(view, url); | |||||
} | |||||
@Override | |||||
public void onPageStarted(WebView view, String url, Bitmap favicon) { | |||||
// WebLoad.setVisibility(View.GONE); | |||||
//开始加载设置为透明 | |||||
super.onPageStarted(view, url, favicon); | |||||
} | |||||
@Override | |||||
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { | |||||
super.onReceivedError(view, request, error); | |||||
} | |||||
@Override | |||||
public void onPageFinished(WebView view, String url) { | |||||
// WebLoad.setVisibility(View.GONE); | |||||
// // 获取页面内容 | |||||
view.loadUrl("javascript:window.java_obj.showSource(" | |||||
+ "document.documentElement.innerText);"); | |||||
// 获取解析<meta name="share-description" content="获取到的值"> | |||||
view.loadUrl("javascript:window.java_obj.showDescription(" | |||||
+ "document.querySelector('meta[name=\"share-description\"]').getAttribute('content')" | |||||
+ ");"); | |||||
// quanyikaText(); | |||||
super.onPageFinished(view, url); | |||||
} | |||||
//处理 [Android]用WebView访问证书有问题的SSL网页 | |||||
//http://blog.sina.com.cn/s/blog_4cd978f90102vrxk.html | |||||
@Override | |||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { | |||||
handler.proceed(); | |||||
} | |||||
} | |||||
} | |||||
@@ -1,12 +1,11 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<!-- Modify this file to customize your launch splash screen --> | <!-- Modify this file to customize your launch splash screen --> | ||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
<item android:drawable="@android:color/white" /> | <!-- <item android:drawable="@android:color/white" />--> | ||||
<!-- You can insert your own image assets here --> | <!-- You can insert your own image assets here --> | ||||
<!-- <item> | <item> | ||||
<bitmap | <bitmap | ||||
android:gravity="center" | android:src="@drawable/bg_launcher" /> | ||||
android:src="@mipmap/launch_image" /> | </item> | ||||
</item> --> | |||||
</layer-list> | </layer-list> |
@@ -0,0 +1,26 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent"> | |||||
<TextView | |||||
android:id="@+id/tv_aliBc" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:clickable="true" | |||||
android:text="登陆" | |||||
android:padding="12dp" | |||||
android:textColor="#FFFFFF" | |||||
android:focusable="true"> | |||||
</TextView> | |||||
<TextView | |||||
android:id="@+id/tv_open_detail" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:focusable="true" | |||||
android:clickable="true" | |||||
android:text="打开淘宝详情" | |||||
/> | |||||
</LinearLayout> |
@@ -0,0 +1,14 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<LinearLayout 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" | |||||
tools:context="cn.zhios.zhiying_base_widget_example.WebActivity"> | |||||
<WebView | |||||
android:id="@+id/webview_main" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent"/> | |||||
</LinearLayout> |
@@ -15,6 +15,10 @@ allprojects { | |||||
repositories { | repositories { | ||||
google() | google() | ||||
jcenter() | jcenter() | ||||
maven { | |||||
url "http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories/" | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -13,6 +13,7 @@ import 'package:provider/provider.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:flutter_alibc/flutter_alibc.dart'; | import 'package:flutter_alibc/flutter_alibc.dart'; | ||||
import 'package:flutter_alibc/alibc_model.dart'; | import 'package:flutter_alibc/alibc_model.dart'; | ||||
import 'package:flutter_alibc/alibc_const_key.dart'; | |||||
class IntellectSearchGoodsDialog extends StatefulWidget { | class IntellectSearchGoodsDialog extends StatefulWidget { | ||||
final IntellectDialogDataModel model; | final IntellectDialogDataModel model; | ||||
@@ -31,7 +32,6 @@ class _IntellectSearchGoodsDialogState | |||||
@override | @override | ||||
void initState() { | void initState() { | ||||
requestStyle(); | requestStyle(); | ||||
super.initState(); | super.initState(); | ||||
} | } | ||||
@@ -243,7 +243,10 @@ class _IntellectSearchGoodsDialogState | |||||
), | ), | ||||
), | ), | ||||
Text( | Text( | ||||
widget?.model?.price ?? "", | (num.tryParse(widget?.model?.price ?? "0") - | ||||
num.tryParse( | |||||
widget?.model?.couponPrice ?? "0")).toString() ?? | |||||
"", | |||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 32.sp, | fontSize: 32.sp, | ||||
color: HexColor.fromHex( | color: HexColor.fromHex( | ||||
@@ -281,12 +284,10 @@ class _IntellectSearchGoodsDialogState | |||||
child: Text( | child: Text( | ||||
(_styleModel?.moduleList?.saveBtn?.content ?? "") + | (_styleModel?.moduleList?.saveBtn?.content ?? "") + | ||||
" ¥" + | " ¥" + | ||||
((double.tryParse( | ((num.tryParse(widget?.model?.couponPrice ?? "0") ?? | ||||
widget?.model?.couponPrice ?? "0.0") ?? | |||||
0) + | 0) + | ||||
double.tryParse( | num.tryParse( | ||||
widget?.model?.commission ?? '0')) | widget?.model?.commission ?? '0')) | ||||
.toString() | |||||
.toString(), | .toString(), | ||||
style: TextStyle( | style: TextStyle( | ||||
color: HexColor.fromHex( | color: HexColor.fromHex( | ||||
@@ -353,17 +354,26 @@ class _IntellectSearchGoodsDialogState | |||||
RouterUtil.goLogin(context); | RouterUtil.goLogin(context); | ||||
return; | return; | ||||
} else { | } else { | ||||
print("平台"+widget?.model?.provider??""); | print("平台" + widget?.model?.provider ?? ""); | ||||
print("链接" + widget?.model?.couponUrl ?? ""); | |||||
if (widget?.model?.provider == 'taobao') { | if (widget?.model?.provider == 'taobao') { | ||||
TradeResult result = | TradeResult result = await FlutterAlibc.openByUrl( | ||||
await FlutterAlibc.openByUrl(url: widget?.model?.couponUrl??""); | url: widget?.model?.couponUrl ?? "", | ||||
openType: AlibcOpenType.AlibcOpenTypeNative, | |||||
backUrl: "alisdk://"); | |||||
Logger.debug('${result.errorCode} ${result.errorMessage} '); | Logger.debug('${result.errorCode} ${result.errorMessage} '); | ||||
print("链接"+widget?.model?.couponUrl??""); | print("链接" + widget?.model?.couponUrl ?? ""); | ||||
print("错误码"+result.errorCode); | print("错误码" + result.errorCode); | ||||
print("原因"+result.errorMessage); | print("原因" + result.errorMessage); | ||||
} else { | } else { | ||||
RouterUtil.openWebview(widget?.model?.couponUrl, context); | await FlutterAlibc.openByUrl( | ||||
url: widget?.model?.couponUrl, | |||||
openType: AlibcOpenType.AlibcOpenTypeNative); | |||||
} | |||||
///关闭弹窗 | |||||
if (Navigator.canPop(context)) { | |||||
Navigator.pop(context); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -10,6 +10,7 @@ class IntellectDialogDataModel { | |||||
String couponUrl; | String couponUrl; | ||||
String couponPrice; | String couponPrice; | ||||
IntellectDialogDataModel( | IntellectDialogDataModel( | ||||
{this.itemId, | {this.itemId, | ||||
this.title, | this.title, | ||||
@@ -0,0 +1,71 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class TipDialog extends StatelessWidget { | |||||
String title; | |||||
TipDialog({this.title = "温馨提示", this.content}); | |||||
String content; | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Scaffold( | |||||
backgroundColor: Colors.transparent, | |||||
body: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
children: <Widget>[ | |||||
Container( | |||||
width: double.infinity, | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, borderRadius: BorderRadius.circular(20)), | |||||
margin: EdgeInsets.only(left: 91.w, right: 91.w), | |||||
child: Column( | |||||
children: <Widget>[ | |||||
Padding( | |||||
padding: const EdgeInsets.only(top: 16), | |||||
child: Text( | |||||
title, | |||||
style: TextStyle(fontSize: 30.sp,fontWeight: FontWeight.w400), | |||||
), | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.all(16), | |||||
constraints: BoxConstraints(minHeight: 100), | |||||
child: Text( | |||||
content, | |||||
style: TextStyle(fontSize: 26.sp), | |||||
), | |||||
), | |||||
Row( | |||||
children: <Widget>[ | |||||
Expanded( | |||||
child: Padding( | |||||
padding: const EdgeInsets.only( | |||||
left: 16, right: 16, bottom: 16), | |||||
child: FlatButton( | |||||
padding: EdgeInsets.only(top: 10, bottom: 10), | |||||
color: HexColor.fromHex("#FFFF4242"), | |||||
shape: RoundedRectangleBorder( | |||||
borderRadius: BorderRadius.circular(50)), | |||||
onPressed: () { | |||||
Navigator.pop(context); | |||||
}, | |||||
child: Text( | |||||
"知道了", | |||||
style: TextStyle( | |||||
color: HexColor.fromHex("#FFFFFF"), | |||||
fontSize: 26.sp), | |||||
)), | |||||
)) | |||||
], | |||||
) | |||||
], | |||||
), | |||||
) | |||||
], | |||||
), | |||||
); | |||||
} | |||||
} |
@@ -1,6 +1,22 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||||
import 'package:zhiying_base_widget/pages/hot_ranking_page/hot_ranking_page_sk.dart'; | |||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart'; | |||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | |||||
import 'package:zhiying_base_widget/utils/contants.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:provider/provider.dart'; | |||||
import 'hot_ranking_page_bloc.dart'; | |||||
class HotRankingPage extends StatefulWidget { | class HotRankingPage extends StatefulWidget { | ||||
final Map<String, dynamic> data; | |||||
const HotRankingPage(this.data, {Key key}) : super(key: key); | |||||
@override | @override | ||||
_HotRankingPageState createState() => _HotRankingPageState(); | _HotRankingPageState createState() => _HotRankingPageState(); | ||||
} | } | ||||
@@ -10,7 +26,6 @@ class _HotRankingPageState extends State<HotRankingPage> { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
print('hot_ranking_page build'); | print('hot_ranking_page build'); | ||||
// | // | ||||
// List<Widget> contentWidgets = tabs.map((item) { | // List<Widget> contentWidgets = tabs.map((item) { | ||||
// BaseTabModel model = BaseTabModel.fromJson(item); | // BaseTabModel model = BaseTabModel.fromJson(item); | ||||
@@ -19,6 +34,134 @@ class _HotRankingPageState extends State<HotRankingPage> { | |||||
// if (_currentIndex >= contentWidgets.length) { | // if (_currentIndex >= contentWidgets.length) { | ||||
// _currentIndex = 0; | // _currentIndex = 0; | ||||
// } | // } | ||||
return Scaffold(); | return Scaffold( | ||||
backgroundColor: Color(0xfff9f9f9), | |||||
body: MultiProvider( | |||||
providers: [ | |||||
ChangeNotifierProvider.value(value: MainPageBgNotifier()), | |||||
], | |||||
child: BlocProvider<HotRankingPageBloc>( | |||||
bloc: HotRankingPageBloc(), | |||||
child: _HotRankingPageContainer(data: widget.data), | |||||
), | |||||
), | |||||
); | |||||
} | |||||
} | |||||
class _HotRankingPageContainer extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
const _HotRankingPageContainer({Key key, this.data}) : super(key: key); | |||||
@override | |||||
__HotRankingPageContainerState createState() => | |||||
__HotRankingPageContainerState(); | |||||
} | |||||
class __HotRankingPageContainerState extends State<_HotRankingPageContainer> { | |||||
HotRankingPageBloc _bloc; | |||||
RefreshController _refreshController; | |||||
String backgroundImage; | |||||
@override | |||||
void initState() { | |||||
_refreshController = RefreshController(); | |||||
_bloc = BlocProvider.of<HotRankingPageBloc>(context); | |||||
if (widget.data.containsKey(Constants.SkipIdentifierName)) { | |||||
_bloc.loadData(widget.data[Constants.SkipIdentifierName]); | |||||
} | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder( | |||||
stream: _bloc.outData, | |||||
builder: (context, asyncSnapshot) { | |||||
var model = asyncSnapshot.data; | |||||
if (model == null) { | |||||
return HotRankingPageSkeleton(); | |||||
} | |||||
for (var item in model) { | |||||
WidgetModel widgetModel = | |||||
WidgetModel.fromJson(Map<String, dynamic>.from(item)); | |||||
if (item.containsKey("mod_name") && | |||||
item['mod_name'] == "hot_rank_bg_img") { | |||||
_bloc.backgroundImage = json.decode(item['data'])['bg_img']; | |||||
break; | |||||
} | |||||
} | |||||
return Stack( | |||||
children: <Widget>[ | |||||
Container( | |||||
height: 293.h, | |||||
decoration: BoxDecoration( | |||||
image: DecorationImage( | |||||
image: CachedNetworkImageProvider( | |||||
_bloc.backgroundImage ?? ""), | |||||
fit: BoxFit.fill)), | |||||
), | |||||
Column( | |||||
children: _createContent(context, model), | |||||
) | |||||
], | |||||
); | |||||
}, | |||||
); | |||||
} | |||||
//刷新 | |||||
void _onLoading() async {} | |||||
///构建子模块 | |||||
_createContent(BuildContext context, List<Map<String, dynamic>> model) { | |||||
List<Widget> list = List(); | |||||
if (model == null) { | |||||
///骨架图 | |||||
} else { | |||||
for (var item in model) { | |||||
WidgetModel widgetModel = | |||||
WidgetModel.fromJson(Map<String, dynamic>.from(item)); | |||||
if (item.containsKey("mod_name") && | |||||
item['mod_name'] == "hot_rank_tab_view") { | |||||
list.add(Expanded( | |||||
child: WidgetFactory.create(widgetModel.modName, | |||||
isSliver: false, model: item)[0])); | |||||
continue; | |||||
} | |||||
list.addAll(WidgetFactory.create(widgetModel.modName, | |||||
isSliver: false, model: item)); | |||||
} | |||||
} | |||||
return list; | |||||
} | |||||
} | |||||
class _SilverAppBarDelegate extends SliverPersistentHeaderDelegate { | |||||
_SilverAppBarDelegate(BuildContext context, this.child) { | |||||
this.context = context; | |||||
} | |||||
BuildContext context; | |||||
final Widget child; | |||||
@override | |||||
double get minExtent => MediaQuery.of(context).padding.top + 44; | |||||
@override | |||||
double get maxExtent => MediaQuery.of(context).padding.top + 44; | |||||
@override | |||||
Widget build( | |||||
BuildContext context, double shrinkOffset, bool overlapsContent) { | |||||
return child; | |||||
} | |||||
@override | |||||
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { | |||||
return false; | |||||
} | } | ||||
} | } |
@@ -3,42 +3,49 @@ import 'dart:async'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | import 'package:zhiying_comm/util/base_bloc.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class HotRankingPage extends BlocBase { | class HotRankingPageBloc extends BlocBase { | ||||
List<Map<String, dynamic>> _pageData = List(); | List<Map<String, dynamic>> _pageData = List(); | ||||
StreamController<List<Map<String, dynamic>>> _dataController = | StreamController<List<Map<String, dynamic>>> _dataController = | ||||
StreamController<List<Map<String, dynamic>>>(); | StreamController<List<Map<String, dynamic>>>(); | ||||
Stream<List<Map<String, dynamic>>> get outData => _dataController.stream; | Stream<List<Map<String, dynamic>>> get outData => _dataController.stream; | ||||
StreamController<Map<String, dynamic>> _eventController = | |||||
StreamController.broadcast(); | |||||
Stream<Map<String, dynamic>> get event => _eventController.stream; | |||||
String backgroundImage; | |||||
@override | @override | ||||
void dispose() { | void dispose() { | ||||
_dataController.close(); | _dataController.close(); | ||||
_eventController.close(); | |||||
_dataController = null; | _dataController = null; | ||||
_eventController.close(); | |||||
} | } | ||||
void loadData(int id) { | loadData(String skipIdentifier) { | ||||
NetUtil.request('/api/v1/mod', | NetUtil.request('/api/v1/mod/${skipIdentifier}', method: NetMethod.GET, | ||||
method: NetMethod.POST, | onCache: (data) { | ||||
params: Map<String, dynamic>.from({ | _loadData(data); | ||||
'ids': [id] | }, onSuccess: (data) { | ||||
}), onCache: (data) { | print(data); | ||||
_loadData(id, data); | _loadData(data); | ||||
}, onSuccess: (data) { | }); | ||||
_loadData(id, data); | |||||
}); | |||||
} | } | ||||
void _loadData(int id, dynamic data) { | void _loadData(dynamic data) { | ||||
String key = id.toString(); | print(data["mod_lis"]); | ||||
Map<String, dynamic> json = Map<String, dynamic>.from(data); | _pageData = List.from(data["mod_list"]).map((v) { | ||||
if (json.containsKey(key)) { | return Map<String, dynamic>.from(v); | ||||
List<dynamic> list = json[key]; | }).toList(); | ||||
_pageData = list.map((item) { | |||||
return Map<String, dynamic>.from(item); | |||||
}).toList(); | |||||
} | |||||
_dataController.add(_pageData); | _dataController.add(_pageData); | ||||
} | } | ||||
void sendEvent(Map<String,dynamic> event){ | |||||
_eventController.add(event); | |||||
} | |||||
} | } |
@@ -0,0 +1,91 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:shimmer/shimmer.dart'; | |||||
class HotRankingPageSkeleton extends StatelessWidget { | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Shimmer.fromColors( | |||||
baseColor: Colors.grey[300], | |||||
highlightColor: Colors.grey[100], | |||||
child: Column( | |||||
mainAxisSize: MainAxisSize.min, | |||||
children: <Widget>[ | |||||
Container( | |||||
color: Colors.white, | |||||
width: double.infinity, | |||||
height: 96, | |||||
), | |||||
Container( | |||||
width: double.infinity, | |||||
margin: EdgeInsets.all(16), | |||||
height: 48, | |||||
child: Row( | |||||
children: _buildTopRow(), | |||||
)), | |||||
Expanded( | |||||
child: Container( | |||||
child: Column( | |||||
children: _buildBottomListItem(), | |||||
), | |||||
)) | |||||
], | |||||
), | |||||
); | |||||
} | |||||
_buildBottomListItem() { | |||||
List<Widget> listWidget = List(); | |||||
for (var index = 0; index < 3; index++) { | |||||
listWidget.add(Container( | |||||
margin: EdgeInsets.only(left: 16, top: 10, bottom: 10), | |||||
child: Row( | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 127, | |||||
height: 127, | |||||
color: Colors.white, | |||||
), | |||||
Container( | |||||
height: 127, | |||||
margin: EdgeInsets.only(left: 10), | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Container( | |||||
height: 40, | |||||
width: 200, | |||||
color: Colors.white, | |||||
), | |||||
Container( | |||||
height: 30, | |||||
width: 100, | |||||
color: Colors.grey, | |||||
), | |||||
Container( | |||||
height: 30, | |||||
width: 200, | |||||
color: Colors.grey, | |||||
) | |||||
], | |||||
), | |||||
) | |||||
], | |||||
), | |||||
)); | |||||
} | |||||
return listWidget; | |||||
} | |||||
_buildTopRow() { | |||||
List<Widget> listWidget = List(); | |||||
for (var index = 0; index < 5; index++) { | |||||
listWidget.add(Container( | |||||
width: 50, | |||||
color: Colors.white, | |||||
margin: EdgeInsets.all(10), | |||||
)); | |||||
} | |||||
return listWidget; | |||||
} | |||||
} |
@@ -6,13 +6,17 @@ import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifi | |||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | ||||
import 'package:zhiying_base_widget/utils/contants.dart'; | import 'package:zhiying_base_widget/utils/contants.dart'; | ||||
import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart'; | import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart'; | ||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_appbar/wallet_appbar_sk.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data_sk.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_sk.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income_sk.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:zhiying_comm/util/base_bloc.dart'; | import 'package:zhiying_comm/util/base_bloc.dart'; | ||||
import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart'; | import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart'; | ||||
import 'wallet_page_bloc.dart'; | import 'wallet_page_bloc.dart'; | ||||
import 'wallet_page_bloc.dart'; | import 'wallet_page_bloc.dart'; | ||||
///钱包页面 | |||||
class WalletPage extends StatefulWidget { | class WalletPage extends StatefulWidget { | ||||
final Map<String, dynamic> data; | final Map<String, dynamic> data; | ||||
@@ -77,8 +81,8 @@ class _WalletPageContainerState extends State<_WalletPageContainer> { | |||||
ScreenUtil.init(context, width: 750, height: 1334); | ScreenUtil.init(context, width: 750, height: 1334); | ||||
return SmartRefresher( | return SmartRefresher( | ||||
controller: _refreshController, | controller: _refreshController, | ||||
enablePullDown: false, | enablePullDown: true, | ||||
enablePullUp: false, | enablePullUp:true, | ||||
header: WaterDropHeader(), | header: WaterDropHeader(), | ||||
onLoading: _onLoading, | onLoading: _onLoading, | ||||
child: Container( | child: Container( | ||||
@@ -86,15 +90,17 @@ class _WalletPageContainerState extends State<_WalletPageContainer> { | |||||
child: Stack( | child: Stack( | ||||
fit: StackFit.passthrough, | fit: StackFit.passthrough, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
MineHeaderBgWidget( | |||||
controller: _controller, | |||||
), | |||||
StreamBuilder( | StreamBuilder( | ||||
stream: _pageBloc.outData, | stream: _pageBloc.outData, | ||||
builder: (context, asyncSnapshot) { | builder: (context, asyncSnapshot) { | ||||
var model = asyncSnapshot.data; | var model = asyncSnapshot.data; | ||||
return CustomScrollView( | return Stack( | ||||
slivers: _createContent(context, model), | children: <Widget>[ | ||||
Container(height: 362.h, color: _pageBloc.backgroundColor), | |||||
CustomScrollView( | |||||
slivers: _createContent(context, model), | |||||
) | |||||
], | |||||
); | ); | ||||
}, | }, | ||||
) | ) | ||||
@@ -108,37 +114,33 @@ class _WalletPageContainerState extends State<_WalletPageContainer> { | |||||
BuildContext context, List<Map<String, dynamic>> model) { | BuildContext context, List<Map<String, dynamic>> model) { | ||||
List<Widget> list = List(); | List<Widget> list = List(); | ||||
if (model == null) { | if (model == null) { | ||||
list.addAll(WidgetFactory.create( | ///骨架图 | ||||
'normal_nav', | list.add(SliverToBoxAdapter( | ||||
isSliver: true, | child: WalletAppbarSkeleton(), | ||||
model: Map(), | |||||
)); | )); | ||||
list.addAll(WidgetFactory.create( | list.add(SliverToBoxAdapter( | ||||
'wallet_data', | child: WalletDataSkeleton(), | ||||
isSliver: true, | |||||
model: Map(), | |||||
)); | )); | ||||
list.addAll(WidgetFactory.create( | list.add(SliverToBoxAdapter( | ||||
'wallet_detail', | child: WalletIncomeSkeleton(), | ||||
isSliver: true, | |||||
model: Map(), | |||||
)); | )); | ||||
list.add(SliverToBoxAdapter( | |||||
list.addAll(WidgetFactory.create( | child: WalletDetailSkeleton(), | ||||
'wallet_income', | |||||
isSliver: true, | |||||
model: Map(), | |||||
)); | )); | ||||
} else { | } else { | ||||
for (var item in model) { | for (var item in model) { | ||||
WidgetModel widgetModel = | WidgetModel widgetModel = | ||||
WidgetModel.fromJson(Map<String, dynamic>.from(item)); | WidgetModel.fromJson(Map<String, dynamic>.from(item)); | ||||
if (item.containsKey("mod_name")&&item['mod_name']=="my_wallet_appbar") { | if (item.containsKey("mod_name") && | ||||
item['mod_name'] == "my_wallet_appbar") { | |||||
list.add(SliverPersistentHeader( | list.add(SliverPersistentHeader( | ||||
delegate: _SilverAppBarDelegate(context, | delegate: _SilverAppBarDelegate( | ||||
WidgetFactory.create(widgetModel.modName, | context, | ||||
isSliver: false, model: item)[0]),pinned: true,)); | WidgetFactory.create(widgetModel.modName, | ||||
continue; | isSliver: false, model: item)[0]), | ||||
pinned: true, | |||||
)); | |||||
continue; | |||||
} | } | ||||
list.addAll(WidgetFactory.create(widgetModel.modName, | list.addAll(WidgetFactory.create(widgetModel.modName, | ||||
isSliver: true, model: item)); | isSliver: true, model: item)); | ||||
@@ -149,23 +151,23 @@ class _WalletPageContainerState extends State<_WalletPageContainer> { | |||||
} | } | ||||
class _SilverAppBarDelegate extends SliverPersistentHeaderDelegate { | class _SilverAppBarDelegate extends SliverPersistentHeaderDelegate { | ||||
_SilverAppBarDelegate(BuildContext context,this.child){ | _SilverAppBarDelegate(BuildContext context, this.child) { | ||||
this.context=context; | this.context = context; | ||||
} | } | ||||
BuildContext context; | BuildContext context; | ||||
final Widget child; | final Widget child; | ||||
@override | @override | ||||
double get minExtent => MediaQuery.of(context).padding.top+44; | double get minExtent => MediaQuery.of(context).padding.top + 44; | ||||
@override | @override | ||||
double get maxExtent => MediaQuery.of(context).padding.top+44; | double get maxExtent => MediaQuery.of(context).padding.top + 44; | ||||
@override | @override | ||||
Widget build( | Widget build( | ||||
BuildContext context, double shrinkOffset, bool overlapsContent) { | BuildContext context, double shrinkOffset, bool overlapsContent) { | ||||
return child; | return child; | ||||
} | } | ||||
@override | @override | ||||
@@ -1,16 +1,22 @@ | |||||
import 'dart:async'; | import 'dart:async'; | ||||
import 'dart:convert'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/utils/contants.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_appbar/model/WalletAppbarModel.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/model/wallet_header_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | import 'package:zhiying_comm/util/base_bloc.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class WalletPageBloc extends BlocBase { | class WalletPageBloc extends BlocBase { | ||||
List<Map<String, dynamic>> _tabs = List(); | |||||
StreamController<List<Map<String, dynamic>>> _tabController = | StreamController<List<Map<String, dynamic>>> _tabController = | ||||
StreamController<List<Map<String, dynamic>>>(); | StreamController<List<Map<String, dynamic>>>(); | ||||
Stream<List<Map<String, dynamic>>> get outData => _tabController.stream; | Stream<List<Map<String, dynamic>>> get outData => _tabController.stream; | ||||
Color backgroundColor = Colors.transparent; | |||||
@override | @override | ||||
void dispose() { | void dispose() { | ||||
_tabController.close(); | _tabController.close(); | ||||
@@ -34,6 +40,14 @@ class WalletPageBloc extends BlocBase { | |||||
var list = List.from(data["mod_list"]).map((v) { | var list = List.from(data["mod_list"]).map((v) { | ||||
return Map<String, dynamic>.from(v); | return Map<String, dynamic>.from(v); | ||||
}).toList(); | }).toList(); | ||||
for (var item in list) { | |||||
if (item['mod_name'] == "my_wallet_appbar") { | |||||
WalletAppbarModel walletAppbarModel = | |||||
WalletAppbarModel.fromJson(json.decode(item["data"])); | |||||
backgroundColor = HexColor.fromHex(walletAppbarModel.appBarBgColor); | |||||
break; | |||||
} | |||||
} | |||||
_tabController.add(list); | _tabController.add(list); | ||||
} | } | ||||
} | } |
@@ -3,6 +3,7 @@ import 'package:sharesdk_plugin/sharesdk_register.dart'; | |||||
import 'package:zhiying_base_widget/pages/favorite_page/favorite_page.dart'; | import 'package:zhiying_base_widget/pages/favorite_page/favorite_page.dart'; | ||||
import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart'; | import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart'; | ||||
import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; | import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; | ||||
import 'package:zhiying_base_widget/pages/hot_ranking_page/hot_ranking_page.dart'; | |||||
import 'package:zhiying_base_widget/pages/invited_friends/invited_friends.dart'; | import 'package:zhiying_base_widget/pages/invited_friends/invited_friends.dart'; | ||||
import 'package:zhiying_base_widget/pages/launch_page/launch_page.dart'; | import 'package:zhiying_base_widget/pages/launch_page/launch_page.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; | import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; | ||||
@@ -29,6 +30,9 @@ import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.d | |||||
import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_widget.dart'; | import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_widget.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_appbar/hot_ranking_appbar.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/hot_ranking_list.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_tab_bar/hot_tab_bar.dart'; | |||||
import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart'; | import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart'; | ||||
import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header.dart'; | import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header.dart'; | ||||
import 'package:zhiying_base_widget/widgets/mine/mine_nav/mine_nav_bg.dart'; | import 'package:zhiying_base_widget/widgets/mine/mine_nav/mine_nav_bg.dart'; | ||||
@@ -99,6 +103,8 @@ class BaseWidgetRegister { | |||||
PageFactory.regist('homePage', (model) => HomePage()); | PageFactory.regist('homePage', (model) => HomePage()); | ||||
PageFactory.regist('pub.flutter.index', (model) => MainPage(model)); | PageFactory.regist('pub.flutter.index', (model) => MainPage(model)); | ||||
PageFactory.regist('pub.flutter.profile', (model) => MainPage(model)); | PageFactory.regist('pub.flutter.profile', (model) => MainPage(model)); | ||||
PageFactory.regist( | |||||
'pub.flutter.hot_rank', (model) => HotRankingPage(model)); | |||||
PageFactory.regist( | PageFactory.regist( | ||||
'pub.flutter.my_wallet', (model) => WalletPage(data: model)); | 'pub.flutter.my_wallet', (model) => WalletPage(data: model)); | ||||
PageFactory.regist('goods_details', (model) => GoodsDetailsPage(model)); | PageFactory.regist('goods_details', (model) => GoodsDetailsPage(model)); | ||||
@@ -304,5 +310,11 @@ class BaseWidgetRegister { | |||||
'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | 'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | ||||
//======================= 账单明细 | //======================= 账单明细 | ||||
//======================== 热榜 | |||||
WidgetFactory.regist('hot_rank_appbar', DefaultWidgetCreater((model)=>HotRankingAppBar(model))); | |||||
WidgetFactory.regist('hot_rank_tabs', DefaultWidgetCreater((model)=>HotRankTableBar(model))); | |||||
WidgetFactory.regist('hot_rank_tab_view', DefaultWidgetCreater((model)=>HotRankingList(model))); | |||||
} | } | ||||
} | } |
@@ -99,7 +99,7 @@ class _GooddsDetailsFooterContainerState | |||||
return; | return; | ||||
} | } | ||||
if (shopType == 'taobao') { | if (shopType == 'taobao') { | ||||
TradeResult result = await FlutterAlibc.openByUrl(url: url); | TradeResult result = await FlutterAlibc.openByUrl(url: url,backUrl: "alisdk://"); | ||||
Logger.debug('${result.errorCode} ${result.errorMessage} '); | Logger.debug('${result.errorCode} ${result.errorMessage} '); | ||||
} else { | } else { | ||||
RouterUtil.openWebview(url, context); | RouterUtil.openWebview(url, context); | ||||
@@ -0,0 +1,49 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_appbar/model/hot_ranking_appbaar_model.dart'; | |||||
import 'package:zhiying_comm/util/extension/color.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HotRankingAppBar extends StatelessWidget { | |||||
final Map<String, dynamic> data; | |||||
const HotRankingAppBar(this.data, {Key key}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
var model = HotRankingAppbarModel.fromJson(json.decode(data['data'])); | |||||
return Container( | |||||
height: MediaQuery.of(context).padding.top + 56, | |||||
child: AppBar( | |||||
elevation: 0, | |||||
leading: Navigator.canPop(context) | |||||
? IconButton( | |||||
icon: Icon(Icons.arrow_back_ios), | |||||
onPressed: () { | |||||
Navigator.of(context).pop(); | |||||
}) | |||||
: Container(), | |||||
backgroundColor: HexColor.fromHex(model.appBarBgColor==""?"#00000000":model.appBarBgColor), | |||||
centerTitle: true, | |||||
title: Container( | |||||
child: Stack( | |||||
alignment: Alignment.center, | |||||
children: <Widget>[ | |||||
Text( | |||||
model.appBarName??"", | |||||
style: | |||||
TextStyle(color: HexColor.fromHex(model.appBarNameColor??"")), | |||||
), | |||||
CachedNetworkImage( | |||||
height: 40.w, | |||||
width: 144.w, | |||||
imageUrl: model.appBarNameImg??"", | |||||
fit: BoxFit.fill, | |||||
) | |||||
], | |||||
), | |||||
)), | |||||
); | |||||
} | |||||
} |
@@ -0,0 +1,32 @@ | |||||
class HotRankingAppbarModel { | |||||
String appBarName; | |||||
String appBarNameColor; | |||||
String appBarBgImg; | |||||
String appBarBgColor; | |||||
String appBarNameImg; | |||||
HotRankingAppbarModel( | |||||
{this.appBarName, | |||||
this.appBarNameColor, | |||||
this.appBarBgImg, | |||||
this.appBarBgColor, | |||||
this.appBarNameImg}); | |||||
HotRankingAppbarModel.fromJson(Map<String, dynamic> json) { | |||||
appBarName = json['app_bar_name']; | |||||
appBarNameColor = json['app_bar_name_color']; | |||||
appBarBgImg = json['app_bar_bg_img']; | |||||
appBarBgColor = json['app_bar_bg_color']; | |||||
appBarNameImg = json['app_bar_name_img']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['app_bar_name'] = this.appBarName; | |||||
data['app_bar_name_color'] = this.appBarNameColor; | |||||
data['app_bar_bg_img'] = this.appBarBgImg; | |||||
data['app_bar_bg_color'] = this.appBarBgColor; | |||||
data['app_bar_name_img'] = this.appBarNameImg; | |||||
return data; | |||||
} | |||||
} |
@@ -1,44 +0,0 @@ | |||||
import 'dart:async'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HotRankingBloc extends BlocBase { | |||||
List<Map<String, dynamic>> _pageData = List(); | |||||
StreamController<List<Map<String, dynamic>>> _dataController = | |||||
StreamController<List<Map<String, dynamic>>>(); | |||||
Stream<List<Map<String, dynamic>>> get outData => _dataController.stream; | |||||
@override | |||||
void dispose() { | |||||
_dataController.close(); | |||||
_dataController = null; | |||||
} | |||||
void loadData(int id) { | |||||
NetUtil.request('/api/v1/mod', | |||||
method: NetMethod.POST, | |||||
params: Map<String, dynamic>.from({ | |||||
'ids': [id] | |||||
}), onCache: (data) { | |||||
_loadData(id, data); | |||||
}, onSuccess: (data) { | |||||
_loadData(id, data); | |||||
}); | |||||
} | |||||
void _loadData(int id, dynamic data) { | |||||
String key = id.toString(); | |||||
Map<String, dynamic> json = Map<String, dynamic>.from(data); | |||||
if (json.containsKey(key)) { | |||||
List<dynamic> list = json[key]; | |||||
_pageData = list.map((item) { | |||||
return Map<String, dynamic>.from(item); | |||||
}).toList(); | |||||
} | |||||
_dataController.add(_pageData); | |||||
} | |||||
} |
@@ -1,91 +0,0 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_goods/hot_ranking_goods.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_sk.dart'; | |||||
class HotRankingContainer extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
const HotRankingContainer({Key key, this.data}) : super(key: key); | |||||
@override | |||||
_HotRankingState createState() => _HotRankingState(); | |||||
} | |||||
class _HotRankingState extends State<HotRankingContainer> | |||||
with TickerProviderStateMixin { | |||||
HotRankingBloc _bloc; | |||||
TabController _tabController; | |||||
@override | |||||
void initState() { | |||||
_bloc = HotRankingBloc(); | |||||
super.initState(); | |||||
} | |||||
_buildTabs() { | |||||
List<Widget> listWidget = List(); | |||||
for (int index = 0; index < 4; index++) { | |||||
listWidget.add(Tab( | |||||
text: "hahah", | |||||
)); | |||||
} | |||||
return listWidget; | |||||
} | |||||
@override | |||||
void dispose() { | |||||
_tabController.dispose(); | |||||
super.dispose(); | |||||
} | |||||
///构建 | |||||
void createTabController() { | |||||
_tabController = TabController(length: 4, vsync: this); | |||||
} | |||||
///构建TabView | |||||
_buildTabView() { | |||||
List<Widget> listWidget = List(); | |||||
for (var index = 0; index < 4; index++) { | |||||
listWidget.add(ListView.builder( | |||||
padding: EdgeInsets.all(0), | |||||
itemCount: 10, | |||||
itemBuilder: (context, index) { | |||||
return Container( | |||||
child: HotRankingGoods(), | |||||
); | |||||
})); | |||||
} | |||||
return listWidget; | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder( | |||||
stream: _bloc.outData, | |||||
builder: (context, snapshot) { | |||||
if (snapshot.data != null) { | |||||
return HotRankingSkeleton(); | |||||
} else { | |||||
createTabController(); | |||||
return Container( | |||||
child: Column( | |||||
children: <Widget>[ | |||||
TabBar( | |||||
controller: _tabController, | |||||
isScrollable: true, | |||||
tabs: _buildTabs(), | |||||
), | |||||
Expanded( | |||||
child: TabBarView( | |||||
controller: _tabController, | |||||
children: _buildTabView())) | |||||
], | |||||
), | |||||
); | |||||
} | |||||
}); | |||||
} | |||||
} |
@@ -1,218 +1,290 @@ | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; | import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | ||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_data_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HotRankingGoods extends StatelessWidget { | class HotRankingGoods extends StatelessWidget { | ||||
Good good; | |||||
HotRankingListModel styleModel; | |||||
int index; | |||||
HotRankingGoods({Key key, this.good, this.styleModel, this.index}) | |||||
: super(key: key); | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Stack( | var indexImage; | ||||
children: <Widget>[ | if (styleModel.hotRankIconList != null && | ||||
Container( | styleModel.hotRankIconList.length > 0 && | ||||
padding: EdgeInsets.all(15.w), | styleModel.hotRankIconList.length - 1 >= index) { | ||||
margin: | indexImage = styleModel.hotRankIconList[index]; | ||||
EdgeInsets.only(top: 8.w, bottom: 8.w, left: 25.w, right: 25.w), | } | ||||
decoration: BoxDecoration( | Providers providers = getProvider(good.provider); | ||||
color: Colors.white, borderRadius: BorderRadius.circular(15.w)), | return GestureDetector( | ||||
child: Row( | onTap: () { | ||||
crossAxisAlignment: CrossAxisAlignment.start, | RouterUtil.route(SkipModel(skipIdentifier: "goods_details"), | ||||
children: <Widget>[ | {"provider": good.provider, "good_id": good.goodId}, context); | ||||
Container( | }, | ||||
width: 254.w, | child: Stack( | ||||
height: 254.w, | children: <Widget>[ | ||||
color: Colors.amber, | Container( | ||||
), | padding: EdgeInsets.all(15.w), | ||||
Expanded( | margin: | ||||
child: Container( | EdgeInsets.only(top: 8.w, bottom: 8.w, left: 25.w, right: 25.w), | ||||
margin: EdgeInsets.only(left: 20.w), | decoration: BoxDecoration( | ||||
child: Column( | color: Colors.white, borderRadius: BorderRadius.circular(15.w)), | ||||
mainAxisSize: MainAxisSize.max, | child: Row( | ||||
children: <Widget>[ | crossAxisAlignment: CrossAxisAlignment.start, | ||||
Container( | children: <Widget>[ | ||||
height: 70.h, | Container( | ||||
child: Row( | width: 254.w, | ||||
children: <Widget>[ | height: 254.w, | ||||
Expanded( | decoration: BoxDecoration( | ||||
child: RichText( | borderRadius: BorderRadius.circular(6), | ||||
overflow: TextOverflow.ellipsis, | image: DecorationImage( | ||||
maxLines: 2, | image: CachedNetworkImageProvider(good.goodImage))), | ||||
text: TextSpan(children: <InlineSpan>[ | ), | ||||
WidgetSpan( | Expanded( | ||||
child: Container( | child: Container( | ||||
decoration: BoxDecoration( | margin: EdgeInsets.only(left: 20.w), | ||||
color: Colors.red, | child: Column( | ||||
borderRadius: | mainAxisSize: MainAxisSize.max, | ||||
BorderRadius.circular(4)), | children: <Widget>[ | ||||
child: Padding( | Container( | ||||
padding: EdgeInsets.only( | height: 70.h, | ||||
left: 4.w, right: 4.w), | child: Row( | ||||
child: Text( | children: <Widget>[ | ||||
"京东", | Expanded( | ||||
child: RichText( | |||||
overflow: TextOverflow.ellipsis, | |||||
maxLines: 2, | |||||
text: TextSpan(children: <InlineSpan>[ | |||||
WidgetSpan( | |||||
child: Container( | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex( | |||||
providers.providerBgColor), | |||||
borderRadius: | |||||
BorderRadius.circular(4)), | |||||
child: Padding( | |||||
padding: EdgeInsets.only( | |||||
left: 4.w, right: 4.w), | |||||
child: Text( | |||||
good.providerName ?? "", | |||||
style: TextStyle( | |||||
color: HexColor.fromHex( | |||||
providers.providerNameColor, | |||||
), | |||||
fontSize: 18.sp), | |||||
), | |||||
), | |||||
)), | |||||
WidgetSpan( | |||||
child: SizedBox( | |||||
width: 4.h, | |||||
)), | |||||
TextSpan( | |||||
text: good.goodTitle, | |||||
style: TextStyle( | style: TextStyle( | ||||
color: HexColor.fromHex( | color: HexColor.fromHex( | ||||
"#FFFFFF", | styleModel.titleColor ?? ""), | ||||
), | fontSize: 30.sp)) | ||||
fontSize: 18.sp), | ]))) | ||||
), | ], | ||||
), | ), | ||||
)), | ), | ||||
WidgetSpan( | Row( | ||||
child: SizedBox( | children: <Widget>[ | ||||
width: 4.h, | good.coupon == "" | ||||
)), | ? Container() | ||||
TextSpan( | : Container( | ||||
text: | margin: EdgeInsets.only( | ||||
"Segway Ninebot mini Pro九号平衡车智能代步...", | top: 4, bottom: 4, right: 15.w), | ||||
style: TextStyle( | decoration: BoxDecoration( | ||||
color: Colors.black, | color: HexColor.fromHex(styleModel | ||||
fontSize: 30.sp)) | .couponCommission.left.couponBgColor), | ||||
]))) | image: DecorationImage( | ||||
image: CachedNetworkImageProvider( | |||||
styleModel.couponCommission.left | |||||
.couponBgImg))), | |||||
child: Padding( | |||||
padding: const EdgeInsets.only( | |||||
left: 8, right: 8, top: 2, bottom: 2), | |||||
child: Text( | |||||
(good.coupon ?? "") + | |||||
(styleModel.couponCommission.left | |||||
.couonText ?? | |||||
""), | |||||
style: TextStyle( | |||||
color: HexColor.fromHex(styleModel | |||||
.couponCommission | |||||
.left | |||||
.couponFontColor), | |||||
fontSize: 22.sp), | |||||
), | |||||
), | |||||
), | |||||
good.commission == "" | |||||
? Container() | |||||
: Container( | |||||
margin: EdgeInsets.only(top: 4, bottom: 4), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(styleModel | |||||
.couponCommission | |||||
.right | |||||
.commissionBgColor ?? | |||||
""), | |||||
image: DecorationImage( | |||||
image: CachedNetworkImageProvider( | |||||
styleModel.couponCommission.right | |||||
.commissionBgImg ?? | |||||
""))), | |||||
child: Padding( | |||||
padding: const EdgeInsets.only( | |||||
left: 8, right: 8, top: 2, bottom: 2), | |||||
child: Text( | |||||
(styleModel.couponCommission.right | |||||
.commissionText ?? | |||||
"") + | |||||
(good.commission ?? ""), | |||||
style: TextStyle( | |||||
color: HexColor.fromHex(styleModel | |||||
.couponCommission | |||||
.right | |||||
.commissionFontColor), | |||||
fontSize: 22.sp), | |||||
), | |||||
), | |||||
), | |||||
], | ], | ||||
), | ), | ||||
), | Padding( | ||||
Row( | padding: const EdgeInsets.only(top: 4, bottom: 4), | ||||
children: <Widget>[ | child: Row( | ||||
Container( | crossAxisAlignment: CrossAxisAlignment.end, | ||||
margin: EdgeInsets.only(top: 4, bottom: 4), | children: <Widget>[ | ||||
decoration: BoxDecoration(color: Colors.red), | Padding( | ||||
child: Padding( | padding: EdgeInsets.only(bottom: 6.sp), | ||||
padding: const EdgeInsets.only( | child: Text( | ||||
left: 8, right: 8, top: 2, bottom: 2), | "¥", | ||||
child: Text( | style: TextStyle( | ||||
"50元券", | color: HexColor.fromHex( | ||||
style: TextStyle( | styleModel.currentPriceColor ?? ""), | ||||
color: Colors.white, fontSize: 22.sp), | fontSize: 20.sp), | ||||
), | |||||
), | ), | ||||
), | Text( | ||||
), | good.currentPrice ?? "", | ||||
SizedBox( | |||||
width: 10.sp, | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 4, bottom: 4), | |||||
decoration: BoxDecoration(color: Colors.red), | |||||
child: Padding( | |||||
padding: const EdgeInsets.only( | |||||
left: 8, right: 8, top: 2, bottom: 2), | |||||
child: Text( | |||||
"50元券", | |||||
style: TextStyle( | style: TextStyle( | ||||
color: Colors.white, fontSize: 22.sp), | color: HexColor.fromHex( | ||||
styleModel.currentPriceColor ?? ""), | |||||
fontSize: 40.sp), | |||||
), | ), | ||||
), | SizedBox( | ||||
) | width: 6, | ||||
], | |||||
), | |||||
Padding( | |||||
padding: const EdgeInsets.only(top: 4, bottom: 4), | |||||
child: Row( | |||||
crossAxisAlignment: CrossAxisAlignment.end, | |||||
children: <Widget>[ | |||||
Padding( | |||||
padding: EdgeInsets.only(bottom: 6.sp), | |||||
child: Text( | |||||
"¥", | |||||
style: | |||||
TextStyle(color: Colors.red, fontSize: 20.sp), | |||||
), | ), | ||||
), | Padding( | ||||
Text( | padding: EdgeInsets.only(bottom: 4.sp), | ||||
"1409", | child: Text( | ||||
style: | "¥" + good.marketPrice ?? "", | ||||
TextStyle(color: Colors.red, fontSize: 40.sp), | style: TextStyle( | ||||
), | color: HexColor.fromHex( | ||||
SizedBox( | styleModel.marketPriceColor ?? ""), | ||||
width: 6, | fontSize: 22.sp, | ||||
), | decoration: TextDecoration.lineThrough), | ||||
Padding( | ), | ||||
padding: EdgeInsets.only(bottom: 4.sp), | |||||
child: Text( | |||||
"¥1409", | |||||
style: TextStyle( | |||||
color: Colors.red, | |||||
fontSize: 22.sp, | |||||
decoration: TextDecoration.lineThrough), | |||||
), | ), | ||||
), | ], | ||||
], | ), | ||||
), | ), | ||||
), | Row( | ||||
Row( | children: <Widget>[ | ||||
children: <Widget>[ | Expanded( | ||||
Expanded( | child: Stack( | ||||
child: Stack( | alignment: Alignment.centerLeft, | ||||
alignment: Alignment.centerLeft, | children: <Widget>[ | ||||
children: <Widget>[ | Row( | ||||
Row( | children: <Widget>[ | ||||
children: <Widget>[ | Expanded( | ||||
Expanded( | child: Container( | ||||
child: Container( | height: 40.w, | ||||
height: 40.w, | padding: EdgeInsets.only( | ||||
padding: EdgeInsets.only( | left: 64.w, | ||||
left: 64.w, | ), | ||||
), | margin: | ||||
margin: EdgeInsets.only(right: 20), | EdgeInsets.only(right: 20, left: 20.w), | ||||
color: Colors.red, | color: HexColor.fromHex( | ||||
child: Text( | styleModel.hotRank.bgColor ?? ""), | ||||
"热销1231.1万件", | child: Text( | ||||
style: TextStyle( | "热销" + good.inorderCount + "件", | ||||
color: Colors.white, fontSize: 22.sp), | style: TextStyle( | ||||
), | color: Colors.white, fontSize: 22.sp), | ||||
)) | ), | ||||
], | )) | ||||
), | ], | ||||
Container( | ), | ||||
color: Colors.amber, | Container( | ||||
width: 48.w, | |||||
height: 48.w, | |||||
child: CachedNetworkImage( | |||||
imageUrl: "", | |||||
width: 48.w, | width: 48.w, | ||||
height: 48.w, | height: 48.w, | ||||
placeholder: (context, _) => | child: CachedNetworkImage( | ||||
Container(color: Colors.yellow), | imageUrl: styleModel.hotRank.hotSaleImg ?? "", | ||||
fit: BoxFit.fill, | width: 48.w, | ||||
), | height: 48.w, | ||||
), | placeholder: (context, _) => | ||||
Align( | Container(color: Colors.yellow), | ||||
alignment: Alignment.centerRight, | fit: BoxFit.fill, | ||||
child: Container( | |||||
decoration: BoxDecoration( | |||||
color: Colors.amber, | |||||
borderRadius: BorderRadius.circular(20)), | |||||
margin: EdgeInsets.only(right: 0), | |||||
child: Padding( | |||||
padding: EdgeInsets.only( | |||||
left: 16, right: 16, top: 4, bottom: 4), | |||||
child: Text( | |||||
"马上抢", | |||||
style: TextStyle( | |||||
color: Colors.white, fontSize: 26.sp), | |||||
), | |||||
), | ), | ||||
), | ), | ||||
) | Align( | ||||
], | alignment: Alignment.centerRight, | ||||
)) | child: Container( | ||||
], | height: 48.h, | ||||
) | width: 127.w, | ||||
], | decoration: BoxDecoration( | ||||
), | image: DecorationImage( | ||||
)) | image: CachedNetworkImageProvider( | ||||
], | styleModel.hotRank.buyNowImg ?? | ||||
), | ""), | ||||
), | fit: BoxFit.fitWidth), | ||||
Align( | borderRadius: | ||||
alignment: Alignment.topLeft, | BorderRadius.circular(20)), | ||||
child: Container( | margin: EdgeInsets.only(right: 0), | ||||
margin: EdgeInsets.only(left: 40.w, top: 8.h), | )) | ||||
color: Colors.red, | ], | ||||
height: 60.w, | )) | ||||
width: 60.w, | ], | ||||
) | |||||
], | |||||
), | |||||
)) | |||||
], | |||||
), | |||||
), | ), | ||||
) | Align( | ||||
], | alignment: Alignment.topLeft, | ||||
child: Container( | |||||
decoration: BoxDecoration( | |||||
image: DecorationImage( | |||||
image: CachedNetworkImageProvider(indexImage ?? ""))), | |||||
margin: EdgeInsets.only(left: 40.w, top: 8.h), | |||||
height: 60.w, | |||||
width: 60.w, | |||||
), | |||||
) | |||||
], | |||||
), | |||||
); | ); | ||||
} | } | ||||
Providers getProvider(String provider) { | |||||
for (var item in styleModel.providers) { | |||||
if (item.type == provider) { | |||||
return item; | |||||
} | |||||
} | |||||
} | |||||
} | } |
@@ -0,0 +1,87 @@ | |||||
import 'dart:async'; | |||||
import 'dart:convert'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_data_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HotRankingListBloc extends BlocBase { | |||||
HotRankingListDataModel _pageData; | |||||
StreamController<HotRankingListDataModel> _dataController = | |||||
StreamController<HotRankingListDataModel>(); | |||||
Stream<HotRankingListDataModel> get outData => _dataController.stream; | |||||
String currentTypeId; | |||||
int currentPage = 1; | |||||
bool isLoading = false; | |||||
@override | |||||
void dispose() { | |||||
_dataController.close(); | |||||
_dataController = null; | |||||
} | |||||
void loadData(String typeId, int page,Function complete) { | |||||
if (isLoading) { | |||||
complete(); | |||||
return; | |||||
} | |||||
isLoading = true; | |||||
currentTypeId = typeId; | |||||
NetUtil.request( | |||||
'/api/v1/rec/taobao?type_id=' + typeId + '&page=' + page.toString(), | |||||
method: NetMethod.GET, onSuccess: (data) { | |||||
complete(); | |||||
isLoading = false; | |||||
_loadData(data); | |||||
}, onError: (e) { | |||||
complete(); | |||||
isLoading = false; | |||||
}); | |||||
} | |||||
void loadMoreData(String typeId,Function complete) { | |||||
if (isLoading) { | |||||
complete(); | |||||
return; | |||||
} | |||||
currentPage++; | |||||
isLoading = true; | |||||
NetUtil.request( | |||||
'/api/v1/rec/taobao?type_id=' + | |||||
typeId + | |||||
'&page=' + | |||||
currentPage.toString(), | |||||
method: NetMethod.GET, onSuccess: (data) { | |||||
complete(); | |||||
isLoading = false; | |||||
_loadMoreData(data); | |||||
}, onError: (e) { | |||||
complete(); | |||||
isLoading = false; | |||||
}); | |||||
} | |||||
void _loadData(dynamic data) { | |||||
if (_pageData != null && _pageData.good != null) { | |||||
_pageData.good.clear(); | |||||
_pageData.good.addAll(HotRankingListDataModel.fromJson(data).good); | |||||
} else { | |||||
_pageData = HotRankingListDataModel.fromJson(data); | |||||
} | |||||
_dataController.add(_pageData); | |||||
} | |||||
void _loadMoreData(dynamic data) { | |||||
if (_pageData != null && _pageData.good != null) { | |||||
_pageData.good.addAll(HotRankingListDataModel.fromJson(data).good); | |||||
_dataController.add(_pageData); | |||||
} | |||||
} | |||||
} | |||||
// http://192.168.0.113:5000/api/v1/rec/taobao?page=1 | |||||
// http://192.168.0.113:5000/api/v1/rec/taobao?page=1 |
@@ -0,0 +1,145 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||||
import 'package:zhiying_base_widget/pages/hot_ranking_page/hot_ranking_page_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_goods/hot_ranking_goods.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_data_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'hot_ranking_bloc.dart'; | |||||
import 'hot_ranking_list_sk.dart'; | |||||
class HotRankingList extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
const HotRankingList(this.data, {Key key}) : super(key: key); | |||||
@override | |||||
_HotRankingState createState() => _HotRankingState(); | |||||
} | |||||
class _HotRankingState extends State<HotRankingList> | |||||
with TickerProviderStateMixin { | |||||
HotRankingListBloc _bloc; | |||||
TabController _tabController; | |||||
RefreshController _refreshController; | |||||
List<Good> goods; | |||||
HotRankingPageBloc _pageBloc; | |||||
ScrollController _scrollcontroller; | |||||
@override | |||||
void initState() { | |||||
_bloc = HotRankingListBloc(); | |||||
_refreshController = RefreshController(); | |||||
_pageBloc = BlocProvider.of<HotRankingPageBloc>(context); | |||||
_scrollcontroller=ScrollController(); | |||||
if (_pageBloc != null) { | |||||
_pageBloc.event.listen((event) { | |||||
if (event.containsKey('type') && event['type'] == "loadData") { | |||||
_bloc.currentPage=1; | |||||
_bloc.loadData(event['type_id'], _bloc.currentPage, () {}); | |||||
} | |||||
}); | |||||
} | |||||
super.initState(); | |||||
} | |||||
_buildTabs() { | |||||
List<Widget> listWidget = List(); | |||||
for (int index = 0; index < 4; index++) { | |||||
listWidget.add(Tab( | |||||
text: "hahah", | |||||
)); | |||||
} | |||||
return listWidget; | |||||
} | |||||
@override | |||||
void dispose() { | |||||
_tabController.dispose(); | |||||
super.dispose(); | |||||
} | |||||
///构建 | |||||
void createTabController() { | |||||
_tabController = TabController(length: 4, vsync: this); | |||||
} | |||||
///构建TabView | |||||
_buildTabView() { | |||||
List<Widget> listWidget = List(); | |||||
for (var index = 0; index < 4; index++) { | |||||
listWidget.add(ListView.builder( | |||||
padding: EdgeInsets.all(0), | |||||
itemCount: 10, | |||||
itemBuilder: (context, index) { | |||||
return Container( | |||||
child: HotRankingGoods(), | |||||
); | |||||
})); | |||||
} | |||||
return listWidget; | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder<HotRankingListDataModel>( | |||||
stream: _bloc.outData, | |||||
builder: (context, snapshot) { | |||||
if (snapshot.data == null) { | |||||
return HotRankingSkeleton(); | |||||
} else { | |||||
goods = snapshot.data.good; | |||||
if(_bloc.currentPage==1){ | |||||
Future.delayed(Duration(milliseconds: 100),(){ | |||||
_scrollcontroller.animateTo(0, duration: Duration(milliseconds: 100), curve: Curves.ease); | |||||
}); | |||||
} | |||||
return SmartRefresher( | |||||
controller: _refreshController, | |||||
enablePullDown: true, | |||||
enablePullUp: true, | |||||
onLoading: _onLoading, | |||||
onRefresh: _onRefresh, | |||||
child: CustomScrollView( | |||||
controller: _scrollcontroller, | |||||
slivers: <Widget>[ | |||||
SliverList( | |||||
delegate: SliverChildBuilderDelegate(_buildListItem, | |||||
childCount: goods.length)) | |||||
], | |||||
), | |||||
); | |||||
} | |||||
}); | |||||
} | |||||
Future _onLoading() async { | |||||
_bloc.loadMoreData(_bloc.currentTypeId, () { | |||||
_refreshController.loadComplete(); | |||||
}); | |||||
return null; | |||||
} | |||||
Future _onRefresh() async { | |||||
_bloc.currentPage = 1; | |||||
_bloc.loadData(_bloc.currentTypeId, _bloc.currentPage, () { | |||||
_refreshController.refreshCompleted(); | |||||
}); | |||||
} | |||||
Widget _buildListItem(BuildContext context, int index) { | |||||
return HotRankingGoods( | |||||
styleModel: | |||||
HotRankingListModel.fromJson(json.decode(widget.data['data'])), | |||||
good: goods[index], | |||||
index: index, | |||||
); | |||||
} | |||||
} |
@@ -8,6 +8,7 @@ class HotRankingSkeleton extends StatelessWidget { | |||||
baseColor: Colors.grey[300], | baseColor: Colors.grey[300], | ||||
highlightColor: Colors.grey[100], | highlightColor: Colors.grey[100], | ||||
child: Column( | child: Column( | ||||
mainAxisSize: MainAxisSize.min, | |||||
children: <Widget>[ | children: <Widget>[ | ||||
Container( | Container( | ||||
width: double.infinity, | width: double.infinity, |
@@ -0,0 +1,82 @@ | |||||
class HotRankingListDataModel { | |||||
String provider; | |||||
List<Good> good; | |||||
HotRankingListDataModel({this.provider, this.good}); | |||||
HotRankingListDataModel.fromJson(Map<String, dynamic> json) { | |||||
provider = json['provider']; | |||||
if (json['good'] != null) { | |||||
good = new List<Good>(); | |||||
json['good'].forEach((v) { | |||||
good.add(new Good.fromJson(v)); | |||||
}); | |||||
} | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['provider'] = this.provider; | |||||
if (this.good != null) { | |||||
data['good'] = this.good.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class Good { | |||||
String provider; | |||||
String providerName; | |||||
String goodId; | |||||
String goodImage; | |||||
String goodTitle; | |||||
String shopName; | |||||
String coupon; | |||||
String commission; | |||||
String marketPrice; | |||||
String currentPrice; | |||||
String inorderCount; | |||||
Good( | |||||
{this.provider, | |||||
this.providerName, | |||||
this.goodId, | |||||
this.goodImage, | |||||
this.goodTitle, | |||||
this.shopName, | |||||
this.coupon, | |||||
this.commission, | |||||
this.marketPrice, | |||||
this.currentPrice, | |||||
this.inorderCount}); | |||||
Good.fromJson(Map<String, dynamic> json) { | |||||
provider = json['provider']; | |||||
providerName = json['provider_name']; | |||||
goodId = json['good_id']; | |||||
goodImage = json['good_image']; | |||||
goodTitle = json['good_title']; | |||||
shopName = json['shop_name']; | |||||
coupon = json['coupon']; | |||||
commission = json['commission']; | |||||
marketPrice = json['market_price']; | |||||
currentPrice = json['current_price']; | |||||
inorderCount = json['inorder_count']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['provider'] = this.provider; | |||||
data['provider_name'] = this.providerName; | |||||
data['good_id'] = this.goodId; | |||||
data['good_image'] = this.goodImage; | |||||
data['good_title'] = this.goodTitle; | |||||
data['shop_name'] = this.shopName; | |||||
data['coupon'] = this.coupon; | |||||
data['commission'] = this.commission; | |||||
data['market_price'] = this.marketPrice; | |||||
data['current_price'] = this.currentPrice; | |||||
data['inorder_count'] = this.inorderCount; | |||||
return data; | |||||
} | |||||
} |
@@ -0,0 +1,211 @@ | |||||
class HotRankingListModel { | |||||
List<String> hotRankIconList; | |||||
String topMargin; | |||||
String leftRighMargin; | |||||
List<Providers> providers; | |||||
String titleColor; | |||||
String currentPriceColor; | |||||
String marketPriceColor; | |||||
String shopNameColor; | |||||
String saleCountColor; | |||||
String shopIcon; | |||||
CouponCommission couponCommission; | |||||
HotRank hotRank; | |||||
HotRankingListModel( | |||||
{this.hotRankIconList, | |||||
this.topMargin, | |||||
this.leftRighMargin, | |||||
this.providers, | |||||
this.titleColor, | |||||
this.currentPriceColor, | |||||
this.marketPriceColor, | |||||
this.shopNameColor, | |||||
this.saleCountColor, | |||||
this.shopIcon, | |||||
this.couponCommission, | |||||
this.hotRank}); | |||||
HotRankingListModel.fromJson(Map<String, dynamic> json) { | |||||
hotRankIconList = json['hot_rank_icon_list'].cast<String>(); | |||||
topMargin = json['top_margin']; | |||||
leftRighMargin = json['left_righ_margin']; | |||||
if (json['providers'] != null) { | |||||
providers = new List<Providers>(); | |||||
json['providers'].forEach((v) { | |||||
providers.add(new Providers.fromJson(v)); | |||||
}); | |||||
} | |||||
titleColor = json['title_color']; | |||||
currentPriceColor = json['current_price_color']; | |||||
marketPriceColor = json['market_price_color']; | |||||
shopNameColor = json['shop_name_color']; | |||||
saleCountColor = json['sale_count_color']; | |||||
shopIcon = json['shop_icon']; | |||||
couponCommission = json['coupon_commission'] != null | |||||
? new CouponCommission.fromJson(json['coupon_commission']) | |||||
: null; | |||||
hotRank = json['hot_rank'] != null | |||||
? new HotRank.fromJson(json['hot_rank']) | |||||
: null; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['hot_rank_icon_list'] = this.hotRankIconList; | |||||
data['top_margin'] = this.topMargin; | |||||
data['left_righ_margin'] = this.leftRighMargin; | |||||
if (this.providers != null) { | |||||
data['providers'] = this.providers.map((v) => v.toJson()).toList(); | |||||
} | |||||
data['title_color'] = this.titleColor; | |||||
data['current_price_color'] = this.currentPriceColor; | |||||
data['market_price_color'] = this.marketPriceColor; | |||||
data['shop_name_color'] = this.shopNameColor; | |||||
data['sale_count_color'] = this.saleCountColor; | |||||
data['shop_icon'] = this.shopIcon; | |||||
if (this.couponCommission != null) { | |||||
data['coupon_commission'] = this.couponCommission.toJson(); | |||||
} | |||||
if (this.hotRank != null) { | |||||
data['hot_rank'] = this.hotRank.toJson(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class Providers { | |||||
String type; | |||||
String providerNameColor; | |||||
String providerBgColor; | |||||
Providers({this.type, this.providerNameColor, this.providerBgColor}); | |||||
Providers.fromJson(Map<String, dynamic> json) { | |||||
type = json['type']; | |||||
providerNameColor = json['provider_name_color']; | |||||
providerBgColor = json['provider_bg_color']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['type'] = this.type; | |||||
data['provider_name_color'] = this.providerNameColor; | |||||
data['provider_bg_color'] = this.providerBgColor; | |||||
return data; | |||||
} | |||||
} | |||||
class CouponCommission { | |||||
Left left; | |||||
Right right; | |||||
CouponCommission({this.left, this.right}); | |||||
CouponCommission.fromJson(Map<String, dynamic> json) { | |||||
left = json['left'] != null ? new Left.fromJson(json['left']) : null; | |||||
right = json['right'] != null ? new Right.fromJson(json['right']) : null; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
if (this.left != null) { | |||||
data['left'] = this.left.toJson(); | |||||
} | |||||
if (this.right != null) { | |||||
data['right'] = this.right.toJson(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class Left { | |||||
String couonText; | |||||
String couponFontColor; | |||||
String couponBgColor; | |||||
String couponBgImg; | |||||
Left( | |||||
{this.couonText, | |||||
this.couponFontColor, | |||||
this.couponBgColor, | |||||
this.couponBgImg}); | |||||
Left.fromJson(Map<String, dynamic> json) { | |||||
couonText = json['couon_text']; | |||||
couponFontColor = json['coupon_font_color']; | |||||
couponBgColor = json['coupon_bg_color']; | |||||
couponBgImg = json['coupon_bg_img']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['couon_text'] = this.couonText; | |||||
data['coupon_font_color'] = this.couponFontColor; | |||||
data['coupon_bg_color'] = this.couponBgColor; | |||||
data['coupon_bg_img'] = this.couponBgImg; | |||||
return data; | |||||
} | |||||
} | |||||
class Right { | |||||
String commissionText; | |||||
String commissionFontColor; | |||||
String commissionBgColor; | |||||
String commissionBgImg; | |||||
Right( | |||||
{this.commissionText, | |||||
this.commissionFontColor, | |||||
this.commissionBgColor, | |||||
this.commissionBgImg}); | |||||
Right.fromJson(Map<String, dynamic> json) { | |||||
commissionText = json['commission_text']; | |||||
commissionFontColor = json['commission_font_color']; | |||||
commissionBgColor = json['commission_bg_color']; | |||||
commissionBgImg = json['commission_bg_img']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['commission_text'] = this.commissionText; | |||||
data['commission_font_color'] = this.commissionFontColor; | |||||
data['commission_bg_color'] = this.commissionBgColor; | |||||
data['commission_bg_img'] = this.commissionBgImg; | |||||
return data; | |||||
} | |||||
} | |||||
class HotRank { | |||||
String isOpen; | |||||
String bgColor; | |||||
String fontColor; | |||||
String hotSaleImg; | |||||
String buyNowImg; | |||||
HotRank( | |||||
{this.isOpen, | |||||
this.bgColor, | |||||
this.fontColor, | |||||
this.hotSaleImg, | |||||
this.buyNowImg}); | |||||
HotRank.fromJson(Map<String, dynamic> json) { | |||||
isOpen = json['is_open']; | |||||
bgColor = json['bg_color']; | |||||
fontColor = json['font_color']; | |||||
hotSaleImg = json['hot_sale_img']; | |||||
buyNowImg = json['buy_now_img']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['is_open'] = this.isOpen; | |||||
data['bg_color'] = this.bgColor; | |||||
data['font_color'] = this.fontColor; | |||||
data['hot_sale_img'] = this.hotSaleImg; | |||||
data['buy_now_img'] = this.buyNowImg; | |||||
return data; | |||||
} | |||||
} |
@@ -0,0 +1,99 @@ | |||||
import 'dart:async'; | |||||
import 'dart:convert'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/pages/hot_ranking_page/hot_ranking_page_bloc.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/util/extension/color.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'model/hot_tabbar_model.dart'; | |||||
class HotRankTableBar extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
const HotRankTableBar(this.data, {Key key}) : super(key: key); | |||||
@override | |||||
_HotRankTableBarState createState() => _HotRankTableBarState(); | |||||
} | |||||
class _HotRankTableBarState extends State<HotRankTableBar> | |||||
with TickerProviderStateMixin { | |||||
TabController _tabController; | |||||
HotRankingTabBarModel _barModel; | |||||
HotRankingPageBloc _pageBloc; | |||||
@override | |||||
void initState() { | |||||
_barModel = | |||||
HotRankingTabBarModel.fromJson(json.decode(widget.data['data'])); | |||||
_tabController = | |||||
TabController(length: _barModel.tabList.length, vsync: this); | |||||
_pageBloc = BlocProvider.of<HotRankingPageBloc>(context); | |||||
///待页面初始化后发送加载事件 | |||||
Timer(Duration(milliseconds: 100), () { | |||||
if (_barModel != null && | |||||
_barModel.tabList != null && | |||||
_barModel.tabList.length > 0) { | |||||
var params = { | |||||
"type": "loadData", | |||||
"type_id": _barModel.tabList[0].typeId | |||||
}; | |||||
_pageBloc.sendEvent(params); | |||||
} | |||||
}); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Container( | |||||
margin: EdgeInsets.only(bottom: 10), | |||||
child: TabBar( | |||||
indicatorPadding: EdgeInsets.only(bottom: 0), | |||||
indicatorSize: TabBarIndicatorSize.label, | |||||
controller: _tabController, | |||||
indicatorColor: HexColor.fromHex( | |||||
_barModel.tabList[_tabController.index].nameSelectColor), | |||||
unselectedLabelColor: HexColor.fromHex( | |||||
_barModel.tabList[_tabController.index].nameNoSelectColor), | |||||
labelColor: HexColor.fromHex( | |||||
_barModel.tabList[_tabController.index].nameSelectColor), | |||||
isScrollable: true, | |||||
tabs: _buildTabs(), | |||||
onTap: (index) { | |||||
var params = { | |||||
"type": "loadData", | |||||
"type_id": _barModel.tabList[_tabController.index].typeId | |||||
}; | |||||
_pageBloc.sendEvent(params); | |||||
}, | |||||
), | |||||
); | |||||
} | |||||
_buildTabs() { | |||||
List<Widget> listWidget = List(); | |||||
for (int index = 0; index < _barModel.tabList.length; index++) { | |||||
var item = _barModel.tabList[index]; | |||||
listWidget.add(Container( | |||||
child: Padding( | |||||
padding: const EdgeInsets.only( | |||||
bottom: 2, | |||||
top: 0, | |||||
), | |||||
child: Text( | |||||
item.name, | |||||
style: TextStyle(fontSize: 26.sp), | |||||
), | |||||
), | |||||
)); | |||||
} | |||||
return listWidget; | |||||
} | |||||
} |
@@ -0,0 +1,51 @@ | |||||
class HotRankingTabBarModel { | |||||
String indicatorColor; | |||||
List<TabList> tabList; | |||||
HotRankingTabBarModel({this.indicatorColor, this.tabList}); | |||||
HotRankingTabBarModel.fromJson(Map<String, dynamic> json) { | |||||
indicatorColor = json['indicator_color']; | |||||
if (json['tab_list'] != null) { | |||||
tabList = new List<TabList>(); | |||||
json['tab_list'].forEach((v) { | |||||
tabList.add(new TabList.fromJson(v)); | |||||
}); | |||||
} | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['indicator_color'] = this.indicatorColor; | |||||
if (this.tabList != null) { | |||||
data['tab_list'] = this.tabList.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class TabList { | |||||
String name; | |||||
String nameSelectColor; | |||||
String nameNoSelectColor; | |||||
String typeId; | |||||
TabList( | |||||
{this.name, this.nameSelectColor, this.nameNoSelectColor, this.typeId}); | |||||
TabList.fromJson(Map<String, dynamic> json) { | |||||
name = json['name']; | |||||
nameSelectColor = json['name_select_color']; | |||||
nameNoSelectColor = json['name_no_select_color']; | |||||
typeId = json['type_id']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['name'] = this.name; | |||||
data['name_select_color'] = this.nameSelectColor; | |||||
data['name_no_select_color'] = this.nameNoSelectColor; | |||||
data['type_id'] = this.typeId; | |||||
return data; | |||||
} | |||||
} |
@@ -1,8 +1,8 @@ | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_container.dart'; | |||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_sk.dart'; | |||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; | import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||||
import 'hot_ranking_list/hot_ranking_list.dart'; | |||||
class HotTest extends StatefulWidget { | class HotTest extends StatefulWidget { | ||||
@override | @override | ||||
_HotTestState createState() => _HotTestState(); | _HotTestState createState() => _HotTestState(); | ||||
@@ -14,7 +14,7 @@ class _HotTestState extends State<HotTest> { | |||||
// 屏幕适配初始化 | // 屏幕适配初始化 | ||||
ScreenUtil.init(context, width: 750, height: 1334); | ScreenUtil.init(context, width: 750, height: 1334); | ||||
return Scaffold( | return Scaffold( | ||||
body: HotRankingContainer(), | body: HotRankingList(null), | ||||
); | ); | ||||
} | } | ||||
} | } |
@@ -15,6 +15,7 @@ class WalletAppbar extends StatelessWidget { | |||||
return Container( | return Container( | ||||
height: MediaQuery.of(context).padding.top + 56, | height: MediaQuery.of(context).padding.top + 56, | ||||
child: AppBar( | child: AppBar( | ||||
elevation: 0, | |||||
leading: Navigator.canPop(context) | leading: Navigator.canPop(context) | ||||
? IconButton( | ? IconButton( | ||||
icon: Icon(Icons.arrow_back_ios), | icon: Icon(Icons.arrow_back_ios), | ||||
@@ -22,11 +23,11 @@ class WalletAppbar extends StatelessWidget { | |||||
Navigator.of(context).pop(); | Navigator.of(context).pop(); | ||||
}) | }) | ||||
: Container(), | : Container(), | ||||
backgroundColor: HexColor.fromHex(model.appBarBgColor), | backgroundColor: HexColor.fromHex(model.appBarBgColor??""), | ||||
centerTitle: true, | centerTitle: true, | ||||
title: Text( | title: Text( | ||||
model.appBarName, | model.appBarName??"", | ||||
style: TextStyle(color: HexColor.fromHex(model.appBarNameColor)), | style: TextStyle(color: HexColor.fromHex(model.appBarNameColor??"")), | ||||
), | ), | ||||
), | ), | ||||
); | ); | ||||
@@ -0,0 +1,20 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:shimmer/shimmer.dart'; | |||||
class WalletAppbarSkeleton extends StatelessWidget { | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Container( | |||||
child: Shimmer.fromColors( | |||||
baseColor: Colors.grey[300], | |||||
highlightColor: Colors.grey[100], | |||||
child: Container( | |||||
child: AppBar( | |||||
backgroundColor: Colors.white, | |||||
), | |||||
), | |||||
), | |||||
); | |||||
} | |||||
} |
@@ -3,6 +3,7 @@ class WalletHeaderModel { | |||||
String headerAvatar; | String headerAvatar; | ||||
String headerCashOutText; | String headerCashOutText; | ||||
String headerCashOutTextColor; | String headerCashOutTextColor; | ||||
String headerCashOutKey; | |||||
String headerCashOutBtnImg; | String headerCashOutBtnImg; | ||||
List<HeaderBottomList> headerBottomList; | List<HeaderBottomList> headerBottomList; | ||||
@@ -11,6 +12,7 @@ class WalletHeaderModel { | |||||
this.headerAvatar, | this.headerAvatar, | ||||
this.headerCashOutText, | this.headerCashOutText, | ||||
this.headerCashOutTextColor, | this.headerCashOutTextColor, | ||||
this.headerCashOutKey, | |||||
this.headerCashOutBtnImg, | this.headerCashOutBtnImg, | ||||
this.headerBottomList}); | this.headerBottomList}); | ||||
@@ -19,6 +21,7 @@ class WalletHeaderModel { | |||||
headerAvatar = json['header_avatar']; | headerAvatar = json['header_avatar']; | ||||
headerCashOutText = json['header_cash_out_text']; | headerCashOutText = json['header_cash_out_text']; | ||||
headerCashOutTextColor = json['header_cash_out_text_color']; | headerCashOutTextColor = json['header_cash_out_text_color']; | ||||
headerCashOutKey = json['header_cash_out_key']; | |||||
headerCashOutBtnImg = json['header_cash_out_btn_img']; | headerCashOutBtnImg = json['header_cash_out_btn_img']; | ||||
if (json['header_bottom_list'] != null) { | if (json['header_bottom_list'] != null) { | ||||
headerBottomList = new List<HeaderBottomList>(); | headerBottomList = new List<HeaderBottomList>(); | ||||
@@ -34,6 +37,7 @@ class WalletHeaderModel { | |||||
data['header_avatar'] = this.headerAvatar; | data['header_avatar'] = this.headerAvatar; | ||||
data['header_cash_out_text'] = this.headerCashOutText; | data['header_cash_out_text'] = this.headerCashOutText; | ||||
data['header_cash_out_text_color'] = this.headerCashOutTextColor; | data['header_cash_out_text_color'] = this.headerCashOutTextColor; | ||||
data['header_cash_out_key'] = this.headerCashOutKey; | |||||
data['header_cash_out_btn_img'] = this.headerCashOutBtnImg; | data['header_cash_out_btn_img'] = this.headerCashOutBtnImg; | ||||
if (this.headerBottomList != null) { | if (this.headerBottomList != null) { | ||||
data['header_bottom_list'] = | data['header_bottom_list'] = | ||||
@@ -44,50 +48,26 @@ class WalletHeaderModel { | |||||
} | } | ||||
class HeaderBottomList { | class HeaderBottomList { | ||||
String totalText; | String text; | ||||
String totalTextColor; | String textColor; | ||||
String totalValueColor; | String valueColor; | ||||
String cashOutText; | String valueKey; | ||||
String cashOutTextColor; | |||||
String cashOutValueColor; | |||||
String unfinalText; | |||||
String unfinalTextColor; | |||||
String unfinalValueColor; | |||||
HeaderBottomList( | HeaderBottomList({this.text, this.textColor, this.valueColor, this.valueKey}); | ||||
{this.totalText, | |||||
this.totalTextColor, | |||||
this.totalValueColor, | |||||
this.cashOutText, | |||||
this.cashOutTextColor, | |||||
this.cashOutValueColor, | |||||
this.unfinalText, | |||||
this.unfinalTextColor, | |||||
this.unfinalValueColor}); | |||||
HeaderBottomList.fromJson(Map<String, dynamic> json) { | HeaderBottomList.fromJson(Map<String, dynamic> json) { | ||||
totalText = json['total_text']; | text = json['text']; | ||||
totalTextColor = json['total_text_color']; | textColor = json['text_color']; | ||||
totalValueColor = json['total_value_color']; | valueColor = json['value_color']; | ||||
cashOutText = json['cash_out_text']; | valueKey = json['value_key']; | ||||
cashOutTextColor = json['cash_out_text_color']; | |||||
cashOutValueColor = json['cash_out_value_color']; | |||||
unfinalText = json['unfinal_text']; | |||||
unfinalTextColor = json['unfinal_text_color']; | |||||
unfinalValueColor = json['unfinal_value_color']; | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['total_text'] = this.totalText; | data['text'] = this.text; | ||||
data['total_text_color'] = this.totalTextColor; | data['text_color'] = this.textColor; | ||||
data['total_value_color'] = this.totalValueColor; | data['value_color'] = this.valueColor; | ||||
data['cash_out_text'] = this.cashOutText; | data['value_key'] = this.valueKey; | ||||
data['cash_out_text_color'] = this.cashOutTextColor; | |||||
data['cash_out_value_color'] = this.cashOutValueColor; | |||||
data['unfinal_text'] = this.unfinalText; | |||||
data['unfinal_text_color'] = this.unfinalTextColor; | |||||
data['unfinal_value_color'] = this.unfinalValueColor; | |||||
return data; | return data; | ||||
} | } | ||||
} | } |
@@ -2,118 +2,159 @@ import 'dart:convert'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/model/wallet_header_model.dart'; | import 'package:zhiying_base_widget/widgets/wallet/wallet_data/model/wallet_header_model.dart'; | ||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data_sk.dart'; | import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data_sk.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class WalletData extends StatelessWidget { | class WalletData extends StatefulWidget { | ||||
final Map<String, dynamic> data; | final Map<String, dynamic> data; | ||||
const WalletData(this.data, {Key key}) : super(key: key); | const WalletData(this.data, {Key key}) : super(key: key); | ||||
@override | @override | ||||
Widget build(BuildContext context) { | _WalletDataState createState() => _WalletDataState(); | ||||
} | |||||
class _WalletDataState extends State<WalletData> { | |||||
Map<String, dynamic> data; | |||||
WalletDataBloc _bloc; | |||||
Map<String, dynamic> dataModel; | |||||
@override | |||||
void initState() { | |||||
data = widget.data; | |||||
_bloc = WalletDataBloc(); | |||||
_bloc.loadHeaderData(); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
print(data); | print(data); | ||||
Map<String, dynamic> temp = json.decode(data['data']); | WalletHeaderModel model; | ||||
var model = WalletHeaderModel.fromJson(temp); | return StreamBuilder( | ||||
return Container( | stream: _bloc.outData, | ||||
width: double.infinity, | builder: (context, asn) { | ||||
child: data == null | dataModel = asn.data; | ||||
? WalletDataSkeleton() | if (data.containsKey('data')) { | ||||
: Container( | Map<String, dynamic> temp = json.decode(data['data']); | ||||
margin: EdgeInsets.only(left: 12.5, right: 12.5,top: 10), | model = WalletHeaderModel.fromJson(temp); | ||||
padding: EdgeInsets.only(left: 36.w, right: 26.w), | } else { | ||||
decoration: BoxDecoration( | return WalletDataSkeleton(); | ||||
image: DecorationImage( | } | ||||
image: CachedNetworkImageProvider(model.headerImg),fit: BoxFit.fill)), | return Container( | ||||
height: 290.h, | width: double.infinity, | ||||
child: Column( | child: dataModel == null | ||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ? WalletDataSkeleton() | ||||
children: <Widget>[ | : Container( | ||||
Row( | margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 10), | ||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | padding: EdgeInsets.only(left: 36.w, right: 26.w), | ||||
children: <Widget>[ | decoration: BoxDecoration( | ||||
Row( | image: DecorationImage( | ||||
children: <Widget>[ | image: CachedNetworkImageProvider( | ||||
CachedNetworkImage( | model?.headerImg ?? ""), | ||||
imageUrl: model.headerAvatar, | fit: BoxFit.fill)), | ||||
height: 66.h, | height: 290.h, | ||||
width: 52.w, | child: Column( | ||||
), | mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||||
Padding( | children: <Widget>[ | ||||
padding: const EdgeInsets.all(8.0), | Row( | ||||
child: Column( | mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
crossAxisAlignment: CrossAxisAlignment.start, | children: <Widget>[ | ||||
Row( | |||||
children: <Widget>[ | children: <Widget>[ | ||||
Text( | CachedNetworkImage( | ||||
model.headerCashOutText, | imageUrl: model?.headerAvatar ?? "", | ||||
style: TextStyle( | height: 66.h, | ||||
fontSize: 25.sp, | width: 52.h, | ||||
color: HexColor.fromHex( | fit: BoxFit.fill, | ||||
model.headerCashOutTextColor)), | |||||
), | |||||
Text( | |||||
"没数据", | |||||
style: TextStyle( | |||||
fontSize: 25.sp, | |||||
color: HexColor.fromHex( | |||||
model.headerCashOutTextColor)), | |||||
), | ), | ||||
Padding( | |||||
padding: const EdgeInsets.all(8.0), | |||||
child: Column( | |||||
crossAxisAlignment: | |||||
CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Text( | |||||
model?.headerCashOutText ?? "", | |||||
style: TextStyle( | |||||
fontSize: 25.sp, | |||||
color: HexColor.fromHex( | |||||
model?.headerCashOutTextColor ?? | |||||
"")), | |||||
), | |||||
Text( | |||||
dataModel.containsKey( | |||||
model.headerCashOutKey) | |||||
? dataModel[model.headerCashOutKey] | |||||
: "", | |||||
style: TextStyle( | |||||
fontSize: 40.sp, | |||||
color: HexColor.fromHex( | |||||
model.headerCashOutTextColor)), | |||||
), | |||||
], | |||||
), | |||||
) | |||||
], | ], | ||||
), | ), | ||||
) | GestureDetector( | ||||
], | child: Container( | ||||
), | decoration: BoxDecoration( | ||||
GestureDetector( | color: Colors.red, | ||||
child: Container( | borderRadius: BorderRadius.circular(10), | ||||
decoration: BoxDecoration( | image: DecorationImage( | ||||
color: Colors.red, | image: CachedNetworkImageProvider(""), | ||||
borderRadius: BorderRadius.circular(10), | fit: BoxFit.fill)), | ||||
image: DecorationImage( | child: Padding( | ||||
image: CachedNetworkImageProvider(""), | padding: EdgeInsets.only( | ||||
fit: BoxFit.fill)), | left: 29.w, | ||||
child: Padding( | right: 29.w, | ||||
padding: EdgeInsets.only( | top: 20.w, | ||||
left: 29.w, | bottom: 20.w), | ||||
right: 29.w, | child: Text( | ||||
top: 20.w, | "提现", | ||||
bottom: 20.w), | style: TextStyle(color: Colors.white), | ||||
child: Text( | ), | ||||
"提现", | ), | ||||
style: TextStyle(color: Colors.white), | ), | ||||
), | ) | ||||
), | ], | ||||
), | |||||
Divider( | |||||
height: 1, | |||||
), | ), | ||||
) | Row( | ||||
], | mainAxisAlignment: MainAxisAlignment.spaceAround, | ||||
), | children: _buildTopListItem(model)) | ||||
Divider( | ], | ||||
height: 1, | ), | ||||
), | )); | ||||
Row( | }, | ||||
mainAxisAlignment: MainAxisAlignment.spaceAround, | |||||
children: _buildTopListItem(model?.headerBottomList)) | |||||
], | |||||
), | |||||
), | |||||
); | ); | ||||
} | } | ||||
///构建顶部Item | ///构建顶部Item | ||||
_buildTopListItem(List<HeaderBottomList> list) { | _buildTopListItem(WalletHeaderModel model) { | ||||
List<Widget> listWidget = List(); | List<Widget> listWidget = List(); | ||||
for (var item in list) { | for (var item in model.headerBottomList) { | ||||
listWidget.add(Column( | listWidget.add(Column( | ||||
mainAxisSize: MainAxisSize.min, | mainAxisSize: MainAxisSize.min, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Text( | Text( | ||||
"9999", | dataModel.containsKey(item.valueKey) | ||||
style: TextStyle(color: Colors.red, fontSize: 30.sp), | ? dataModel[item.valueKey] | ||||
: "", | |||||
style: TextStyle( | |||||
color: HexColor.fromHex(item.valueColor), fontSize: 30.sp), | |||||
), | ), | ||||
Text( | Text( | ||||
"累计到账(元)", | item.text, | ||||
style: TextStyle(color: Colors.grey, fontSize: 22.sp), | style: TextStyle( | ||||
color: HexColor.fromHex(item.textColor), fontSize: 22.sp), | |||||
), | ), | ||||
], | ], | ||||
)); | )); | ||||
@@ -0,0 +1,29 @@ | |||||
import 'dart:async'; | |||||
import 'dart:convert'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class WalletDataBloc extends BlocBase { | |||||
StreamController<Map<String, dynamic>> _dataController = | |||||
StreamController<Map<String, dynamic>>(); | |||||
Stream<Map<String, dynamic>> get outData => _dataController.stream; | |||||
@override | |||||
void dispose() { | |||||
_dataController.close(); | |||||
_dataController = null; | |||||
} | |||||
/// | |||||
/// 加载头部数据 | |||||
/// | |||||
loadHeaderData() async { | |||||
await NetUtil.request("/api/v1/user/wallet/header",onSuccess: (data){ | |||||
_dataController.add(data); | |||||
}); | |||||
} | |||||
} |
@@ -1,7 +1,8 @@ | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'wallet_data.dart'; | |||||
class WalletDataCreater extends WidgetCreater { | class WalletDataCreater extends WidgetCreater { | ||||
@override | @override | ||||
List<Widget> createWidgets(Map<String, dynamic> model) { | List<Widget> createWidgets(Map<String, dynamic> model) { | ||||
@@ -0,0 +1,45 @@ | |||||
class WalletDetailDataModel { | |||||
String type; | |||||
String finish; | |||||
String selfbuyEstimatedIncome; | |||||
String selfbuyPayOrder; | |||||
String directPromoteEstimatedIncome; | |||||
String directPromotePayOrder; | |||||
String indirectPromoteEstimatedIncome; | |||||
String indirectPromotePayOrder; | |||||
WalletDetailDataModel( | |||||
{this.type, | |||||
this.finish, | |||||
this.selfbuyEstimatedIncome, | |||||
this.selfbuyPayOrder, | |||||
this.directPromoteEstimatedIncome, | |||||
this.directPromotePayOrder, | |||||
this.indirectPromoteEstimatedIncome, | |||||
this.indirectPromotePayOrder}); | |||||
WalletDetailDataModel.fromJson(Map<String, dynamic> json) { | |||||
type = json['type']; | |||||
finish = json['finish']; | |||||
selfbuyEstimatedIncome = json['selfbuy_estimated_income']; | |||||
selfbuyPayOrder = json['selfbuy_pay_order']; | |||||
directPromoteEstimatedIncome = json['direct_promote_estimated_income']; | |||||
directPromotePayOrder = json['direct_promote_pay_order']; | |||||
indirectPromoteEstimatedIncome = json['indirect_promote_estimated_income']; | |||||
indirectPromotePayOrder = json['indirect_promote_pay_order']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['type'] = this.type; | |||||
data['finish'] = this.finish; | |||||
data['selfbuy_estimated_income'] = this.selfbuyEstimatedIncome; | |||||
data['selfbuy_pay_order'] = this.selfbuyPayOrder; | |||||
data['direct_promote_estimated_income'] = this.directPromoteEstimatedIncome; | |||||
data['direct_promote_pay_order'] = this.directPromotePayOrder; | |||||
data['indirect_promote_estimated_income'] = | |||||
this.indirectPromoteEstimatedIncome; | |||||
data['indirect_promote_pay_order'] = this.indirectPromotePayOrder; | |||||
return data; | |||||
} | |||||
} |
@@ -72,27 +72,46 @@ class Providers { | |||||
} | } | ||||
class DateList { | class DateList { | ||||
String isDefault; | |||||
String text; | String text; | ||||
String type; | |||||
String textSelectColor; | String textSelectColor; | ||||
String textUnselectColor; | String textUnselectColor; | ||||
String btnImg; | String btnImg; | ||||
String btnNoColorImg; | |||||
String btnColorImg; | |||||
DateList( | DateList( | ||||
{this.text, this.textSelectColor, this.textUnselectColor, this.btnImg}); | {this.isDefault, | ||||
this.text, | |||||
this.type, | |||||
this.textSelectColor, | |||||
this.textUnselectColor, | |||||
this.btnImg, | |||||
this.btnNoColorImg, | |||||
this.btnColorImg}); | |||||
DateList.fromJson(Map<String, dynamic> json) { | DateList.fromJson(Map<String, dynamic> json) { | ||||
isDefault = json['is_default']; | |||||
text = json['text']; | text = json['text']; | ||||
type = json['type']; | |||||
textSelectColor = json['text_select_color']; | textSelectColor = json['text_select_color']; | ||||
textUnselectColor = json['text_unselect_color']; | textUnselectColor = json['text_unselect_color']; | ||||
btnImg = json['btn_img']; | btnImg = json['btn_img']; | ||||
btnNoColorImg = json['btn_no_color_img']; | |||||
btnColorImg = json['btn_color_img']; | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['is_default'] = this.isDefault; | |||||
data['text'] = this.text; | data['text'] = this.text; | ||||
data['type'] = this.type; | |||||
data['text_select_color'] = this.textSelectColor; | data['text_select_color'] = this.textSelectColor; | ||||
data['text_unselect_color'] = this.textUnselectColor; | data['text_unselect_color'] = this.textUnselectColor; | ||||
data['btn_img'] = this.btnImg; | data['btn_img'] = this.btnImg; | ||||
data['btn_no_color_img'] = this.btnNoColorImg; | |||||
data['btn_color_img'] = this.btnColorImg; | |||||
return data; | return data; | ||||
} | } | ||||
} | } | ||||
@@ -139,49 +158,62 @@ class ProviderDashbord { | |||||
} | } | ||||
class Finish { | class Finish { | ||||
String isShow; | |||||
String text; | String text; | ||||
String textColor; | String textColor; | ||||
String valueColor; | String valueColor; | ||||
String vauleKey; | |||||
String bgImg; | String bgImg; | ||||
String tipIcon; | |||||
String tipText; | |||||
Finish({this.text, this.textColor, this.valueColor, this.bgImg}); | Finish( | ||||
{this.isShow, | |||||
this.text, | |||||
this.textColor, | |||||
this.valueColor, | |||||
this.vauleKey, | |||||
this.bgImg, | |||||
this.tipIcon, | |||||
this.tipText}); | |||||
Finish.fromJson(Map<String, dynamic> json) { | Finish.fromJson(Map<String, dynamic> json) { | ||||
isShow = json['is_show']; | |||||
text = json['text']; | text = json['text']; | ||||
textColor = json['text_color']; | textColor = json['text_color']; | ||||
valueColor = json['value_color']; | valueColor = json['value_color']; | ||||
vauleKey = json['vaule_key']; | |||||
bgImg = json['bg_img']; | bgImg = json['bg_img']; | ||||
tipIcon = json['tip_icon']; | |||||
tipText = json['tip_text']; | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['is_show'] = this.isShow; | |||||
data['text'] = this.text; | data['text'] = this.text; | ||||
data['text_color'] = this.textColor; | data['text_color'] = this.textColor; | ||||
data['value_color'] = this.valueColor; | data['value_color'] = this.valueColor; | ||||
data['vaule_key'] = this.vauleKey; | |||||
data['bg_img'] = this.bgImg; | data['bg_img'] = this.bgImg; | ||||
data['tip_icon'] = this.tipIcon; | |||||
data['tip_text'] = this.tipText; | |||||
return data; | return data; | ||||
} | } | ||||
} | } | ||||
class SelfBuy { | class SelfBuy { | ||||
String isShow; | |||||
String title; | String title; | ||||
String titleColor; | String titleColor; | ||||
String leftBgImg; | |||||
String rightBgImg; | |||||
List<ItemList> itemList; | List<ItemList> itemList; | ||||
SelfBuy( | SelfBuy({this.isShow, this.title, this.titleColor, this.itemList}); | ||||
{this.title, | |||||
this.titleColor, | |||||
this.leftBgImg, | |||||
this.rightBgImg, | |||||
this.itemList}); | |||||
SelfBuy.fromJson(Map<String, dynamic> json) { | SelfBuy.fromJson(Map<String, dynamic> json) { | ||||
isShow = json['is_show']; | |||||
title = json['title']; | title = json['title']; | ||||
titleColor = json['title_color']; | titleColor = json['title_color']; | ||||
leftBgImg = json['left_bg_img']; | |||||
rightBgImg = json['right_bg_img']; | |||||
if (json['list'] != null) { | if (json['list'] != null) { | ||||
itemList = new List<ItemList>(); | itemList = new List<ItemList>(); | ||||
json['list'].forEach((v) { | json['list'].forEach((v) { | ||||
@@ -192,10 +224,9 @@ class SelfBuy { | |||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['is_show'] = this.isShow; | |||||
data['title'] = this.title; | data['title'] = this.title; | ||||
data['title_color'] = this.titleColor; | data['title_color'] = this.titleColor; | ||||
data['left_bg_img'] = this.leftBgImg; | |||||
data['right_bg_img'] = this.rightBgImg; | |||||
if (this.itemList != null) { | if (this.itemList != null) { | ||||
data['list'] = this.itemList.map((v) => v.toJson()).toList(); | data['list'] = this.itemList.map((v) => v.toJson()).toList(); | ||||
} | } | ||||
@@ -204,23 +235,42 @@ class SelfBuy { | |||||
} | } | ||||
class ItemList { | class ItemList { | ||||
String bgImg; | |||||
String text; | String text; | ||||
String textColor; | String textColor; | ||||
String vauleKey; | |||||
String valueColor; | String valueColor; | ||||
String tipIcon; | |||||
String tipText; | |||||
ItemList({this.text, this.textColor, this.valueColor}); | ItemList( | ||||
{this.bgImg, | |||||
this.text, | |||||
this.textColor, | |||||
this.vauleKey, | |||||
this.valueColor, | |||||
this.tipIcon, | |||||
this.tipText}); | |||||
ItemList.fromJson(Map<String, dynamic> json) { | ItemList.fromJson(Map<String, dynamic> json) { | ||||
bgImg = json['bg_img']; | |||||
text = json['text']; | text = json['text']; | ||||
textColor = json['text_color']; | textColor = json['text_color']; | ||||
vauleKey = json['vaule_key']; | |||||
valueColor = json['value_color']; | valueColor = json['value_color']; | ||||
tipIcon = json['tip_icon']; | |||||
tipText = json['tip_text']; | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['bg_img'] = this.bgImg; | |||||
data['text'] = this.text; | data['text'] = this.text; | ||||
data['text_color'] = this.textColor; | data['text_color'] = this.textColor; | ||||
data['vaule_key'] = this.vauleKey; | |||||
data['value_color'] = this.valueColor; | data['value_color'] = this.valueColor; | ||||
data['tip_icon'] = this.tipIcon; | |||||
data['tip_text'] = this.tipText; | |||||
return data; | return data; | ||||
} | } | ||||
} | } |
@@ -2,9 +2,12 @@ import 'dart:convert'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/dialog/tip_dialog/tip_dialog.dart'; | |||||
import 'package:zhiying_base_widget/pages/withdraw_page/withdraw_page.dart'; | import 'package:zhiying_base_widget/pages/withdraw_page/withdraw_page.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | ||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/model/wallet_detail_data_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/model/wallet_detail_model.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'; | |||||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_sk.dart'; | import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_sk.dart'; | ||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; | import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
@@ -25,7 +28,11 @@ class WalletDetail extends StatefulWidget { | |||||
class _WalletDetailState extends State<WalletDetail> | class _WalletDetailState extends State<WalletDetail> | ||||
with TickerProviderStateMixin { | with TickerProviderStateMixin { | ||||
WalletDetailModel _model; | WalletDetailModel _model; | ||||
TabController _tabController; | TabController _tabController; | ||||
WalletDetailBloc _bloc; | |||||
@override | @override | ||||
void initState() { | void initState() { | ||||
if (widget.data != null) { | if (widget.data != null) { | ||||
@@ -33,92 +40,139 @@ class _WalletDetailState extends State<WalletDetail> | |||||
_tabController = | _tabController = | ||||
TabController(length: _model.providers.length, vsync: this); | TabController(length: _model.providers.length, vsync: this); | ||||
} | } | ||||
_bloc = new WalletDetailBloc(); | |||||
_bloc.loadData(_model.providers[0].type); | |||||
super.initState(); | super.initState(); | ||||
} | } | ||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Container( | return StreamBuilder( | ||||
margin: EdgeInsets.only(left: 12.5, right: 12.5), | stream: _bloc.outData, | ||||
child: Column( | builder: (context, asyn) { | ||||
children: <Widget>[ | if (_bloc.listDataModel.length == 0) { | ||||
Container( | ///骨架图 | ||||
child: TabBar( | return WalletDetailSkeleton(); | ||||
// isScrollable: true, | } | ||||
controller: _tabController, | return Container( | ||||
tabs: _buildTabs()), | decoration: BoxDecoration( | ||||
), | color: Colors.white, borderRadius: BorderRadius.circular(8)), | ||||
Container( | margin: | ||||
height: 75.h, | EdgeInsets.only(left: 12.5, right: 12.5, top: 15.h, bottom: 15.h), | ||||
child: ListView.builder( | padding: EdgeInsets.only(bottom: 15.h), | ||||
padding: EdgeInsets.only(top: 16), | child: Column( | ||||
itemCount: _model.dateList.length, | children: <Widget>[ | ||||
scrollDirection: Axis.horizontal, | Container( | ||||
itemBuilder: _buildTimeItem), | child: TabBar( | ||||
), | isScrollable: true, | ||||
Container( | unselectedLabelColor: | ||||
height: 126.h, | HexColor.fromHex(_model.providers[0].unselectColor), | ||||
margin: EdgeInsets.only(top: 16), | labelColor: | ||||
width: double.infinity, | HexColor.fromHex(_model.providers[0].selectColor), | ||||
decoration: BoxDecoration( | controller: _tabController, | ||||
image: DecorationImage( | indicatorColor: | ||||
image: CachedNetworkImageProvider( | HexColor.fromHex(_model.providers[0].selectColor), | ||||
_model.providerDashbord.finish.bgImg), | indicatorSize: TabBarIndicatorSize.label, | ||||
fit: BoxFit.fill)), | onTap: (index) { | ||||
child: Column( | ///变更平台 | ||||
mainAxisAlignment: MainAxisAlignment.center, | changeProvider(_model.providers[index].type); | ||||
children: <Widget>[ | }, | ||||
Row( | tabs: _buildTabs()), | ||||
), | |||||
///日期选择 | |||||
Container( | |||||
height: 75.h, | |||||
child: ListView.builder( | |||||
padding: EdgeInsets.only(top: 16,left: 16.w), | |||||
itemCount: _model.dateList.length, | |||||
scrollDirection: Axis.horizontal, | |||||
itemBuilder: _buildTimeItem), | |||||
), | |||||
Container( | |||||
height: 126.h, | |||||
margin: EdgeInsets.only(top: 16, left: 30.w, right: 30.w), | |||||
width: double.infinity, | |||||
decoration: BoxDecoration( | |||||
image: DecorationImage( | |||||
image: CachedNetworkImageProvider( | |||||
_model.providerDashbord.finish.bgImg), | |||||
fit: BoxFit.fill)), | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | mainAxisAlignment: MainAxisAlignment.center, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Text( | _model.providerDashbord.finish.isShow == "1" | ||||
"已结算", | ? Container() | ||||
style: TextStyle(color: Colors.black, fontSize: 22.sp), | : Padding( | ||||
), | padding: const EdgeInsets.all(8.0), | ||||
InkWell( | child: Text( | ||||
child: Padding( | _model.providerDashbord.finish.text, | ||||
padding: const EdgeInsets.all(8.0), | style: TextStyle( | ||||
child: CachedNetworkImage( | fontSize: 28.sp, | ||||
imageUrl: "", | color: HexColor.fromHex(_model | ||||
width: 20.h, | .providerDashbord.finish.textColor)), | ||||
height: 20.h, | ), | ||||
fit: BoxFit.fill, | |||||
), | ), | ||||
Row( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
Text( | |||||
_model.providerDashbord.finish.text ?? "", | |||||
style: | |||||
TextStyle(color: Colors.black, fontSize: 22.sp), | |||||
), | ), | ||||
onTap: () { | InkWell( | ||||
///问好 | child: Padding( | ||||
}) | padding: const EdgeInsets.all(8.0), | ||||
child: CachedNetworkImage( | |||||
imageUrl: | |||||
_model.providerDashbord.finish.tipIcon ?? | |||||
"", | |||||
width: 20.h, | |||||
height: 20.h, | |||||
fit: BoxFit.fill, | |||||
), | |||||
), | |||||
onTap: () { | |||||
///显示弹窗 | |||||
showTipDialog( | |||||
null, _model.providerDashbord.finish.tipText); | |||||
}) | |||||
], | |||||
), | |||||
Text( | |||||
_bloc.selectDateData.finish ?? "", | |||||
style: TextStyle(color: Colors.red, fontSize: 40.sp), | |||||
) | |||||
], | ], | ||||
), | ), | ||||
Text( | ), | ||||
"158", | Container( | ||||
style: TextStyle(color: Colors.red, fontSize: 40.sp), | child: ListView.builder( | ||||
) | padding: EdgeInsets.all(0), | ||||
], | itemCount: 3, | ||||
), | shrinkWrap: true, | ||||
physics: NeverScrollableScrollPhysics(), | |||||
itemBuilder: (context, index) { | |||||
return _buildBottomItem( | |||||
context, index, _model.providerDashbord); | |||||
}), | |||||
) | |||||
], | |||||
), | ), | ||||
Container( | ); | ||||
child: ListView.builder( | }, | ||||
itemCount: 3, | |||||
shrinkWrap: true, | |||||
physics: NeverScrollableScrollPhysics(), | |||||
itemBuilder: (context, index) { | |||||
return _buildBottomItem( | |||||
context, index, _model.providerDashbord); | |||||
}), | |||||
) | |||||
], | |||||
), | |||||
); | ); | ||||
} | } | ||||
///平台选择 | |||||
_buildTabs() { | _buildTabs() { | ||||
List<Widget> listWidget = List(); | List<Widget> listWidget = List(); | ||||
for (var item in _model.providers) { | for (var item in _model.providers) { | ||||
listWidget.add(Tab( | listWidget.add(Tab( | ||||
child: Text( | child: Text( | ||||
item.name, | item.name, | ||||
style: TextStyle(color: Colors.grey), | style: TextStyle(fontSize: 28.sp), | ||||
), | ), | ||||
)); | )); | ||||
} | } | ||||
@@ -127,53 +181,173 @@ class _WalletDetailState extends State<WalletDetail> | |||||
Widget _buildTimeItem(BuildContext context, int index) { | Widget _buildTimeItem(BuildContext context, int index) { | ||||
var item = _model.dateList[index]; | var item = _model.dateList[index]; | ||||
return Container( | return InkWell( | ||||
margin: EdgeInsets.only(top: 0, left: 8, right: 8), | child: Container( | ||||
decoration: BoxDecoration( | margin: EdgeInsets.only(top: 0, left: 8, right: 8), | ||||
color: Colors.grey[200], borderRadius: BorderRadius.circular(50)), | decoration: BoxDecoration( | ||||
child: Padding( | image: DecorationImage( | ||||
padding: const EdgeInsets.only(left: 16, right: 16), | image: CachedNetworkImageProvider( | ||||
child: Center( | item.type == _bloc.selectDateData.type | ||||
child: Text( | ? item.btnImg ?? "" | ||||
item.text, | : item.btnNoColorImg ?? ""), | ||||
style: TextStyle(color: Colors.grey), | fit: BoxFit.fitWidth), | ||||
)), | ), | ||||
child: Padding( | |||||
padding: const EdgeInsets.only(left: 16, right: 16), | |||||
child: Center( | |||||
child: Text( | |||||
item.text, | |||||
style: TextStyle( | |||||
fontSize: 22.sp, | |||||
color: HexColor.fromHex(item.type == _bloc.selectDateData.type | |||||
? item.textSelectColor | |||||
: item.textUnselectColor)), | |||||
)), | |||||
), | |||||
), | ), | ||||
onTap: () { | |||||
for (var select in _bloc.listDataModel) { | |||||
if (select.type == item.type) { | |||||
_bloc.selectDay = item.type; | |||||
_bloc.refresh(); | |||||
return; | |||||
} | |||||
} | |||||
}, | |||||
); | ); | ||||
} | } | ||||
///底部显示 | |||||
Widget _buildBottomItem( | Widget _buildBottomItem( | ||||
BuildContext context, int index, ProviderDashbord dashbord) { | BuildContext context, int index, ProviderDashbord dashbord) { | ||||
var item = dashbord.selfBuy; | SelfBuy item; | ||||
if (index == 0) { | |||||
item = dashbord.selfBuy; | |||||
} else if (index == 1) { | |||||
item = dashbord.directPromote; | |||||
} else { | |||||
item = dashbord.indirectPromote; | |||||
} | |||||
var dataMap = _bloc.selectDateData.toJson(); | |||||
return Container( | return Container( | ||||
child: Column( | child: Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Text( | SizedBox( | ||||
item.title, | height: 15.h, | ||||
style: TextStyle(color: HexColor.fromHex(item.titleColor)), | ), | ||||
item.isShow == "0" | |||||
? Container() | |||||
: Text( | |||||
item.title, | |||||
style: TextStyle( | |||||
color: HexColor.fromHex(item.titleColor), | |||||
fontSize: 28.sp), | |||||
), | |||||
SizedBox( | |||||
height: 15.h, | |||||
), | ), | ||||
Row( | Row( | ||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Expanded( | Expanded( | ||||
child: Container( | child: Container( | ||||
height: 123.h, | height: 123.h, | ||||
margin: EdgeInsets.only(right: 8), | margin: EdgeInsets.only(right: 8, left: 30.w), | ||||
decoration: BoxDecoration( | padding: EdgeInsets.only(left: 20.w), | ||||
image: DecorationImage( | decoration: BoxDecoration( | ||||
image: CachedNetworkImageProvider(item?.leftBgImg ?? ''), | image: DecorationImage( | ||||
fit: BoxFit.fill)), | image: CachedNetworkImageProvider( | ||||
child: Center(child: Text("ddd")), | item.itemList[0].bgImg ?? ""), | ||||
), | fit: BoxFit.fill)), | ||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Row( | |||||
children: <Widget>[ | |||||
Text( | |||||
item.itemList[0].text ?? "", | |||||
style: TextStyle( | |||||
fontSize: 22.sp, | |||||
color: HexColor.fromHex( | |||||
item.itemList[0].textColor)), | |||||
), | |||||
InkWell( | |||||
child: Padding( | |||||
padding: const EdgeInsets.all(8.0), | |||||
child: CachedNetworkImage( | |||||
imageUrl: item.itemList[0].tipIcon, | |||||
width: 20.h, | |||||
height: 20.h, | |||||
fit: BoxFit.fill, | |||||
), | |||||
), | |||||
onTap: () { | |||||
//弹窗 | |||||
showTipDialog(null, item.itemList[0].tipText); | |||||
}, | |||||
) | |||||
], | |||||
), | |||||
Text(dataMap[item.itemList[0].vauleKey], | |||||
style: TextStyle( | |||||
fontSize: 34.sp, | |||||
color: | |||||
HexColor.fromHex(item.itemList[1].valueColor), | |||||
)) | |||||
], | |||||
)), | |||||
), | ), | ||||
Expanded( | Expanded( | ||||
child: Container( | child: Container( | ||||
height: 123.h, | height: 123.h, | ||||
margin: EdgeInsets.only(left: 8), | margin: EdgeInsets.only(left: 8, right: 30.w), | ||||
padding: EdgeInsets.only(left: 20.w), | |||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
image: DecorationImage( | image: DecorationImage( | ||||
image: CachedNetworkImageProvider(item?.rightBgImg ?? ''))), | image: CachedNetworkImageProvider( | ||||
child: Center(child: Text("dddd")), | item.itemList[1].bgImg ?? ""), | ||||
fit: BoxFit.fill)), | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Row( | |||||
children: <Widget>[ | |||||
Text( | |||||
item.itemList[1].text ?? "", | |||||
style: TextStyle( | |||||
fontSize: 22.sp, | |||||
color: | |||||
HexColor.fromHex(item.itemList[1].textColor)), | |||||
), | |||||
InkWell( | |||||
child: Padding( | |||||
padding: const EdgeInsets.all(8.0), | |||||
child: CachedNetworkImage( | |||||
imageUrl: item.itemList[1].tipIcon, | |||||
width: 20.h, | |||||
height: 20.h, | |||||
fit: BoxFit.fill, | |||||
), | |||||
), | |||||
onTap: () { | |||||
//弹窗 | |||||
showTipDialog(null, item.itemList[1].tipText); | |||||
}, | |||||
) | |||||
], | |||||
), | |||||
Text( | |||||
dataMap[item.itemList[1].vauleKey], | |||||
style: TextStyle( | |||||
fontSize: 34.sp, | |||||
color: HexColor.fromHex(item.itemList[1].valueColor)), | |||||
) | |||||
], | |||||
), | |||||
)) | )) | ||||
], | ], | ||||
) | ) | ||||
@@ -181,4 +355,14 @@ class _WalletDetailState extends State<WalletDetail> | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
///变更平台 | |||||
void changeProvider(String type) { | |||||
_bloc.loadData(type); | |||||
} | |||||
///显示提示框 | |||||
void showTipDialog(String title, String content) { | |||||
showDialog(context: context, child: TipDialog(content: content)); | |||||
} | |||||
} | } |
@@ -0,0 +1,52 @@ | |||||
import 'dart:async'; | |||||
import 'dart:convert'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'model/wallet_detail_data_model.dart'; | |||||
class WalletDetailBloc extends BlocBase { | |||||
StreamController<WalletDetailDataModel> _dataController = | |||||
StreamController<WalletDetailDataModel>(); | |||||
Stream<WalletDetailDataModel> get outData => _dataController.stream; | |||||
///选中的某一时间的数据 | |||||
WalletDetailDataModel selectDateData; | |||||
String selectDay = "today"; | |||||
List<WalletDetailDataModel> listDataModel = new List(); | |||||
@override | |||||
void dispose() { | |||||
_dataController.close(); | |||||
_dataController = null; | |||||
} | |||||
/// | |||||
/// 加载头部数据 | |||||
/// | |||||
loadData(String type) async { | |||||
await NetUtil.request("/api/v1/user/wallet/" + type, onSuccess: (data) { | |||||
listDataModel.clear(); | |||||
listDataModel.addAll(List.from(data).map((v) { | |||||
return WalletDetailDataModel.fromJson(v); | |||||
}).toList()); | |||||
refresh(); | |||||
}); | |||||
} | |||||
///刷新页面 | |||||
refresh() { | |||||
for (var item in listDataModel) { | |||||
if (selectDay == item.type) { | |||||
selectDateData = item; | |||||
_dataController.add(selectDateData); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; | |||||
import 'package:shimmer/shimmer.dart'; | import 'package:shimmer/shimmer.dart'; | ||||
class WalletDetailSkeleton extends StatelessWidget { | class WalletDetailSkeleton extends StatelessWidget { | ||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Container( | return Container( | ||||
@@ -12,23 +13,93 @@ class WalletDetailSkeleton extends StatelessWidget { | |||||
child: Shimmer.fromColors( | child: Shimmer.fromColors( | ||||
baseColor: Colors.grey[300], | baseColor: Colors.grey[300], | ||||
highlightColor: Colors.grey[100], | highlightColor: Colors.grey[100], | ||||
child: Row( | child: Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Container( | Container( | ||||
width: 18, | width: double.infinity, | ||||
height: 18, | child: _createTab(), | ||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(9), | |||||
color: Colors.white), | |||||
), | ), | ||||
Container( | Container( | ||||
margin: EdgeInsets.only(left: 8), | margin: EdgeInsets.only(top: 6), | ||||
width: 120, | width: double.infinity, | ||||
height: 14, | child: _createTags(), | ||||
color: Colors.white, | |||||
), | ), | ||||
Container( | |||||
margin: EdgeInsets.only(top: 6), | |||||
height: 64, | |||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
color: Colors.white), | |||||
), | |||||
_createDataRow(), | |||||
_createDataRow(), | |||||
_createDataRow(), | |||||
], | ], | ||||
)), | )), | ||||
); | ); | ||||
} | } | ||||
Widget _createTab() { | |||||
return Row( | |||||
children: List.generate(5, (index) { | |||||
return Expanded( | |||||
child: Container( | |||||
height: 14, | |||||
margin: EdgeInsets.only(left: 10, right: 10, top: 4, bottom: 4), | |||||
color: Colors.white, | |||||
), | |||||
); | |||||
}), | |||||
); | |||||
} | |||||
Widget _createTags() { | |||||
return Row( | |||||
children: List.generate(5, (index) { | |||||
return Expanded( | |||||
child: Container( | |||||
height: 20, | |||||
margin: EdgeInsets.only(left: 10, right: 10, top: 4, bottom: 4), | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, borderRadius: BorderRadius.circular(10)), | |||||
), | |||||
); | |||||
}), | |||||
); | |||||
} | |||||
Widget _createDataRow() { | |||||
return Column( | |||||
children: <Widget>[ | |||||
Container( | |||||
margin: EdgeInsets.only(top: 8, bottom: 2), | |||||
width: 64, | |||||
height: 18, | |||||
color: Colors.white, | |||||
), | |||||
Row( | |||||
children: <Widget>[ | |||||
Expanded( | |||||
child: Container( | |||||
margin: EdgeInsets.only(top: 6, right: 5), | |||||
height: 64, | |||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
color: Colors.white), | |||||
), | |||||
), | |||||
Expanded( | |||||
child: Container( | |||||
margin: EdgeInsets.only(top: 6, left: 5), | |||||
height: 64, | |||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
color: Colors.white), | |||||
), | |||||
) | |||||
], | |||||
) | |||||
], | |||||
); | |||||
} | |||||
} | } |
@@ -12,93 +12,23 @@ class WalletIncomeSkeleton extends StatelessWidget { | |||||
child: Shimmer.fromColors( | child: Shimmer.fromColors( | ||||
baseColor: Colors.grey[300], | baseColor: Colors.grey[300], | ||||
highlightColor: Colors.grey[100], | highlightColor: Colors.grey[100], | ||||
child: Column( | child: Row( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Container( | Container( | ||||
width: double.infinity, | width: 18, | ||||
child: _createTab(), | height: 18, | ||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 6), | |||||
width: double.infinity, | |||||
child: _createTags(), | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 6), | |||||
height: 64, | |||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
borderRadius: BorderRadius.circular(7.5), | borderRadius: BorderRadius.circular(9), | ||||
color: Colors.white), | color: Colors.white), | ||||
), | ), | ||||
_createDataRow(), | Container( | ||||
_createDataRow(), | margin: EdgeInsets.only(left: 8), | ||||
_createDataRow(), | width: 120, | ||||
height: 14, | |||||
color: Colors.white, | |||||
), | |||||
], | ], | ||||
)), | )), | ||||
); | ); | ||||
} | } | ||||
Widget _createTab() { | |||||
return Row( | |||||
children: List.generate(5, (index) { | |||||
return Expanded( | |||||
child: Container( | |||||
height: 14, | |||||
margin: EdgeInsets.only(left: 10, right: 10, top: 4, bottom: 4), | |||||
color: Colors.white, | |||||
), | |||||
); | |||||
}), | |||||
); | |||||
} | |||||
Widget _createTags() { | |||||
return Row( | |||||
children: List.generate(5, (index) { | |||||
return Expanded( | |||||
child: Container( | |||||
height: 20, | |||||
margin: EdgeInsets.only(left: 10, right: 10, top: 4, bottom: 4), | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, borderRadius: BorderRadius.circular(10)), | |||||
), | |||||
); | |||||
}), | |||||
); | |||||
} | |||||
Widget _createDataRow() { | |||||
return Column( | |||||
children: <Widget>[ | |||||
Container( | |||||
margin: EdgeInsets.only(top: 8, bottom: 2), | |||||
width: 64, | |||||
height: 18, | |||||
color: Colors.white, | |||||
), | |||||
Row( | |||||
children: <Widget>[ | |||||
Expanded( | |||||
child: Container( | |||||
margin: EdgeInsets.only(top: 6, right: 5), | |||||
height: 64, | |||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
color: Colors.white), | |||||
), | |||||
), | |||||
Expanded( | |||||
child: Container( | |||||
margin: EdgeInsets.only(top: 6, left: 5), | |||||
height: 64, | |||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
color: Colors.white), | |||||
), | |||||
) | |||||
], | |||||
) | |||||
], | |||||
); | |||||
} | |||||
} | } |