可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
So, I have a TextView like so:
<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" />
I use it as a sort of running log, displayed to the user so they can monitor progress of a task that takes about 3 minutes. However, once I go over 8 lines, the text goes off screen. This is unintuitive to the user because they have no way of knowing that it went off screen, other than to manually poll by trying scroll down.
How can I make it so that every time I add some text to this TextView I make it scroll down as low as it can go?
Also, this is in Xamarin Android, but I don't think it's relevant. It's easy to translate between it and Java
回答1:
As per answer here Making TextView Scrollable in Android
You don't need to use a ScrollView actually.
Just set the
android:maxLines = "AN_INTEGER"
android:scrollbars = "vertical"
properties of your TextView in your layout's xml file.
Then use:
yourTextView.setMovementMethod(new ScrollingMovementMethod());
in your code.
That will work..
回答2:
From your Code, two steps have to do:
Step 1
Although you code in Xamarin Android, but as in Java in the xxxActivity.java for terminalOutput invoke must be like this
TextView outputText = (TextView) findViewById(R.id.terminalOutput);
outputText.setMovementMethod(new ScrollingMovementMethod());
Method setMovementMethod() by parameter ScrollingMovementMethod() is the gimmick.
Step 2
And in the layout as in Java-Android also in activity_xxx.xml for the TextView Declaration as above must have to add this
android:gravity="bottom"
When you add new line into the outputText like this
outputText.append("\n"+"New text line.");
It will scroll to the last line automatically,
and these all the magic for your need.
回答3:
Had the same question. Tried several decisions from this and similar discussions, nothing worked. Solved it this way:
edtConsoleText.setSelection(edtConsoleText.getText().length());
after every .append()
.
回答4:
You can try in 2 solutions:
Put TextView in a 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>
Use custom scroll TextView (same as traditional TextView but it can scroll)
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;
}
}
How to use:
ScrollTextView scrolltext = (ScrollTextView) findViewById(R.id.YourTextView);
(ScrollTextView class source: http://bear-polka.blogspot.com/2009/01/scrolltextview-scrolling-textview-for.html)
回答5:
None of these answers were quite what I wanted, so I came up with this.
textView.append(log);
while (textView.canScrollVertically(1)) {
textView.scrollBy(0, 10);
}
Do not forget to set movement method before scrolling
textView.setMovementMethod(new ScrollingMovementMethod());
回答6:
From "How to scroll to bottom in a ScrollView on activity startup":
final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
@Override
public void run() {
scrollview.fullScroll(ScrollView.FOCUS_DOWN);
}
});
What you need is to put fullScroll()
after append operation.
回答7:
I am using Xmarin.
My solution is as many people mentioned, to textView inside a ScrollView.
If you want to see the new line at the bottom of the view, use
android:layout_gravity="bottom"
This keeps the new line at the bottom until you scroll the view. The view stays wherever you have scrolled.
No code is needed.
However, if you want the contents is always at bottom after appending, you need to add code after append():
myText.Append(...);
myscroll.FullScroll(FocusSearchDirection.Down);
回答8:
For me nothing worked perfectly except a combination of these two :-
- Setting
scroller.scrollTo(0, 70);
in your java class.Use it before setting your textview but after appending that String. 52 dp is the height of my device.You can find it out using scroller.getBottom()); So I used 70 to adjust for the scroll view.
- Setting
android:scrollY="30dp"
in your textview.