Android中文本行的垂直滚动

Android中文本行的垂直滚动,android,text,scroller,Android,Text,Scroller,我已经从Android Note Pad示例代码中实现了编辑器代码。现在我想添加垂直滚动文本行的功能。我想完成的一个例子是在ANDROID中快速滚动选项行 我在谷歌上搜索了scroller和fling的例子,但我找不到任何适合我需要的东西。我还没有找到哪怕是一点点符合我正在尝试做的事情 我用鲜血、汗水和眼泪找到了问题的答案。我会把它贴在这里,希望它能帮助其他人。以下方法放置在Android Note Pad示例代码中的LinedEditText类中 =======================

我已经从Android Note Pad示例代码中实现了编辑器代码。现在我想添加垂直滚动文本行的功能。我想完成的一个例子是在ANDROID中快速滚动选项行


我在谷歌上搜索了scroller和fling的例子,但我找不到任何适合我需要的东西。我还没有找到哪怕是一点点符合我正在尝试做的事情

我用鲜血、汗水和眼泪找到了问题的答案。我会把它贴在这里,希望它能帮助其他人。以下方法放置在Android Note Pad示例代码中的LinedEditText类中

============================

    public void InitScroller(Context context) {
        mScroller = new Scroller(context);       // Get a scroller object
        mScrollY = 0 ;                          // Set beginning of program as top of screen.
        mMinScroll = getLineHeight ()/2;            // Set minimum scroll distance
        mFlingV = 750;                         // Minimum fling velocity

    }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
     super.onTouchEvent(event);

  if (mVelocityTracker == null) {                       // If we do not have velocity tracker
         mVelocityTracker = VelocityTracker.obtain();   // then get one
     }
     mVelocityTracker.addMovement(event);               // add this movement to it

  final int action = event.getAction();  // Get action type
  final float y = event.getY();          // Get the displacement for the action

  switch (action) {

     case MotionEvent.ACTION_DOWN:          // User has touched screen
         if (!mScroller.isFinished()) {     // If scrolling, then stop now
             mScroller.abortAnimation();
         }
         mLastMotionY = y;                  // Save start (or end) of motion
         mScrollY = this.getScrollY();              // Save where we ended up
         mText.setCursorVisible (true);
         didMove = false;

         break;

     case MotionEvent.ACTION_MOVE:          // The user finger is on the move
         didMove = true;
         final int deltaY = (int) (mLastMotionY - y);  // Calculate distance moved since last report
         mLastMotionY = y;                             // Save the start of this motion

         if (deltaY < 0) {                              // If user is moving finger up screen
             if (mScrollY > 0) {                        // and we are not at top of text
                 int m = mScrollY - mMinScroll;         // Do not go beyond top of text
                 if (m < 0){
                     m = mScrollY; 
                 }else m = mMinScroll;

              scrollBy(0, -m);                           // Scroll the text up
             }
         } else 
             if (deltaY > 0) {                           // The user finger is moving up
                 int max = getLineCount() * getLineHeight () - sHeight;   // Set max up value
                 if (mScrollY < max-mMinScroll){
                     scrollBy(0, mMinScroll);           // Scroll up
                 }
             }
         postInvalidate();
         break;

     case MotionEvent.ACTION_UP:                       // User finger lifted up
         final VelocityTracker velocityTracker = mVelocityTracker;      // Find out how fast the finger was moving
         velocityTracker.computeCurrentVelocity(mFlingV);          
         int velocityY = (int) velocityTracker.getYVelocity();

         if (Math.abs(velocityY) > mFlingV){                                // if the velocity exceeds threshold
             int maxY = getLineCount() * getLineHeight () - sHeight;        // calculate maximum Y movement
             mScroller.fling(0, mScrollY, 0, -velocityY, 0, 0, 0, maxY);    // Do the filng
         }else{
             if (mVelocityTracker != null) {                                // If the velocity less than threshold
                 mVelocityTracker.recycle();                                // recycle the tracker
                 mVelocityTracker = null;
             }
         }
         break;
     }

     mScrollY = this.getScrollY();              // Save where we ended up

  return true ;                                 // Tell caller we handled the move event
 }



 public void computeScroll() {                  // Called while flinging to execute a fling step
     if (mScroller.computeScrollOffset()) {      
         mScrollY = mScroller.getCurrY();       // Get where we should scroll to 
         scrollTo(0, mScrollY);                 // and do it
         postInvalidate();                      // the redraw the sreem
     }
 }
