ChatGPT解决这个技术问题 Extra ChatGPT

使 TextView 在 Android 上可滚动

我在 TextView 中显示的文本似乎太长而无法放入一个屏幕。我需要让我的 TextView 可滚动。我怎样才能做到这一点?

这是代码:

final TextView tv = new TextView(this);
tv.setBackgroundResource(R.drawable.splash);
tv.setTypeface(face);
tv.setTextSize(18);
tv.setTextColor(R.color.BROWN);
tv.setGravity(Gravity.CENTER_VERTICAL| Gravity.CENTER_HORIZONTAL);
tv.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent e) {
        Random r = new Random();
        int i = r.nextInt(101);
        if (e.getAction() == e.ACTION_DOWN) {
            tv.setText(tips[i]);
            tv.setBackgroundResource(R.drawable.inner);
        }
        return true;
    }
});
setContentView(tv);

A
Amit Chintawar

您实际上不需要使用 ScrollView

只需设置

android:scrollbars = "vertical"

布局的 xml 文件中 TextView 的属性。

然后使用:

yourTextView.setMovementMethod(new ScrollingMovementMethod());

在你的代码中。

宾果游戏,它滚动!


但肯定 maxLines 要求您输入任意数字;这不是适用于每种屏幕尺寸和字体大小的东西吗?我发现用 ScrollView 包装它更简单,这意味着我不必添加任何其他 XML 属性或代码(如设置移动方法)。
@Christopher,ScrollView 也需要 'android:layout_height'。
@Regex:是的。要么让 ScrollView 占用所需的空间(例如通过 android:fillViewport 属性),要么设置所需的特定大小。不应该使用 maxLines 来设置 UI 元素的大小,所以这不是解决方案。
你不需要定义maxlines。剩下的。
澄清大家对“平滑”滚动的看法:如果您使用这种方法,滚动实际上是“平滑”的(因为您可以逐像素滚动),但它不是动态的。只要您移开手指,它就会立即停止滚动 - 没有轻弹。这对于现代 UI 来说是非常不可接受的,所以我将编辑答案以确保其他人不会在这个“解决方案”上浪费时间。
P
Peter Mortensen

这就是我纯粹在 XML 中所做的:

<?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/SCROLLER_ID"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:fillViewport="true">

        <TextView
            android:id="@+id/TEXT_STATUS_ID"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"/>
    </ScrollView>
</LinearLayout>

笔记:

android:fillViewport="true" 结合 android:layout_weight="1.0" 将使 textview 占用所有可用空间。定义滚动视图时,不要指定 android:layout_height="fill_parent" 否则滚动视图不起作用! (这让我刚才浪费了一个小时!FFS)。

专家提示:

要在附加文本后以编程方式滚动到底部,请使用以下命令:

mTextStatus = (TextView) findViewById(R.id.TEXT_STATUS_ID);
mScrollView = (ScrollView) findViewById(R.id.SCROLLER_ID);

private void scrollToBottom()
{
    mScrollView.post(new Runnable()
    {
        public void run()
        {
            mScrollView.smoothScrollTo(0, mTextStatus.getBottom());
        }
    });
}

无需使用 mTextView.getBottom(),只需使用方法 mScrollView.fullScroll(View.FOCUS_DOWN),因为它是 ScrollView API 的一部分。有关详细信息,请参阅 herehere
Android 警告 LinearLayoutScrollView 在此示例中可能无用(我完全删除了 LinearLayout)。它还警告说,对于 TextView,它应该是 android:layout_height="wrap_content" 以匹配 ScrollView。这些警告可能是由于自发布此答案以来已经过去了 3 年。无论如何,这个答案支持平滑滚动和轻弹...+1
在 xml 文件中的 ScrollView 上方添加 <!--suppress AndroidLintUselessParent --> 将处理这些警告。
在 Android API 级别 9 中,“专业提示”对我不起作用。文本视图在附加文本后保持滚动到顶部。
这种方法要好得多,使用公认的答案方法不会产生流畅的用户体验。
P
Peter Mortensen

真正需要的只是 setMovementMethod()。这是一个使用 LinearLayout 的示例。

文件 main.xml

<?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"
    >
<TextView
    android:id="@+id/tv1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="@string/hello"
    />
</LinearLayout>

文件 WordExtractTest.java

public class WordExtractTest extends Activity {

