QA@IT

TitaniumのLabelでline-heightを指定したい(行間を空けたい)

3167 PV

Labelで行間を空けたいのですが何かいい方法はありますでしょうか。

https://lh3.ggpht.com/lHwBYKSkWnOqx9NJHTk1KTKsyZRnWq17aFV7aqMw13vzoLKfInP2TYUETG141C3T-A

↑要はこういうので行間を空けたいです。

webViewはパフォーマンスの問題で使えませんでした。(一文字ずつ出すとカクカクする)

回答

AndroidのTextViewではsetLineSpacingメソッドを使って行間を比率で指定することができます。

ところが、残念なお知らせが二つあります。

ひとつはTitanium MobileはsetLineSpacingに対応していないので自力で実装する必要があります。Titanium Mobileのソースから該当する箇所をいじってしまうのが手っ取り早く出来ますが運用が面倒になり、モジュールを作ると面倒くさいですが運用は健全になります。

もうひとつは、setLineSpacingを設定するとXperiaではTextViewの背景色が指定出来なくなるなど不具合が発生することが報告されています。またAndroid 4系ではsetLineSpacingが効かなくなるという報告もあります。なので、せっかく対応しても無駄になるかもしれません。関係各位にはもっとやる気を出してもらいたいものですね。

本体に手を入れる場合ですが、たぶん下のようにすればいけるんじゃないかと思います。

diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUILabel.java b/android/modules/ui/src/java/ti/modules/titanium/ui/w
index 7de229a..4b4a800 100644
--- a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUILabel.java
+++ b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUILabel.java
@@ -58,7 +58,9 @@ public class TiUILabel extends TiUIView
                        tv.setText(TiConvert.toString(d,TiC.PROPERTY_TEXT));
                } else if (d.containsKey(TiC.PROPERTY_TITLE)) { //TODO this may not need to be supported.
                        tv.setText(TiConvert.toString(d,TiC.PROPERTY_TITLE));
-               }
+               } else if (d.containsKey(TiC.PROPERTY_LINEHEIGHT)) {
+      tv.setLineSpacing(0, TiConvert.toFloat(d, TiC.PROPERTY_LINEHEIGHT));
+    }

                if (d.containsKey(TiC.PROPERTY_COLOR)) {
                        tv.setTextColor(TiConvert.toColor(d, TiC.PROPERTY_COLOR));
diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiC.java b/android/titanium/src/java/org/appcelerator/titanium/TiC.java
index ded4e25..684d26a 100644
--- a/android/titanium/src/java/org/appcelerator/titanium/TiC.java
+++ b/android/titanium/src/java/org/appcelerator/titanium/TiC.java
@@ -1940,4 +1940,9 @@ public class TiC
        public static final String URL_APP_SCHEME = "app";
        public static final String URL_APP_JS = "app://app.js";
        public static final String URL_ANDROID_ASSET_RESOURCES = "file:///android_asset/Resources/";
+
+  /**
+   *  @module.api
+   */
+  public static final String TiC.PROPERTY_LINEHEIGHT = "lineHeight";
 }

これで、JSの方は

var label = Ti.UI.createLabel({text:text, lineHeight:2.0});

みたいに指定します。ただ、上のようにAndroid側の不具合もあるのであまりオススメはできません。

そこで別の提案です。例えば世界的に有名な日の出の勢いで流行しながら日没後の日本を恐怖に陥れているサイト「怖話」のような表示をご希望であれば、以下のようなコードでやってみてはいかがでしょうか。createLabelで原稿用紙のようにマスを描画しておいて、その中のテキストを更新するのです。そのいや、インチキくさいのは百も承知ですが。

Ti.UI.setBackgroundColor("#000000");

// 表示するテキスト
var text = '平俗な名利の念を離れて、暫く人事の匆忙を忘れる時、自分は時として目ざめたるまゝの夢を見る事がある。或は模糊たる、影の如き夢を見る。或は歴々として、我足下の大地の如く、個体の面目を備へたる夢を見る。其模糊たると、歴々たるとを問はず、夢は常に其赴くが儘に赴いて、我意力は之に対して殆ど其一劃を変ずるの権能すらも有してゐない。夢は夢自らの意志を持つて居る。そして彼方此方と揺曳えうえいして、其意志の命ずるまゝに、われとわが姿を変へるのである。'; // http://www.aozora.gr.jp/cards/001085/files/1128_17118.html

var win = Ti.UI.createWindow();
var tile_width = (Ti.Platform.displayCaps.platformWidth - 20) / 20;
var base = 0;

var bg = Ti.UI.createView({top:0, width:Ti.Platform.displayCaps.platformWidth, height:Ti.UI.FILL});
win.add(bg);

// マスを描画
var id = 0;
var boxes = [];
for(var i = 0; i <= 9; i++){
  for(var j = 1; j <= 14; j++){
    var box = Ti.UI.createLabel({
      left:base + (20 * j),
      top:i * (20 + 10),
      width:tile_width,
      height:tile_width + 10,
      color:'White',
      font:{fontSize:18},
      textAlign:'center',
      verticalAlign:'center',
      text:'',
      id:id
    });
    bg.add(box);
    boxes.push(box);
    id++;
  }
} 

// 最後のマスが埋まったらクリアする
boxes.clear = function(){
  for(var i = 0; i < boxes.length; i++){
    boxes[i].text = '';
  }
};

// ウィンドウを表示したらタイマーで一文字ずつマスを埋める
win.addEventListener('open', function(){
  var length = text.length - 1;
  var box_id = 0;
  var i = 0;
  var interval = null;
  interval = setInterval(function(){
    box = boxes[box_id];
    box.text = text[i];
    i++;
    box_id++;
    // 最後のマスが埋まったらクリアして最初から
    if(box_id == id){
      boxes.clear();
      box_id = 0;
    }
    if(i > length){
      clearInterval(interval);
    }
  }, 100);
});

win.open();
編集 履歴 (0)
  • ありがとうございます。ただ、半角文字に対応するのが大変そうです。ゲームのような2Dグラフィックスでは普通テキストをどうやって描画するんでしょう。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。