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:
- 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").
- 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)?
- 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!
Add below lines to xml edittext control,
and then add this liens to coding
Its late but may help some one with this issue.. It takes around 200 miniseconds to add the last element and update it for a scrollView so this will surely work.
Just call
scrollDown();
after adding element to scrollView."3. programmatically scroll the EditText, it doesnt' work"
Post a Runnable with scrolling code to ScrollView instead of calling scrolling methods directly.
post (Runnable action)
from: ScrollView and programmatically scrolling