以编程方式在ScrollView上滚动EditText

时间:2010-07-19 07:28:34

标签: android textview scrollview

我正在尝试制作一个放置在ScrollView中的不可编辑的EditText,并以编程方式控制滚动(当检测到左/右投掷时)。

好的,这是我简单的布局:

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

这是我的简单程序:

    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
        }

    }
}

因此,为了简单解释一下,我有两个自定义的simplegesture类,我附加到EditText和ScrollView。对于EditText,我正在尝试检测左/右投掷,当检测到时,我将其向上/向下滚动1页。附加到ScrollView的自定义simplegesture用于禁用手指滚动。

这是完成正确投掷后的屏幕截图: http://img830.imageshack.us/i/textcut.png/

我现在有点工作,但我有两个问题:

  1. 如何控制滚动以使线条不会“切断”(请参阅​​上图中屏幕上第一行有点“关闭”)。
  2. 为什么当我以编程方式向上/向下滚动页面时,EditText会自动全选(请参阅上图,滚动后整个屏幕变为橙色)?
  3. 为什么当我更改MyGestureDetector以检测Y轴上的投掷(垂直投掷)并以编程方式滚动EditText时,它不起作用?即使我在ScrollGestureDetector中进行了更改,它也无法工作。它与ScrollView的行为有关吗?
  4. 谢谢!

3 个答案:

答案 0 :(得分:1)

“3.以编程方式滚动EditText,它不起作用”

将带有滚动代码的Runnable发布到ScrollView,而不是直接调用滚动方法。

发布(Runnable动作)

  

使Runnable添加到消息队列中。 runnable将在。上运行   用户界面线程。

来自:ScrollView and programmatically scrolling

  

Lance Nanek

     

你可以使用过去的线程   挖出。基本上你必须给予   ScrollView有机会实现它   添加了一些东西。例如:
  scroll.post(new Runnable(){
  public void run(){
        scroll.fullScroll(ScrollView.FOCUS_DOWN);   }});

答案 1 :(得分:0)

将以下行添加到xml edittext控件,

android:scrollbars="vertical" android:fadeScrollbars="false"

然后将此留言添加到编码

"EditText Control Object".setMovementMethod(new ScrollingMovementMethod());

答案 2 :(得分:0)

它迟到但可能会帮助一个人解决这个问题.. 添加最后一个元素并为scrollView更新它需要大约200分钟,所以这肯定会有效。

void scrollDown()
{
    Thread scrollThread = new Thread(){
        public void run(){
            try {
                sleep(200);
                ChatActivity.this.runOnUiThread(new Runnable() {
                    public void run() {
                        myScrollView.fullScroll(View.FOCUS_DOWN);
                    }    
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    scrollThread.start();
}

在向scrollView添加元素后调用scrollDown();