Search code examples
androidandroid-layoutandroid-softkeyboard

How do I change the cursor scroll behavior for an EditText?


I just made a super basic test where all I did was take the hello world sample template and add a multiline text object. The text object is at the bottom of the screen. When I enter multiple lines of text, and then move the cursor around, the entire screen scrolls downward, and so the soft keyboard starts to cover up the text box. I'm trying (in a more complex app but having this same issue, so hence using a basic test case) to have the behavior match the default messaging app: if you move the cursor, it doesn't pan the entire viewport, and will only scroll the text object as appropriate. It's easier to explain visually.

enter image description here

Here we have 3 lines, I'm about to scroll upward (doesn't matter if I use arrow keys or use the little teardrop selector thing).

enter image description here

Here I've grabbed the little selector teardrop thing and moved up 2 lines: notice that the entire window has scrolled down. I don't want that behavior. What I'm looking for is this from the default messaging app:

enter image description here

Notice how moving the cursor does not scroll the viewport. It doesn't scroll at all. If I had too much text to fit, it would instead just scroll the contents of the edit text as appropriate, and not scroll anything else.

How do i get that behavior? In case it matters, for this simple test here's what the layout looks like.

enter image description here

Edit: as per request, I'm posting the xml and java. Note that this is just the default Android Studio hello world project with an edittext added. AndroidManifest.xml:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.jeffw.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.jeffw.myapplication.MainActivity"
    tools:showIn="@layout/activity_main">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.529"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.705" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="363dp"
        android:layout_height="109dp"
        android:layout_marginTop="8dp"
        android:ems="10"
        android:inputType="textMultiLine"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        tools:layout_editor_absoluteX="11dp" />
</android.support.constraint.ConstraintLayout>

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.jeffw.myapplication.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

And the java code:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Solution

  • To achieve this behavior you should add this android:windowSoftInputMode="adjustPan" and android:isScrollContainer="true" to your activity in manifest file.

    For more details you can review developers documents. https://developer.android.com/guide/topics/manifest/activity-element.html#wsoft

    Update

    Update this to your manifest android:windowSoftInputMode="adjustResize|stateHidden".. I have used RelativeLayout instead of android.support.constraint.ConstraintLayout and it is working fine for me.