Show dialog on click
This commit is contained in:
parent
4af81e646d
commit
9b90e62d76
9 changed files with 102 additions and 53 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
package com.gianlucaparadise.flutter_cast_framework
|
package com.gianlucaparadise.flutter_cast_framework
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.mediarouter.app.MediaRouteChooserDialog
|
||||||
|
import androidx.mediarouter.app.MediaRouteControllerDialog
|
||||||
import com.google.android.gms.cast.framework.CastContext
|
import com.google.android.gms.cast.framework.CastContext
|
||||||
import io.flutter.plugin.common.MethodCall
|
import io.flutter.plugin.common.MethodCall
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
|
@ -8,8 +10,14 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||||
import io.flutter.plugin.common.MethodChannel.Result
|
import io.flutter.plugin.common.MethodChannel.Result
|
||||||
import io.flutter.plugin.common.PluginRegistry.Registrar
|
import io.flutter.plugin.common.PluginRegistry.Registrar
|
||||||
|
|
||||||
class FlutterCastFrameworkPlugin(registrar: Registrar, private val channel: MethodChannel): MethodCallHandler {
|
class FlutterCastFrameworkPlugin(private val registrar: Registrar, private val channel: MethodChannel) : MethodCallHandler {
|
||||||
companion object {
|
companion object {
|
||||||
|
const val TAG = "AndroidCastPlugin"
|
||||||
|
|
||||||
|
// @StyleRes
|
||||||
|
// var customStyleResId: Int? = null
|
||||||
|
// private val themeResId get() = customStyleResId ?: R.style.Theme_AppCompat_DayNight_Dialog_Alert
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun registerWith(registrar: Registrar) {
|
fun registerWith(registrar: Registrar) {
|
||||||
val channel = MethodChannel(registrar.messenger(), "flutter_cast_framework")
|
val channel = MethodChannel(registrar.messenger(), "flutter_cast_framework")
|
||||||
|
|
@ -19,16 +27,42 @@ class FlutterCastFrameworkPlugin(registrar: Registrar, private val channel: Meth
|
||||||
|
|
||||||
init {
|
init {
|
||||||
CastContext.getSharedInstance(registrar.activeContext()).addCastStateListener { i ->
|
CastContext.getSharedInstance(registrar.activeContext()).addCastStateListener { i ->
|
||||||
Log.d("Android", "Method call on flutter: $i")
|
Log.d(TAG, "Cast state changed: $i")
|
||||||
channel.invokeMethod("onCastStateChanged", i)
|
channel.invokeMethod("onCastStateChanged", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMethodCall(call: MethodCall, result: Result) {
|
override fun onMethodCall(call: MethodCall, result: Result) {
|
||||||
if (call.method == "getPlatformVersion") {
|
when (call.method) {
|
||||||
result.success("Android ${android.os.Build.VERSION.RELEASE}")
|
"showCastDialog" -> showCastDialog()
|
||||||
|
else -> result.notImplemented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showCastDialog() {
|
||||||
|
val castContext = CastContext.getSharedInstance(registrar.activeContext())
|
||||||
|
val castSession = castContext.sessionManager.currentCastSession
|
||||||
|
|
||||||
|
val activity = this.registrar.activity()
|
||||||
|
val themeResId = activity.packageManager.getActivityInfo(activity.componentName, 0).themeResource
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (castSession != null) {
|
||||||
|
// This dialog allows the user to control or disconnect from the currently selected route.
|
||||||
|
MediaRouteControllerDialog(registrar.activeContext(), themeResId)
|
||||||
|
.show()
|
||||||
} else {
|
} else {
|
||||||
result.notImplemented()
|
// This dialog allows the user to choose a route that matches a given selector.
|
||||||
|
MediaRouteChooserDialog(registrar.activeContext(), themeResId).apply {
|
||||||
|
routeSelector = castContext.mergedSelector
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex: IllegalArgumentException) {
|
||||||
|
Log.d(TAG, "Exception while opening Dialog")
|
||||||
|
throw IllegalArgumentException("Error while opening MediaRouteDialog." +
|
||||||
|
" Did you use AppCompat theme on your activity?" +
|
||||||
|
" Check https://developers.google.com/cast/docs/android_sender/integrate#androidtheme", ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@ flutter {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
|
|
||||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
<style name="LaunchTheme" parent="@style/Theme.AppCompat">
|
||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
Flutter draws its first frame -->
|
Flutter draws its first frame -->
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_cast_framework/cast/CastContext.dart';
|
import 'package:flutter_cast_framework/cast/CastContext.dart';
|
||||||
import 'package:flutter_cast_framework/cast/widget/CastButton.dart';
|
import 'package:flutter_cast_framework/cast/widgets/CastButton.dart';
|
||||||
import 'package:flutter_cast_framework/flutter_cast_framework.dart';
|
import 'package:flutter_cast_framework/flutter_cast_framework.dart';
|
||||||
|
|
||||||
void main() => runApp(MyApp());
|
void main() => runApp(MyApp());
|
||||||
|
|
@ -20,6 +20,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCastStateChanged() {
|
void _onCastStateChanged() {
|
||||||
|
debugPrint("Cast state changed from example");
|
||||||
setState(() {
|
setState(() {
|
||||||
_castState = FlutterCastFramework.castContext.state.value;
|
_castState = FlutterCastFramework.castContext.state.value;
|
||||||
});
|
});
|
||||||
|
|
@ -34,12 +35,8 @@ class _MyAppState extends State<MyApp> {
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [Text('Cast State: $_castState'), CastButton()],
|
||||||
Text('Cast State: $_castState'),
|
)),
|
||||||
CastButton()
|
|
||||||
],
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_cast_framework/flutter_cast_framework.dart';
|
||||||
|
|
||||||
class CastContext {
|
class CastContext {
|
||||||
static final _instance = new CastContext._internal();
|
|
||||||
|
|
||||||
CastContext._internal();
|
|
||||||
|
|
||||||
static CastContext get instance => _instance;
|
|
||||||
|
|
||||||
final ValueNotifier<CastState> state = ValueNotifier(CastState.unavailable);
|
final ValueNotifier<CastState> state = ValueNotifier(CastState.unavailable);
|
||||||
|
final MethodChannel _channel;
|
||||||
|
|
||||||
|
CastContext(this._channel);
|
||||||
|
|
||||||
|
void showCastChooserDialog() {
|
||||||
|
_channel.invokeMethod(MethodNames.showCastDialog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CastState {
|
enum CastState {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_cast_framework/cast/widget/CastIcon.dart';
|
|
||||||
|
|
||||||
class CastButton extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
child: CastIcon(),
|
|
||||||
onTap: () => debugPrint("Clicked"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12
lib/cast/widgets/CastButton.dart
Normal file
12
lib/cast/widgets/CastButton.dart
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_cast_framework/cast/widgets/CastIcon.dart';
|
||||||
|
import 'package:flutter_cast_framework/flutter_cast_framework.dart';
|
||||||
|
|
||||||
|
class CastButton extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: CastIcon(),
|
||||||
|
onTap: () => FlutterCastFramework.castContext.showCastChooserDialog());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,11 +2,17 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_cast_framework/cast/CastContext.dart';
|
import 'package:flutter_cast_framework/cast/CastContext.dart';
|
||||||
|
|
||||||
class FlutterCastFramework {
|
class MethodNames {
|
||||||
|
static const onCastStateChanged = "onCastStateChanged";
|
||||||
|
static const showCastDialog = "showCastDialog";
|
||||||
|
}
|
||||||
|
|
||||||
static const MethodChannel _channel = const MethodChannel('flutter_cast_framework');
|
class FlutterCastFramework {
|
||||||
|
static const MethodChannel _channel =
|
||||||
|
const MethodChannel('flutter_cast_framework');
|
||||||
|
|
||||||
static bool _isInitiated = false;
|
static bool _isInitiated = false;
|
||||||
|
|
||||||
static _init() {
|
static _init() {
|
||||||
_channel.setMethodCallHandler((MethodCall call) async {
|
_channel.setMethodCallHandler((MethodCall call) async {
|
||||||
String method = call.method;
|
String method = call.method;
|
||||||
|
|
@ -14,7 +20,7 @@ class FlutterCastFramework {
|
||||||
debugPrint("Method call on flutter: $method $arguments");
|
debugPrint("Method call on flutter: $method $arguments");
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case "onCastStateChanged":
|
case MethodNames.onCastStateChanged:
|
||||||
int castState = arguments;
|
int castState = arguments;
|
||||||
castContext.state.value = CastState.values[castState];
|
castContext.state.value = CastState.values[castState];
|
||||||
break;
|
break;
|
||||||
|
|
@ -26,9 +32,16 @@ class FlutterCastFramework {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CastContext _castContext;
|
||||||
|
|
||||||
// This must be the plugin entry point
|
// This must be the plugin entry point
|
||||||
static CastContext get castContext {
|
static CastContext get castContext {
|
||||||
if (!_isInitiated) _init();
|
if (!_isInitiated || _castContext == null) {
|
||||||
return CastContext.instance;
|
_castContext = CastContext(_channel);
|
||||||
|
// TODO: find a better way to init the plugin
|
||||||
|
_isInitiated = true;
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
return _castContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue