Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to imitate instagram to realize automatic typesetting of characters in Android

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "how to imitate instagram to realize text automatic typesetting function in Android". In daily operation, I believe many people have doubts about how to imitate instagram to realize text automatic typesetting function in Android. Xiaobian consulted all kinds of materials and sorted out simple and easy operation methods. I hope to answer your doubts about "how to imitate instagram to realize text automatic typesetting function in Android"! Next, please follow the small series to learn together!

1 summarizes

Friends who have played ins should know that ins has a function of editing text automatic typesetting. The application will automatically typeset each line of text entered by the user to achieve a compact and beautiful effect.

The renderings are as follows:

2 thoughts to explore

Because I couldn't find any relevant information on the Internet, I guessed the approximate realization idea directly by playing ins. I sorted out some of my initial questions.

When more and more text is entered, how can we ensure that the maximum text displayed in each line remains unchanged?

Normally, as your font size gets smaller and the input box width stays the same, you can type more text per line, but you find that the maximum amount of text that can fit per line remains the same no matter how large the font size is. My guess is that the input box changes with the font.

By opening the developer options app layout border, you can see that the width of the ins input box is actually dynamically changing.

Below is the effect of opening the applied layout boundary:

Of course, this may introduce a new problem, which is how the width of the input box changes dynamically?

So that it can just hold the same maximum number of text as the font size changes.

This question will be addressed below, but not here.

How is the font size of each line determined and how does it change in tandem?

I thought about this problem for a long time at the beginning. I think if I understand this problem, I will have already succeeded in half. Most people may easily fall into local thinking at first, including me, who has been struggling with how each line of fonts changes, but in fact, it should be considered from the overall perspective, everything will become very simple from the overall consideration, and the code implementation will become easier, without having to deal with various special situations.

Specific ideas:

traversing each line of text to adapt to the maximum text width to calculate the font size of each line, then calculating the height of each line according to the font size of each line, accumulating the height of each line to obtain the total height of the text, then judging whether the total height of the text is greater than the maximum text height, and if so, reducing the font size of each line proportionally to reduce the height of each line to obtain a new total height of the text until the total height of the text is less than the maximum text height.

The above paragraph sums up in four steps:

line splitting

Calculate font size per line by matching maximum width

Calculate font size per line by maximum matching height

Readjust EditText Width

3 Knowledge Reserves

There are a few things we need to know before we start:

span

span You can segment TextView to display different styles of text. In automatic typesetting, because each line of text has a different font size, we need to set a different span for each line of text.

Layout

Layout is an auxiliary class for various text calculations, TextView text layout is dependent on Layout implementation. Because Layout is completely decoupled from TextView, we can construct a suitable Layout to help us calculate font size.

Here is the official definition of Layout:

A base class that manages text layout in visual elements on the screen.

For text that will be edited, use a DynamicLayout, which will be updated as the text changes. For text that will not change, use a StaticLayout.

Layout has several subclasses, of which the more commonly used are DynamicLayout and StaticLayout. According to the official saying, DynamicLayout is used when your text is editable, and StaticLayout is used when your text is not editable.

Therefore, EditText's text calculation work should be handed over to DynamicLayout implementation.

4 Specific realizations

First we need to listen for text input changes, calculate the font size of each line as the text changes, and finally render it to the screen. The code to listen for text changes is as follows:

addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { refresh(); } @Override public void afterTextChanged(Editable s) { } });

I. line splitting

After listening to the text change, you need to split the text to get the text of each line. We can do this with Layout, code like this:

