web-dev-qa-db-fra.com

Comment faire défiler automatiquement un TextView lorsque j'ajoute plusieurs lignes de texte?

Donc, j'ai un TextView comme suit:

<TextView
    Android:layout_width="fill_parent"
    Android:layout_height="140.7dp"
    Android:id="@+id/terminalOutput"
    Android:layout_marginBottom="0.0dp"
    Android:scrollbars="vertical"
    Android:scrollbarAlwaysDrawVerticalTrack="true"
    Android:maxLines="8" />

Je l'utilise comme une sorte de journal en cours d'exécution, affiché à l'utilisateur afin qu'il puisse surveiller la progression d'une tâche qui prend environ 3 minutes. Cependant, une fois que je dépasse 8 lignes, le texte disparaît de l'écran. Ceci n’est pas intuitif pour l’utilisateur car il n’a aucun moyen de savoir qu’il est sorti de l’écran, si ce n’est d’interroger manuellement en essayant de faire défiler vers le bas. 

Comment puis-je faire en sorte que chaque fois que j'ajoute du texte à cet objet TextView, je le fais défiler aussi bas que possible? 

En outre, cela est dans Xamarin Android, mais je ne pense pas que ce soit pertinent. Il est facile de traduire entre cela et Java

30
Earlz

Selon la réponse ici Making TextView Scrollable in Android

Vous n'avez pas besoin d'utiliser un ScrollView en fait.

Il suffit de définir le

Android:maxLines = "AN_INTEGER"

Android: scrollbars = "vertical" propriétés de votre TextView dans le fichier XML de votre mise en page.

Alors utilisez:

yourTextView.setMovementMethod(new ScrollingMovementMethod());

dans votre code.

Ça marchera..

33
DarwinLouis

À partir de votre code, vous devez suivre deux étapes:

Étape 1

Bien que vous codiez dans Xamarin Android, mais comme dans Java dans xxxActivity.Java pour terminalOutput invoke doit être comme ceci

TextView outputText = (TextView) findViewById(R.id.terminalOutput);
outputText.setMovementMethod(new ScrollingMovementMethod());

La méthode setMovementMethod () par le paramètre ScrollingMovementMethod () est le gimmick.

Étape 2

Et dans la mise en page comme dans Java-Android, il faut aussi ajouter ceci à activity_xxx.xml pour la déclaration TextView, comme ci-dessus.

Android:gravity="bottom"

Quand vous ajoutez une nouvelle ligne dans le outputText comme ceci

outputText.append("\n"+"New text line.");

Il défilera automatiquement à la dernière ligne, et tout cela la magie pour votre besoin.

69
NOTSermsak

Avait la même question. J'ai essayé plusieurs décisions de cette discussion et de discussions similaires, mais rien n'a fonctionné. Résolu de cette façon:

edtConsoleText.setSelection(edtConsoleText.getText().length());

après chaque .append()

6
Alexander Marochko

