androidandroid-edittextandroid-scrollviewhorizontalscrollviewfocusable

Android EditText text entry causing scroll


This is a similar problem to what I posted earlier - but different.

I have a HorizontalScrollView which contains 3 "pages". When my app starts up, I tell the scrollview to scroll one screen width so that the middle page is always displayed first. See below:

+------+------+------+
+  ET  +      +      +
+------+      +      +
+      +      +      +
+      +      +      +
+------+------+------+
       ^      ^

ET above represents an EditText view. In order to stop my scrollview from automatically scrolling to the leftmost page, I call setFocusable(false) on the EditText. This allows my app to stay on the central page.

When I scroll to the leftmost page, I call setFocusableInTouchMode(true) to allow entry of text in the EditText.

Now come the strange parts:

1) When I enter text on my tablet, the scrollview scrolls to the rightmost page. My tablet has a physical keyboard.

2) I remove the physical keyboard from my tablet. When I enter text on my tablet, the scrollview scrolls to the rightmost page as soon as the virual keyboard is displayed.

3) When I enter text on my phone, the scrollview remains on the leftmost page as it should. My phone displays the virtual keyboard when I tap on the EditText.

Why is my tablet doing this when my phone isn't? My tablet is older than my phone and obviously has an older version of Android but what's causing this behaviour and how do I stop it?

I would provide sample code but there's a lot to factor out. I'm not using an XML layout in this bit of code either. The rightmost page consists of buttons - the only EditText is on the leftmost page.

Update: If I remove the rightmost page, it still jumps to the second page instead of the leftmost. I don't seem to have any additional focusable views on that second page either.

Here's a simplified MainActivity.java which illustrates my problem. Note that it doesn't happen on my phone so I suspect it will only happen on certain Android versions. My tablet is running Android 4.2.1 and its an Asus Transformer Pad TF300TG.

package com.example.testscroll;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.widget.EditText;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ListView;

public class MainActivity extends Activity
{
  public HorizontalScrollView testScrollView;
  public int screenWidth, screenHeight;

  LinearLayout mLeftBaseLinearLayout;
  EditText     mEditText;
  ListView     mListView;

  TextWatcher mTextWatcher = new TextWatcher() 
  {
    @Override
    public void afterTextChanged( Editable s ) 
    {
      String sSimple = s.toString();
      System.out.printf(  "Text now[" + sSimple + "]\n" );
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after){}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count){}     
  };


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

    Point size = new Point();

    getWindowManager().getDefaultDisplay().getSize( size );

    screenWidth  = size.x;
    screenHeight = size.y;

    LinearLayout layout = new LinearLayout( this );
    layout.setLayoutParams( new LinearLayout.LayoutParams( 3 * screenWidth, LinearLayout.LayoutParams.MATCH_PARENT ) );
    layout.setOrientation( LinearLayout.HORIZONTAL );

    //-------- LEFT PAGE --------
    mLeftBaseLinearLayout = new LinearLayout( this );
    mLeftBaseLinearLayout.setLayoutParams( new LinearLayout.LayoutParams( screenWidth, screenHeight ) );
    mLeftBaseLinearLayout.setOrientation( LinearLayout.VERTICAL );
    mLeftBaseLinearLayout.setBackgroundColor( Color.TRANSPARENT );

    mEditText = new EditText( this );

    mEditText.setWidth( screenWidth );
    mEditText.setHeight( 20 );
    mEditText.setBackgroundColor( Color.DKGRAY );
    mEditText.setGravity( Gravity.CENTER );
    mEditText.setText( "" );
    mEditText.setTextColor( Color.YELLOW );
    mEditText.setTextSize( 30 );
    mEditText.setSingleLine();
    mEditText.setLayoutParams( new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT ) );

    //mEditText.setFocusable( false );
    mEditText.setFocusable( true );
    mEditText.addTextChangedListener( mTextWatcher );

    mListView = new ListView( this );
    mListView.setBackgroundColor( Color.WHITE );
    mListView.setLayoutParams( new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1 ) );

    //mLeftBaseLinearLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
    mLeftBaseLinearLayout.addView( mEditText );    
    mLeftBaseLinearLayout.addView( mListView );
    //-------    

    layout.addView( mLeftBaseLinearLayout );

    LinearLayout linLayout   = new LinearLayout( this );
    linLayout.setBackgroundColor( Color.GREEN );    
    linLayout.setLayoutParams( new LinearLayout.LayoutParams( 1280, LinearLayout.LayoutParams.MATCH_PARENT ) );
    layout.addView( linLayout );

    testScrollView     = new HorizontalScrollView( this );
    testScrollView.setLayoutParams( new LinearLayout.LayoutParams( 3 * screenWidth, LinearLayout.LayoutParams.MATCH_PARENT ) );
    testScrollView.addView( layout );

    setContentView( testScrollView );

    testScrollView.post( new Runnable() 
    { 
      public void run() 
      { 
        testScrollView.scrollTo( screenWidth, 0 );
      } 
    });    
  }
}

Solution

  • I found my solution - override scrollTo() and do absolutely nothing.