C# 如何在Xamarin.Forms中为ToolbarItem创建自定义渲染器?
我正在使用Xamarin.Forms应用程序。我正试图通过一个工具栏项单击向Xamarin.Forms添加语音到文本功能。当我单击工具上的按钮时,我希望内置电话语音服务打开并将我的语音转换为文本,并添加到页面的标签中 问题:触发特定于android的语音服务。我需要工具栏项的自定义渲染器。因此,我可以在该自定义渲染器的OnClick方法中将语音代码添加到文本中。但我似乎找不到工具栏项的渲染器类 下面是我当前尝试使用工具栏项渲染器的代码 VoiceToolbarItemRenderer.csC# 如何在Xamarin.Forms中为ToolbarItem创建自定义渲染器?,c#,xamarin.forms,xamarin.android,speech-to-text,C#,Xamarin.forms,Xamarin.android,Speech To Text,我正在使用Xamarin.Forms应用程序。我正试图通过一个工具栏项单击向Xamarin.Forms添加语音到文本功能。当我单击工具上的按钮时,我希望内置电话语音服务打开并将我的语音转换为文本,并添加到页面的标签中 问题:触发特定于android的语音服务。我需要工具栏项的自定义渲染器。因此,我可以在该自定义渲染器的OnClick方法中将语音代码添加到文本中。但我似乎找不到工具栏项的渲染器类 下面是我当前尝试使用工具栏项渲染器的代码 VoiceToolbarItemRenderer.cs [a
[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");
}
}
}
}
[程序集:ExportRenderer(typeof(VoiceToolbarItem)、typeof(VoiceToolbarItemRenderer))]
命名空间Xamarin_App.Droid
{
公共类VoiceToolbarItemRenderer:PageRenderer,Android.Views.View.IOnClickListene
{
私人档案记录;
专用只读int语音=10;
私人活动;
私有VoiceToolbarItem共享ToolBarItem;
专用工具栏nativeButton;
私人语音识别器;
私人意图mSpeechRecognizerIntent;
公共VoiceToolbarItemRenderer(上下文):基本(上下文)
{
isRecording=false;
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
activity=this.Context作为MainActivity;
nativeButton=新的全局::Android.Widget.Toolbar(上下文);
if(e.OldElement==null)
{
//执行初始设置
//SetNativeControl();
nativeButton.Clickable=true;
nativeButton.Focusable=true;
nativeButton.SetOnClickListener(此);
}
if(e.OldElement!=null)
{
activity.ActivityResult-=手动过滤活性Result;
}
if(例如NewElement!=null)
{
activity.ActivityResult+=手动过滤活性Result;
sharedToolbarItem=e.NewElement.ToolbarItems作为VoiceToolbarItem;
}
}
public void OnClick(Android.Views.View)
{
尝试
{
string rec=Android.Content.PM.PackageManager.feature麦克风;
if(rec!=“安卓.硬件.麦克风”)
{
//没有麦克风,没有录音。禁用按钮并输出警报
var alert=new AlertDialog.Builder(上下文);
SetTitle(“你似乎没有麦克风来录音”);
alert.SetPositiveButton(“确定”,(发送方,e)=>{
返回;
});
alert.Show();
}
其他的
{
//创建意图并开始活动
var voiceIntent=新意图(RecognizerIntent.ActionRecognizeSpeech);
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguageModel,RecognizerIntent.LanguageModelFreeForm);
如果还有1.5秒的沉默,请考虑演讲。
voiceIntent.PutExtra(识别器Intent.ExtraspeechInputCompleteSilenceLength,1500);
voiceIntent.PutExtra(识别器Intent.ExtraspeechInputPossiblyCompleteSilenceLength,1500);
voiceIntent.PutExtra(识别器Intent.ExtraSpeechInputMinimumLengthMillis,15000);
voiceIntent.PutExtra(RecognizerIntent.ExtraMaxResults,1);
//例如,您可以在此处指定可识别的其他语言
//PutExtra(RecognizerIntent.ExtraLanguage,Java.Util.Locale.German);
//如果您希望它识别默认的语言环境语言和德语
//如果你使用另一个地区,地区方言可能不会被很好地识别
PutExtra(RecognizerIntent.ExtraLanguage,Java.Util.Locale.Default);
activity.StartActivityForResult(语音意图、语音);
}
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
}
}
私有void HandleActivityResult(对象发送方,ActivityResultEventArgs e)
{
如果(例如,请求代码==语音)
{
if(e.ResultCode==Result.Ok)
{
var matches=e.Data.GetStringArrayListExtra(RecognizerIntent.ExtraResults);
如果(matches.Count!=0)
{
字符串textInput=匹配[0];
//将输出限制为500个字符
如果(textInput.Length>500)
textInput=textInput.Substring(0500);
sharedToolbarItem.OnTextChanged?.Invoke(textInput);
//Text=textInput;
}
其他的
sharedToolbarItem.OnTextChanged?.Invoke(“未识别语音”);
}
}
}
}
}
如果有人想制作toolbarItem的自定义呈现程序或任何其他建议,请告诉我。我想您指的是导航栏(或获取页面标题的栏,对吗?) 如果是这种情况,那么您有两个选择:
我尝试过为工具栏定制渲染器,但这似乎不是一件容易的工作。您可以按照下面的步骤来实现徽章图标