2

背景

我有一个类似表单的活动,它有一些可以在按下时动态创建的视图。

我为每个在单击按钮时膨胀的字段使用 xml。

我需要的是,在选择添加新项目时,它将获得焦点,如果需要滚动,并显示键盘,以便用户可以在其中输入内容。键盘可能会在添加字段或单击 EditText 时显示。

问题

出于某种原因,在某些设备上(我认为这甚至不是 android 版本问题)在为新视图充气时,其中的 editText 可以获得焦点但它不显示键盘,即使它有焦点并且用户点击它。

在这种情况下,显示键盘的唯一方法是单击另一个 EditText。

我已经对其进行了测试,并注意到当我根本不使用 xml 时它不会发生,这意味着当我只在代码中创建视图时。

问题

为什么会发生?我该怎么做才能修复它?

我已经尝试了很多可能的解决方案,但没有一个适用于所有设备。

示例代码

下一个代码在 xperia j (android 4.0.4) 和 Galaxy mini (android 2.3.6) 上有描述的问题。

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ViewGroup container = (ViewGroup) findViewById(R.id.LinearLayout1);
    final LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    findViewById(R.id.button).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(final View v) {
            final View view = inflater.inflate(R.layout.field, null);
            // using the next code works when using it instead of inflating a layout:
            // final EditText editText = new EditText(MainActivity.this);
            // editText.setText("item " + container.getChildCount());
            container.addView(view);
        }
    });
}

字段布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/RelativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFffffff"
    android:gravity="center_vertical" >

    <Spinner
        android:id="@+id/typeSpinner"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_centerVertical="true"
        android:background="@null"
        android:padding="5dp" />

    <include
        android:id="@+id/removeItemView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        layout="@layout/remove_item_view" />

    <EditText
        android:id="@+id/fieldEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/removeItemView"
        android:layout_toRightOf="@+id/typeSpinner"
        android:ems="10"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:hint="field"
        android:imeOptions="actionDone"
        android:inputType="phone"
        android:minWidth="200dp"
        android:padding="5dp"
        android:singleLine="true"
        tools:ignore="HardcodedText" >
    <requestFocus />
    </EditText>

</RelativeLayout>

主布局文件:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/LinearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="click"
            tools:ignore="HardcodedText" />
    </LinearLayout>

</ScrollView>

编辑:找到了一个不会立即显示键盘的部分解决方案,但至少在按下editText时会显示它:

public static void forceFocusOnView(final View view) {
    if (view == null)
        return;
    view.post(new Runnable() {
        @Override
        public void run() {
            view.clearFocus();
            view.post(new Runnable() {
                @Override
                public void run() {
                    view.requestFocus();
                }
            });
        }
    });
}
4

1 回答 1

0

我不确定这个问题的原因。当 Android sdk 被重写以匹配某些设备时,可能会出现一些不匹配。所以我认为对你来说最好的解决方案是手动显示你的键盘,不要试图移动火车,走阻力最小的路径:

EditText et=(EditText)this.findViewById(R.id.edit_text);
et.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                 imm.showSoftInput(et, 0);<----------------

        }
    });

给你,伙计。祝您好运。

哦,我懂了...

private EditText et;
private Runnable setFocus;
......
protected void onCreate(...){
.
.
.
 setFocus=new Runnable(){

                @Override
                public void run() {
                    et.requestFocus();

                }
            };
}
....
 findViewById(R.id.button).setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(final View v) {
        final View view = inflater.inflate(R.layout.field, null);
      //try this:
        et=(EditText)view.findViewById(r.id.fieldEditText);
et.setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
             imm.showSoftInput(et, 0);<----------------

    }
});
        container.addView(view);
        container.requestLayout();<--------------
        et.postDelayed(setFocus,300);
    }
});
于 2013-06-17T14:36:38.937 回答