草庐IT

c# - Xamarin 自定义键盘

coder 2023-12-26 原文

我正在尝试为特定页面创建一个自定义键盘,但我在处理所有键的监听器时遇到了一些问题,而且这方面的文档非常有限。

我正在使用 XamarinC# 进行开发:

所以这里我有一个 Activity (OrderActivity):

mKeyboard = new Keyboard(this,Resource.Layout.Keyboard);
mKeyboardView = this.FindViewById<KeyboardView> (Resource.Id.keyboardview);
mKeyboardView.Keyboard = mKeyboard;

// PROBLEM HERE
mKeyboardView.OnKeyboardActionListener = new KeyboardView.IOnKeyboardActionListener () {};

有一个 Keyboard.axml,它们可以完美地显示在屏幕上,但我有问题,不知道如何调用监听器,这里有人有任何教程或如何解决这个问题吗?或者在创建自定义键盘方面是否有其他选择?

最佳答案

正如监听器的名称所示,它是您需要实现的接口(interface)。 C# 目前不允许像 Java 那样使用匿名类。

请记住,在实现 Java 接口(interface)时,您需要从 Java.Lang.Object 继承,因为它需要一个句柄。

因此您的实现可能类似于:

public class KeyboardOnKeyEventArgs : KeyboardKeyCodeEventArgs
{
    public Keycode[] KeyCodes { get; set; }
}

public class KeyboardKeyCodeEventArgs : EventArgs
{
    public Keycode PrimaryCode { get; set; }
}

public class KeyboardOnTextEventArgs : EventArgs
{
    public ICharSequence Text { get; set; }
}

public class MyKeyboardListener : Java.Lang.Object, KeyboardView.IOnKeyboardActionListener
{
    public event EventHandler<KeyboardOnKeyEventArgs> Key;
    public event EventHandler<KeyboardKeyCodeEventArgs> Press;
    public event EventHandler<KeyboardKeyCodeEventArgs> Release;
    public event EventHandler<KeyboardOnTextEventArgs> Text;
    public event EventHandler OnSwipeDown;
    public event EventHandler OnSwipeLeft;
    public event EventHandler OnSwipeRight;
    public event EventHandler OnSwipeUp;

    public void OnKey(Keycode primaryCode, Keycode[] keyCodes)
    {
        if (Key != null)
            Key(this, new KeyboardOnKeyEventArgs {
                KeyCodes = keyCodes,
                PrimaryCode = primaryCode
            });
    }

    public void OnPress(Keycode primaryCode)
    {
        if (Press != null)
            Press(this, new KeyboardKeyCodeEventArgs { PrimaryCode = primaryCode });
    }

    public void OnRelease(Keycode primaryCode)
    {
        if (Release != null)
            Release(this, new KeyboardKeyCodeEventArgs { PrimaryCode = primaryCode });
    }

    public void OnText(ICharSequence text)
    {
        if (Text != null)
            Text(this, new KeyboardOnTextEventArgs {Text = text});

    }

    public void SwipeDown()
    {
        if(OnSwipeDown != null)
            OnSwipeDown(this, EventArgs.Empty);
    }

    public void SwipeLeft()
    {
        if (OnSwipeLeft != null)
            OnSwipeLeft(this, EventArgs.Empty);
    }

    public void SwipeRight()
    {
        if (OnSwipeRight != null)
            OnSwipeRight(this, EventArgs.Empty);
    }

    public void SwipeUp()
    {
        if (OnSwipeUp != null)
            OnSwipeUp(this, EventArgs.Empty);
    }
}

用法是:

var keyboardListener = new MyKeyboardListener();
keyboardListener.Press += (s, e) => { /* do something */ };
mKeyboardView.OnKeyboardActionListener = keyboardListener;

编辑:

用它做了更多工作,但我无法重现您的错误。

keyboard.xml

<?xml version="1.0" encoding="utf-8" ?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="33%p" android:horizontalGap="0px"
    android:verticalGap="0px" android:keyHeight="54dip">

  <Row>
    <Key android:codes="8" android:keyLabel="1" android:keyEdgeFlags="left" />
    <Key android:codes="9" android:keyLabel="2" />
    <Key android:codes="10" android:keyLabel="3" android:keyEdgeFlags="right" />
  </Row>

  <Row>
    <Key android:codes="11" android:keyLabel="4" android:keyEdgeFlags="left" />
    <Key android:codes="12" android:keyLabel="5" />
    <Key android:codes="13" android:keyLabel="6" android:keyEdgeFlags="right" />
  </Row>

  <Row>
    <Key android:codes="14" android:keyLabel="7" android:keyEdgeFlags="left" />
    <Key android:codes="15" android:keyLabel="8" />
    <Key android:codes="16" android:keyLabel="9" android:keyEdgeFlags="right" />
  </Row>
</Keyboard>

Main.axml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <EditText
        android:layout_above="@+id/keyboard_view"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:id="@+id/target"
        android:layout_height="wrap_content" />
    <android.inputmethodservice.KeyboardView
        android:id="@+id/keyboard_view"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

slide_up.xml

<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <translate android:fromYDelta="-50%p" android:toYDelta="0" android:duration="200"/>
  <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="200" />
</set>

MyKeyboardListener.cs

public class MyKeyboardListener : Java.Lang.Object, KeyboardView.IOnKeyboardActionListener
{
    private readonly Activity _activity;

    public MyKeyboardListener(Activity activity) {
        _activity = activity;
    }

    public void OnKey(Keycode primaryCode, Keycode[] keyCodes)
    {
        var eventTime = DateTime.Now.Ticks;
        var keyEvent = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, primaryCode, 0);
        _activity.DispatchKeyEvent(keyEvent);
    }

    public void OnPress(Keycode primaryCode) { }
    public void OnRelease(Keycode primaryCode) { }
    public void OnText(ICharSequence text) { }
    public void SwipeDown() { }
    public void SwipeLeft() { }
    public void SwipeRight() { }
    public void SwipeUp() { }
}

MainActivity.cs

[Activity(Label = "App14", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    private Keyboard _keyBoard;
    private EditText _targetView;
    private KeyboardView _keyboardView;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        _keyBoard = new Keyboard(this, Resource.Xml.keyboard);
        _keyboardView = FindViewById<KeyboardView>(Resource.Id.keyboard_view);
        _keyboardView.Keyboard = _keyBoard;
        _keyboardView.OnKeyboardActionListener = new MyKeyboardListener(this);
        _targetView = FindViewById<EditText>(Resource.Id.target);
        _targetView.Touch += (sender, args) => {
            var bottomUp = AnimationUtils.LoadAnimation(this, Resource.Animation.slide_up);
            _keyboardView.StartAnimation(bottomUp);
            _keyboardView.Visibility = ViewStates.Visible;
            args.Handled = true;
        };
    }
}

键盘显示和字符被发送到 EditText

关于c# - Xamarin 自定义键盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31266845/

有关c# - Xamarin 自定义键盘的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  5. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  8. ruby - 如何在 Grape 中定义哈希数组? - 2

    我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>

  9. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  10. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

随机推荐