Display country flag character in Flutter - flutter

This answer has some code to convert a locale to a country emoji in Java. I tried implementing it in Dart but no success.
I tried converting the code above to Dart
void _emoji() {
int flagOffset = 0x1F1E6;
int asciiOffset = 0x41;
String country = "US";
int firstChar = country.codeUnitAt(0) - asciiOffset + flagOffset;
int secondChar = country.codeUnitAt(1) - asciiOffset + flagOffset;
String emoji =
String.fromCharCode(firstChar) + String.fromCharCode(secondChar);
print(emoji);
}
"US" locale should output "🇺🇸"

The code you posted works correctly, i.e. print(emoji) successfully prints 🇺🇸.
I assume that the real problem you have is that the Flutter Text widget displays it like this:
It is the US flag, however, I have to agree that it does not look like it when you see it on device as the font size is very small and the flag has a rather high resolution.
You will need to use a custom font and apply it to your Text widget using the following:
Text(emoji,
style: TextStyle(
fontFamily: '...',
),
)
Otherwise, both the conversion and displaying the flags works fine. I believe that they just look different than you expected.

Related

How to specify Japanese encoding for a UILabel?

When I attempt to display a Japanese string in a UILabel on iOS, it gets displayed using Chinese encoding instead of Japanese.
The two encodings are nearly identical, except in a few specific cases. For example, here is how the character ç›´ (Unicode U+76F4) is rendered in Chinese (top) vs. Japanese (bottom):
(see here for more examples)
The only time Japanese strings render correctly is when the user's system locale is ja-jp (Japan), but I'd like it to render as Japanese for all users.
Is there any way to force the Japanese encoding? Android has TextView.TextLocale, but I don't see anything similar on iOS UILabel
(Same question for Android. I tagged this Swift/Objective-C because, although I'm looking for a Xamarin.iOS solution, the API is almost the same)
You just need to specify language identifier for attributed string, like
let label = UILabel()
let text = NSAttributedString(string: "ç›´", attributes: [
.languageIdentifier: "ja", // << this !!
.font: UIFont.systemFont(ofSize: 64)
])
label.attributedText = text
Tested with Xcode 13.2 / iOS 15.2
I found an extremely hacky solution that seems to work. However, it seems absurd that there's no way to simply set the locale of a label, so if anyone finds something I missed, please post an answer.
The trick relies on the fact that the Hiragino font displays kanji using Japanese encoding rather than Chinese encoding by default. However, the font looks like shit for English text, so I have to search every string in every label for Japanese substrings and manually change the font using NSMutableAttributedString. The font is also completely broken so I had to find another workaround to fix that.
[assembly: ExportRenderer(typeof(Label), typeof(RingotanLabelRenderer))]
namespace MyApp
{
public class MyLabelRenderer : LabelRenderer
{
private readonly UIFont HIRAGINO_FONT = UIFont.FromName("HiraginoSans-W6", 1); // Size gets updated later
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
// BUGFIX: Chinese encoding is shown by default. Switch to Hiragino font, which correctly shows Japanese characters
// Taken from https://stackoverflow.com/a/71045204/238419
if (Control?.Text != null && e.PropertyName == "Text")
{
var kanjiRanges = GetJapaneseRanges(Control.Text).ToList();
if (kanjiRanges.Count > 0)
{
var font = HIRAGINO_FONT.WithSize((nfloat)Element.FontSize);
var attributedString = Control.AttributedText == null
? new NSMutableAttributedString(Control.Text)
: new NSMutableAttributedString(Control.AttributedText);
// Search through string for all instances of Japanese characters and update the font
foreach (var (start, end) in kanjiRanges)
{
int length = end - start + 1;
var range = new NSRange(start, length);
attributedString.AddAttribute(UIStringAttributeKey.Font, font, range);
// Bugfix: Hiragino font is broken (https://stackoverflow.com/a/44397572/238419) so needs to be adjusted upwards
// jesus christ Apple
attributedString.AddAttribute(UIStringAttributeKey.BaselineOffset, (NSNumber)(Element.FontSize/10), range);
}
Control.AttributedText = attributedString;
}
}
}
// Returns all (start,end) ranges in the string which contain only Japanese strings
private IEnumerable<(int,int)> GetJapaneseRanges(string str)
{
for (int i = 0; i < str.Length; i++)
{
if (IsJapanese(str[i]))
{
int start = i;
while (i < str.Length - 1 && KanjiHelper.IsJapanese(str[i]))
{
i++;
}
int end = i;
yield return (start, end);
}
}
}
private static bool IsJapanese(char character)
{
// An approximation. See https://github.com/caguiclajmg/WanaKanaSharp/blob/792f45a27d6e543d1b484d6825a9f22a803027fd/WanaKanaSharp/CharacterConstants.cs#L110-L118
// for a more accurate version
return character >= '\u3000' && character <= '\u9FFF'
|| character >= '\uFF00';
}
}
}

How can I detect a Paste event in a TextEditingController?

I have a TextEditingController which is for phone numbers. If text is pasted in it, I need to process and modify it, trimming whitespaces etc. But that should not happen if the user is typing in whitespaces. How can I differentiate between these two types of events, and call my function only when user pastes text into the field?
Currently my code looks like this and uses onChanged. I'm looking for something like onPaste:
String getCorrectedPhone(String phone) {
phone = phone.replaceAll(RegExp(r"\s+"), "");
return phone;
}
FormBuilderTextField(
controller: _phoneController,
name: "phone",
onChanged: (String txt) {
print('Phone field changed! Is now $txt');
_phoneController.text = getCorrectedPhone(txt);
},
),
You can do something like declare a length with the phone number field and add a listener to the text editing controller or in oNchanged which checks if its length - the old length is >1. Then its pasted
int length = 0;
...
_phoneController.addListener((){
if (abs(textEditingController.text.length - length)>1){
// Do your thingy
}
length = _phoneController.length;
});
So there is another way, that is to ignore any touches on the text field using the IgnorePointer widget and then use Gesture Detector to implement custom long tap and short taps. For long taps, you'll have to create your own small pop up menu for copy cut paste and stuff. Here is some sample code for the UI. As for the functioning, I would recommend using the https://api.flutter.dev/flutter/services/Clipboard-class.html class of flutter. If you need any help in doing this let me know but it should be mostly straightforward

Non-breaking space in Flutter string interpolation

From time to time I need a non-breaking space in my Flutter Text widgets, e.g. a "Show more" link or a number with unit like "50 km/h".
The following code works fine but it looks overly complicated:
const int $nbsp = 0x00A0; // from https://pub.dev/packages/charcode
print('Hello${String.fromCharCode($nbsp)}World'); // --> prints "Hello World", does not break
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :/
I'm curious if there is a shorter way to use an integer constant from the charcode package in my interpolated string?
The easy way to do it is using escape combination [\u{00A0}]:
Text('Hello\u{00A0}world');
The best solution I have come up with is creating a String extension method.
// string_extension.dart
const int $nbsp = 0x00A0;
extension StringExtension on String {
String get nonBreaking => replaceAll(' ', String.fromCharCode($nbsp));
}
Usage example:
// import 'string_extension.dart';
Text('Hello World'.nonBreaking)

Flutter/Dart programmatically unicode string

I have a list of customized icons to my app, it comes like below setted as IconData, note codePoint (0xe931).
IconData angry_face = IconData(0xe931, fontFamily: _fontFamily);
There's nothing wrong with that, but I've some cases where I need this icon as Unicode string to be used as a text. It should be done just like:
// It works too
Text('\ue931', style: TextStyle(fontFamily: _fontFamily));
The problem is:
I don't wanna use this code "by hand" because this icons are changed constantly by designers team and sometimes it changes its code messing up my app icons. What I need to do is get the icon object and parse it to the Unicode string, so I can use it with a Text widget.
I thought that would work to get programmatically that code and just use it, but it don't:
var iconcode = iconData.codePoint.toRadixString(16);
var result;
// Error: An escape sequence starting with '\u'
// must be followed by 4 hexadecimal digits or
// from 1 to 6 digits between '{' and '}'
result = '\u$iconcode';
// Just a simple string
result = '\\u$iconcode';
In few words: How can I parse programmatically int codePoint to a valid Unicode string?
Here's the right answer. I tried everything but this... Thank you #julemand101
final result = String.fromCharCode(iconData.codePoint);

Creating advanced user interfaces blackberry

I am looking out to create a text box similar to the image shown below in my blackberry form. As of now i am able to add a textfield which has a label like say
Name:(Cursor blinks)
Also when i try adding an image it doesnt show up beside the label but below it.I have tried aligning and adjusting image size etc but all in vain.How can layout managers help me do this any idea?
Can some one provide me an exact way as to how this can be achieved.Thanks in advance.
//Lets say adding textfield with validation for name
TextField1 = new TextField("\n Customer Name: ",null)
{
protected boolean keyChar(char ch, int status, int time)
{
if (CharacterUtilities.isLetter(ch) || (ch == Characters.BACKSPACE || (ch == Characters.SPACE)))
{
return super.keyChar(ch, status, time);
}
return true;
}
};
add(TextField1);
//Or either by using this,the text is placed within the image
Border myBorder = BorderFactory.createBitmapBorder(
new XYEdges(20, 16, 27, 23),
Bitmap.getBitmapResource("border.png"));
TextField myField = new TextField(" Write something ",TextField.USE_ALL_WIDTH | TextField.FIELD_HCENTER)
{
protected void paint(Graphics g) {
g.setColor(Color.BLUE);
super.paint(g);
}
};
myField.setBorder(myBorder);
add(myField);
//After trying out code given at Blackberry App Appearance VS Facebook App i am getting the following layout
I would still want to achieve a box that stands beside the label.Like the one shown in green image.Please guide.
Have a look to this answer. I think it may be helpful to you. Just play with the code until you get your desired look and feel.