feat:input add onSubmitEditing

This commit is contained in:
pengfei.zhou 2021-06-11 15:17:20 +08:00 committed by osborn
parent ff641bf983
commit 5263731dd7
12 changed files with 239 additions and 49 deletions

View File

@ -23,10 +23,12 @@ import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
@ -221,6 +223,28 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
}
}
break;
case "onSubmitEditing":
if (!prop.isString()) {
return;
}
final String functionId = prop.asString().value();
view.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
switch (actionId) {
case EditorInfo.IME_ACTION_UNSPECIFIED:
case EditorInfo.IME_ACTION_NEXT:
case EditorInfo.IME_ACTION_DONE:
case EditorInfo.IME_ACTION_GO:
case EditorInfo.IME_ACTION_SEARCH:
case EditorInfo.IME_ACTION_SEND:
callJSResponse(functionId, v.getText().toString());
return true;
}
return false;
}
});
break;
default:
super.blend(view, name, prop);
break;

View File

@ -6,14 +6,12 @@ import {
layoutConfig,
LayoutSpec,
Input,
Gravity,
log,
Color,
input,
text,
InputType,
} from "doric";
import { title, colors } from "./utils";
import { preferenceView } from "./components/PreferenceView";
import { title } from "./utils";
function getInput(c: Partial<Input>) {
const inputView = input(c);
@ -37,56 +35,64 @@ function getInput(c: Partial<Input>) {
inputView.onTextChange = (text) => {
inputed.text = `Inputed:${text}`;
};
return [inputView, isFocused, inputed];
inputView.onSubmitEditing = (text) => {
inputed.text = `Submited: ${text}`
};
return [
inputView,
isFocused,
inputed,
preferenceView().applyChild({
title: {
text: "Multiline"
},
switch: {
state: true,
onSwitch: (ret) => {
inputView.multiline = ret
}
}
}),
preferenceView().applyChild({
title: {
text: "Editable"
},
switch: {
state: true,
onSwitch: (ret) => {
inputView.editable = ret
}
}
}),
];
}
@Entry
class InputDemo extends Panel {
build(root: Group) {
var [inputView, ...otherView] = getInput({
layoutConfig: {
widthSpec: LayoutSpec.FIT,
heightSpec: LayoutSpec.FIT,
},
hintText: "Please input something in one line",
border: {
width: 1,
color: Color.GRAY,
},
multiline: false,
textSize: 20,
maxLength: 20,
padding: { top: 10, bottom: 11 },
inputType: InputType.Decimal,
password: true,
});
let inputView: Input
scroller(
vlayout(
[
title("Demo"),
// ...getInput({
// layoutConfig: {
// widthSpec: LayoutSpec.JUST,
// heightSpec: LayoutSpec.FIT,
// },
// width: 300,
// hintText: "Please input something",
// border: {
// width: 1,
// color: Color.GRAY,
// },
// textSize: 40,
// maxLength: 20,
// }),
inputView,
...otherView,
...getInput({
layoutConfig: {
widthSpec: LayoutSpec.MOST,
heightSpec: LayoutSpec.FIT,
},
hintText: "Please input something",
border: {
width: 1,
color: Color.GRAY,
},
}),
],
{
space: 10,
layoutConfig: layoutConfig().most().configHeight(LayoutSpec.MOST),
onClick: () => {
(inputView as Input).releaseFocus(context);
},
}
),
{

View File

@ -28,6 +28,8 @@
typedef void (^onFocusChangeBlock)(BOOL focused, DoricInputNode *node);
typedef void (^onSubmitEditingBlock)(NSString *text, DoricInputNode *node);
@implementation DoricInputView
- (instancetype)init {
@ -71,7 +73,8 @@ - (CGSize)sizeThatFits:(CGSize)size {
@interface DoricInputNode () <UITextViewDelegate>
@property(nonatomic, copy) onTextChangeBlock onTextChange;
@property(nonatomic, copy) onFocusChangeBlock onFocusShange;
@property(nonatomic, copy) onFocusChangeBlock onFocusChange;
@property(nonatomic, copy) onSubmitEditingBlock onSubmitEditing;
@property(nonatomic, strong) NSNumber *maxLength;
@end
@ -107,6 +110,9 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
BOOL value = [(NSNumber *) prop boolValue];
if (!value) {
view.textContainer.maximumNumberOfLines = 1;
if (view.text.length > 0) {
view.text = [view.text stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
}
} else {
view.textContainer.maximumNumberOfLines = 0;
}
@ -124,11 +130,11 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
}
} else if ([name isEqualToString:@"onFocusChange"]) {
if ([prop isKindOfClass:[NSString class]]) {
self.onFocusShange = ^(BOOL focused, DoricInputNode *node) {
self.onFocusChange = ^(BOOL focused, DoricInputNode *node) {
[node callJSResponse:prop, @(focused), nil];
};
} else {
self.onFocusShange = nil;
self.onFocusChange = nil;
}
} else if ([name isEqualToString:@"maxLength"]) {
@ -161,6 +167,9 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
} else if ([name isEqualToString:@"editable"]) {
view.editable = [(NSNumber *) prop boolValue];
} else if ([name isEqualToString:@"returnKeyType"]) {
if (view.textContainer.maximumNumberOfLines == 1) {
return;
}
switch ([(NSNumber *) prop integerValue]) {
case 1:
view.returnKeyType = UIReturnKeyDone;
@ -182,6 +191,14 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
view.returnKeyType = UIReturnKeyDefault;
break;
}
} else if ([name isEqualToString:@"onSubmitEditing"]) {
if ([prop isKindOfClass:[NSString class]]) {
self.onSubmitEditing = ^(NSString *text, DoricInputNode *node) {
[node callJSResponse:prop, text, nil];
};
} else {
self.onSubmitEditing = nil;
}
} else {
[super blendView:view forPropName:name propValue:prop];
}
@ -237,15 +254,27 @@ - (void)releaseFocus {
#pragma mark - UITextViewDelegate
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
if (self.onFocusShange) {
self.onFocusShange(YES, self);
if (self.onFocusChange) {
self.onFocusChange(YES, self);
}
return YES;
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
if (self.onFocusShange) {
self.onFocusShange(NO, self);
if (self.onFocusChange) {
self.onFocusChange(NO, self);
}
return YES;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:@"\n"]) {
if (textView.textContainer.maximumNumberOfLines == 1) {
if (self.onSubmitEditing) {
self.onSubmitEditing(textView.text, self);
}
return NO;
}
}
return YES;
}

View File

@ -2767,6 +2767,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") { return Reflect.metadata(k, v); }
};
exports.ReturnKeyType = void 0;
(function (ReturnKeyType) {
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
var Input = /** @class */ (function (_super) {
__extends$5(Input, _super);
function Input() {
@ -2836,6 +2845,18 @@ var Input = /** @class */ (function (_super) {
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "password", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "editable", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Number)
], Input.prototype, "returnKeyType", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
return Input;
}(View));
exports.InputType = void 0;

View File

@ -2135,6 +2135,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
exports.ReturnKeyType = void 0;
(function (ReturnKeyType) {
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
class Input extends View {
getText(context) {
return this.nativeChannel(context, 'getText')();
@ -2200,6 +2209,18 @@ __decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "password", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "editable", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Number)
], Input.prototype, "returnKeyType", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
exports.InputType = void 0;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

View File

@ -3656,6 +3656,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
exports.ReturnKeyType = void 0;
(function (ReturnKeyType) {
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
class Input extends View {
getText(context) {
return this.nativeChannel(context, 'getText')();
@ -3721,6 +3730,18 @@ __decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "password", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "editable", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Number)
], Input.prototype, "returnKeyType", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
exports.InputType = void 0;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

11
doric-js/index.d.ts vendored
View File

@ -760,6 +760,14 @@ declare module 'doric/lib/src/widget/input' {
import { Color } from "doric/lib/src/util/color";
import { Gravity } from "doric/lib/src/util/gravity";
import { BridgeContext } from "doric/lib/src/runtime/global";
export enum ReturnKeyType {
Default = 0,
Done = 1,
Search = 2,
Next = 3,
Go = 4,
Send = 5
}
export class Input extends View {
text?: string;
textColor?: Color;
@ -773,6 +781,9 @@ declare module 'doric/lib/src/widget/input' {
onFocusChange?: (focused: boolean) => void;
maxLength?: number;
password?: boolean;
editable?: boolean;
returnKeyType?: ReturnKeyType;
onSubmitEditing?: (text: string) => void;
getText(context: BridgeContext): Promise<string>;
setSelection(context: BridgeContext, start: number, end?: number): Promise<string>;
requestFocus(context: BridgeContext): Promise<any>;

View File

@ -2,6 +2,14 @@ import { View } from "../ui/view";
import { Color } from "../util/color";
import { Gravity } from "../util/gravity";
import { BridgeContext } from "../runtime/global";
export declare enum ReturnKeyType {
Default = 0,
Done = 1,
Search = 2,
Next = 3,
Go = 4,
Send = 5
}
export declare class Input extends View {
text?: string;
textColor?: Color;
@ -15,6 +23,9 @@ export declare class Input extends View {
onFocusChange?: (focused: boolean) => void;
maxLength?: number;
password?: boolean;
editable?: boolean;
returnKeyType?: ReturnKeyType;
onSubmitEditing?: (text: string) => void;
getText(context: BridgeContext): Promise<string>;
setSelection(context: BridgeContext, start: number, end?: number): Promise<string>;
requestFocus(context: BridgeContext): Promise<any>;

View File

@ -26,6 +26,15 @@ import { View, Property, InconsistProperty } from "../ui/view";
import { Color } from "../util/color";
import { Gravity } from "../util/gravity";
import { layoutConfig } from "../util/index.util";
export var ReturnKeyType;
(function (ReturnKeyType) {
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
})(ReturnKeyType || (ReturnKeyType = {}));
export class Input extends View {
getText(context) {
return this.nativeChannel(context, 'getText')();
@ -91,6 +100,18 @@ __decorate([
Property,
__metadata("design:type", Boolean)
], Input.prototype, "password", void 0);
__decorate([
Property,
__metadata("design:type", Boolean)
], Input.prototype, "editable", void 0);
__decorate([
Property,
__metadata("design:type", Number)
], Input.prototype, "returnKeyType", void 0);
__decorate([
Property,
__metadata("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
export var InputType;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

View File

@ -72,6 +72,10 @@ export class Input extends View {
@Property
returnKeyType?: ReturnKeyType
@Property
onSubmitEditing?: (text: string) => void
getText(context: BridgeContext) {
return this.nativeChannel(context, 'getText')() as Promise<string>
}

View File

@ -3710,6 +3710,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
exports.ReturnKeyType = void 0;
(function (ReturnKeyType) {
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
class Input extends View {
getText(context) {
return this.nativeChannel(context, 'getText')();
@ -3775,6 +3784,18 @@ __decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "password", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Boolean)
], Input.prototype, "editable", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Number)
], Input.prototype, "returnKeyType", void 0);
__decorate$3([
Property,
__metadata$3("design:type", Function)
], Input.prototype, "onSubmitEditing", void 0);
exports.InputType = void 0;
(function (InputType) {
InputType[InputType["Default"] = 0] = "Default";

File diff suppressed because one or more lines are too long