こんにちは、日比谷です。
今回は乗り換え案内等を作成しました。内容は動画を観ていただくとしてここでは誰でもトレインビジョン内部のプログラムのお話を概要だけしてみます。
乗り換え案内の表示で行っている事は乗り換え路線名を設定順に左詰めで表示する事です。これを行っているプログラムは赤字の箇所です。(以下、プログラムコードに関する参照箇所は単に「赤字」等とする)ただし、この方法では路線名が長い場合に表示が画面外まで及ぶ事があります(図①参照)そこで、表示が画面外に及ぶかどうかを判定して(青字)別々の処理を行います。
表示が画面外に及ぶ場合は、画面外となってしまうサイズを計算します。そしてそのサイズ等分して各乗り換え路線の表示を縮小します。(図②参照)(緑字)
しかし、この方法にも問題があります。一つだけ極端に長い路線名と短い路線名が混在する場合に縮小幅が短い路線名のサイズよりも大きくなるのです。(図③、図④参照)
これを防ぐために、路線名の縮小サイズに制限を設けました。具体的には日本語2文字分を最小サイズとしてそれ以下の縮小を行わないようにしました。ただ、これでは制限により縮小サイズに余りが生じます。そこで、余った縮小サイズを等分して残りの路線名の縮小サイズに追加させます。(図⑤参照)(橙字)
これで問題なく乗り換え路線名が表示できます。
ざっくりとでしたがこんな感じでプログラムを作っています。起こりうる全パターンを考えて作らなければならない事が面倒くさいですね。それでも読み込むデータはXMLである程度固定しているのでまだ楽ですが・・・
public void transfer() {
int sumWidth = rate(190);
int count = 0;
int x = rate(190);
//乗り換え路線数の取得
for (int i=0; i<5; i++) {
if (transferExist(i)) {
count++;
}
else {
break;
}
}
//乗り換え表示の幅が画面サイズを越える場合は縮小、超えない場合はそのまま並べる
for (int i=0; i<count; i++) {
sumWidth += transNameWidth(i);
}
if (sumWidth > xmlData.getSize()) {
int[] sub = new int[5];
int notOverCount = count;
int tmpSize = 0;
boolean over = true;
for (int i=0; i<count; i++) {
sub[i] = transNameWidth(i) - ((sumWidth - xmlData.getSize()) / count ) - rate(81);
}
while (over) {
for (int i=0; i<count; i++) {
if (sub[i] != rate(88)) {
sub[i] -= tmpSize / notOverCount;
}
}
over = false;
for (int i=0; i<count; i++) {
if (sub[i] < rate(88) && notOverCount > 1) {
tmpSize = rate(88) - sub[i];
sub[i] = rate(88);
notOverCount--;
over = true;
break;
}
}
}
for (int i=0; i<count; i++) {
transferView(i, x, 590, sub[i], transNameHeight(i));
x += sub[i] + rate(81);
}
}
else {
for (int i=0; i<count; i++) {
transferView(i, x, 590, transNameWidth(i) - rate(81), transNameHeight(i));
x += transNameWidth(i);
}
}
}
[0回]
PR