開始
開発中のフラッターは、常に以下の2つのやむを得ない質問があるでしょう。
- 移行プロジェクトをフラッターへのネイティブ、我々はネイティブプロジェクトでフラッターにアクセスする必要があります
- フラッタープロジェクトは、より成熟したアプリケーションの一部に使用されるように、我々は、このようなような、オーディオやビデオなどの成熟したネイティブライブラリ、さまざまなを使用するつもりは避けることができません
この記事では紹介された、上記の2例になります
アンドロイドでフラッターアクセスインタフェース
あなたは、Androidプロジェクトにフォームモジュールでフラッターにアクセスする必要があります
フラッターモジュールを作成します。
現在のプロジェクトにAndroidの、ルートディレクトリに次のコマンドを実行します。
flutter create -t module my_flutter
上記は、フラッターモジュールと呼ばれるmy_flutterの作成を表し
実行した後
cd my_flutter
cd .android/
./gradlew flutter:assembleDebug
また、あなたのプロジェクトディレクトリアンドロイドアプリ/ build.gradleであることを確認して、次のコードを追加しています。
android {
compileSdkVersion 28
defaultConfig {
...
}
buildTypes {
...
}
//flutter相关声明
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
次に、プロジェクトのアンドロイドのルートディレクトリの下に次のコードを追加しますsettings.gradle
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
rootDir.path + '/my_flutter/.android/include_flutter.groovy'
))
アンドロイドプロジェクトの下にアプリ/ build.gradleにmy_flutterを導入する。最後に、必要
dependencies {
...
//导入flutter
implementation project(':flutter')
}
ここでは、フラッタのコンテンツへのアクセスを開始する準備ができています
あなたのAndroidプロジェクトがandroidxに移動された場合でも、注意を払う必要がある。この時間は、あなたは下のこの問題が発生する可能性があります
フラッターは、moudleを作成androidx変換をしなかったため、コマンドがmoudle androidxの作成をサポートしていないため、この問題は、明らかです
以下は、この問題を解決するために始めました
androidxによって引き起こされる問題を解決するために、
あなたのオリジナルのAndroidプロジェクトがandroidxに移行された場合、最初に、ルートディレクトリにあるgrale.propertiesは、次のものが必要
# 表示使用 androidx
android.useAndroidX=true
# 表示将第三方库迁移到 androidx
android.enableJetifier=true
my_flutterディレクトリに以下、/my_flutter/.android/Flutter/build.gradleであなたのAndroidプロジェクトにライブラリの依存部分を修正
デフォルトでは、次のようにする場合:
dependencies {
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:support-v13:27.1.1'
implementation 'com.android.support:support-annotations:27.1.1'
}
すべてのバージョンをandroidxするように修正依存します:
dependencies {
testImplementation 'junit:junit:4.12'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.annotation:annotation:1.0.0'
}
同期後にアンドロイドスタジオに今すぐ同期]をクリックした後、
Flutter.javaとFlutterFragment.javaのディレクトリ下に再入力するあなたのAndroidプロジェクト/my_flutter/.android/Flutter/src/main/java/io/flutter/facade/ディレクトリを個別に変更することが
FlutterFragment.javaを変更
次のようにもともと依存
エラー部分はandroidxバージョンを置き換えられます
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
Flutter.javaを変更
次のようにもともと依存
エラー部分はandroidxバージョンを置き換えられます
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
だから今、問題が解決持ち込まandroidx、以下が正式なアクセスフラッタを準備し始めました
編集エントリフラッタで
ディレクトリのlibディレクトリにMy_flutter、デフォルトのページカウンタであるmain.dartファイルシステムは、そこに来て見ることができ、我々は一部を変更します。
void main() => runApp(getRouter(window.defaultRouteName));
Widget getRouter(String name) {
switch (name) {
case 'route1':
return MyApp();
default:
return Center(
child: Text('Unknown route: $name', textDirection: TextDirection.ltr),
);
}
}
「route1の」に置き換え入口は、ネーミングに入ります
次のステップでは、Androidで動作させることです
アンドロイドのアクセスフラッター
プロジェクトにアンドロイド、MainActivityに、私たちは、次の操作を行います。
bt_flutter.setOnClickListener {
val flutterView = Flutter.createView(
this@MainActivity,
lifecycle,
"route1"
)
val layout = ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
layout.leftMargin = 0
layout.bottomMargin = 26
addContentView(flutterView, layout)
}
我々は、カウンタページのフラッタを表示するボタンをクリックしてイベントを持って、上記のコードから見ることができます。次のように実際の効果は次のとおりです。
だから、アンドロイドアクセスフラッターは、ここでは、以上であるアクセスアンドロイドのフラッターであります
アンドロイドでフラッターアクセスインタフェース
私たちは、この例をテストするフラッタープロジェクトを作成することができます
kotinの使用は、その次のコマンドを使用しているため
flutter create -a kotlin counter_native
-a kotlin counter_native作成フラッター
Androidのデータ収集
主にMethodChannelを使用して、データを取得する方法について
MainActivityのアンドロイドのコードを見てください
class MainActivity: FlutterActivity() {
private val channelName = "samples.flutter.io/counter_native";
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
MethodChannel(flutterView, channelNameTwo).setMethodCallHandler { methodCall, result ->
when(methodCall.method){
"getCounterData" -> {
result.success(getCounterData())
}
else -> {
result.notImplemented();
}
}
}
}
private fun getCounterData():Int{
return 100;
}
}
メソッド名が直接getCounterData 100返された場合、コールバックMethodChannel結果では、我々は、スクリーニングしました
その後に次のコードを記述しフラッター:
static const platform =
const MethodChannel('samples.flutter.io/counter_native');
void getCounterData() async {
int data;
try {
final int result = await platform.invokeMethod('getCounterData');
data = result;
} on PlatformException catch (e) {
data = -999;
}
setState(() {
counterData = data;
});
}
結果は以下の通りであります:
ここでは、Android上でデータを取得し、次はアンドロイドのページを取得することです
アンドロイドレイアウトを取得
データと比較すると、レイアウトがアンドロイドより複雑になります
アンドロイドビューを作成します
ここアンドロイド表示したいレイアウトでフラッターを作成したプロジェクト、そして、我々はレイアウトを作成するために、xmlファイルを結合するが、XMLの方法を使用し、ケースファイルはRが表示されます見つからない、この時間は、コンパイラは一時的に、文句を言うでしょう管理するません。
class CounterView(context: Context, messenger: BinaryMessenger, id: Int)
: PlatformView, MethodChannel.MethodCallHandler {
private var methodChannel: MethodChannel =
MethodChannel(messenger, "samples.flutter.io/counter_view_$id")
private var counterData: CounterData = CounterData()
private var view: View = LayoutInflater.from(context).inflate(R.layout.test_layout, null);
private var myText: TextView
init {
methodChannel.setMethodCallHandler(this)
myText = view.findViewById(R.id.tv_counter)
}
override fun getView(): View {
return view
}
override fun dispose() {
}
override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
when (methodCall.method) {
"increaseNumber" -> {
counterData.counterData++
myText.text = "当前Android的Text数值是:${counterData.counterData}"
result.success(counterData.counterData)
}
"decreaseNumber" -> {
counterData.counterData--
myText.text = "当前Android的Text数值是:${counterData.counterData}"
result.success(counterData.counterData)
}
"decreaseSize" -> {
if(myText.textSize > 0){
val size = myText.textSize
myText.setTextSize(TypedValue.COMPLEX_UNIT_PX,size-1)
result.success(myText.textSize)
} else{
result.error("出错", "size无法再小了!", null)
}
}
"increaseSize" -> {
if(myText.textSize < 100){
val size = myText.textSize
myText.setTextSize(TypedValue.COMPLEX_UNIT_PX,size+1)
result.success(myText.textSize)
} else{
result.error("出错", "size无法再大了!", null)
}
}
"setText" -> {
myText.text = (methodCall.arguments as String)
result.success(myText.text)
}
else -> {
result.notImplemented();
}
}
}
}
データを格納するための上記CounterDataクラスは、クラスを作成しました:
class CounterData(var counterData: Int = 0) {
}
次に、我々はレイアウトに取得するために使用CounterViewFactoryクラスを作成します。
class CounterViewFactory(private val messenger: BinaryMessenger)
: PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, id: Int, o: Any?): PlatformView {
return CounterView(context, messenger, id)
}
}
最後に、ビューを登録するために使用されるCounterViewPlugin.ktファイル、初期化エントリの等価物を作成します
class CounterViewPlugin{
fun registerWith(registrar: Registrar) {
registrar.platformViewRegistry().registerViewFactory("samples.flutter.io/counter_view", CounterViewFactory(registrar.messenger()))
}
}
一度作成に登録MainActivityでビュー:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CounterViewPlugin().registerWith(flutterView.pluginRegistry.registrarFor("CounterViewPlugin"))
...
}
次に、それは何かをする必要のあるフラッター
フラッターのビューでアンドロイドを取得
内部フラッターで、私は、Androidのビューを取得したいAndroidViewを介して取得する必要があります
Widget build(BuildContext context) {
if (Platform.isAndroid) {
return AndroidView(
viewType: 'samples.flutter.io/counter_view',
onPlatformViewCreated: _onPlatformViewCreated,
);
}
return Text(
'$defaultTargetPlatform 还不支持这个布局');
}
onPlatformViewCreatedアプローチでは、我々は、この方法は、書面でアンドロイドを求めMethodChannelを作成する必要があり、我々はこれらのロジックを処理するためにコントローラをカプセル化することができます。
final CounterController counterController;
void _onPlatformViewCreated(int id) {
if (widget.counterController == null) {
return;
}
widget.counterController.setId(id);
}
ここCounterControllerです
typedef void CounterViewCreatedCallBack(CounterController controller);
class CounterController {
MethodChannel _channel;
void setId(int id){
_channel = new MethodChannel('samples.flutter.io/counter_view_$id');
print("id");
}
Future increaseNumber() async {
final int result = await _channel.invokeMethod(
'increaseNumber',
);
print("result:${result}");
}
Future decreaseNumber() async {
final int result = await _channel.invokeMethod(
'decreaseNumber',
);
}
Future increaseSize() async {
final result = await _channel.invokeMethod(
'increaseSize',
);
}
Future decreaseSize() async {
final result = await _channel.invokeMethod(
'decreaseSize',
);
}
Future setText(String text) async {
final result = await _channel.invokeMethod(
'setText',text,
);
}
}
結果は以下の通りであります: