草庐IT

android - 自定义键盘隐藏了 Android 中的编辑框

coder 2023-12-12 原文

我设计了一个只有数字键的自定义键盘。我已点击以下链接: example

现在当我触摸编辑框时,键盘出现了。但是,如果我有 10 个编辑框,并且我正在触摸第 10 个编辑框,则会出现键盘并隐藏编辑框。我怎样才能让编辑框自动向上滚动,这样它就不会被隐藏。

我已经为 xml 文件编写了以下布局代码:

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <EditText
                android:id="@+id/edittext0"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="30dp"
                android:inputType="text" />

            <EditText
                android:id="@+id/edittext1"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/edittext0"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="30dp"
                android:inputType="text" />

            <EditText
                android:id="@+id/edittext2"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/edittext1"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="40dp"
                android:inputType="text" />

            <EditText
                android:id="@+id/edittext3"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/edittext2"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="40dp"
                android:inputType="text" />

            <EditText
                android:id="@+id/edittext4"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/edittext3"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="40dp"
                android:inputType="text" />
        </RelativeLayout>
    </ScrollView>

    <android.inputmethodservice.KeyboardView
        android:id="@+id/keyboardview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:visibility="gone" />

</RelativeLayout>

这也是我的自定义键盘 java 类:

    class CustomKeyboard {

    /** A link to the KeyboardView that is used to render this CustomKeyboard. */
    private KeyboardView mKeyboardView;
    /** A link to the activity that hosts the {@link #mKeyboardView}. */
    private Activity mHostActivity;

    /** The key (code) handler. */
    private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {

        public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
        public final static int CodePrev = 55000;
        public final static int CodeNext = 55001;
        public final static int CodeDone = 55002;

        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            // NOTE We can say '<Key android:codes="49,50" ... >' in the xml
            // file; all codes come in keyCodes, the first in this list in
            // primaryCode
            // Get the EditText and its Editable
            View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
            if (focusCurrent == null
                    || focusCurrent.getClass() != EditText.class)
                return;
            EditText edittext = (EditText) focusCurrent;
            Editable editable = edittext.getText();
            int start = edittext.getSelectionStart();
            // Apply the key to the edittext
            if (primaryCode == CodeDone) {
                hideCustomKeyboard();
            } 
            else if (primaryCode == CodeDelete) 
            {
                if (editable != null && start > 0)
                    editable.delete(start - 1, start);
            } 
            else if (primaryCode == CodePrev) {
                View focusNew = edittext.focusSearch(View.FOCUS_BACKWARD);
                if (focusNew != null)
                    focusNew.requestFocus();
            } 
            else if (primaryCode == CodeNext) {
                View focusNew = edittext.focusSearch(View.FOCUS_FORWARD);
                if (focusNew != null)
                    focusNew.requestFocus();
            } 
            else { // insert character
                editable.insert(start, Character.toString((char) primaryCode));
            }
        }

        @Override
        public void onPress(int arg0) {
        }

        @Override
        public void onRelease(int primaryCode) {
        }

        @Override
        public void onText(CharSequence text) {
        }

        @Override
        public void swipeDown() {
        }

        @Override
        public void swipeLeft() {
        }

        @Override
        public void swipeRight() {
        }

        @Override
        public void swipeUp() {
        }
    };

    /**
     * Create a custom keyboard, that uses the KeyboardView (with resource id
     * <var>viewid</var>) of the <var>host</var> activity, and load the keyboard
     * layout from xml file <var>layoutid</var> (see {@link Keyboard} for
     * description). Note that the <var>host</var> activity must have a
     * <var>KeyboardView</var> in its layout (typically aligned with the bottom
     * of the activity). Note that the keyboard layout xml file may include key
     * codes for navigation; see the constants in this class for their values.
     * Note that to enable EditText's to use this custom keyboard, call the
     * {@link #registerEditText(int)}.
     * 
     * @param host
     *            The hosting activity.
     * @param viewid
     *            The id of the KeyboardView.
     * @param layoutid
     *            The id of the xml file containing the keyboard layout.
     */
    public CustomKeyboard(Activity host, int viewid, int layoutid) {
        mHostActivity = host;
        mKeyboardView = (KeyboardView) mHostActivity.findViewById(viewid);
        mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
        mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview
                                                // balloons
        mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
        // Hide the standard keyboard initially
        mHostActivity.getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    /** Returns whether the CustomKeyboard is visible. */
    public boolean isCustomKeyboardVisible() {
        return mKeyboardView.getVisibility() == View.VISIBLE;
    }

    /**
     * Make the CustomKeyboard visible, and hide the system keyboard for view v.
     */
    public void showCustomKeyboard(View v) {
        mKeyboardView.setVisibility(View.VISIBLE);
        mKeyboardView.setEnabled(true);
        if (v != null)
            ((InputMethodManager) mHostActivity
                    .getSystemService(Activity.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

    /** Make the CustomKeyboard invisible. */
    public void hideCustomKeyboard() {
        mKeyboardView.setVisibility(View.GONE);
        mKeyboardView.setEnabled(false);
    }

    /**
     * Register <var>EditText<var> with resource id <var>resid</var> (on the
     * hosting activity) for using this custom keyboard.
     * 
     * @param resid
     *            The resource id of the EditText that registers to the custom
     *            keyboard.
     */
    public void registerEditText(int resid) {
        // Find the EditText 'resid'
        EditText edittext = (EditText) mHostActivity.findViewById(resid);
        // Make the custom keyboard appear
        edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
            // NOTE By setting the on focus listener, we can show the custom
            // keyboard when the edit box gets focus, but also hide it when the
            // edit box loses focus
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus)
                    showCustomKeyboard(v);
                else
                    hideCustomKeyboard();
            }
        });
        edittext.setOnClickListener(new OnClickListener() {
            // NOTE By setting the on click listener, we can show the custom
            // keyboard again, by tapping on an edit box that already had focus
            // (but that had the keyboard hidden).
            @Override
            public void onClick(View v) {
                showCustomKeyboard(v);
            }
        });
        // Disable standard keyboard hard way
        // NOTE There is also an easy way:
        // 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a
        // cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
        edittext.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                EditText edittext = (EditText) v;
                int inType = edittext.getInputType(); // Backup the input type
                edittext.setInputType(InputType.TYPE_NULL); // Disable standard
                                                            // keyboard
                edittext.onTouchEvent(event); // Call native handler
                edittext.setInputType(inType); // Restore input type
                return true; // Consume touch event
            }
        });
        // Disable spell check (hex strings look like words to Android)
        edittext.setInputType(edittext.getInputType()
                | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    }

}

