android - 将android原生小部件添加到flutter(宽度道具方法和监听器)
问题描述
我想在我的颤振项目中使用这个本机小部件(仅限 android 端)。
https://github.com/mmin18/RealtimeBlurView
(我知道有实时模糊的替代方案,但这只是其他一些小部件之间的一个例子,我正在寻找一个通用的解决方案和一个示例代码)。所以:
如何在 Container 等 Flutter 布局上集成和使用它,甚至创建一个新布局?
这个小部件有一些道具(例如 realtimeBlurRadius 和 realtimeOverlayColor),我如何从 dart 文件中访问和分配这些值?
如果小部件有方法或侦听器怎么办?有没有办法根据需要从颤动中调用或定义它们?
谢谢你的帮助。
解决方案
如果你想在 Flutter 中使用 android 特定库或 iOS 特定库,你应该使用MethodChannel
所以对于您的问题,我的解决方案是在您的 android 框架中添加RealtimeBlurView依赖项,然后使用MethodChannel访问它
所以让我们开始吧:
- 创建名为BlurViewWidget的小部件,如下所示:
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
typedef BlurViewWidgetCreatedCallback = void Function(
BlurViewWidgetController controller);
class BlurViewWidget extends StatefulWidget {
const BlurViewWidget({
Key key,
this.onBlurViewWidgetCreated,
}) : super(key: key);
final BlurViewWidgetCreatedCallback onBlurViewWidgetCreated;
@override
State<StatefulWidget> createState() => _BlurViewWidgetState();
}
class _BlurViewWidgetState extends State<BlurViewWidget> {
@override
Widget build(BuildContext context) {
if (defaultTargetPlatform == TargetPlatform.android) {
return AndroidView(
viewType: 'plugins/blur_view_widget',
onPlatformViewCreated: _onPlatformViewCreated,
);
}
return const Text('iOS platform version is not implemented yet.');
}
void _onPlatformViewCreated(int id) {
if (widget.onBlurViewWidgetCreated == null) {
return;
}
widget.onBlurViewWidgetCreated(BlurViewWidgetController._(id));
}
}
class BlurViewWidgetController {
BlurViewWidgetController._(int id)
: _channel = MethodChannel('plugins/blur_view_widget_$id');
final MethodChannel _channel;
Future<void> draggable(bool value) async {
return _channel.invokeMethod('draggable',value);
}
}
2.打开android文件夹并添加RealtimeBlurView依赖项,如下所示:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.github.mmin18:realtimeblurview:1.2.1'
}
3.在 res 文件夹中创建 layout forlder 并在其中创建blur_view_widget.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:id="@+id/blur_frame"
android:gravity="center"
android:background="@android:color/darker_gray"
android:layout_width="360dp"
android:layout_height="360dp"
android:layout_gravity="center">
<com.github.mmin18.widget.RealtimeBlurView
android:id="@+id/blur_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</FrameLayout>
4.转到src/your/package/name并创建BlurViewWidget.kt,该类负责为您的 xml 视图和MethodChannel响应:
package com.taleb.flutter_platformview
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.platform.PlatformView
class BlurViewWidget internal constructor(context: Context, id: Int, messenger: BinaryMessenger) : PlatformView, MethodCallHandler {
private var view: View = LayoutInflater.from(context).inflate(R.layout.blur_view_widget, null)
private val methodChannel: MethodChannel = MethodChannel(messenger, "plugins/blur_view_widget_$id")
override fun getView(): View {
return view
}
init {
methodChannel.setMethodCallHandler(this)
}
override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
when (methodCall.method) {
"draggable" -> draggable(methodCall, result)
else -> result.notImplemented()
}
}
@SuppressLint("ClickableViewAccessibility")
private fun draggable(methodCall: MethodCall, result: Result) {
val isDraggable: Boolean = methodCall.arguments as Boolean
if (isDraggable)
view.findViewById<View>(R.id.blur_frame).setOnTouchListener(touchListener)
else
view.findViewById<View>(R.id.blur_frame).setOnTouchListener(null)
result.success(null)
}
override fun dispose() {
}
private val touchListener: View.OnTouchListener = object : View.OnTouchListener {
var dx = 0f
var dy = 0f
override fun onTouch(v: View?, event: MotionEvent): Boolean {
val view = view.findViewById<View>(R.id.blur_frame)
if (event.action == MotionEvent.ACTION_DOWN) {
dx = view.x - event.rawX
dy = view.y - event.rawY
} else if (event.action == MotionEvent.ACTION_MOVE) {
view.x = event.rawX + dx
view.y = event.rawY + dy
}
return true
}
}
}
5.然后创建BlurViewWidgetFactory.kt:
package com.taleb.flutter_platformview
import android.content.Context
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory
class BlurViewWidgetFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, id: Int, o: Any?): PlatformView {
return BlurViewWidget(context = context, id = id, messenger = messenger)
}
}
6.然后创建BlurViewWidgetPlugin.kt
package com.taleb.flutter_platformview
import io.flutter.plugin.common.PluginRegistry.Registrar
object BlurViewWidgetPlugin {
fun registerWith(registrar: Registrar) {
registrar
.platformViewRegistry()
.registerViewFactory(
"plugins/blur_view_widget", BlurViewWidgetFactory(registrar.messenger()))
}
}
7.并更改MainActivity.kt如下所示:
package com.taleb.flutter_platformview
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
BlurViewWidgetPlugin.registerWith(this.registrarFor("com.taleb.flutter_platformview.BlurViewWidgetPlugin"))
}
}
最后从main.dart测试你的小部件,如下所示:
import 'package:flutter/material.dart';
import 'package:flutter_platformview/widget/blur_view_widget.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: BlurViewWidget(
onBlurViewWidgetCreated: _onBlurViewWidgetCreated,
),
),
);
}
void _onBlurViewWidgetCreated(BlurViewWidgetController controller){
controller.draggable(true);
}
}
就是这样。你可以在这里得到这个答案的完整源代码
推荐阅读
- python - 有没有办法从数据框中检查尾列?
- html - 应用的 css 适用于 chrome 和 mozilla,应该只适用于 mozilla
- javascript - 如何在Jquery中找到标题包含的e元素内的跨度
- c# - 在这种情况下,.NET Core Web 应用程序中实际运行的是什么代码?
- assembly - 瑞萨 M32R 处理器程序前调用和返回
- python - 用 NaN 更新列,过滤行的平均值
- python-3.x - LTRect 和 LTLine 提取 - pdfminer
- android - 尝试在 ubuntu 18.04 上安装 ionic 时出错
- python-3.x - 从 discord.py wait_for_messages 捕获和响应超时的方法是什么?
- java - Java 8 将字符串列表转换为映射