标題的内容可能寫的有點讓人暈~下面我來解釋下,實際上是這麼回事
PagerView是官方提供的可以呈現滑屏效果的控件
其布局檔案代碼為
1
2
<code><android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"</code>
<code> </code><code>xmlns:tools="http://schemas.android.com/tools"</code>
而其也提供了一個标題的布局,
3
4
<code><android.support.v4.view.PagerTitleStrip</code>
<code> </code><code>android:id="@+id/pager_title_strip"</code>
<code> </code><code>android:layout_width="wrap_content"</code>
<code> </code><code>android:layout_height="wrap_content"</code>
但是這個标題有一個限制,就是沒法多行顯示,如果想做出一個類似調查問卷的東西,帶有滑屏效果的話,标題可想而知一定是問卷的問題,是以這種情況下是必須把标題全部顯示出來的,是以大家自然而然的就能想到用TextView去替代官方提供的這個PagerTitleStrip。是以問題就很容易解決,隻要在TextView中添加
<code>android:singleLine="false"</code>
這個屬性就能使标題自動換行,看似問題已經解決了。當然,如果需求就是做到如此的話,那還是不錯,至少簡單輕松達到目的。
但是如果接下來這樣的需求,為了滑屏的時候頁與頁之間銜接的美觀一些(想想,如果第一頁的标題内容能自動換成3行,而第二頁的内容自動換成2行,這種情況下就會出現頁與頁之間标題下面的内容不在一個水準線上的情況),那麼是不是就應該使用每頁的标題都能有同一高度,這樣就好了呢?
的确如此,這就是我标題所想闡述的,不過這樣的情況我相信極極極極少人會遇到的,如果你遇到了,可以考慮用下面的方法
首先,我想到了在代碼中動态去擷取每頁标題自動換行後的高度,即
<code>int</code> <code>currentHeight = tvTitle.getLineCount() * tvTitle.getLineHeight();</code>
這樣一段代碼去實作,然後周遊每頁的标題高度,取出值最大,也就是最高的一個然後
<code>tvTitle.setHeight(maxHeight);</code>
将其設定。
但是這麼做有兩個問題,1,因為整個視圖的建立我是在Fragment類的onCreateView()方法裡實作的,導緻tvTitle.getLineCount()始終是0,因為這個方法是隻有在視圖成功建立之後才能擷取到真實值,否則就會傳回0,這已經是一個無法逾越的鴻溝了。
但是還有第二個問題,2,我上面提到的周遊每頁的高度,那真是扯蛋,但是我當時以為是可以的,如果你去檢視Fragment類裡的視圖生命周期或者在onCreateView()裡加些列印資訊,你就會發現除非你自己去滑動頁面,否則系統根本不會去“觸碰”那些沒有呈現的頁,是以此方法不可行。
但是問題是必須要解決的,而且從來沒有解決不了的問題。是以出現了第二種方法。
因為标題的内容是已知的,是以我們可以算出每頁标題的像素(pixels)總大小,然後選擇一個最大的,再通過計算TextView一行所顯示的像素大小,兩者進行相除,就能算出是多少行。我想我目前也隻能做到這個程度了。
因為标題内容可能有漢字,字元,數字和其他符号,是以我們必須都要考慮在内。這裡用到一個函數
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<code>//通過計算得出字元串像素大小</code>
<code> </code><code>public</code> <code>int</code> <code>getPixels(String parseStr){</code>
<code> </code><code>if</code> <code>(parseStr == </code><code>null</code> <code>|| parseStr.length() <= </code><code>0</code><code>) {</code>
<code> </code><code>return</code> <code>0</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>int</code> <code>pixelsLength = </code><code>0</code><code>;</code>
<code> </code><code>char</code> <code>c;</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = parseStr.length()-</code><code>1</code><code>; i >= </code><code>0</code><code>; i--) {</code>
<code> </code><code>c = parseStr.charAt(i);</code>
<code> </code><code>if</code> <code>((c >= </code><code>'0'</code> <code>&& c <= </code><code>'9'</code><code>) || (c >= </code><code>'a'</code> <code>&& c <= </code><code>'z'</code><code>) || (c >= </code><code>'A'</code> <code>&& c <= </code><code>'Z'</code><code>)) {</code>
<code> </code><code>//字母, 數字</code>
<code> </code><code>pixelsLength++;</code>
<code> </code><code>else</code> <code>{</code>
<code> </code><code>if</code> <code>(Character.isLetter(c)) {</code>
<code> </code><code>//中文</code>
<code> </code><code>pixelsLength += </code><code>2</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>else</code> <code>{</code>
<code> </code><code>//符号或控制字元</code>
<code> </code><code>pixelsLength++;</code>
<code> </code><code>}</code>
<code> </code><code>pixelsLength = (</code><code>int</code><code>)pixelsLength/</code><code>2</code><code>;</code>
<code> </code><code>return</code> <code>pixelsLength;</code>
<code> </code><code>}</code>
其中後面有一段pixelsLength/2的内容,因為我發現當計算出的長度/2以後,才是真正TextView一行的像素值,這塊我真沒力氣去深入研究了,包括字間距什麼的,我開始本以為要加,但是經過實際操作,發現那些都是多餘。
是以就按照我的方法來吧。
<code>try</code><code>{</code>
<code> </code><code>//得到TextView的像素大小(pixels),即單行所有像素大小</code>
<code> </code><code>int</code> <code>titleWidth = screenWidth - tvTitle.getPaddingLeft() - tvTitle.getPaddingRight();</code>
<code> </code><code>//單行能放多少個像素單元</code>
<code> </code><code>int</code> <code>singleLineLength = (</code><code>int</code><code>)(titleWidth/(</code><code>int</code><code>)tvTitle.getTextSize());</code>
<code> </code><code>//總的像素大小/單行像素大小=需要多少行</code>
<code> </code><code>int</code> <code>lineNum = titleLength/singleLineLength;</code>
<code> </code><code>if</code> <code>(lineNum == </code><code>0</code><code>){</code>
<code> </code><code>lineNum = </code><code>1</code><code>;</code>
<code> </code><code>if</code> <code>(lineNum != </code><code>0</code><code>){</code>
<code> </code><code>lineNum++;</code>
<code> </code><code>} </code>
<code> </code><code>//設定TextView的高度</code>
<code> </code><code>tvTitle.setHeight(lineNum*tvTitle.getLineHeight()+</code><code>5</code><code>);</code>
<code> </code><code>}</code><code>catch</code><code>(Exception e){</code>
<code> </code><code>e.printStackTrace();</code>
最後再加上這一段,算是把這個問題暫時告一段落了。
本文轉自 我不會抽煙 51CTO部落格,原文連結:http://blog.51cto.com/zhouhongyu1989/1285357,如需轉載請自行聯系原作者