请帮帮我!!

谢谢, 阿林达姆

最佳答案

我遇到了完全相同的问题,经过一整天的研究,我终于解决了它。

方法如下:

我的 xml 布局与您的布局几乎相同,但我有多个 KeyboardView,因为我需要为不同的 EditText 使用不同的键盘。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="HardcodedText,TextFields" >    

<ScrollView 
    android:id="@+id/scroll_content"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:orientation="vertical"
        android:layout_gravity="center_horizontal"
        android:paddingBottom="16dp">

        <TextView
            android:id="@+id/DecLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Decimal" />

        <EditText
            android:id="@+id/DecText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:focusable="true"
            android:focusableInTouchMode="true" />

        <TextView
            android:id="@+id/HexLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text="Hexadecimal" />

        <EditText
            android:id="@+id/HexText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:focusable="true"
            android:focusableInTouchMode="true" />

        <TextView
            android:id="@+id/BinaryLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text="Binary" />

        <EditText
            android:id="@+id/BinaryText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:focusable="true"
            android:focusableInTouchMode="true" />

        <TextView
            android:id="@+id/OctalLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text="Octal" />

        <EditText
            android:id="@+id/OctalText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:layout_gravity="fill" />
    </LinearLayout>

</ScrollView>

<android.inputmethodservice.KeyboardView
    android:id="@+id/keyboardview_hex"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_margin="0dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:keyBackground="@drawable/btn_keyboard_key_ics"
    android:visibility="gone" />

