在程序中使用下面的代碼取得 TextView 中指定字符所在的行號,可是運行時 getLayout() 返回了 null。這是因為設置 text 后控件的狀態還沒有刷新,只要調用 onPreDraw() 刷新一下狀態就可以了
TextView.setText(body);
TextView.getLayout().getLineForOffset(pos);
改進后的代碼
TextView.setText(body);
TextView.onPreDraw();
TextView.getLayout().getLineForOffset(pos);
新的問題是 getLayout() 能夠正確取得結果,但是 getLineForOffset(pos) 的結果與 pos 相等,另一個問題是直接通過TextView.getLineCount()方法獲取行數時,總是0,研究發現,setText()后立即調用getLineCount(),
這時TextView還未完成measure,要想正確的獲取TextView的行數有兩種方法:
1.用ViewTreeObserver監聽View初始化的各種狀態
使用ViewTreeObserver的OnPreDrawListener在TextView完成測量和定位即將繪制時調用getLineCount()即可得到TextView的真實行數,代碼如下:
tv_test.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
//這個回調會調用多次,獲取完行數記得注銷監聽
tv_test.getViewTreeObserver().removeOnPreDrawListener(this);
LogUtils.e("TextView 行數:" + tv_test.getLineCount());
return false;
}
});
tv_test.setText("老人取件發現“巨獎” 將計就計反忽悠騙子老人取件發現“巨獎”");
2.View.post(Runnable r)方法
tv_test.post(new Runnable() {
@Override
public void run() {
LogUtils.e("行數:" + tv_test.getLineCount());
}
});
tv_test.setText("老人取件發現“巨獎” 將計就計反忽悠騙子老人取件發現“巨獎”");