String text = layout.getText().toString(); int lineCount = layout.getLineCount(); for (int i = 0; i

< lineCount; i++) { int start = layout.getLineStart(i); int end = layout.getLineEnd(i); String rowStr = text.substring(start,end); } 但是,但是,但是,这里有一个点需要特别注意,不能通过EditText自带的Layout来计算每行文本,不然拿到的每行文本是错误的。 为什么呢? 举个例子: 如下图所示,当你在第二行将要输入"好"时,因为你输入"好"后该行文本宽度已经大于此时EditText的宽度了,所以"好"字会被认为是重启一行,这样你得到的每行文本就是错的了,因为"好"应该显示在第二行才对。 这就涉及到我在思路探究中提到的第一个问题,无论我字体怎么缩小放大,如何保证每行最多可显示的文本都是一样的? 那么如何保证呢? 其实很简单,因为影响到文字自动换行的因素主要就是字体大小和最大文本宽度,那么只要保证这两个因素不变,无论你输入什么文本,都能准确一致的拆分出每一行的文字。 因为EditText的每行字体在变,而且宽度也在变,所以通过EditText自带的Layout算出的每行文本肯定是错误的。 所以,思路应该是这样的,你需要构建一个用于计算的Layout,这个Layout的字体大小和宽度必须是固定不变的,这样它就能够保证每行最多可容纳的文本始终是一样的,这样我就能够准确拆分出每行文本。 前面已经说过EditText的计算工作都是交给DynamicLayout,所以我们需要创建的是DynamicLayout。代码如下 protected Layout buildCalculateLayout(CharSequence text,TextView host){ TextPaint paint = new TextPaint(host.getPaint()); paint.setTextSize(mDefFontSize); return new DynamicLayout(text,paint, mDefMaxTextWidth,host.getLayout().getAlignment(),host.getLayout().getSpacingMultiplier(),host.getLayout().getSpacingAdd(),host.getIncludeFontPadding()); } 需要注意的是,这里除了字体大小和宽度,其他的参数都需要跟EditText的参数一样。 其中mDefFontSize是一开始定义的一个默认字体大小,mDefMaxTextWidth是EditText在没动态调整宽度前的宽度(需要减去padding)。 这样子每次都是通过自构建的Layout去计算每行的文本,就不需要考虑EditText的字体和宽度的动态变化。 二.按匹配最大宽度计算每行字体大小 搞定了第一步拆行后,其实已经离成功不远了,接下来就是如何确定每行字体大小了。 确定字体大小说简单简单,说难也难,关键是看你有没有想到那个点。比如一开始我一直纠结于每行文字是怎么随着输入文字个数和行数变化动态改变的,陷入了局部细节,搞得自己晕头转向,如果按照这个方向思考我感觉估计是怎么做都搞不定的。 后来,想了两天后还是没搞明白,我就试着换个思维方式,从整体来考虑,接下来就有种恍然大悟的感觉,原来其实没那么难。 首先,有一个规律是很显然的: 每行文字越多,它的字体就越小,文字越少,字体就越大。 那么我就想一开始时你把每行文字的宽度放大到最大文本宽度,算出匹配这个宽度的字体应该多大,这样文字越少的行,字体就越大,文字越多的行,字体就越小,这个不就是符合那个规律吗。 计算文本宽度的代码如下: float width = paint.measureText(text); 因为需要通过不断更改字体大小,去算出匹配最大宽度的字体,所以为了减少计算量,一开始可以做一个初始字体大小的换算。 当字体大小是mDefFontSize时对应的文本宽度是mDefMaxTextWidth,那么当文本宽度是x时,对应的字体大小是y,因为字体大小和宽度成反比(宽度越小,字体越大),所以y的计算公式就是: y = mDefMaxTextWidth \ x * mDefFontSizex = paint.measureText(text); 这样我们就可以得到一个比较接近目标值的字体大小,这时候再去判断此时文本宽度是否匹配最大文本宽度,不等于的话再去改变字体大小,直到文本宽度匹配最大文本宽度为止。 代码如下: public float calculateMatchWidthSize(Paint paint,String text,int maxWidth){ float textSize = paint.getTextSize(); float width = paint.measureText(text); if(maxWidth >

= width && maxWidth - width maxWidth){ textSize = getNarrowFitTextSize(paint,text,maxWidth,1); }else{ textSize = getZoomFitTextSize(paint,text,maxWidth,1); } return textSize; } private float getNarrowFitTextSize(Paint paint,String text,int maxWidth,float rate){ float textSize = paint.getTextSize(); textSize -= 1 * rate; paint.setTextSize(textSize); float width = paint.measureText(text); if(maxWidth >= width && maxWidth - width = width && maxWidth - width

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report