<android.inputmethodservice.KeyboardView
    android:id="@+id/keyboardview_dec"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_margin="0dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:keyBackground="@drawable/btn_keyboard_key_ics"
    android:visibility="gone" />

<android.inputmethodservice.KeyboardView
    android:id="@+id/keyboardview_oct"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_margin="0dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:keyBackground="@drawable/btn_keyboard_key_ics"
    android:visibility="gone" />

<android.inputmethodservice.KeyboardView
    android:id="@+id/keyboardview_bin"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_margin="0dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:keyBackground="@drawable/btn_keyboard_key_ics"
    android:visibility="gone" />

这还不够。我还需要在显示 KeyboardView 时设置 ScrollView 的 android:layout_above 属性,我是通过一个界面完成的:

public interface OnKeyboardStateChangedListener
{
    public void OnDisplay(View currentview, KeyboardView currentKeyboard);

    public void OnHide(KeyboardView currentKeyboard);
} 

并将此接口(interface)实现到我的 MainActivity 以编辑 ScrollView 的属性:

public class MainActivity extends Activity BaseKeyboard.OnKeyboardStateChangedListener

我还通过 MainActivity 作为参数并保存为 OnKeyboardStateChangedListener:

private OnKeyboardStateChangedListener mStateListener;

public BaseKeyboard(Activity host, int viewid, int layoutid, OnKeyboardStateChangedListener listener) {
    ..
    ..
    mStateListener = listener;
}

并在显示/隐藏键盘时调用它:

public void showCustomKeyboard( View v ) {
    mKeyboardView.setVisibility(View.VISIBLE);
    mKeyboardView.setEnabled(true);
    if( v!=null ) {
        mStateListener.OnDisplay(v, mKeyboardView);
        ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
}

public void hideCustomKeyboard() {
    mKeyboardView.setVisibility(View.GONE);
    mKeyboardView.setEnabled(false);
    mStateListener.OnHide(mKeyboardView);
}

最后我编辑了 MainActivity 中的参数:

@Override
public void OnDisplay(View currentview, KeyboardView currentKeyboard) {
    ScrollView mScroll = (ScrollView) findViewById(R.id.scroll_content);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT);
    params.addRule(RelativeLayout.ABOVE,  currentKeyboard.getId());
    mScroll.setLayoutParams(params);                
    mScroll.scrollTo(0, currentview.getBaseline()); //Scrolls to focused EditText

}

@Override
public void OnHide(KeyboardView currentKeyboard) {
    ScrollView mScroll = (ScrollView) findViewById(R.id.scroll_content);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);
    mScroll.setLayoutParams(params);

}

截图如下:

注意事项:

  • 我在 ScrollView 中使用 LinearLayout 而不是 RelativeLayout,因为当我的键盘显示时,ScrollView 会根据需要工作,但它会将最底部的 View 切成两半,并且在这种情况下填充或边距不适用于 RelativeLayout,但会添加一个paddingBottom 到 LinearLayout 将其推回并且所有 View 都可见。我找不到其他方法来解决这个问题。

  • 您应该尝试不同大小的填充来满足您的需求。

  • 如果您需要,我可以提供完整的源代码和其他信息。

关于android - 自定义键盘隐藏了 Android 中的编辑框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21097986/

有关android - 自定义键盘隐藏了 Android 中的编辑框的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. 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

  5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  6. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  7. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  8. 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

  9. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  10. 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,如果没有检查,请帮助我,非常感谢,谢谢

随机推荐