    TextView tv1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv1 = (TextView)findViewById(R.id.tv1);

        loadDoc();
    }

    private void loadDoc() {

        String s = "";

        for(int x=0; x<=100; x++) {
            s += "Line: " + String.valueOf(x) + "\n";
        }

        tv1.setMovementMethod(new ScrollingMovementMethod());

        tv1.setText(s);
    }
}

有没有办法在 XML 中设置这个属性?我想知道他们为什么会忽略这个选项。
它可以工作,但是滚动后有什么方法可以刷新它吗?我的意思是在滚动 TextView 后,我将更改其上的文本,但即使不需要,它的位置也会保持滚动。它的 bcose 以前我已经应用了滚动...
没有滚动条,与 ScrollView 方法相比,滚动很笨拙。
使用 StringBuilder 而不是 String...您所拥有的有点浪费。
这可行,但滚动不流畅。仍然有效,但谢谢。
K
Keith Smiley

让你的文本视图只是添加这个

TextView textview= (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(new ScrollingMovementMethod());

这不会进行动态滚动。不要使用这个。
@Timmmm 如何获得动能滚动?
您不希望对必须阅读的文本进行“动态滚动”。
P
Peter Mortensen

没有必要放入

android:Maxlines="AN_INTEGER"`

您只需添加以下内容即可完成您的工作:

android:scrollbars = "vertical"

并且,将此代码放入您的 Java 类中:

textview.setMovementMethod(new ScrollingMovementMethod());

比公认的解决方案要好得多,因为滚动条的大小完全适合文本,而且您不会浪费空间。
当我使用 ScrollView 作为父级时,它不起作用
我想知道 textview 是否垂直长...就像这里的讨论一样。但是如果我们想聚焦(显示)到位于...的文本的特定位置怎么办?它是否像在带有 ID #anchoring 的 html 中一样可用...?在android中... textview 这可能吗? @AhsanRaza
P
Peter Mortensen

你可以

用 ScrollView 包围 TextView;或将 Movement 方法设置为 ScrollingMovementMethod.getInstance();。


P
Peter Mortensen

我发现的最好方法:

将 TextView 替换为具有以下额外属性的 EditText:

android:background="@null"
android:editable="false"
android:cursorVisible="false"

无需包装在 ScrollView 中。


最好和最合适的答案很容易,特别是考虑到 EditText 是 TextView 子类,问题是如何使 textview 可滚动,而不是如何解决问题。如果可以的话,我会投票两次:)
@JustinBuser 不能再不同意了。 :) 这纯粹是偶然的,并且不能保证它会在未来的 Android 版本中使用。如果要滚动,请使用 Android 提供的滚动工具。 ScrollView 是正确的方法。
@Madbreaks 没有什么“意外”,EditText 是一个 TextView,带有一些添加的方法和覆盖,专门为适应不同长度的文本而定制。特别是 EditText 会覆盖 TextView getDefaultMovementMethod 函数的返回值。默认实现返回 NULL,EditText 基本上与所有其他答案的建议相同。就使用 Android 提供的工具而言,与这些答案中找到的任何其他方法相比,EditText 类被弃用的可能性要小得多。
@JustinBuser我的问题是你依赖于EditText的默认行为,这就是我的意思很可能会在未来发生变化(根本不会反对EditText)。您可以争辩说,但同样,这个想法是使用适合手头任务的组件和功能。 ScrollView 被明确设计为包含滚动。我总是尝试并且总是建议其他人使用正确的工具来完成这项工作。对于任何给定的编程问题,几乎总是有多种方法。无论如何,感谢您的周到回复。
9 年后仍在工作,所以我猜评论中的场景没有发生(还)
M
MBH

简单的。我是这样做的:

XML 端: Java 端:tv_log = (TextView) findViewById(R.id.tv_log); tv_log.setMovementMethod(new ScrollingMovementMethod());

奖金:

要让文本视图在文本填充时向下滚动,您必须添加:

    android:gravity="bottom"

到 TextView xml 文件。随着更多文本进入,它将自动向下滚动。

当然,您需要使用 append 函数而不是 set text 添加文本:

    tv_log.append("\n" + text);

我将它用于日志目的。

我希望这有帮助 ;)


P
Peter Mortensen

这是“如何将 ScrollBar 应用到您的 TextView”,仅使用 XML。

首先,您需要在 main.xml 文件中获取一个 Textview 控件并在其中写入一些文本......像这样:

<TextView
    android:id="@+id/TEXT"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="@string/long_text"/>

接下来,将文本视图控件放置在滚动视图之间以显示此文本的滚动条:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent">

    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_height="150px"
        android:layout_width="fill_parent">

        <TextView
            android:id="@+id/TEXT"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="@string/long_text"/>

    </ScrollView>
</RelativeLayout>

而已...


为什么还要写这个?这是一个几乎相同但不太正确的答案版本,该版本是在您编写答案之前 6 个月发布的。
R
Raluca Lucaci

在 kotlin 中用于使 textview 可滚动

myTextView.movementMethod= ScrollingMovementMethod()

并在 xml 中添加此属性

    android:scrollbars = "vertical"

I
IT-Dan

这将提供带有滚动条的平滑滚动文本。

ScrollView scroller = new ScrollView(this);
TextView tv = new TextView(this);
tv.setText(R.string.my_text);
scroller.addView(tv);

启用蓝色动画。最好的答案在这里海事组织。
C
Community

上面来自 Somewhere (Making TextView scrollable on Android) 的“专业提示”效果很好,但是,如果您将文本动态添加到 ScrollView 并希望在追加后自动滚动到底部 only当用户位于 ScrollView 的底部时? (也许是因为如果用户向上滚动阅读了一些您不想在追加期间自动重置到底部的内容,这会很烦人。)

无论如何,这里是:

if ((mTextStatus.getMeasuredHeight() - mScrollView.getScrollY()) <=
        (mScrollView.getHeight() + mTextStatus.getLineHeight())) {
    scrollToBottom();
}

mTextStatus.getLineHeight() 将使您不会在用户位于 ScrollView 末尾的一行内时使用 scrollToBottom()。


P
Peter Mortensen

如果您希望在 textview 中滚动文本,则可以按照以下步骤操作:

首先,您应该对 textview 进行子类化。

然后使用它。

以下是子类文本视图的示例。

public class AutoScrollableTextView extends TextView {

    public AutoScrollableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    public AutoScrollableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    public AutoScrollableTextView(Context context) {
        super(context);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

现在,您必须以这种方式在 XML 中使用它:

 <com.yourpackagename.AutoScrollableTextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="This is very very long text to be scrolled"
 />

而已。


P
Peter Mortensen

在 XML 的 textview 中添加以下内容。

android:scrollbars="vertical"

最后,添加

textView.setMovementMethod(new ScrollingMovementMethod());

在 Java 文件中。


这不会进行动态滚动。不要使用它。
M
Mori

如果你使用 Kotlin,这样:XML

 <TextView
            android:id="@+id/tvMore"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLines="3"
            android:scrollbars="vertical" />

活动

tvMore.movementMethod = ScrollingMovementMethod()

a
android.weasel

我没有发现 TextView 滚动以支持“轻弹”手势,它在向上或向下轻弹后继续滚动。我最终自己实现了它,因为出于各种原因我不想使用 ScrollView,而且似乎没有一个 MovementMethod 都允许我选择文本并单击链接。


soo...你是如何添加投掷手势的?
P
Peter Mortensen

完成可滚动后,在视图中输入任何内容时,将此行添加到视图的最后一行:

((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);

伙计,tablescroller 是一个由 id 属性从 XML 中处理的视图标识..你试试吧..它会正常工作..它对我有用..
J
Justin Buser

如果您不想使用 EditText 解决方案,那么您可能会有更好的运气:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.yourLayout);
    (TextView)findViewById(R.id.yourTextViewId).setMovementMethod(ArrowKeyMovementMethod.getInstance());
}

P
Peter Mortensen

将此添加到您的 XML 布局中:

android:ellipsize="marquee"
android:focusable="false"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="To Make An textView Scrollable Inside The TextView Using Marquee"

在代码中,您必须编写以下行:

textview.setSelected(true);
textView.setMovementMethod(new ScrollingMovementMethod());

这不会进行动态滚动。不要使用它。
我不想省略结尾文本。我该怎么做。
@SagarNayak 使用 android:ellipsize="none"
s
slfan
yourtextView.setMovementMethod(new ScrollingMovementMethod());

你现在可以滚动它。


这是 the accepted answer 已经说过的。 From Review
F
FoxDonut

我知道这是一篇较旧的帖子,但这就是我在 Java 方面处理问题的方式。

    // Allow textView to scroll
    tv.setSingleLine(true);
    tv.setHorizontallyScrolling(true);
    tv.setEllipsize(TextUtils.TruncateAt.MARQUEE);
    tv.setMarqueeRepeatLimit(-1); // Infinite
    // TextView must be 'selected'
    tv.setSelected(true);
    // Padding not necessary, but this helps so the text isn't right
    // up against the side of a screen/layout
    tv.setPadding(10, 0, 10, 0);

w
whitepearl

下面的代码创建了一个自动水平滚动的文本视图:

在将 TextView 添加到 xml 时使用

<TextView android:maxLines="1" 
          android:ellipsize="marquee"
          android:scrollHorizontally="true"/>

在 onCreate() 中设置 TextView 的以下属性

tv.setSelected(true);
tv.setHorizontallyScrolling(true); 

R
Rohit Mandiwal

我在 ScrollView 中使用 TextView 时遇到了这个问题。这个解决方案对我有用。

scrollView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                description.getParent().requestDisallowInterceptTouchEvent(false);

                return false;
            }
        });

        description.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                description.getParent().requestDisallowInterceptTouchEvent(true);

                return false;
            }
        });

L
Linh

像这样使用它

<TextView  
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:maxLines = "AN_INTEGER"
    android:scrollbars = "vertical"
/>

AN_INTEGER' 与属性 maxLines (attr) 整数 min=0 不兼容。
什么是 AN_INTEGER?
K
Khemraj Sharma

maxLinesscrollbars 放在 xml 中的 TextView 中。

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"
    android:maxLines="5" // any number of max line here.
    />

然后在java代码中。

textView.setMovementMethod(new ScrollingMovementMethod());


P
Prince Dholakiya

每当您需要使用 ScrollView 作为父级时,您还可以使用 TextView 的滚动移动方法。

当您从纵向到横向设备时,会出现一些问题。 (like) 整个页面是可滚动的,但滚动移动方法不起作用。

如果您仍然需要使用 ScrollView 作为父级或滚动移动方法,那么您也可以使用下面的 desc。

如果您没有任何问题,则使用 EditText 而不是 TextView

见下文 :

<EditText
     android:id="@+id/description_text_question"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@null"
     android:editable="false"
     android:cursorVisible="false"
     android:maxLines="6"/>

在这里,EditText 的行为类似于 TextView

您的问题将得到解决


r
rll

在我的情况下。Constraint Layout.AS 2.3。

代码实现:

YOUR_TEXTVIEW.setMovementMethod(new ScrollingMovementMethod());

XML:

android:scrollbars="vertical"
android:scrollIndicators="right|end"

P
Peter Mortensen

我为此苦苦挣扎了一个多星期,终于想出了如何使这项工作!

我的问题是一切都会像“块”一样滚动。文本本身是滚动的,但作为一个块而不是逐行滚动。这显然对我不起作用,因为它会切断底部的线条。以前的所有解决方案都不适合我,所以我自己制作了。

这是迄今为止最简单的解决方案:

在包中创建一个名为“PerfectScrollableTextView”的类文件,然后复制并粘贴此代码:

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.TextView;

public class PerfectScrollableTextView extends TextView {

    public PerfectScrollableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    public PerfectScrollableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    public PerfectScrollableTextView(Context context) {
        super(context);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

最后在 XML 中更改您的“TextView”:

来自:<TextView

收件人:<com.your_app_goes_here.PerfectScrollableTextView


100% 完美答案。我遇到了与您在描述中提到的相同的问题。应用许多解决方案,但不能完美地工作。但您的解决方案在任何情况下都能完美运行。节省我的时间:)谢谢
对我根本不起作用。根本没有滚动。其他解决方案的唯一问题是缺少动态滚动。看不到您的解决方案如何解决这个问题。
@Lothar 我不确定,这是 7 年前的事了,所以我相信很多事情都发生了变化,对此感到抱歉!
h
hash

XML - 您可以使用 android:scrollHorizontally 属性

是否允许文本比视图宽(因此可以水平滚动)。

可以是布尔值,例如“true”或“false”。

Prigramacaly - setHorizontallyScrolling(boolean)


m
mohamad sheikhi

尝试这个:

android:scrollbars = "vertical"