簡體   English   中英

如何在Xamarin.Forms中為ToolbarItem創建自定義渲染器?

[英]How can I make a custom renderer for ToolbarItem in Xamarin.Forms?

我正在使用Xamarin.Forms應用程序。 我試圖通過工具欄項單擊將語音轉換為文本功能添加到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的自定義渲染器有任何想法,請告訴我。

通過工具欄,我想您的意思是導航欄(或獲得“頁面標題”的欄,對吧?)

如果是這種情況,那么您有兩個選擇:

  1. 等待Xamarin.Forms的下一個發行版,他們正在努力向工具欄添加內容。 (例如,您可以擁有自己的后退按鈕)

  2. 您可以創建自己的工具欄,只需確保不在NavigationPage上顯示導航欄,然后制作自己的工具欄(例如,將標題和所需的按鈕放在其中的水平堆棧布局(或flexlayout),並且具有背景色) 。

我嘗試為工具欄做自定義渲染器,看來這不是一件容易的事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM