flutter_wanandroid

by Sky24n

🔥🔥🔥 基于Google Flutter的WanAndroid客户端,支持Android和iOS。包括BLoC、RxDart 、国际化、主题色、启动页、引导页,拥有较好的项目结构&比较规范的代...

4.6K Stars 1.0K Forks Last release: Not found BSD 2-Clause "Simplified" License 108 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

Flutter版 WanAndroid App.

本项目包含启动页,引导页,主题色,国际化,Bloc,RxDart。拥有较好的项目结构,比较规范的代码。 App拥有精致的UI界面,统一的交互,侧滑退出,列表和Web界面均提供快速滚动至顶部功能。

有关项目最新动态,可以关注App内第一条Hot Item信息。

运行本项目注意!!!

Support [√] Flutter (Channel stable, v1.17.0).

由于在国内访问Flutter有时可能会受到限制,clone项目后,请勿直接packages get,建议运行如下目录行:

export PUB_HOSTED_URL=https://pub.flutter-io.cn  
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn  
flutter packages get
flutter run --release

更新说明

v0.2.6 (2020.05.08)
Support [√] Flutter (Channel stable, v1.17.0).
版本升级功能(仅供参考)

FlutterRepos

  1. base_library Flutter基础组件库,方便多个项目共用。
  2. login_demo 关于App启动时,未登录跳登录页,已登录进主页。
  3. flutter_gallery 也许是Google官方最后一个版本的gallery(旧版)。

App目录结构

  • |--lib
    • |-- blocs (bloc相关)
    • |-- common (常用类,例如常量Constant)
    • |-- data (网络数据层)
    • |-- db (数据库)
    • |-- demos (flutter demos)
    • |-- event (事件类)
    • |-- models (实体类)
    • |-- res (资源文件,string,colors,dimens,styles)
    • |-- ui (界面相关page,dialog,widgets)
    • |-- utils (工具类)

data网络数据层

  • |--data
    • |-- api (url字段)
    • |-- net (单例DioUtil)
    • |-- protocol (请求与返回实体类)
    • |-- repository (接口请求&解析)

api

class WanAndroidApi {
  /// 首页banner http://www.wanandroid.com/banner/json
  static const String BANNER = "banner";
  static const String USER_REGISTER = "user/register"; //注册
  static const String USER_LOGIN = "user/login"; //登录
  static const String USER_LOGOUT = "user/logout"; //退出

// 拼接url static String getPath({String path: '', int page, String resType: 'json'}) { StringBuffer sb = new StringBuffer(path); if (page != null) { sb.write('/$page'); } if (resType != null && resType.isNotEmpty) { sb.write('/$resType'); } return sb.toString(); } }

网络请求工具类 DioUtil

// 打开debug模式.
DioUtil.openDebug();   

// 配置网络参数. Options options = DioUtil.getDefOptions(); options.baseUrl = "http://www.wanandroid.com/"; HttpConfig config = new HttpConfig(options: options); DioUtil().setConfig(config);

// 两种单例请求方式. DioUtil().request(Method.get, "banner/json"); DioUtil.getInstance().request(Method.get, "banner/json");

//示例 LoginReq req = new LoginReq('username', 'password'); DioUtil().request(Method.post, "user/login",data: req.toJson());

//示例 FormData formData = new FormData.from({ "username": "username", "password": "password", }); DioUtil().requestR(Method.post, "user/login",data: rformData);

请求与返回实体类 protocol

class LoginReq {
  String username;
  String password;

LoginReq(this.username, this.password);

LoginReq.fromJson(Map json) : username = json['username'], password = json['password'];

Map toJson() => { 'username': username, 'password': password, };

@override String toString() { StringBuffer sb = new StringBuffer('{'); sb.write(""username":"$username""); sb.write(","password":$password"); sb.write('}'); return sb.toString(); } }

接口请求&解析 repository

 class WanRepository {
  Future> getBanner() async {
    BaseResp baseResp = await DioUtil().request(
        Method.get, WanAndroidApi.getPath(path: WanAndroidApi.BANNER));
    List bannerList;
    if (baseResp.code != Constant.STATUS_SUCCESS) {
      return new Future.error(baseResp.msg);
    }
    if (baseResp.data != null) {
      bannerList = baseResp.data.map((value) {
        return BannerModel.fromJson(value);
      }).toList();
    }
    return bannerList;
  }
}

资源文件 res

