mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
* Support all keyboard actions. (#11344)
This commit is contained in:
parent
bc6b2501c2
commit
061e899b55
@ -172,12 +172,36 @@ class InputConnectionAdaptor extends BaseInputConnection {
|
||||
|
||||
@Override
|
||||
public boolean performEditorAction(int actionCode) {
|
||||
// TODO(abarth): Support more actions.
|
||||
switch (actionCode) {
|
||||
// TODO(mattcarroll): is newline an appropriate action for "none"?
|
||||
case EditorInfo.IME_ACTION_NONE:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.newline"));
|
||||
break;
|
||||
case EditorInfo.IME_ACTION_UNSPECIFIED:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.unspecified"));
|
||||
break;
|
||||
case EditorInfo.IME_ACTION_GO:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.go"));
|
||||
break;
|
||||
case EditorInfo.IME_ACTION_SEARCH:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.search"));
|
||||
break;
|
||||
case EditorInfo.IME_ACTION_SEND:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.send"));
|
||||
break;
|
||||
case EditorInfo.IME_ACTION_NEXT:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.next"));
|
||||
break;
|
||||
case EditorInfo.IME_ACTION_PREVIOUS:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
Arrays.asList(mClient, "TextInputAction.previous"));
|
||||
break;
|
||||
default:
|
||||
case EditorInfo.IME_ACTION_DONE:
|
||||
mFlutterChannel.invokeMethod("TextInputClient.performAction",
|
||||
|
||||
@ -115,9 +115,29 @@ public class TextInputPlugin implements MethodCallHandler {
|
||||
}
|
||||
|
||||
private static int inputActionFromTextInputAction(String inputAction) {
|
||||
if (inputAction.equals("TextInputAction.newline"))
|
||||
return EditorInfo.IME_ACTION_NONE;
|
||||
return EditorInfo.IME_ACTION_DONE;
|
||||
switch (inputAction) {
|
||||
case "TextInputAction.newline":
|
||||
return EditorInfo.IME_ACTION_NONE;
|
||||
case "TextInputAction.none":
|
||||
return EditorInfo.IME_ACTION_NONE;
|
||||
case "TextInputAction.unspecified":
|
||||
return EditorInfo.IME_ACTION_UNSPECIFIED;
|
||||
case "TextInputAction.done":
|
||||
return EditorInfo.IME_ACTION_DONE;
|
||||
case "TextInputAction.go":
|
||||
return EditorInfo.IME_ACTION_GO;
|
||||
case "TextInputAction.search":
|
||||
return EditorInfo.IME_ACTION_SEARCH;
|
||||
case "TextInputAction.send":
|
||||
return EditorInfo.IME_ACTION_SEND;
|
||||
case "TextInputAction.next":
|
||||
return EditorInfo.IME_ACTION_NEXT;
|
||||
case "TextInputAction.previous":
|
||||
return EditorInfo.IME_ACTION_PREVIOUS;
|
||||
default:
|
||||
// Present default key if bad input type is given.
|
||||
return EditorInfo.IME_ACTION_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
public InputConnection createInputConnection(FlutterView view, EditorInfo outAttrs)
|
||||
|
||||
@ -8,7 +8,16 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, FlutterTextInputAction) {
|
||||
FlutterTextInputActionUnspecified,
|
||||
FlutterTextInputActionDone,
|
||||
FlutterTextInputActionGo,
|
||||
FlutterTextInputActionSend,
|
||||
FlutterTextInputActionSearch,
|
||||
FlutterTextInputActionNext,
|
||||
FlutterTextInputActionContinue,
|
||||
FlutterTextInputActionJoin,
|
||||
FlutterTextInputActionRoute,
|
||||
FlutterTextInputActionEmergencyCall,
|
||||
FlutterTextInputActionNewline,
|
||||
};
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h"
|
||||
|
||||
#include <UIKit/UIKit.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
static const char _kTextAffinityDownstream[] = "TextAffinity.downstream";
|
||||
static const char _kTextAffinityUpstream[] = "TextAffinity.upstream";
|
||||
@ -30,9 +31,46 @@ static UIKeyboardType ToUIKeyboardType(NSDictionary* type) {
|
||||
}
|
||||
|
||||
static UIReturnKeyType ToUIReturnKeyType(NSString* inputType) {
|
||||
if ([inputType isEqualToString:@"TextInputType.multiline"])
|
||||
// Where did the term "unspecified" come from? iOS has a "default" and Android
|
||||
// has "unspecified." These 2 terms seem to mean the same thing but we need
|
||||
// to pick just one. "unspecified" was chosen because "default" is often a
|
||||
// reserved word in languages with switch statements (dart, java, etc).
|
||||
if ([inputType isEqualToString:@"TextInputAction.unspecified"])
|
||||
return UIReturnKeyDefault;
|
||||
return UIReturnKeyDone;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.done"])
|
||||
return UIReturnKeyDone;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.go"])
|
||||
return UIReturnKeyGo;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.send"])
|
||||
return UIReturnKeySend;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.search"])
|
||||
return UIReturnKeySearch;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.next"])
|
||||
return UIReturnKeyNext;
|
||||
|
||||
if (@available(iOS 9.0, *))
|
||||
if ([inputType isEqualToString:@"TextInputAction.continueAction"])
|
||||
return UIReturnKeyContinue;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.join"])
|
||||
return UIReturnKeyJoin;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.route"])
|
||||
return UIReturnKeyRoute;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.emergencyCall"])
|
||||
return UIReturnKeyEmergencyCall;
|
||||
|
||||
if ([inputType isEqualToString:@"TextInputAction.newline"])
|
||||
return UIReturnKeyDefault;
|
||||
|
||||
// Present default key if bad input type is given.
|
||||
return UIReturnKeyDefault;
|
||||
}
|
||||
|
||||
static UITextAutocapitalizationType ToUITextAutocapitalizationType(NSString* inputType) {
|
||||
@ -277,14 +315,52 @@ static UITextAutocapitalizationType ToUITextAutocapitalizationType(NSString* inp
|
||||
}
|
||||
|
||||
- (BOOL)shouldChangeTextInRange:(UITextRange*)range replacementText:(NSString*)text {
|
||||
if (self.returnKeyType == UIReturnKeyDone && [text isEqualToString:@"\n"]) {
|
||||
[self resignFirstResponder];
|
||||
[self removeFromSuperview];
|
||||
[_textInputDelegate performAction:FlutterTextInputActionDone withClient:_textInputClient];
|
||||
if (self.returnKeyType == UIReturnKeyDefault && [text isEqualToString:@"\n"]) {
|
||||
[_textInputDelegate performAction:FlutterTextInputActionNewline withClient:_textInputClient];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if ([text isEqualToString:@"\n"]) {
|
||||
FlutterTextInputAction action;
|
||||
switch (self.returnKeyType) {
|
||||
case UIReturnKeyDefault:
|
||||
action = FlutterTextInputActionUnspecified;
|
||||
break;
|
||||
case UIReturnKeyDone:
|
||||
action = FlutterTextInputActionDone;
|
||||
break;
|
||||
case UIReturnKeyGo:
|
||||
action = FlutterTextInputActionGo;
|
||||
break;
|
||||
case UIReturnKeySend:
|
||||
action = FlutterTextInputActionSend;
|
||||
break;
|
||||
case UIReturnKeySearch:
|
||||
case UIReturnKeyGoogle:
|
||||
case UIReturnKeyYahoo:
|
||||
action = FlutterTextInputActionSearch;
|
||||
break;
|
||||
case UIReturnKeyNext:
|
||||
action = FlutterTextInputActionNext;
|
||||
break;
|
||||
case UIReturnKeyContinue:
|
||||
action = FlutterTextInputActionContinue;
|
||||
break;
|
||||
case UIReturnKeyJoin:
|
||||
action = FlutterTextInputActionJoin;
|
||||
break;
|
||||
case UIReturnKeyRoute:
|
||||
action = FlutterTextInputActionRoute;
|
||||
break;
|
||||
case UIReturnKeyEmergencyCall:
|
||||
action = FlutterTextInputActionEmergencyCall;
|
||||
break;
|
||||
}
|
||||
|
||||
[_textInputDelegate performAction:action withClient:_textInputClient];
|
||||
return NO;
|
||||
}
|
||||
if (self.returnKeyType == UIReturnKeyDefault && [text isEqualToString:@"\n"])
|
||||
[_textInputDelegate performAction:FlutterTextInputActionNewline withClient:_textInputClient];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -612,7 +688,7 @@ static UITextAutocapitalizationType ToUITextAutocapitalizationType(NSString* inp
|
||||
- (void)setTextInputClient:(int)client withConfiguration:(NSDictionary*)configuration {
|
||||
NSDictionary* inputType = configuration[@"inputType"];
|
||||
_view.keyboardType = ToUIKeyboardType(inputType);
|
||||
_view.returnKeyType = ToUIReturnKeyType(inputType[@"name"]);
|
||||
_view.returnKeyType = ToUIReturnKeyType(configuration[@"inputAction"]);
|
||||
_view.autocapitalizationType = ToUITextAutocapitalizationType(inputType[@"name"]);
|
||||
_view.secureTextEntry = [configuration[@"obscureText"] boolValue];
|
||||
NSString* autocorrect = configuration[@"autocorrect"];
|
||||
|
||||
@ -717,9 +717,40 @@ static inline blink::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* to
|
||||
- (void)performAction:(FlutterTextInputAction)action withClient:(int)client {
|
||||
NSString* actionString;
|
||||
switch (action) {
|
||||
case FlutterTextInputActionUnspecified:
|
||||
// Where did the term "unspecified" come from? iOS has a "default" and Android
|
||||
// has "unspecified." These 2 terms seem to mean the same thing but we need
|
||||
// to pick just one. "unspecified" was chosen because "default" is often a
|
||||
// reserved word in languages with switch statements (dart, java, etc).
|
||||
actionString = @"TextInputAction.unspecified";
|
||||
break;
|
||||
case FlutterTextInputActionDone:
|
||||
actionString = @"TextInputAction.done";
|
||||
break;
|
||||
case FlutterTextInputActionGo:
|
||||
actionString = @"TextInputAction.go";
|
||||
break;
|
||||
case FlutterTextInputActionSend:
|
||||
actionString = @"TextInputAction.send";
|
||||
break;
|
||||
case FlutterTextInputActionSearch:
|
||||
actionString = @"TextInputAction.search";
|
||||
break;
|
||||
case FlutterTextInputActionNext:
|
||||
actionString = @"TextInputAction.next";
|
||||
break;
|
||||
case FlutterTextInputActionContinue:
|
||||
actionString = @"TextInputAction.continue";
|
||||
break;
|
||||
case FlutterTextInputActionJoin:
|
||||
actionString = @"TextInputAction.join";
|
||||
break;
|
||||
case FlutterTextInputActionRoute:
|
||||
actionString = @"TextInputAction.route";
|
||||
break;
|
||||
case FlutterTextInputActionEmergencyCall:
|
||||
actionString = @"TextInputAction.emergencyCall";
|
||||
break;
|
||||
case FlutterTextInputActionNewline:
|
||||
actionString = @"TextInputAction.newline";
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user