views:

140

answers:

0

Hi there,

I am trying to make a non-editable EditText that is placed in a ScrollView and scrolling is controlled programmatically (when a left/right fling is detected).

Ok, here's my simple layout:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <ScrollView
        android:id="@+id/sv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <EditText android:id="@+id/maintext"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:longClickable="false"
            android:selectAllOnFocus="false"
            android:focusable="false"
            android:editable="false"/>
    </ScrollView>
</LinearLayout>

And here is my simple program:

    package com.test.testscroll;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Toast;

public class TestScroll extends Activity {
    private EditText mMainText;
    private ScrollView mScrollView;
    private GestureDetector gestureDetector; 
    View.OnTouchListener gestureListener; 
    private GestureDetector scrollGestureDetector;
    View.OnTouchListener scrollGestureListener;
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    private final String testString = "This is a very long line for testing purpose. Line number    1" +
    "This is a very long line for testing purpose. Line number  2" +
    "This is a very long line for testing purpose. Line number  3" +
    "This is a very long line for testing purpose. Line number  4" +
    "This is a very long line for testing purpose. Line number  5" +
    "This is a very long line for testing purpose. Line number  6" +
    "This is a very long line for testing purpose. Line number  7" +
    "This is a very long line for testing purpose. Line number  8" +
    "This is a very long line for testing purpose. Line number  9" +
    "This is a very long line for testing purpose. Line number  10" +
    "This is a very long line for testing purpose. Line number  11" +
    "This is a very long line for testing purpose. Line number  12" +
    "This is a very long line for testing purpose. Line number  13" +
    "This is a very long line for testing purpose. Line number  14" +
    "This is a very long line for testing purpose. Line number  15" +
    "This is a very long line for testing purpose. Line number  16" +
    "This is a very long line for testing purpose. Line number  17" +
    "This is a very long line for testing purpose. Line number  18" +
    "This is a very long line for testing purpose. Line number  19" +
    "This is a very long line for testing purpose. Line number  20" +
    "This is a very long line for testing purpose. Line number  21" +
    "This is a very long line for testing purpose. Line number  22" +
    "This is a very long line for testing purpose. Line number  23" +
    "This is a very long line for testing purpose. Line number  24" +
    "This is a very long line for testing purpose. Line number  25" +
    "This is a very long line for testing purpose. Line number  26" +
    "This is a very long line for testing purpose. Line number  27" +
    "This is a very long line for testing purpose. Line number  28" +
    "This is a very long line for testing purpose. Line number  29" +
    "This is a very long line for testing purpose. Line number  30" +
    "This is a very long line for testing purpose. Line number  31" +
    "This is a very long line for testing purpose. Line number  32" +
    "This is a very long line for testing purpose. Line number  33" +
    "This is a very long line for testing purpose. Line number  34" +
    "This is a very long line for testing purpose. Line number  35" +
    "This is a very long line for testing purpose. Line number  36" +
    "This is a very long line for testing purpose. Line number  37" +
    "This is a very long line for testing purpose. Line number  38" +
    "This is a very long line for testing purpose. Line number  39" +
    "This is a very long line for testing purpose. Line number  40" +
    "This is a very long line for testing purpose. Line number  41" +
    "This is a very long line for testing purpose. Line number  42" +
    "This is a very long line for testing purpose. Line number  43" +
    "This is a very long line for testing purpose. Line number  44" +
    "This is a very long line for testing purpose. Line number  45" +
    "This is a very long line for testing purpose. Line number  46" +
    "This is a very long line for testing purpose. Line number  47" +
    "This is a very long line for testing purpose. Line number  48" +
    "This is a very long line for testing purpose. Line number  49" +
    "This is a very long line for testing purpose. Line number  50";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mMainText = (EditText) findViewById(R.id.maintext);
        mScrollView = (ScrollView) findViewById(R.id.sv);
        mMainText.setText(testString);

     // Gesture detection 
        gestureDetector = new GestureDetector(new MyGestureDetector()); 
        gestureListener = new View.OnTouchListener() { 
            public boolean onTouch(View v, MotionEvent event) { 
                if (gestureDetector.onTouchEvent(event)) { 
                    return true; 
                } 
                return false; 
            } 
        }; 

        mMainText.setOnTouchListener(gestureListener);

        scrollGestureDetector = new GestureDetector(new ScrollGestureDetector()); 
        scrollGestureListener = new View.OnTouchListener() { 
            public boolean onTouch(View v, MotionEvent event) { 
                if (scrollGestureDetector.onTouchEvent(event)) { 
                    return true; 
                } 
                return false; 
            } 
        }; 

        mScrollView.setOnTouchListener(scrollGestureListener); 
    }

    class MyGestureDetector extends SimpleOnGestureListener { 
        @Override 
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
            try { 
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
                    return false; 
                // right to left swipe 
                if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
                    Toast.makeText(TestScroll.this, "Left Swipe", Toast.LENGTH_SHORT).show();
                    mScrollView.pageScroll(ScrollView.FOCUS_UP);
                    return true;
                }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
                    Toast.makeText(TestScroll.this, "Right Swipe", Toast.LENGTH_SHORT).show(); 
                    mScrollView.pageScroll(ScrollView.FOCUS_DOWN);
                    return true;
                } 
            } catch (Exception e) { 
                // nothing 
            } 
            return false; 
        }

    }

    class ScrollGestureDetector extends SimpleOnGestureListener { 
        @Override 
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
            return true; 
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e)
        {
            // Do nothing
        }

    }
}

So, to explain it simply, I have two custom simplegesture classes that I attached to the EditText and the ScrollView. For the EditText, I'm trying to detect a left/right fling and when detected, I'm scrolling the it up 1 page up/down. The custom simplegesture attached to the ScrollView is to disable finger scrolling.

Here's a screen shot after a right fling was done: http://img830.imageshack.us/i/textcut.png/

I kinda works right now but I have two questions:

  1. How do I control the scroll so that lines won't get "cut-off" (please refer to the picture above where the first line on the screen is a bit "cuf-off").
  2. Why when I scroll the page up/down programmatically, the EditText is auto select-all (please refer to the picture above where the whole screen turns orange after scrolling)?
  3. Why when I changed MyGestureDetector to detect fling on the Y-axis (vertical fling) and programmatically scroll the EditText, it doesnt' work? It wouldn't work even if I made the change in ScrollGestureDetector too. Does it have something to do with the behaviour of the ScrollView?

Thank you!