Вертикальная прокрутка текстовой строки в Android

Я реализовал код редактора из примера кода Android Note Pad. Теперь я хотел бы добавить возможность вертикальной прокрутки прокрутки строк текста. Примером того, чего я хочу достичь, является прокрутка строк опций в Андориде.

Я гуглил примеры скроллера и флинга, но не могу найти ничего подходящего для того, что мне нужно. Я не нашел ничего, что хотя бы отдаленно соответствовало тому, что я пытаюсь сделать.

2 ответа

Решение

Я разработал ответ на свой вопрос через кровь, пот и слезы. Я опубликую это здесь в надежде, что это поможет кому-то еще. Следующие методы размещены в классе LinedEditText из примера кода Android Note Pad.

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

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

Это более простая версия, которая в основном одинакова на уровне 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;
    }
});
Другие вопросы по тегам