2014-01-09 38 views
3

我試圖在TextView中顯示帶有和絃的歌詞。爲此,我需要在主文本的特定部分上方放置字母或符號。我的想法至今是繼承ReplacementSpan這樣的:Android TextView:如何將文本放置在行中的特定位置上方/ ReplacementScan子類的設置高度

import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Paint.FontMetricsInt; 
import android.text.style.ReplacementSpan; 

public class ChordSpan extends ReplacementSpan { 

    String chord; 

    public ChordSpan(String chord) { 
     super(); 

     this.chord = chord; 
    } 

    @Override 
    public void draw(Canvas canvas, 
     CharSequence text, int start, int end, 
     float x, int top, int y, int bottom, 
     Paint paint) { 

     FontMetricsInt fm = paint.getFontMetricsInt(); 
     int space = fm.ascent-fm.descent+fm.leading; 

     canvas.drawText(text, start, end, x, y, paint); 
     canvas.drawText(chord, x, y+space, paint); 
    } 

    @Override 
    public int getSize(Paint paint, CharSequence text, int start, int end, 
     FontMetricsInt fm) { 

     return Math.round(paint.measureText(text, start, end)); 
    } 

} 

這很好地工作在把上面的文字和絃符號。但是,當我添加和絃時,我還沒有找到調整線高的方法,因此和絃會在TextView中的前一行中繪製。此代碼演示了我的意思:

package com.example.chordspan; 

import android.os.Bundle; 
import android.app.Activity; 
import android.text.Spannable; 
import android.text.SpannableStringBuilder; 
import android.view.Gravity; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     TextView tv = new TextView(this.getBaseContext()); 
     tv.setGravity(Gravity.CENTER_VERTICAL); 

     SpannableStringBuilder sb = new SpannableStringBuilder(); 

     sb.append("The line above\n"); 

     int start = sb.length(); 
     sb.append("A line with chords\n"); 
     sb.setSpan(new ChordSpan("C"), start, start+2, 
      Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     sb.setSpan(new ChordSpan("Am"), start+7, start+11, 
      Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

     sb.append("The line below"); 

     tv.setText(sb); 

     setContentView(tv); 
    } 
} 

你會看到和絃排列並得到正確繪製但「上面的線」重疊。

有沒有辦法實現我想要的,即在繪製我的自定義跨度時以某種方式調整線的線高度?我還沒有找到任何ReplacementSpan子類的好例子。

另外,我很樂意收到有關如何達到預期效果的其他建議。也許我正在考慮一個完全錯誤的方向。

感謝您閱讀迄今爲止以及提供的任何幫助!

回答

5

四處尋找在Android源相當長一段時間之後,我想我找到了解決方案:ReplacementSpangetSize方法不應該只返回跨度的寬度爲int,但也可以改變作爲參數傳遞的FontMetricsInt

public int getSize(Paint paint, CharSequence text, int start, int end, 
    FontMetricsInt fm) { 

    if (fm != null) { 

     int space = paint.getFontMetricsInt(fm); 

     fm.ascent -= space; 
     fm.top -= space; 

    } 

    return Math.round(paint.measureText(text, start, end)); 

} 
+1

值得一提的是,FM = NULL檢查是必要的:

用下面的代碼行間距工作根據需要

左右。 – spierce7

相關問題