c# - 如何在 Xamarin.Forms 中为 ToolbarItem 制作自定义渲染器?
问题描述
我正在使用 Xamarin.Forms 应用程序。我正在尝试通过单击工具栏项将 Speech to Text 功能添加到 Xamarin.Forms。当我单击工具上的按钮时,我希望内置电话语音服务打开并将我的语音转换为文本并添加到页面标签。
问题:为了触发特定于 android 的语音服务。我需要工具栏项的自定义渲染器。因此,我可以在该自定义渲染器的 OnClick 方法中将语音代码添加到文本中。但我似乎找不到工具栏项的渲染器类。
这是我当前尝试工具栏项渲染器的代码
VoiceToolbarItemRenderer.cs
[assembly: ExportRenderer(typeof(VoiceToolbarItem), typeof(VoiceToolbarItemRenderer))]
namespace Xamarin_App.Droid
{
public class VoiceToolbarItemRenderer : PageRenderer, Android.Views.View.IOnClickListene
{
private bool isRecording;
private readonly int VOICE = 10;
private MainActivity activity;
private VoiceToolbarItem sharedToolbarItem;
private Toolbar nativeButton;
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent;
public VoiceToolbarItemRenderer(Context context) : base(context)
{
isRecording = false;
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
activity = this.Context as MainActivity;
nativeButton = new global::Android.Widget.Toolbar(Context);
if (e.OldElement == null)
{
// perform initial setup
//SetNativeControl();
nativeButton.Clickable = true;
nativeButton.Focusable = true;
nativeButton.SetOnClickListener(this);
}
if (e.OldElement != null)
{
activity.ActivityResult -= HandleActivityResult;
}
if (e.NewElement != null)
{
activity.ActivityResult += HandleActivityResult;
sharedToolbarItem = e.NewElement.ToolbarItems as VoiceToolbarItem;
}
}
public void OnClick(Android.Views.View view)
{
try
{
string rec = Android.Content.PM.PackageManager.FeatureMicrophone;
if (rec != "android.hardware.microphone")
{
// no microphone, no recording. Disable the button and output an alert
var alert = new AlertDialog.Builder(Context);
alert.SetTitle("You don't seem to have a microphone to record with");
alert.SetPositiveButton("OK", (sender, e) => {
return;
});
alert.Show();
}
else
{
// create the intent and start the activity
var voiceIntent = new Intent(RecognizerIntent.ActionRecognizeSpeech);
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguageModel, RecognizerIntent.LanguageModelFreeForm);
// if there is more then 1.5s of silence, consider the speech over
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputCompleteSilenceLengthMillis, 1500);
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputPossiblyCompleteSilenceLengthMillis, 1500);
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputMinimumLengthMillis, 15000);
voiceIntent.PutExtra(RecognizerIntent.ExtraMaxResults, 1);
// you can specify other languages recognised here, for example
// voiceIntent.PutExtra(RecognizerIntent.ExtraLanguage, Java.Util.Locale.German);
// if you wish it to recognise the default Locale language and German
// if you do use another locale, regional dialects may not be recognised very well
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguage, Java.Util.Locale.Default);
activity.StartActivityForResult(voiceIntent, VOICE);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void HandleActivityResult(object sender, ActivityResultEventArgs e)
{
if (e.RequestCode == VOICE)
{
if (e.ResultCode == Result.Ok)
{
var matches = e.Data.GetStringArrayListExtra(RecognizerIntent.ExtraResults);
if (matches.Count != 0)
{
string textInput = matches[0];
// limit the output to 500 characters
if (textInput.Length > 500)
textInput = textInput.Substring(0, 500);
sharedToolbarItem.OnTextChanged?.Invoke(textInput);
//textBox.Text = textInput;
}
else
sharedToolbarItem.OnTextChanged?.Invoke("No speech was recognised");
}
}
}
}
}
如果有人有制作toolbarItem 的自定义渲染器的想法或任何其他建议,请告诉我。
解决方案
通过工具栏,我想您的意思是导航栏(或获得 Page Title 的栏,对吗?)
如果是这种情况,那么您有两种选择:
等待 Xamarin.Forms 的下一个版本,他们正在努力将内容添加到工具栏。(例如,您可以拥有自己的后退按钮)
您可以制作自己的工具栏,只需确保不在 NavigationPage 上显示导航栏,并制作自己的工具栏(例如,放置标题和所需按钮的水平堆栈布局(或 flexlayout)。并具有背景色.
我试图为工具栏做自定义渲染器,似乎这不是一件容易的事。
推荐阅读
- angular - Rxjs 如何过滤延迟 http 调用,直到条件与下面的代码匹配?
- java - Spring Restemplate 异常处理错误描述 null - 结果为 500 null
- terraform - Terrafrom v11.13 内联资源循环
- android - java.lang.SecurityException android.telephony.TelephonyManager.getDeviceId
- java - 类路径包含多个 SLF4J 绑定,请告诉我应该从 pom 中删除哪个依赖项来解决这个问题
- javascript - 任何可用于设置相对于画布中心点而不是 FabricJS 中的顶部和左侧的对象的选项
- android - 在kotlin中迭代枚举内部值
- python - 如何在 Python 中调度线程(和异步任务)?
- django - 是否应该在单独的 BooleanField 中跟踪重要指标,还是 CharField 就足够了?
- android - Pjsip Android 视频通话:如何使用 Pjsip 库在 SurfaceView 中显示您的视图