Vous pouvez essayer 2 solutions:

  1. Mettre TextView dans un ScrollView

    <ScrollView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content">
            <TextView
            Android:id="@+id/TextView01"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Your Text" >
        </TextView>
    </ScrollView>
    
  2. Utiliser le défilement personnalisé TextView (identique au TextView traditionnel mais il peut défiler)

    import Android.content.Context;
    import Android.graphics.Rect;
    import Android.text.TextPaint;
    import Android.util.AttributeSet;
    import Android.view.animation.LinearInterpolator;
    import Android.widget.Scroller;
    import Android.widget.TextView;
    
     public class ScrollTextView extends TextView {
    
    
        // scrolling feature
        private Scroller mSlr;
    
        // milliseconds for a round of scrolling
        private int mRndDuration = 250;
    
        // the X offset when paused
        private int mXPaused = 0;
    
        // whether it's being paused
        private boolean mPaused = true;
    
        /*
         * constructor
         */
        public ScrollTextView(Context context) {
            this(context, null);
            // customize the TextView
            setSingleLine();
            setEllipsize(null);
            setVisibility(INVISIBLE);
        }
    
        /*
         * constructor
         */
        public ScrollTextView(Context context, AttributeSet attrs) {
            this(context, attrs, Android.R.attr.textViewStyle);
            // customize the TextView
            setSingleLine();
            setEllipsize(null);
            setVisibility(INVISIBLE);
        }
    
        /*
         * constructor
         */
        public ScrollTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // customize the TextView
            setSingleLine();
            setEllipsize(null);
            setVisibility(INVISIBLE);
        }
    
        /**
         * begin to scroll the text from the original position
         */
        public void startScroll() {
            // begin from the very right side
            mXPaused = -1 * getWidth();
            // assume it's paused
            mPaused = true;
            resumeScroll();
        }
    
        /**
         * resume the scroll from the pausing point
         */
        public void resumeScroll() {
    
            if (!mPaused)
                return;
    
            // Do not know why it would not scroll sometimes
            // if setHorizontallyScrolling is called in constructor.
            setHorizontallyScrolling(true);
    
            // use LinearInterpolator for steady scrolling
            mSlr = new Scroller(this.getContext(), new LinearInterpolator());
            setScroller(mSlr);
    
            int scrollingLen = calculateScrollingLen();
            int distance = scrollingLen - (getWidth() + mXPaused);
            int duration = (new Double(mRndDuration * distance * 1.00000
                    / scrollingLen)).intValue();
    
            setVisibility(VISIBLE);
            mSlr.startScroll(mXPaused, 0, distance, 0, duration);
            mPaused = false;
        }
    
        /**
         * calculate the scrolling length of the text in pixel
         * 
         * @return the scrolling length in pixels
         */
        private int calculateScrollingLen() {
            TextPaint tp = getPaint();
            Rect rect = new Rect();
            String strTxt = getText().toString();
            tp.getTextBounds(strTxt, 0, strTxt.length(), rect);
            int scrollingLen = rect.width() + getWidth();
            rect = null;
            return scrollingLen;
        }
    
        /**
         * pause scrolling the text
         */
        public void pauseScroll() {
            if (null == mSlr)
                return;
    
            if (mPaused)
                return;
    
            mPaused = true;
    
            // abortAnimation sets the current X to be the final X,
            // and sets isFinished to be true
            // so current position shall be saved
            mXPaused = mSlr.getCurrX();
    
            mSlr.abortAnimation();
        }
    
        @Override
        /*
         * override the computeScroll to restart scrolling when finished so as that
         * the text is scrolled forever
         */
        public void computeScroll() {
            super.computeScroll();
    
            if (null == mSlr)
                return;
    
            if (mSlr.isFinished() && (!mPaused)) {
                this.startScroll();
            }
        }
    
        public int getRndDuration() {
            return mRndDuration;
        }
    
        public void setRndDuration(int duration) {
            this.mRndDuration = duration;
        }
    
        public boolean isPaused() {
            return mPaused;
        }
     }
    

Comment utiliser:

ScrollTextView scrolltext = (ScrollTextView) findViewById(R.id.YourTextView);

(Source de la classe ScrollTextView: http://bear-polka.blogspot.com/2009/01/scrolltextview-scrolling-textview-for.html )

5
Truong Phu Quoc

Aucune de ces réponses ne correspondait exactement à ce que je voulais, alors je suis arrivé à cela.

textView.append(log);

while (textView.canScrollVertically(1)) {
    textView.scrollBy(0, 10);
}

N'oubliez pas de définir la méthode de déplacement avant de faire défiler

textView.setMovementMethod(new ScrollingMovementMethod());
5
dogauzun

De " Comment faire défiler vers le bas une ScrollView au démarrage de l’activité ":

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
  @Override
  public void run() {
    scrollview.fullScroll(ScrollView.FOCUS_DOWN);
  }
});

Ce dont vous avez besoin est de mettre fullScroll() après l'opération d'ajout.

2
Mansour

J'utilise Xmarin.

Ma solution est, comme beaucoup de gens l'ont mentionné, de textView à l'intérieur d'un ScrollView.

Si vous voulez voir la nouvelle ligne au bas de la vue, utilisez

Android:layout_gravity="bottom"

Cela garde la nouvelle ligne en bas jusqu'à ce que vous faites défiler la vue. La vue reste partout où vous avez fait défiler. 

Aucun code n'est requis.

Cependant, si vous voulez que le contenu soit toujours en bas après l'ajout, vous devez ajouter le code après append ():

myText.Append(...);

myscroll.FullScroll(FocusSearchDirection.Down);
2
Jim Oian

Pour moi, rien ne fonctionnait parfaitement, sauf une combinaison de ces deux: -

  • Paramétrez scroller.scrollTo(0, 70); dans votre classe Java. Utilisez-le avant de définir votre textview mais après avoir ajouté cette chaîne. 52 dp est la hauteur de mon appareil.Vous pouvez le trouver en utilisant scroller.getBottom ()); J'ai donc utilisé 70 pour ajuster l'affichage par défilement.
  • Paramétrer Android:scrollY="30dp" dans votre textview.
0
Surbhit Rao