动态 Textview 滚动条不显示

Dynamic Textview scrollbar not showing

我动态创建了一个 textview 并希望使其可滚动。

final RelativeLayout.LayoutParams params = parseLayoutParams(
                frameMargins, context);
tv.setText(Utility.getpropertyString(controls.getText()));
final String textColor = Utility.getpropertyString(controls.getTextcolor());
tv.setTextColor(Color.parseColor(textColor));
tv.setTextSize(12);
tv.setGravity(Gravity.CENTER_VERTICAL);
tv.setTextSize(tSize);
tv.setEllipsize(TextUtils.TruncateAt.END);
tv.setMaxLines(controls.getMaxlines());
tv.setTag(controls.getTagId());
tv.setLayoutParams(params);
tv.setEllipsize(TextUtils.TruncateAt.END);
tv.setVisibility(controls.getVisibility());
tv.setVerticalScrollBarEnabled(isScrollable);
tv.setScroller(new Scroller(context));
tv.setMovementMethod(new ScrollingMovementMethod());         
tv.setScrollBarFadeDuration(0);

但是无论是不滚动还是滚动时,我都无法在 textview 中看到滚动条。请帮忙!

从 Api 21 开始,View 滚动条可见性仅保留给 xml 布局,因为一个名为 initializaScrollBars 的重要功能由于传递 TypeArray 时出现问题而被删除变量作为参数。

因此,要以编程方式完成您需要的操作,您可以这样做

创建一个名为 scrolltextview.xml

的 xml 布局
<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"/>

现在,以编程方式创建它

    TextView tv = (TextView) LayoutInflater.from(this).inflate(R.layout.scrolltextview, null, false);
    // now decorate it as your needs
    tv.setText(m);
    tv.setTextColor(Color.BLUE);
    tv.setTextSize(23);
    ...
    tv.setMovementMethod(new ScrollingMovementMethod());

    // this is needed only if you want to show scrollbar also when text is not scrolling
    tv.setScrollBarFadeDuration(0);
    // thecontainer = the layout you want to add your new textview
    thecontainer.addView(tv);

正如 Ferran 指出的那样,initializeScrollBars() 已被删除。有关错误报告及其删除的理由,请参阅 here。据我所知,没有其他严格的编程方式可以为视图指定 scollbars。所有路径都经过 XML。 :-(

我认为 Ferran 的回答是一个很好的方法:它有效,易于理解并且应该易于记录。但是,还有其他方法可以在样式的轻微帮助下以编程方式创建带有滚动条的 TextView

对于API 21岁及以上
定义一个名为 "ViewWithScrollBars" 的样式如下:

<style name="ViewWithScrollbars">
    <item name="android:scrollbars">vertical</item>
</style>

我们现在可以使用 TextView 的 four-argument 构造函数来应用样式。

TextView tv = new TextView(this, null, 0, R.style.ViewWithScrollbars);

此方法将创建一个带有滚动条的 TextView。然而,至少有一个警告。当使用单个参数

创建 TextView
new TextView(Context)

构造函数通过添加额外参数的其他构造函数进行伸缩。这些构造函数之一定义如下:

public TextView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.textViewStyle);
}

第三个参数 com.android.internal.R.attr.textViewStyle 是一个 Android 内部样式,它将从主题中获取默认的 textViewStyle。我建议的调用对第三个参数使用零,因此不会应用主题中定义的任何 textViewStyle

合理的解决方法可能是执行以下操作:

tv = new TextView(this, null, android.R.attr.textViewStyle, R.style.ViewWithScrollbars);

不幸的是,如果主题中定义了第三个参数(defStyleAttr),那么第四个参数(defStyleRes)就不会被使用.因此,滚动条不会出现。

如果您使用 textViewStyle 则您将不得不进行调整或仅使用以下方法。

所有APIs
使用上面的样式 "ViewWithScrollBars",我们可以定义一个 ContextThemeWrapper,它将滚动条安装到将用于创建 TextView.[=21= 的主题中]

ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.ViewWithScrollbars); // "this" is the Activity
tv = new TextView(ctw);

我建议您阅读 Chris Banes 的一篇题为 "Theme vs Style" 的文章,其中解释了主题叠加的工作原理。

下面将所有这些放在一起。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = new TextView(this);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            // This will actually work for API 21 and above.
            ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.ViewWithScrollbars);
            tv = new TextView(ctw);
        } else {
            tv = new TextView(this, null, 0, R.style.ViewWithScrollbars);
        }
        tv.setText(R.string.lorem);
        tv.setTextColor(Color.parseColor("red"));
        tv.setTextSize(12);
        tv.setGravity(Gravity.CENTER_VERTICAL);
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
        tv.setEllipsize(TextUtils.TruncateAt.END);
        tv.setMaxLines(7);
        tv.setTag(View.generateViewId());
        RelativeLayout.LayoutParams params =
                new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
                        RelativeLayout.LayoutParams.WRAP_CONTENT);
        tv.setLayoutParams(params);
        tv.setEllipsize(TextUtils.TruncateAt.END);
        tv.setVisibility(View.VISIBLE);
        tv.setVerticalScrollBarEnabled(true);
        tv.setScroller(new Scroller(this));
        tv.setMovementMethod(new ScrollingMovementMethod());
        tv.setScrollBarFadeDuration(0);
        ((RelativeLayout) findViewById(R.id.layout)).addView(tv);
    }

}