  • |--res
    • |-- colors.dart
    • |-- dimens.dart
    • |-- strings.dart
    • |-- styles.dart

colors.dart

class Colours {
  static const Color app_main = Color(0xFF666666);  

static const Color text_dark = Color(0xFF333333); static const Color text_normal = Color(0xFF666666); static const Color text_gray = Color(0xFF999999);
}

dimens.dart

class Dimens {
  static const double font_sp12 = 12;
  static const double font_sp14 = 14;
  static const double font_sp16 = 16;

static const double gap_dp5 = 5; static const double gap_dp10 = 10; }

strings.dart

class Ids {
  static const String titleHome = 'title_home';
}  
Map>> localizedValues = {
  'en': {
    'US': {
      Ids.titleHome: 'Home',
    }
  },
  'zh': {
    'CN': {
      Ids.titleHome: '主页',
    },
    'HK': {
      Ids.titleHome: '主頁',
    },
    'TW': {
      Ids.titleHome: '主頁',
    }
  }
};

styles.dart

class TextStyles {
  static TextStyle listTitle = TextStyle(
    fontSize: Dimens.font_sp16,
    color: Colours.text_dark,
    fontWeight: FontWeight.bold,
  );
  static TextStyle listContent = TextStyle(
    fontSize: Dimens.font_sp14,
    color: Colours.text_normal,
  );
  static TextStyle listExtra = TextStyle(
    fontSize: Dimens.font_sp12,
    color: Colours.text_gray,
  );
}
//  间隔
class Gaps {
  // 水平间隔
  static Widget hGap5 = new SizedBox(width: Dimens.gap_dp5);
  static Widget hGap10 = new SizedBox(width: Dimens.gap_dp10);
  // 垂直间隔
  static Widget vGap5 = new SizedBox(height: Dimens.gap_dp5);
  static Widget vGap10 = new SizedBox(height: Dimens.gap_dp10);
}

Flutter 国际化相关 fluintl

fluintl是一个为应用提供国际化的库,可快速集成实现应用多语言。该库封装了一个国际化支持类,通过提供统一方法getString(id)获取字符串。 ```dart // 在MyApp initState配置多语言资源 setLocalizedValues(localizedValues); //配置多语言资源 // 在MaterialApp指定localizationsDelegates和supportedLocales MaterialApp(
home: MyHomePage(),
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
CustomLocalizations.delegate //设置本地化代理
],
supportedLocales: CustomLocalizations.supportedLocales,//设置支持本地化语言集合
); // 字符串获取 IntlUtil.getString(context, Ids.titleHome); CustomLocalizations.of(context).getString(StringIds.titleHome);

// 支持复用。替换字符串格式要求:'%\${index}\$s' ,{index} 第几个参数,从0开始。 Ids.clicktimes: '%\$0\$s点击了%\$1\$s次',
IntlUtil.getString(context, Ids.click
times, params: ['Tom', '$_counter'])
// print: Tom点击了0次 ```

Flutter 屏幕适配 ScreenUtil

方案一、不依赖context ```dart // 步骤1 // 如果设计稿尺寸默认配置一致,无需该设置。 配置设计稿尺寸 默认 360.0 / 640.0 / 3.0 setDesignWHD(designW,designH,_designD);

// 步骤2 // 在MainPageState build 调用MediaQuery.of(context) class MainPageState extends State { @override Widget build(BuildContext context) { // 在 MainPageState build 调用 MediaQuery.of(context) MediaQuery.of(context); return new Scaffold( appBar: new AppBar(), ); } }

// 步骤3 ScreenUtil.getInstance().screenWidth ScreenUtil.getInstance().screenHeight //屏幕适配相关
ScreenUtil.getInstance().getWidth(size); //返回根据屏幕宽适配后尺寸(单位 dp or pt) ScreenUtil.getInstance().getHeight(size); //返回根据屏幕高适配后尺寸 (单位 dp or pt) ScreenUtil.getInstance().getWidthPx(sizePx); //sizePx 单位px ScreenUtil.getInstance().getHeightPx(sizePx); //sizePx 单位px ScreenUtil.getInstance().getSp(fontSize); //返回根据屏幕宽适配后字体尺寸

double adapterSize = ScreenUtil.getInstance().getAdapterSize(100);

方案二、依赖context
dart //如果设计稿尺寸默认配置一致,无需该设置。 配置设计稿尺寸 默认 360.0 / 640.0 / 3.0 setDesignWHD(designW,designH,_designD);

ScreenUtil.getScreenW(context); //屏幕 宽 ScreenUtil.getScreenH(context); //屏幕 高 //屏幕适配相关
ScreenUtil.getScaleW(context, size); //返回根据屏幕宽适配后尺寸(单位 dp or pt) ScreenUtil.getScaleH(context, size); //返回根据屏幕高适配后尺寸 (单位 dp or pt) ScreenUtil.getScaleSp(context, size) ;//返回根据屏幕宽适配后字体尺寸

double adapterSize = ScreenUtil.getAdapterSizeCtx(context, 100) ```

Flutter 数据存储 SpUtil

单例"同步" SharedPreferences 工具类。
支持get获取默认参数、支持存储实体对象、支持存储实体对象数组。 ```dart // 等待Sp初始化完成。 await SpUtil.getInstance();

SpUtil.getString('key', defValue: '');
SpUtil.getInt('key', defValue: 0);

/// save object example. /// 存储实体对象示例。 City city = new City(); city.name = "成都市"; SpUtil.putObject("loc_city", city);

City hisCity = SpUtil.getObj("loc_city", (v) => City.fromJson(v)); print("thll Str: " + (hisCity == null ? "null" : hisCity.toString()));

/// save object list example. /// 存储实体对象List示例。 List list = new List(); list.add(new City(name: "成都市")); list.add(new City(name: "北京市")); SpUtil.putObjectList("loc_city_list", list);

List _cityList = SpUtil.getObjList("loc_city_list", (v) => City.fromJson(v)); print("thll List: " + (_cityList == null ? "null" : _cityList.toString()));

Flutter Demos

>- |--demos > - |-- city_select_page.dart 城市列表(索引&悬停)示例 > - |-- date_page.dart 日期格式化示例 > - |-- image_size_page.dart 获取图片尺寸示例 > - |-- money_page.dart 金额(元转分/分转元)示例 > - |-- pinyin_page.dart 汉字转拼音示例 > - |-- regex_page.dart 正则工具类示例 > - |-- round_portrait_page.dart 圆形圆角头像示例 > - |-- timeline_page.dart 时间轴示例 > - |-- timer_page.dart 倒计时/定时任务示例 > - |-- widget_page.dart 获取Widget尺寸/屏幕坐标示例

Screenshots

截图无法查看?

掘金地址
简书地址

主界面 启动页 侧滑Back
快速滚动到顶部 分类页面 国际化
主题色 闪屏广告页 引导页

Thanks

① 感谢鸿洋大佬提供的开源api
② 界面参考gitme
Github Trending Api
Streams-Block-Reactive-Programming-in-Flutter

项目问题汇总

Q1:Flutter国际化系统切换iOS不生效问题?
A1:在Xcode项目Localizations下添加支持语言即可,原文

App

Apk:flutter_wanandroid.apk
iOS:请自行clone项目代码运行。

关于作者

GitHub : Sky24n
简书     : Sky24n
掘金     : Sky24n
Email   : [email protected]
⭐⭐⭐ 如果您觉得本项目不错的话,来个star支持下作者吧! ⭐⭐⭐
关于项目任何问题请提交issues,私发QQ邮件将不再回复~

⭐⭐⭐ 最新开源 ⭐⭐⭐
nine_grid_view
Flutter仿微信/微博九宫格、拖拽排序,钉钉群组,微信群组头像。

⭐⭐⭐ 个人作品 ⭐⭐⭐
Fitness
Flutter开发的微博客户端,同时支持Android和iOS。与官方微博x9.99%相似度体验,离线模式,多语言支持,主题随心换,超乎想象的流畅度,各种惊喜的细节等待你一一发现。

Flutter仿微博客户端 Flutter Weibo

GitHub stars

Flutter仿微信/微博九宫格 NineGridView

GitHub stars

Flutter版玩安卓 flutter_wanandroid

GitHub stars

Flutter仿滴滴出行 GreenTravel

GitHub stars

Flutter常用工具类库 flustars

GitHub stars

Dart常用工具类库 common_utils

GitHub stars

Flutter城市列表 azlistview

GitHub stars

Flutter汉字转拼音库 lpinyin

GitHub stars

Flutter国际化库 fluintl

GitHub stars

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.