Joh*_*ohn 26 soft-keyboard xamarin xamarin.forms
是否可以将键盘上"return"键中的文本更改为"next"或"done"?我有一个包含用户名和密码的登录表单.我希望返回键在用户名字段上显示"下一步",然后在密码字段上显示"完成",但无论如何都没有看到这样做.这是一个共享项目,Android和iOS.
Sus*_*ver 25
自定义EntryRenderer
可以处理更改键盘返回键描述.
iOS:UITextField
具有ReturnKeyType
可以设置为预分配列表的属性(请参阅UIReturnType
枚举).
Android:EntryEditText
有一个ImeOptions
属性可以控制键盘上的"Action"按钮的作用,以及一个SetImeActionLabel
可以用来为它设置任何文本字符串的方法.
new EntryExt {
Text = "Next Key",
ReturnKeyType = ReturnKeyTypes.Next
},
new EntryExt {
Text = "Done Key",
ReturnKeyType = ReturnKeyTypes.Done
}
Run Code Online (Sandbox Code Playgroud)
Xamarin.Forms
自定义的Entry
类:namespace YourNameSpaceHere
{
public class EntryExt : Entry
{
public const string ReturnKeyPropertyName = "ReturnKeyType";
public EntryExt() { }
public static readonly BindableProperty ReturnKeyTypeProperty = BindableProperty.Create(
propertyName: ReturnKeyPropertyName,
returnType: typeof(ReturnKeyTypes),
declaringType: typeof(EntryExt),
defaultValue: ReturnKeyTypes.Done);
public ReturnKeyTypes ReturnKeyType
{
get { return (ReturnKeyTypes)GetValue(ReturnKeyTypeProperty); }
set { SetValue(ReturnKeyTypeProperty, value); }
}
}
// Not all of these are support on Android, consult EntryEditText.ImeOptions
public enum ReturnKeyTypes : int
{
Default,
Go,
Google,
Join,
Next,
Route,
Search,
Send,
Yahoo,
Done,
EmergencyCall,
Continue
}
}
Run Code Online (Sandbox Code Playgroud)
EntryRenderer
:[assembly: ExportRenderer(typeof(Entry), typeof(EntryExtRenderer_iOS))]
namespace KeyboardDone.iOS
{
public class EntryExtRenderer_iOS : EntryRenderer
{
public EntryExtRenderer_iOS() { }
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if ((Control != null) && (e.NewElement != null))
Control.ReturnKeyType = (e.NewElement as EntryExt).ReturnKeyType.GetValueFromDescription();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == EntryExt.ReturnKeyPropertyName)
{
D.WriteLine($"{(sender as EntryExt).ReturnKeyType.ToString()}");
Control.ReturnKeyType = (sender as EntryExt).ReturnKeyType.GetValueFromDescription();
}
}
}
public static class EnumExtensions
{
public static UIReturnKeyType GetValueFromDescription(this ReturnKeyTypes value)
{
var type = typeof(UIReturnKeyType);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attribute != null)
{
if (attribute.Description == value.ToString())
return (UIReturnKeyType)field.GetValue(null);
}
else
{
if (field.Name == value.ToString())
return (UIReturnKeyType)field.GetValue(null);
}
}
throw new NotSupportedException($"Not supported on iOS: {value}");
}
}
}
Run Code Online (Sandbox Code Playgroud)
EntryRenderer
:[assembly: ExportRenderer(typeof(Entry), typeof(EntryExtRenderer_Droid))]
namespace KeyboardDone.Droid
{
public class EntryExtRenderer_Droid : EntryRenderer
{
public EntryExtRenderer_Droid() { }
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if ((Control != null) && (e.NewElement != null))
{
var entryExt = (e.NewElement as EntryExt);
Control.ImeOptions = entryExt.ReturnKeyType.GetValueFromDescription();
// This is hackie ;-) / A Android-only bindable property should be added to the EntryExt class
Control.SetImeActionLabel(entryExt.ReturnKeyType.ToString(), Control.ImeOptions);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == EntryExt.ReturnKeyPropertyName)
{
var entryExt = (sender as EntryExt);
Control.ImeOptions = entryExt.ReturnKeyType.GetValueFromDescription();
// This is hackie ;-) / A Android-only bindable property should be added to the EntryExt class
Control.SetImeActionLabel(entryExt.ReturnKeyType.ToString(), Control.ImeOptions);
}
}
}
public static class EnumExtensions
{
public static ImeAction GetValueFromDescription(this ReturnKeyTypes value)
{
var type = typeof(ImeAction);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attribute != null)
{
if (attribute.Description == value.ToString())
return (ImeAction)field.GetValue(null);
}
else
{
if (field.Name == value.ToString())
return (ImeAction)field.GetValue(null);
}
}
throw new NotSupportedException($"Not supported on Android: {value}");
}
}
}
Run Code Online (Sandbox Code Playgroud)
tes*_*ing 13
这是另一种方法,但类似于SushiHangover的解决方案.它包括UWP支持:
PCL中的ReturnType.cs
public enum ReturnType
{
Go,
Next,
Done,
Send,
Search
}
Run Code Online (Sandbox Code Playgroud)
PCL中的BaseEntry.cs
public class BaseEntry : Entry
{
// Need to overwrite default handler because we cant Invoke otherwise
public new event EventHandler Completed;
public static readonly BindableProperty ReturnTypeProperty = BindableProperty.Create(
nameof(ReturnType),
typeof(ReturnType),
typeof(BaseEntry),
ReturnType.Done,
BindingMode.OneWay
);
public ReturnType ReturnType
{
get { return (ReturnType)GetValue(ReturnTypeProperty); }
set { SetValue(ReturnTypeProperty, value); }
}
public void InvokeCompleted()
{
if (this.Completed != null)
this.Completed.Invoke(this, null);
}
}
Run Code Online (Sandbox Code Playgroud)
适用于Android的BaseEntryRenderer.cs
public class BaseEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
BaseEntry entry = (BaseEntry)this.Element;
if(this.Control != null)
{
if(entry != null)
{
SetReturnType(entry);
// Editor Action is called when the return button is pressed
Control.EditorAction += (object sender, TextView.EditorActionEventArgs args) =>
{
if (entry.ReturnType != ReturnType.Next)
entry.Unfocus();
// Call all the methods attached to base_entry event handler Completed
entry.InvokeCompleted();
};
}
}
}
private void SetReturnType(BaseEntry entry)
{
ReturnType type = entry.ReturnType;
switch (type)
{
case ReturnType.Go:
Control.ImeOptions = ImeAction.Go;
Control.SetImeActionLabel("Go", ImeAction.Go);
break;
case ReturnType.Next:
Control.ImeOptions = ImeAction.Next;
Control.SetImeActionLabel("Next", ImeAction.Next);
break;
case ReturnType.Send:
Control.ImeOptions = ImeAction.Send;
Control.SetImeActionLabel("Send", ImeAction.Send);
break;
case ReturnType.Search:
Control.ImeOptions = ImeAction.Search;
Control.SetImeActionLabel("Search", ImeAction.Search);
break;
default:
Control.ImeOptions = ImeAction.Done;
Control.SetImeActionLabel("Done", ImeAction.Done);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
适用于iOS的BaseEntryRenderer.cs
public class BaseEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
BaseEntry entry = (BaseEntry)this.Element;
if (this.Control != null)
{
if(entry != null)
{
SetReturnType(entry);
Control.ShouldReturn += (UITextField tf) =>
{
entry.InvokeCompleted();
return true;
};
}
}
}
private void SetReturnType(BaseEntry entry)
{
ReturnType type = entry.ReturnType;
switch (type)
{
case ReturnType.Go:
Control.ReturnKeyType = UIReturnKeyType.Go;
break;
case ReturnType.Next:
Control.ReturnKeyType = UIReturnKeyType.Next;
break;
case ReturnType.Send:
Control.ReturnKeyType = UIReturnKeyType.Send;
break;
case ReturnType.Search:
Control.ReturnKeyType = UIReturnKeyType.Search;
break;
case ReturnType.Done:
Control.ReturnKeyType = UIReturnKeyType.Done;
break;
default:
Control.ReturnKeyType = UIReturnKeyType.Default;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
UWP的BaseEntryRenderer.cs
public class BaseEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
BaseEntry entry = (BaseEntry)this.Element;
if(this.Control != null)
{
if(entry != null)
{
this.Control.KeyDown += (object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs eventArgs) =>
{
if (eventArgs.Key == Windows.System.VirtualKey.Enter)
{
entry.InvokeCompleted();
// Make sure to set the Handled to true, otherwise the RoutedEvent might fire twice
eventArgs.Handled = true;
}
};
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在UWP上似乎无法将返回键更改为next/done/...您需要ExportRenderer
自己为所有自定义渲染器添加属性.
用法
XAML文件
<renderer:BaseEntry x:Name="username" Text="Username" ReturnType="Next" />
<renderer:BaseEntry x:Name="password" Text ="Password" IsPassword="true" ReturnType="Done" />
Run Code Online (Sandbox Code Playgroud)
代码隐藏文件:
this.username.Completed += (object sender, EventArgs e) => this.password.Focus();
Run Code Online (Sandbox Code Playgroud)
基于此来源.
最新的 Xamarin Forms 包为 Entry 元素添加了 ReturnType 属性。单击“完成”按钮时,它还将执行命令。现在都支持 Done、Next、Search、Go 和 Send 的 IMEAction 类型。
是的,最新的Xamarin表单直接允许ReturnType作为属性,只需要在Xaml中添加ReturnType
<Entry x:Name="myEntry" ReturnType="Done"/>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15798 次 |
最近记录: |