Peter
Peter

Reputation: 66

Android - 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

here's the bug

here's the proof it is the landscape mode that is bugged

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

Upvotes: 1

Views: 2415

Answers (2)

Markus Dietrich
Markus Dietrich

Reputation: 618

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.

Upvotes: 0

kerosene
kerosene

Reputation: 31

Try to use android:imeOptions = "flagNoFullscreen" in your EditText options in activity_main.xml.

Upvotes: 2

Related Questions