简体   繁体   English

将 android 原生小部件添加到 flutter(宽度道具方法和侦听器)

[英]Adding android native widgets to flutter (width props methods and listeners)

I want to use this native widget inside my flutter project (only android side).我想在我的 flutter 项目(仅 android 端)中使用这个原生小部件。

https://github.com/mmin18/RealtimeBlurView https://github.com/mmin18/RealtimeBlurView

(I know there are alternatives for real time blurring, but this is just an example between some other widgets and I'm looking for a general solution and an example code). (我知道有实时模糊的替代方案,但这只是其他一些小部件之间的一个示例,我正在寻找一个通用解决方案和示例代码)。 So:所以:

  • How can I integrate and use it on flutter layouts like Container, or even make a new one?如何在 Container 等 flutter 布局上集成和使用它,甚至制作一个新布局?

  • this widget has some props (for example realtimeBlurRadius and realtimeOverlayColor), how can I access and assign these values from dart file?这个小部件有一些道具(例如 realtimeBlurRadius 和 realtimeOverlayColor),我如何从 dart 文件中访问和分配这些值?

  • What if the widget has methods or listeners?如果小部件有方法或侦听器怎么办? Is there a way to call or define them from flutter by need?有没有办法根据需要从 flutter 调用或定义它们?

Thanks for your help.谢谢你的帮助。

you should use MethodChannel if you want to use android specific library or iOS specific library in Flutter如果要在 Flutter 中使用android特定库或 iOS 特定库,则应使用 MethodChannel

so for your problem my solution is to add RealtimeBlurView dependency in your android framework then access that with MethodChannel所以对于您的问题,我的解决方案是在您的 android 框架中添加RealtimeBlurView依赖项,然后使用MethodChannel访问它

so lets start:所以让我们开始吧:

  1. create widget named BlurViewWidget like below:创建名为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.open android folder and add RealtimeBlurView dependency like below: 2.打开android文件夹并添加RealtimeBlurView依赖如下:

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.github.mmin18:realtimeblurview:1.2.1'
}

3.create layout forlder in res folder and create blur_view_widget.xml inside it: 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.go to src/your/package/name and create BlurViewWidget.kt ,this class has responsibility to inflate you xml view and response to MethodChannel : 4.go 到src/your/package/name并创建BlurViewWidget.kt ,这个 class 有责任给你充气xml视图:

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.then create BlurViewWidgetFactory.kt : 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.then create BlurViewWidgetPlugin.kt 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.and change the MainActivity.kt like below: 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"))
    }
}

and finally test your widget from main.dart like below:最后从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);
  }
}

That's it.而已。 you can get complete source code of this answer Here你可以在这里得到这个答案的完整源代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM