現實生活中常見的問題

他山之石

pub.dev

網路的互動

http: ^0.13.3

flutter_html: ^2.1.2

http 302 redirect

Future<String> getRealImgUrl(String urlString) async {
  var client = baseClient();

  http.Request req = http.Request("Get", Uri.parse(urlString))
    ..followRedirects = false;

  try {
    http.StreamedResponse response = await client.send(req);
    if (response.statusCode == 302) {
      return await getRealImgUrl(response.headers['location']);
    } else if (response.statusCode == 200) {
      return urlString;
    }
  } finally {
    client.close();
  }

  return "";
}

Debug

break point

Uri parse / Url encode / decode

Object Mapping

Local Storage

Function / CallBack

Fun

exception

try/catch/finally

exception

型別轉換

is Type

print(("" is String).toString());

Extension methods

extension AkiStringExtension on String {
  DateTime stringToDate(
      {bool parseUTC = false}) {
    String fromPattern = "yyyy-MM-dd'T'HH:mm:ss";  
    final fromFormatter = DateFormat(fromPattern);
    if (parseUTC) {
      return fromFormatter.parseUTC(this);
    } else {
      return fromFormatter.parseUTC(this).toLocal();
    }
  }

常用的WIDGET / 按鈕 / 布局

Icons / Images

Collection

map / filter / where / first / toList()

myList.asMap().entries.map((entry) {
    int idx = entry.key;
    String val = entry.value;

    return something;
}).toList();

snackbar

字體

顏色

const Color blue = Color(0xFF008BCD);

Color fromHex(String hexString) {
  final buffer = StringBuffer();
  if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
  buffer.write(hexString.replaceFirst('#', ''));
  return Color(int.parse(buffer.toString(), radix: 16));
}

extension

extension AkiColorExtension on String {
  Color toColor() {
    final buffer = StringBuffer();
    if (this.length == 6 || this.length == 7) buffer.write('ff');
    buffer.write(this.replaceFirst('#', ''));
    return Color(int.parse(buffer.toString(), radix: 16));
  }
}

加解密

多語系

多環境開發

EasyLoading

EasyLoading.init(builder: (context, widget) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
          child: widget!,
        )

不同手機的螢幕尺寸處理

動畫

Push

Deep Link

與原生互動

Method Channel

Flutter

Future<String> getDeviceIDFV() async {
  const platform = const MethodChannel('com.yuaki/utils');

  try {
    return await platform.invokeMethod('getDeviceIDFV');
  } on PlatformException catch (_) {
    return "";
  }
}

iOS

 let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let customChannel = FlutterMethodChannel(name: "com.yuaki/utils",
                                                 binaryMessenger: controller.binaryMessenger)
        customChannel.setMethodCallHandler({(call: FlutterMethodCall, result: FlutterResult) -> Void in
            
            switch call.method {
            case "getDeviceIDFV":
                result(getDeviceIDFV())
                break;
            case "setBadgeNum":
                guard let args = call.arguments as? [String: Int] else {
                    result(FlutterError.init(code: "1", message: "Parameters Error", details: nil))
                    return
                }
                
                guard let number: Int = args["number"] else {
                    result(FlutterError.init(code: "2", message: "Parameters Error", details: nil))
                    return
                }
                
                result(self.setBadgeNum(number))
                break;
                
            case "getDeviceToken":
                result("\(UserDefaults.standard.object(forKey:"DeviceToken") ?? "")")
                break;
            case "getFirebaseToken":
                result(UserDefaults.standard.object(forKey:"FireBaseToken") ?? "")
                break;
                
            default:
                result(FlutterMethodNotImplemented)
            }
        })
        
        
func getDeviceIDFV()->String {
    var idfv : String = UserDefaults.standard.object(forKey: "APP_DEVICE_IDFV") as? String ?? ""
    
    if(idfv == ""){
        idfv = UIDevice.current.identifierForVendor?.uuidString ?? ""
        if(idfv != ""){
            UserDefaults.standard.setValue(idfv, forKey: "APP_DEVICE_IDFV")
            UserDefaults.standard.synchronize();
        }
    }
    return idfv;
}

Android

 private val CHANNEL = "com.yuaki/utils"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        this.flutterEngine?.let {

            val methodChannel = MethodChannel(it.getDartExecutor(), CHANNEL)

            methodChannel.setMethodCallHandler(object : MethodCallHandler {
                override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
                    if ("getDeviceIDFV" == methodCall.method) {
                        result.success(getDeviceIDFV(context))
                    } else {
                        result.notImplemented()
                    }
                }

            })
        };
    }
fun getDeviceIDFV(c:Context): String? {
    return Secure.getString(c.getContentResolver(),
            Secure.ANDROID_ID)
}

Flutter SDK/Library of Native APP

Theme / Light Mode / Dark Mode

Last updated