public void InitScroller(上下文){
mScroller=新滚动条(上下文);//获取滚动条对象
mScrollY=0;//将程序开头设置为屏幕顶部。
mMinScroll=getLineHeight()/2;//设置最小滚动距离
mFlingV=750;//最小投掷速度
}
@凌驾
公共布尔onTouchEvent(运动事件){
超级事件(事件);
如果(mVelocityTracker==null){//如果我们没有速度跟踪器
mVelocityTracker=VelocityTracker.get();//然后获取一个
}
mVelocityTracker.addMovement(event);//将此移动添加到其中
final int action=event.getAction();//获取操作类型
final float y=event.getY();//获取操作的位移
开关(动作){
case MotionEvent.ACTION_DOWN://用户已触屏
如果(!mScroller.isFinished()){//如果正在滚动,请立即停止
mScroller.abortAnimation();
}
mLastMotionY=y;//保存运动的开始(或结束)
mScrollY=this.getScrollY();//保存我们结束的地方
mText.setCursorVisible(true);
didMove=false;
打破
case MotionEvent.ACTION_MOVE://用户手指正在移动
didMove=true;
final int deltaY=(int)(mLastMotionY-y);//计算自上次报告以来移动的距离
mLastMotionY=y;//保存此运动的开始
if(deltaY<0){//if用户正在向上移动手指屏幕
如果(mScrollY>0){//并且我们不在文本顶部
int m=mScrollY-mMinScroll;//不要超出文本顶部
if(m<0){
m=mScrollY;
}否则m=mMinScroll;
滚动(0,-m);//向上滚动文本
}
}否则
如果(deltaY>0){//用户手指向上移动
int max=getLineCount()*getLineHeight()-sHeight;//设置最大值
如果(mScrollY<最大mMinScroll){
滚动(0,mMinScroll);//向上滚动
}
}
后验证();
打破
case MotionEvent.ACTION_UP://用户举起手指
final VelocityTracker VelocityTracker=mVelocityTracker;//找出手指移动的速度
velocityTracker.computeCurrentVelocity(mFlingV);
int-velocityY=(int)velocityTracker.getYVelocity();
如果(Math.abs(velocityY)>mFlingV){//如果速度超过阈值
int maxY=getLineCount()*getLineHeight()-sHeight;//计算最大Y移动
mscroll.fling(0,mScrollY,0,-velocityY,0,0,0,maxY);//进行填充
}否则{
如果(mVelocityTracker!=null){//如果速度小于阈值
mVelocityTracker.recycle();//回收跟踪程序
mVelocityTracker=null;
}
}
打破
}
mScrollY=this.getScrollY();//保存我们结束的地方
return true;//告诉调用方我们已处理移动事件
}
public void computeScroll(){//在抛出时调用以执行抛出步骤
如果(mScroller.computeScrollOffset()){
mScrollY=mscroll.getCurrY();//获取我们应该滚动到的位置
滚动到(0,mScrollY);//然后执行
postInvalidate();//重新绘制sreem
}
}

这是一个更简单的版本,在scoller级别上基本相同。它不是完美的,但它提供了另一种看待它的方式

final TextView textview = ((TextView) VIEW.findViewById(R.id.text));
final Scroller scroller = new Scroller(CONTEXT);

textview.setText(TEXT);
textview.setMovementMethod(new ScrollingMovementMethod());
textview.setScroller(scroller);
textview.setOnTouchListener(new View.OnTouchListener() {

    // Could make this a field member on your activity
    GestureDetector gesture = new GestureDetector(CONTEXT, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            scroller.fling(0, textview.getScrollY(), 0, (int)-velocityY, 0, 0, 0, (textview.getLineCount() * textview.getLineHeight()));
            return super.onFling(e1, e2, velocityX, velocityY);
        }

    });

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        gesture.onTouchEvent(event);
        return false;
    }
});

最后一个方法computerScroll()前面需要一个@Override。这里的发帖软件确实知道如何处理在那里的问题。你能确认一下屏幕的高度吗?