I've seen various answers to this question for older versions but not sure how to translate to MAUI. The question being, is there a way that you can minimize the soft keyboard on a device from the Text Completed event of an Entry control?
I finally figured out how to do this. This solution is for Android only right now. It doesn't use a custom handler since I could not get the window token from PlatformView. Instead the code looks like this:
#if ANDROID
var imm = (Android.Views.InputMethods.InputMethodManager)MauiApplication.Current.GetSystemService(Android.Content.Context.InputMethodService);
if (imm != null)
{
//this stuff came from here: https://www.syncfusion.com/kb/12559/how-to-hide-the-keyboard-when-scrolling-in-xamarin-forms-listview-sflistview
var activity = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity;
Android.OS.IBinder wToken = activity.CurrentFocus?.WindowToken;
imm.HideSoftInputFromWindow(wToken, 0);
}
#endif
So credit to the syncfusion folks that published their version, and this code above is modified from that to work in MAUI.
The code belongs in a custom handler. Based on Customize a control with a mapper.
In that Maui handler, handler.PlatformView is the Android control. Xamarin.Android properties/methods would be on that.
Something like:
using Microsoft.Maui.Platform;
namespace CustomizeHandlersDemo;
public partial class CustomizeEntryPage : ContentPage
{
public CustomizeEntryPage()
{
InitializeComponent();
ModifyEntry();
}
void ModifyEntry()
{
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(
"MyCustomization", (handler, view) =>
{
#if ANDROID
handler.PlatformView....
#elif IOS
#elif WINDOWS
#endif
});
}
}
NOTE: That example modifies ALL Entries.
If you want to modify only SOME Entries, you instead define a subclass (e.g. public class MyEntry : Entry {}), and do this:
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(
"MyEntryCustomizationOrWhatever", (handler, view) =>
{
if (view is MyEntry)
{
#if ANDROID
handler.PlatformView....
#elif IOS
#elif WINDOWS
#endif
}
});
For your specific situation, the line you were having trouble adapting to Maui contains btnSignIn.WindowToken.
Replace that with handler.PlatformView.WindowToken.
I prefer my curly braces looking like this:
function eg()
{
}
But when I try to format my code, vscode auto corrects to this:
function eg() {
}
Is there any plugins that I can download or setting that I can tweak to change this?
Try :
"javascript.format.placeOpenBraceOnNewLineForFunctions": true;
"javascript.format.placeOpenBraceOnNewLineForControlBlocks": true;
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true;
"typescript.format.placeOpenBraceOnNewLineForFunctions": true;
I'm looking for a way to execute code in Flutter when the app is in Debug mode. Is that possible in Flutter? I can't seem to find it anywhere in the documentation.
Something like this
If(app.inDebugMode) {
print("Print only in debug mode");
}
How can I check if the Flutter application is running in debug or release mode?
In later versions, you can use kDebugMode:
if (kDebugMode)
doSomething();
While asserts can technically be used to manually create an "is debug mode" variable, you should avoid that.
Instead, use the constant kReleaseMode from package:flutter/foundation.dart
The difference is all about tree shaking.
Tree shaking (aka the compiler removing unused code) depends on variables being constants.
The issue is, with asserts our isInReleaseMode boolean is not a constant. So when shipping our app, both the dev and release code are included.
On the other hand, kReleaseMode is a constant. Therefore the compiler is correctly able to remove unused code, and we can safely do:
if (kReleaseMode) {
} else {
// Will be tree-shaked on release builds.
}
Here is a simple solution to this:
import 'package:flutter/foundation.dart';
Then you can use kReleaseMode like
if(kReleaseMode){ // Is Release Mode??
print('release mode');
} else {
print('debug mode');
}
Please use Remi's answer with kReleaseMode and kDebugMode or Dart compilation won't be able to tree-shake your code.
This little snippet should do what you need:
bool get isInDebugMode {
bool inDebugMode = false;
assert(inDebugMode = true);
return inDebugMode;
}
If not, you can configure your IDE to launch a different main.dart in debug mode where you can set a Boolean.
kDebugMode
You can now use the kDebugMode constant.
if (kDebugMode) {
// Code here will only be included in debug mode.
// As kDebugMode is a constant, the tree shaker
// will remove the code entirely from compiled code.
} else {
}
This is preferable over !kReleaseMode as it also checks for profile mode, i.e., kDebugMode means not in release mode and not in profile mode.
kReleaseMode
If you just want to check for release mode and not for profile mode, you can use kReleaseMode instead:
if (kReleaseMode) {
// Code here will only be run in release mode.
// As kReleaseMode is a constant, the tree shaker
// will remove the code entirely from other builds.
} else {
}
kProfileMode
If you just want to check for profile mode and not for release mode, you can use kProfileMode instead:
if (kProfileMode) {
// Code here will only be run in release mode.
// As kProfileMode is a constant, the tree shaker
// will remove the code entirely from other builds.
} else {
}
While this works, using constants kReleaseMode or kDebugMode is preferable. See Rémi's answer below for a full explanation, which should probably be the accepted question.
The easiest way is to use assert as it only runs in debug mode.
Here's an example from Flutter's Navigator source code:
assert(() {
if (navigator == null && !nullOk) {
throw new FlutterError(
'Navigator operation requested with a context that does not include a Navigator.\n'
'The context used to push or pop routes from the Navigator must be that of a '
'widget that is a descendant of a Navigator widget.'
);
}
return true;
}());
Note in particular the () at the end of the call - assert can only operate on a Boolean, so just passing in a function doesn't work.
Not to be picky, but the foundation package includes a kDebugMode constant.
So:
import 'package:flutter/foundation.dart' as Foundation;
if(Foundation.kDebugMode) {
print("App in debug mode");
}
I believe the latest way to do this is:
const bool prod = const bool.fromEnvironment('dart.vm.product');
src
Just import this
import 'package:flutter/foundation.dart'
String bulid = kReleaseMode ? "Release" : "";
or
String bulid = kDebugMode ? "Debug" : "";
or
String bulid = kProfileMode ? "Profile" : "";
Or try this
if (kDebugMode) {
print("Debug");
} else if (kReleaseMode) {
print("Release");
} else if (kProfileMode) {
print("Profile");
}
Make a file named constants.dart. Add these variables in it:
const bool kReleaseMode = bool.fromEnvironment('dart.vm.product');
const bool kProfileMode = bool.fromEnvironment('dart.vm.profile');
const bool kDebugMode = !kReleaseMode && !kProfileMode;
printk(String string) {
if (kDebugMode) {
// ignore: avoid_print
print(string);
}
}
Then import this constant file in any other file and use it like this:
import 'package:package_name/constants.dart';
if(kDebugMode){
//Debug code
}else{
//Non-Debug code
}
printk("Debug Log");
I've created this useful class, based on other answers and inspired on Android usage.
If anything changes on "Foundation" package, it would not be necessary to change the entire application, it would be necessary to change only this class.
import 'package:flutter/foundation.dart' as Foundation;
abstract class Build {
static const bool isDebugMode = Foundation.kDebugMode;
static const bool isReleaseMode = Foundation.kReleaseMode;
static const bool isWeb = Foundation.kIsWeb;
static const bool isProfileMode = Foundation.kProfileMode;
}
Extracted from Dart Documentation:
When exactly do assertions work? That depends on the tools and
framework you’re using:
Flutter enables assertions in debug mode.
Development-only tools such as dartdevc typically enable assertions by default.
Some tools, such as dart and dart2js, support assertions through a command-line flag: --enable-asserts.
In production code, assertions are ignored, and the arguments to
assert aren’t evaluated.
I'm using VS2013 and I'd like to change indentation. However, Visual's settings aren't enough for me. I'd like it to auto indent it like this:
int function()
{
int a=1;
while (a)
{
if(a>0)
{
a=0;
return;
}
}
}
Are there any plugins, or anything like this to help me with indentation?
While working on a google webfont import mixin, I noticed that it is not possible to build #import URLs dynamically.
.gFontImport (#name, #weights, #subsets) {
#url: "http://fonts.googleapis.com/css?family=#{name}:#{weights}&subset=#{subsets}";
#import url(#url);
}
Which can be narrowed down to
#url: "http://localhost/test.css";
#import url(#url);
Neither any of these additional tests work:
#import url("#{url}"); // this one renders at least
#import url(~"#{url}");
When the compiler renders the CSS file the #import URL is always left unchanged, e.g. "#{url}"
It seems to work in 1.4 beta.
1.4
Doing something like this (I tried it out at less2css.org) in LESS:
.gFontImport (#name, #weights, #subsets) {
#import url('http://fonts.googleapis.com/css?family=#{name}:#{weights}&subset=#{subsets}');
}
.gFontImport("Roboto+Slab",400,latin);
will have the expected output in CSS:
#import url('http://fonts.googleapis.com/css?family=Roboto+Slab:400&subset=latin');
<=1.3.3
If it does not work for you, you can use a workaround that injects the #import call into a selector name:
.gFontImport (#name, #weights, #subsets) {
#gimport: ~"#import url('http://fonts.googleapis.com/css?family=#{name}:#{weights}&subset=#{subsets}');";
#{gimport} some-selector {/* */};
}
so calling something like this in LESS:
.gFontImport("Roboto+Slab",400,latin);
will output this in CSS:
#import url('http://fonts.googleapis.com/css?family=Roboto+Slab:400&subset=latin');
some-selector {
/**/
}
This works, but it is a tiny bit messy. In a javascript implementation of LESS you can use
`'\n'`
and
`'\t'`
in the string interpolation to make it look a bit tidier.
I've made a gist with working mixins for both versions
https://gist.github.com/line-o/5568723
A working example, that defines font sets :
(with Less v1.7.3)
// Google font import mixin
.gFontImport (#name; #weights: 400; #subsets: latin) {
#nameEsc: ~`"#{name}".replace(/'([^']+)'/,'$1').replace(' ', '+')`;
#import url('http://fonts.googleapis.com/css?family=#{nameEsc}:#{weights}&subset=#{subsets}');
}
// Font sets
// The variable #post-fontset is dynamic (user input)
// ------------------
// foo1
.font(#fontset) when (#fontset = foo1){
.gFontImport('Roboto');
.gFontImport('Lato');
}
.font-text() when (#post-fontset = foo1){
font-family:Lato;
}
.font-headings() when (#post-fontset = foo1){
font-family:Lato;
}
.font-sitetitle() when (#post-fontset = foo1){
font-family:Roboto;
}
// foo2
.font(#fontset) when (#fontset = foo2){
.gFontImport('Oswald');
.gFontImport('Lato');
.gFontImport('Roboto Slab');
}
.font-text() when (#post-fontset = foo2){
font-family:'Roboto Slab';
}
.font-headings() when (#post-fontset = foo2){
font-family:Lato;
}
.font-sitetitle() when (#post-fontset = foo2){
font-family:Oswald;
}
// Using the mixins in the CSS
// ------------------
// This executes the font import mixin
.font(#post-fontset);
// Site title
h1{.font-sitetitle();}
// Heading
h2, h3, h4, h5, h6{.font-headings();}
// Text
body{.font-text();}