Android實(shí)現(xiàn)文字和圖片混排(文字環(huán)繞圖片)效果
本文實(shí)例講述了Android實(shí)現(xiàn)文字和圖片混排(文字環(huán)繞圖片)效果。分享給大家供大家參考,具體如下:
在平時(shí)我們做項(xiàng)目中,或許有要對(duì)一張圖片或者某一個(gè)東西進(jìn)行文字和圖片說(shuō)明,這時(shí)候要求排版美觀,所以會(huì)出現(xiàn)文字和圖片混排的情況,如圖:

這種情況就是上下兩個(gè)文字說(shuō)明是連續(xù)在一起的,這就要求我們計(jì)算上面的文字說(shuō)明怎么和下面的文字說(shuō)明連貫結(jié)合在一起呢,這就要求我們進(jìn)行計(jì)算了,下面給出代碼,代碼中也有詳細(xì)的注釋,原理也很簡(jiǎn)單。
因?yàn)樗闶潜容^簡(jiǎn)單,直接就在activity中去計(jì)算了:
package com.example.test;
import android.app.Activity;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
boolean imageMeasured = false;
TextView tv_right;
TextView tv_bottom;
static final String text = "葉凡:小說(shuō)主角,與眾老同學(xué)在泰山聚會(huì)時(shí)一同被九龍拉棺帶離地球," +
"進(jìn)入北斗星域,得知自己是荒古圣葉凡 葉凡體。歷險(xiǎn)禁地,習(xí)得源術(shù),斗圣地世家,戰(zhàn)太古生物," +
"重組天庭,葉凡輾轉(zhuǎn)四方得到許多際遇和挑戰(zhàn),功力激增,眼界也漸漸開(kāi)闊。一個(gè)浩大的仙俠世界," +
"就以他的視角在讀者面前展開(kāi)。姬紫月:姬家小姐,出場(chǎng)年齡十七歲。被葉凡劫持一同經(jīng)歷青銅古殿歷險(xiǎn)," +
"依靠碎裂的神光遁符解除禁制,反過(guò)來(lái)挾持葉凡一同進(jìn)入太玄派尋找秘術(shù)。" +
"在葉凡逃離太玄后姬紫月在孔雀王之亂中被華云飛追殺,又與葉凡[2]相遇,被葉凡護(hù)送回姬家" +
",漸漸對(duì)葉凡產(chǎn)生微妙感情。后成為葉凡的妻子,千載后于飛仙星成仙,在葉凡也進(jìn)入仙路后再見(jiàn)龐博:" +
"葉凡大學(xué)時(shí)最好的朋友,壯碩魁偉,直率義氣。到達(dá)北斗星域后因服用了圣果被靈墟洞天作為仙苗," +
"在青帝墳?zāi)固帪榍嗟凼糯鷮O附體離去,肉身被錘煉至四極境界。后葉凡與黑皇鎮(zhèn)壓老妖神識(shí)," +
"龐博重新掌控自己身軀,取得妖帝古經(jīng)和老妖本體祭煉成的青蓮法寶,習(xí)得妖帝九斬和天妖八式," +
"但仍偽裝成老妖留在妖族。出關(guān)后找上葉凡,多次與他共進(jìn)退。星空古路開(kāi)啟后由此離開(kāi)北斗," +
"被葉凡從妖皇墓中救出,得葉凡授予者字秘、一氣化三清,與葉凡同闖試煉古路,一起建設(shè)天庭";
// 屏幕的高度
int screenWidth = 0;
// 總共可以放多少個(gè)字
int count = 0;
// textView全部字符的寬度
float textTotalWidth = 0.0f;
// textView一個(gè)字的寬度
float textWidth = 0.0f;
Paint paint = new Paint();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_right = (TextView) findViewById(R.id.test_tv_right);
tv_bottom = (TextView) findViewById(R.id.test_tv_bottom);
final ImageView imageView = (ImageView) findViewById(R.id.test_image);
imageView.setImageResource(R.drawable.ee);
screenWidth = getWindowManager().getDefaultDisplay().getWidth();
/**
* 獲取一個(gè)字的寬度
*/
textWidth = tv_right.getTextSize();
paint.setTextSize(textWidth);
/**
* 因?yàn)閳D片一開(kāi)始的時(shí)候,高度是測(cè)量不出來(lái)的,通過(guò)增加一個(gè)監(jiān)聽(tīng)器,即可獲取其圖片的高度和長(zhǎng)度
*/
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
if (!imageMeasured) {
imageMeasured = true;
int height = imageView.getMeasuredHeight();
int width = imageView.getMeasuredWidth();
drawImageViewDone(width, height);
}
return imageMeasured;
}
});
}
private void drawImageViewDone(int width, int height) {
// 一行字體的高度
int lineHeight = tv_right.getLineHeight();
// 可以放多少行
int lineCount = (int) Math.ceil((double) height / (double) lineHeight);
// 一行的寬度
float rowWidth = screenWidth - width - tv_right.getPaddingLeft() - tv_right.getPaddingRight();
// 一行可以放多少個(gè)字
int columnCount = (int) (rowWidth / textWidth);
// 總共字體數(shù)等于 行數(shù)*每行個(gè)數(shù)
count = lineCount * columnCount;
// 一個(gè)TextView中所有字符串的寬度和(字體數(shù)*每個(gè)字的寬度)
textTotalWidth = (float) ((float) count * textWidth);
measureText();
tv_right.setText(text.substring(0, count));
// 檢查行數(shù)是否大于設(shè)定的行數(shù),如果大于的話,就每次減少一個(gè)字符,重新計(jì)算行數(shù)與設(shè)定的一致
while (tv_right.getLineCount() > lineCount) {
count -= 1;
tv_right.setText(text.substring(0, count));
}
tv_bottom.setPadding(0, lineCount * lineHeight - height, 0, 0);
tv_bottom.setText(text.substring(count));
}
/**
* 測(cè)量已經(jīng)填充的長(zhǎng)度,計(jì)算其剩下的長(zhǎng)度
*/
private void measureText() {
String string = text.substring(0, count);
float size = paint.measureText(string);
int remainCount = (int) ((textTotalWidth - size) / textWidth);
if (remainCount > 0) {
count += remainCount;
measureText();
}
}
}
其中xml文件布局如下:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/test_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
<TextView
android:id="@+id/test_tv_right"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/test_image"
android:gravity="fill_horizontal"
android:paddingLeft="7dp"
android:textSize="16sp" />
<TextView
android:id="@+id/test_tv_bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/test_image"
android:gravity="fill_horizontal"
android:textSize="16sp" />
</RelativeLayout>
</ScrollView>
代碼很少,原理也很簡(jiǎn)單,后來(lái)發(fā)現(xiàn)這種做法在大部分手機(jī)運(yùn)行是完美的,但是少部分手機(jī)還是有點(diǎn)問(wèn)題。是什么問(wèn)題呢,是在我們測(cè)量textView的長(zhǎng)度的是,因?yàn)槭俏覀儎倓傔M(jìn)行setText,然后馬上進(jìn)行測(cè)量,這樣得到的結(jié)果是不正確的,所以大家可以優(yōu)化一下。溫馨提示,當(dāng)我們setText之后,可以延時(shí)一些時(shí)間再去測(cè)量,這樣獲取的值就是掙錢的了,當(dāng)然那個(gè)延遲的時(shí)間很短50毫秒就可以了,因?yàn)槲覀円嘈舤extView的繪制速度還是很快的。
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- 控制Android LED燈顏色的代碼實(shí)例
- 詳解Android應(yīng)用層制作LED指示燈
- android顯示TextView文字的倒影效果實(shí)現(xiàn)代碼
- Android實(shí)現(xiàn)文字翻轉(zhuǎn)動(dòng)畫(huà)的效果
- Android實(shí)現(xiàn)文字滾動(dòng)效果
- Android自定義Dialog實(shí)現(xiàn)文字動(dòng)態(tài)加載效果
- Android中使用TextView實(shí)現(xiàn)文字跑馬燈效果
- Android編程實(shí)現(xiàn)文字倒影效果的方法
- Android Shader應(yīng)用開(kāi)發(fā)之霓虹閃爍文字效果
- Android編程實(shí)現(xiàn)類似天氣預(yù)報(bào)圖文字幕垂直滾動(dòng)效果的方法
- Android基于ViewFilpper實(shí)現(xiàn)文字LED顯示效果示例
相關(guān)文章
Android工程:引用另一個(gè)Android工程的方法詳解
本篇文章是對(duì)在Android中引用另一個(gè)Android工程的方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05
Android EditText實(shí)現(xiàn)分割輸入內(nèi)容
這篇文章主要為大家詳細(xì)介紹了Android EditText實(shí)現(xiàn)分割輸入內(nèi)容的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Android中常見(jiàn)的圖形繪制方式總結(jié)
Android中繪制圖片或形狀是我們常遇到的事情,通過(guò)最近的學(xué)習(xí)與在網(wǎng)上學(xué)習(xí)的案例與資料那么我今天就總結(jié)一下,這篇文章主要給大家介紹了關(guān)于Android中常見(jiàn)的圖形繪制方式,需要的朋友可以參考下2021-07-07
Android 斷點(diǎn)續(xù)傳原理以及實(shí)現(xiàn)
這篇文章主要介紹了Android 斷點(diǎn)續(xù)傳原理以及實(shí)現(xiàn)的相關(guān)資料,這里對(duì)斷點(diǎn)續(xù)傳原理進(jìn)行了詳細(xì)介紹,需要的朋友可以參考下2016-12-12
Android源碼學(xué)習(xí)之觀察者模式應(yīng)用及優(yōu)點(diǎn)介紹
定義對(duì)象間一種一對(duì)多的依賴關(guān)系,使得當(dāng)一個(gè)對(duì)象改變狀態(tài),則所有依賴于它的對(duì)象都會(huì)得到通知并被自動(dòng)更新等等,需要了解的朋友可以參考下2013-01-01
Android實(shí)現(xiàn)簡(jiǎn)單的下拉阻尼效應(yīng)示例代碼
下面小編就為大家分享一篇Android實(shí)現(xiàn)簡(jiǎn)單的下拉阻尼效應(yīng)示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Android自定義控件之圓形/圓角的實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android自定義控件之圓形/圓角的實(shí)現(xiàn)代碼,感興趣的小伙伴們可以參考一下2016-03-03

