Как сделать пользовательский рендер для ToolbarItem в Xamarin.Forms? - PullRequest
0 голосов
/ 26 июня 2018

Я работаю с приложением 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");
            }
        }

    }

}

}

Если у кого-то есть идея сделать панель инструментов пользовательского рендераItem или какие-либо другие предложения, пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 27 июня 2018

Под панелью инструментов я предполагаю, что вы имеете в виду панель навигации (или панель, где вы получаете заголовок страницы, верно?)

Если это так, то у вас есть два варианта:

  1. Дождитесь следующего выпуска Xamarin. Формы, над которыми они работают, позволяют добавлять вещи на панель инструментов. (например, вы можете иметь свою собственную кнопку назад)

  2. Вы можете создать свою собственную панель инструментов, просто убедитесь, что панель навигации не отображается на NavigationPage, и создайте свою собственную панель инструментов (например, горизонтальное расположение в стеке (или flexlayout), где вы размещаете заголовок и нужные вам кнопки .и имеет цвет фона.

Я попытался сделать пользовательский рендерер для панели инструментов, и кажется, что это нелегкая работа.

...