bug with soft keyboard in landscape mode

The soft keyboard in landscape mode corrupts the default text selection CAB.

Here is some code to reproduce the bug.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Foo</string>
    <string name="action_settings">Settings</string>
    <string name="select_me">Select Me</string>

</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.example.foo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="org.example.foo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="org.example.foo.MainActivity"
    tools:ignore="MergeRootFrame" />

fragment_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="org.example.foo.PlaceholderFragment" >

    <TextView
        android:id="@+id/tv"
        android:textIsSelectable="true"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:text="@string/select_me"
    />
    <EditText
        android:id="@+id/phrase"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:width="150dp"
        android:inputType="text"
        android:scrollHorizontally="true"/>
</LinearLayout>

MainActivity.java

package org.example.foo;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public static class PlaceholderFragment extends Fragment
    {
        public PlaceholderFragment()
        {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            return rootView;
        }
    }
}

So to reproduce the bug, follow these steps

  • 1) start app in portrait mode
  • 2) select the text in TextView, CAB shows as expected
  • 3) enter the EditText field to pop soft keyboard
  • 4) exit soft keyboard
  • 5) select the text in TextView, CAB shows as expected
  • 6) deselect the text
  • here's the bug

  • 7) flip to landscape
  • 8) select the text in TextView, CAB shows as expected
  • 9) enter the EditText field to pop soft keyboard
  • 10) exit soft keyboard
  • 11) select the text in TextView, CAB does not show as expected, instead you have the text highlighted
  • here's the proof it is the landscape mode that is bugged

  • 12) flip to portrait mode
  • 13) enter the EditText field to pop soft keyboard
  • 14) exit soft keyboard
  • 15) flip to landscape
  • 16) select the text in TextView, CAB shows as expected
  • so to be clear, when you enter a text field in landscape mode, the soft keyboard corrupts the default text selection CAB, regardless of whether you enter any text or not. Entering a text field in portrait mode resets the default text selection CAB, regardless of whether you enter any text or not.

    Note that you do not have to deselect the text when flipping back to portrait. Simply entering the soft keyboard in portrait mode, resets the default text selection CAB.

    I am currently experiencing this bug on a Huawei Y300-100 phone, running Android 4.1.1

    Unfortunately I cannot test it with a higher version in the emulator as it does weird things with landscape mode on linux, effectively providing no landscape but that's a whole different story.

    EDIT

    I have reported this bug to google, issue number 68443


    尝试在activity_main.xml的EditText选项中使用android:imeOptions = "flagNoFullscreen"


    I struggled with this for a day now and although this is over a year old, maybe i can save someone else the trouble. I just started with android development a few months ago so this might be total garbage. Anyway...

    android:imeOptions = "flagNoFullscreen" or "flagNoExtractUi" might solve the problem, although not an all devices i tested it on. It also disables the full screen text input that you might not be a desired behaviour.

    The following fix was only tested with Xamarin.Android but it should work on everything else in the same manner:

    The TextView widget has a private Editor mEditor; Field. You need to get a Reference to it (Reflection or JNI or any other weapon of your choice).

    To start the ActionMode manually, simply call <mEditor>.startSelectionActionMode() .

    Then you can call <mEditor>.getSelectionController().show() and <mEditor>.getSelectionController().hide() to make sure the textselection markers are drawn correctly.

    You should probably do this in an overridden onSelectionChanged(int start, int end) Method in a derived TextView/EditText.

    链接地址: http://www.djcxy.com/p/93028.html

    上一篇: 键盘放置掩盖了EditText下方的视图想要保持可见

    下一篇: 横向模式下软键盘的错误