- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道是否有一种简单的方法可以在没有换行或重叠的情况下自动调整 TextView 中的文本大小以适应其可用空间(垂直和水平)。我的目标是在任何设备上使文本尽可能大。这应该适用于横向和纵向。
我几乎可以正常工作(仅在纵向模式下),它看起来像这样:
简化的 javacode:
public class MainActivity extends Activity{
private TextView mTV_veryTop;
private TextView mTV_top;
private TextView mTV_middle;
private TextView mTV_bottomLeft;
private TextView mTV_bottomRight;
private Boolean resized = false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.cockpit_layout);
mTV_veryTop = (TextView) findViewById(R.id.veryTop);
mTV_top = (TextView) findViewById(R.id.top);
mTV_middle = (TextView) findViewById(R.id.middle);
mTV_bottomLeft = (TextView) findViewById(R.id.bottomLeft);
mTV_bottomRight = (TextView) findViewById(R.id.bottomRight);
}
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
if (resized == false)
{
shrinkTextToFit(mTV_veryTop.getWidth(), mTV_veryTop, 300, 10);
shrinkTextToFit(mTV_top.getWidth(), mTV_top, 300, 10);
shrinkTextToFit(mTV_middle.getWidth(), mTV_middle, 300, 10);
shrinkTextToFit(mTV_bottomLeft.getWidth(),mTV_bottomLeft, 300, 10);
shrinkTextToFit(mTV_bottomRight.getWidth(), mTV_bottomRight, 300, 10);
resized = true;
}
}
public static void shrinkTextToFit(float availableWidth, TextView textView, float startingTextSize, float minimumTextSize)
{
CharSequence text = textView.getText();
float textSize = startingTextSize;
textView.setTextSize(startingTextSize);
while (text != (TextUtils.ellipsize(text, textView.getPaint(), availableWidth, TextUtils.TruncateAt.END)))
{
textSize -= 1;
if (textSize < minimumTextSize)
{
break;
}
else
{
textView.setTextSize(textSize);
}
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" >
<TextView
android:id="@+id/veryTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="very top"
android:textColor="@android:color/white"
android:textSize="500dp" >
</TextView>
<TextView
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="5"
android:gravity="center"
android:text="top"
android:textColor="@android:color/white"
android:textSize="500dp" />
<TextView
android:id="@+id/middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="middle"
android:text="N.A."
android:textColor="@android:color/white"
android:textSize="500dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="horizontal" >
<TextView
android:id="@+id/bottomLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="5"
android:gravity="center"
android:text="bottom left"
android:textColor="@android:color/white"
android:textSize="500dp" >
</TextView>
<TextView
android:id="@+id/bottomRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="5"
android:gravity="center"
android:text="bottom right"
android:textColor="@android:color/white"
android:textSize="500dp" >
</TextView>
</LinearLayout>
</LinearLayout>
.......但这在风景中不起作用,甚至在肖像中也不完美(底部缺少一些像素)
我读过几篇这样的文章:
How to scale/resize text to fit a TextView?
Auto Scale TextView Text to Fit within Bounds
......并尝试了不同的方法/textView 类,但总有一些无法满足我的需要。
有什么帮助吗?
更新:
我不知道为什么我的问题被否决了,因为要找到一个类/ TextView (在“百万库”下)来满足我的所有要求并不容易。这是我需要的所有类(class)(可能对某人有帮助):
public class AutoResizeTextview extends TextView
{
private interface SizeTester
{
/**
*
* @param suggestedSize
* Size of text to be tested
* @param availableSpace
* available space in which text must fit
* @return an integer < 0 if after applying {@code suggestedSize} to
* text, it takes less space than {@code availableSpace}, > 0
* otherwise
*/
public int onTestSize(int suggestedSize, RectF availableSpace);
}
private RectF mTextRect = new RectF();
private RectF mAvailableSpaceRect;
private SparseIntArray mTextCachedSizes;
private TextPaint mPaint;
private float mMaxTextSize;
private float mSpacingMult = 1.0f;
private float mSpacingAdd = 0.0f;
private float mMinTextSize = 3;
private int mWidthLimit;
private static final int NO_LINE_LIMIT = -1;
private int mMaxLines;
private boolean mEnableSizeCache = true;
private boolean mInitiallized;
public AutoResizeTextview(Context context)
{
super(context);
initialize();
}
public AutoResizeTextview(Context context, AttributeSet attrs)
{
super(context, attrs);
initialize();
}
public AutoResizeTextview(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
initialize();
}
private void initialize()
{
mPaint = new TextPaint(getPaint());
mMaxTextSize = getTextSize();
mAvailableSpaceRect = new RectF();
mTextCachedSizes = new SparseIntArray();
if (mMaxLines == 0)
{
// no value was assigned during construction
mMaxLines = NO_LINE_LIMIT;
}
mInitiallized = true;
}
@Override
public void setText(final CharSequence text, BufferType type)
{
super.setText(text, type);
adjustTextSize(text.toString());
}
@Override
public void setTextSize(float size)
{
mMaxTextSize = size;
mTextCachedSizes.clear();
adjustTextSize(getText().toString());
}
@Override
public void setMaxLines(int maxlines)
{
super.setMaxLines(maxlines);
mMaxLines = maxlines;
reAdjust();
}
public int getMaxLines()
{
return mMaxLines;
}
@Override
public void setSingleLine()
{
super.setSingleLine();
mMaxLines = 1;
reAdjust();
}
@Override
public void setSingleLine(boolean singleLine)
{
super.setSingleLine(singleLine);
if (singleLine)
{
mMaxLines = 1;
}
else
{
mMaxLines = NO_LINE_LIMIT;
}
reAdjust();
}
@Override
public void setLines(int lines)
{
super.setLines(lines);
mMaxLines = lines;
reAdjust();
}
@Override
public void setTextSize(int unit, float size)
{
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
mMaxTextSize = TypedValue.applyDimension(unit, size, r.getDisplayMetrics());
mTextCachedSizes.clear();
adjustTextSize(getText().toString());
}
@Override
public void setLineSpacing(float add, float mult)
{
super.setLineSpacing(add, mult);
mSpacingMult = mult;
mSpacingAdd = add;
}
/**
* Set the lower text size limit and invalidate the view
*
* @param minTextSize
*/
public void setMinTextSize(float minTextSize)
{
mMinTextSize = minTextSize;
reAdjust();
}
private void reAdjust()
{
adjustTextSize(getText().toString());
}
private void adjustTextSize(String string)
{
if (!mInitiallized)
{
return;
}
int startSize = (int) mMinTextSize;
int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom() - getCompoundPaddingTop();
mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
mAvailableSpaceRect.right = mWidthLimit;
mAvailableSpaceRect.bottom = heightLimit;
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, efficientTextSizeSearch(startSize, (int) mMaxTextSize, mSizeTester, mAvailableSpaceRect));
}
private final SizeTester mSizeTester = new SizeTester()
{
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public int onTestSize(int suggestedSize, RectF availableSPace)
{
mPaint.setTextSize(suggestedSize);
String text = getText().toString();
boolean singleline = getMaxLines() == 1;
// if (singleline) { //my comment-out
// mTextRect.bottom = mPaint.getFontSpacing(); //my comment-out
// mTextRect.right = mPaint.measureText(text); //my comment-out
// } else { //my comment-out
StaticLayout layout = new StaticLayout(text, mPaint, mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult,
mSpacingAdd, true);
// return early if we have more lines
if (getMaxLines() != NO_LINE_LIMIT && layout.getLineCount() > getMaxLines())
{
return 1;
}
mTextRect.bottom = layout.getHeight();
int maxWidth = -1;
for (int i = 0; i < layout.getLineCount(); i++)
{
if (maxWidth < layout.getLineWidth(i))
{
maxWidth = (int) layout.getLineWidth(i);
}
}
mTextRect.right = maxWidth;
// } //my comment-out
mTextRect.offsetTo(0, 0);
if (availableSPace.contains(mTextRect))
{
// may be too small, don't worry we will find the best match
return -1;
}
else
{
// too big
return 1;
}
}
};
/**
* Enables or disables size caching, enabling it will improve performance
* where you are animating a value inside TextView. This stores the font
* size against getText().length() Be careful though while enabling it as 0
* takes more space than 1 on some fonts and so on.
*
* @param enable
* enable font size caching
*/
public void enableSizeCache(boolean enable)
{
mEnableSizeCache = enable;
mTextCachedSizes.clear();
adjustTextSize(getText().toString());
}
private int efficientTextSizeSearch(int start, int end, SizeTester sizeTester, RectF availableSpace)
{
if (!mEnableSizeCache)
{
return binarySearch(start, end, sizeTester, availableSpace);
}
String text = getText().toString();
int key = text == null ? 0 : text.length();
int size = mTextCachedSizes.get(key);
if (size != 0)
{
return size;
}
size = binarySearch(start, end, sizeTester, availableSpace);
mTextCachedSizes.put(key, size);
return size;
}
private static int binarySearch(int start, int end, SizeTester sizeTester, RectF availableSpace)
{
int lastBest = start;
int lo = start;
int hi = end - 1;
int mid = 0;
while (lo <= hi)
{
mid = (lo + hi) >>> 1;
int midValCmp = sizeTester.onTestSize(mid, availableSpace);
if (midValCmp < 0)
{
lastBest = lo;
lo = mid + 1;
}
else
if (midValCmp > 0)
{
hi = mid - 1;
lastBest = hi;
}
else
{
return mid;
}
}
// make sure to return last best
// this is what should always be returned
return lastBest;
}
@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after)
{
super.onTextChanged(text, start, before, after);
reAdjust();
}
@Override
protected void onSizeChanged(int width, int height, int oldwidth, int oldheight)
{
mTextCachedSizes.clear();
super.onSizeChanged(width, height, oldwidth, oldheight);
if (width != oldwidth || height != oldheight)
{
reAdjust();
}
}
}
最佳答案
已经有大约一百万个图书馆提供此服务。查看它们的实现,或者直接使用它。
https://github.com/grantland/android-autofittextview
https://bitbucket.org/ankri/autoscaletextview/src
Google 上的 5 秒给了我这些。
关于android - 如何自动调整 TextView 中的文本大小以适应垂直和水平可用空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25556718/
我遇到了问题,似乎无法解决。 基本上,我希望我的菜单和文本随着分辨率的变化/放大/缩小而调整大小;图片工作正常,内容 div 工作正常,只是菜单似乎无法适应。 请帮我解决这个问题.. 普通 View
我在map reduce上开发了大约20个工作,包括pagerank算法。我从未发现任何具有挑战性的问题可以在线适应mapreduce框架。我想提高自己的技能。有这样的指南吗? 最佳答案 您正在寻找的
我了解到 Java 中没有 NOR,我可以使用 !A && !B 或 !(A||B)。既然 A 和 B 都是假的,为什么我不能使用 !A || B? 最佳答案 因为Java没有NOR运算符,你的表达式
我需要根据构建 CLI 工具的要求评估“GO”,该工具应该可以在不同的操作系统中运行。这是如何在诸如“Cloud Foundry CLI”之类的 CLI 工具中实现的?GO 如何处理这种对操作系统的适
所以我试图让我的下拉菜单正常工作。下拉列表位于我的标题中的列表项下,该列表项会根据用户的用户名而变化。这使得大小不同,但我无法让下拉菜单跟随宽度调整大小。 示例 1: http://jsfiddle.
我已经很努力了,但我还是被 matplotlib 卡住了。请忽略,mpl 文档让我有点困惑。我的问题涉及以下方面: 我用 matshow 函数画了一个对称的 n*n 矩阵 D。行得通。 我想做同样的事
我正在尝试调整 Boyer-Moore c(++) Wikipedia implementation获取字符串中模式的所有匹配项。实际上,维基百科实现返回第一个匹配项。主要代码如下: char* bo
我在底部嵌套了带有文本的 flex 元素。顶部元素具有小于文本的固定宽度: .list-header { display: flex; width: 150px; height: 80px
我想初始化 std::any带有仅 move 类型变量。我找到了 Cannot move std::any . 编译错误案例 在使用链接答案中的 shared_ptr 解决方法之前,我测试了以下代码:
现在我正在使用 webview 处理 ListView 。在这个 listview webview 中用于显示图像。它来自 url。现在我面临一个问题,我无法从 url 获得唯一尺寸的图像,一些图像很
我的文件夹结构是这样的: src --main.cpp tests --src ----main_test.cpp Makefile 我想制作一个像make main_test这样的目标,以便能够以.
前段时间我也在讨论类似的话题。我正在查看我的应用程序,我认为它有很多不必要的代码。我的意思是我有服务负责从两家书店的不同类别的书籍中抓取数据。现在我有 5 个类别,所以我有 5 个方法,但如果我要添加
我使用多个 div 子元素创建父元素,然后根据 data-value 属性在 JavaScript 中计算这些子元素的宽度。 如果我对所有 child 的计算宽度求和,我最终将得到 100%。但出于某
我像这样使用减速板 gem : require 'airbrake' Airbrake.configure do |config| config.api_key = 'XXXXX' confi
我们在企业环境中有一个 svn 存储库结构,如下所示: root libs shared_lib1 shared_lib2 private_lib public_cod
我制作了一个应用程序,其中有许多从 UIView 子类化的 View 。这些 View 的大小和方向是随机的,并且可以保存应用程序屏幕的状态。当用户在打开屏幕的同一设备上保存屏幕时,屏幕状态为“正常”
我需要调整 lucene 的 StandardTokenizer 以适应有关 twitter 数据的一些特殊目的。目前,我使用 StandardTokenizer 来标记一些我想要处理的推文。它工作得
在Windows Store应用中,如果内容是固定的,我们可以把它封装成一个ViewBox,让内容适应不同的分辨率。但是,如果内容不固定,在我的应用程序中,有一个 GridView 哪些项目是动态的,
一切都在标题中。 在我的应用程序中,根据用户所做的选择,我用一个列表填充一个组合框,该列表有时很小(1 个元素)有时很大(150 个元素)。 我想要的不是在启动时将固定高度设置为给定值,而是将 max
我的 2 div 动画感谢我下面的 jquery 脚本。当屏幕小于 700px 时,div 变成更小的正方形(35px 而不是 50px)。我希望 .animate({width:100px}); 仅
我是一名优秀的程序员,十分优秀!