2011年02月27日

やっぱり駄目だぁ!(EditTextのスクロール)

先日EditTextにScrollViewを組み込んで実用的なスクロール速度になったというエントリーを書いて、いい気になっていた私ですが、テストしていたら大問題が発覚して再び失意のズンドコ、じゃなかったどん底に陥りました。
というのは、スクロールしていって、どこかでタップすると、EditTextの読み込んでいる文書の先頭行にカーソルが戻ってしまうのです。
最初はどこかで記述ミスでもしているのかと思ったのですが、どうもそうじゃないらしい。少なくとも記述ミスは見つけられないのです。一昨日からずっとこの問題が気になって気になって、ずっとやっているのですが、解決できません。
このスクロール速度は(ScrollViewを使わない場合が異常に遅いため)捨てがたいので、どうしても解決したいのですが、どうにもうまくいきません。
とはいえ、ある程度までは改善する方法はあるのですが、これにも深刻な問題があります。
その方法は

editText.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
editText.scrollTo(0,scrollView.getScrollY());
editText.moveCursorToVisibleOffset();
return false;
}
});

として、editTextをScrollViewのスクロールしたところまでスクロールさせる方法。
実際はタップした場所とカーソルが移る場所がなぜか微妙にずれているように見えますが、タップと同時にソフトキーボードが出てしまうので、はっきり分からないながらも近い位置にカーソルが移動します。
これがeditText.setSelection(etBody.getSelectionStart());とかではNGなので、現状としてはもっとも解決に近いように思えますが、スクロールを続けて読み込んでいる文書の末尾を過ぎてもスクロールし、画面が真っ白になってしまいます。
if(scrollView.getScrollY() < editText.getBottom()){}などと制限をかけてみても変わらず。

なので、実際には使い物になりません。

絶対にどこか間違いをしているのではないかと思いますが、なぜこんな単純なことが単純にできないのかも疑問に思います。
しかもWebで情報を探しても例えば「Andorid EditText スクロール」とかで検索しても驚くほど情報は少ないのです。
同じようなことをしている人はたくさんいそうなものなのに不思議です。
エディタ系のアプリを作成している人はどうしているのだろうかとも思います。
ソースを見せて欲しい。(笑)

いずれにしてもこの問題が解決しないと公開できない気がしています。
もう三月になるというのに、いつになったら完成するものやら。
しかも、完成が遅れまくったことによりシーズン到来!(花粉の)
そのため、集中力が20%以下になり、ただでさえ他の人より集中力がないので、常人の100分の1くらいの集中力で作業をしなければいけないのではないでしょうか?

ああ、もうアプリ公開などということは、僕にとっては永遠に「到達不能コード」なのでしょうか?
posted by 白虹 at 22:15| Comment(1) | TrackBack(0) | Android開発

2011年02月24日

EditText/TextViewで文末まで自動スクロールしたい

続きでその2です。

スクロール速度が実用的な速度になったからには(?)、読み込んだ文章の末尾にも飛べるようにしたいという願望が再度芽生えてきました。
まあ、これも何度か失敗しているのですが、文の行数を数えてその最後にスクロールすればできるはず!
と、ここで素人のアサカサハ、じゃなかった浅ハカサ。最初の誤解があったのですが、賢明な皆様はすぐに気づいているはずですね。(笑)

文の行数を数えるといっても、どうしようか最初悩みました。
SQLから取り出したメモの本文は、ファイルではなく変数に格納されています。
かなり巨大な文章をも格納されることも考えられるのですが、そもそもSQLの一カラムとして登録して良いのかどうかは置いておいて、文章はファイルではなく変数に格納されることになります。
ファイルならリード時ループで回す時にカウントしていけば良い訳ですが、1変数に入っている状態のものはどうしよう?という疑問でした。
ここもindexOf()を使うとか、配列に入れて配列長で調べるとかいう方法が考えられるようでしたが、もっと簡単かつ簡潔にできるのではないかと。
調べていたら、アットマーク・アイティの記事に素晴らしい方法が見つかりました。

http://www.atmarkit.co.jp/fdotnet/dotnettips/911countchar/countchar.html

これは文字列内に含まれる特定文字のカウント方法ということで、元の文字列の長さからreplaceAll()で特定文字を""に置き換えた結果の長さを引くと、置き換えた回数が分かるというものです。
素晴らしく簡単簡潔!
これなら僕にも理解できます。(笑)

さて、ではあとは行数を設定してスクロールだっ!
と思ったら、ScrollViewのscrollTo(int x,int y)は別に行を指定してスクロールする訳ではなかったのでした。(苦笑)

ああ、じゃあやっぱり僕には無理かぁ、と断念しかけたのですが、ふとEditTextの方でなんとかならないのかな?と思ってちょっと調べてみました。
そして、JavaDriveにてsetSelection(int index)の説明を見つけました。
しかし、これは(画面キャプチャーが一行テキストのものなので)複数行のEditTextには適用されないよな、などと思いながら試しに

editText.requestFocus(); // 最初は別のEditTextにフォーカスがあるため目的のEditTextに移動
editText.setSelection(editText.getText().length())

としてみたところ、見事に文末へ!
これは素晴らしい!

よーし!じゃあ、今度はTextViewだっ!と勢いに乗ってやろうとしたところ、TextViewは基本的にSelectionするものではない!
なので、setSelectionは存在しないのでした。(笑)

やっぱりTextViewは諦めだな、とまたまた落ち込んでから、eclipseの補完機能で今度もScrollViewではなく、TextViewのメソッドを見ていたところ、getBottom()というメソッドがありました。説明には「The bottom of this view, in pixels. 」を返すとあります。
ん?英語の意味は不確かだけれど、これはイケそう!と思って、

scrollView.scrollTo(0, textView.getBottom());

とやってみたところ、これまた見事に文末へジャンプ!

う、嬉しいっ!
久々にうまくいった感じ!
実際はすぐにうまくいったのではなく、かなり時間はかかっていますが、一日で2項目も進展があると(ホントはもう公開前に機能追加や改善はしない予定だったのですが)、なんだかスキッとしますね。

また公開日は遠ざかった感じだけど、懸案事項が解決するのは良いことです。

追記:
(ところで、ここで告白するともうひとつ大きな懸案事項として残っているのが、データベースの問題。実は9つほどのカラムを持つDBなのですが、テーブルを分けていないのでした。本来はテーブルは分けるべきなのでしょうけど、SQL素人でもあり、どうせSDカードにDBを置けないのだから、とりあえずだ!と思っていたために安易な一枚テーブルで作成してしまったのでした。DBの肥大化にも繋がり、正しくないことは分かっていなくはなかったのですけどね。でも、ここでまたデータ構造が変わるのは辛いので、どーせ「想い出作り」で終わる可能性大なので、このまま突き進む予定です。)
posted by 白虹 at 23:55| Comment(2) | TrackBack(0) | Android開発

EditTextのスクロールが異常に遅かった原因判明

昨日から今日にかけて、自分的にかなり重要な進展が二つほどありました。
本当は何度目かの最終テストをしているはずだったのですが(笑)、ふと気になっていたところをいじっていたら今後の検討課題としていた問題が(多分)解決してしまったのです(かなり運良く?当てずっぽうがあたったというか)。

まずは、その1。
最初からどうも文書編集用のEditTextのスクロールが遅すぎると思っていたのですが、いずれ解決しようと諦めていたところ、ここにきて突然解決しました。
これまで遅いのはカスタマイズが原因か、何か自分の知らない方法があるのだろうと思っていたのです。
しかし、ふとxmlのレイアウト定義でEditTextをScrollViewで囲んだところ、普通の速度でスクロールできるようになりました!

というか、何故ScrollViewで囲んでいなかったんだ?と言われそうですが、TextViewと違って、EditTextはそのままで一応スクロールできてしまったからでした。
(以前にもこの解決方法は試したような気がするのですが……)

しかし、これを設定したら、いままで問題なく表示できていたのに、表示されている文章の行が画面より短いと画面いっぱいにEditTextが表示されなくなってしまいました。
これはちょっとかっこわるい。
(元々ScrollViewをつける以前に同じような表示になっていたのでandroid:layout_weight="1"を縦に二段あるEditTextの下側に設定したところ、画面いっぱいに表示されるようになっていた)

そこで試行錯誤の結果、ScrollViewにandroid:fillViewport="true"を設定したところ、解決しました。

これで本当に大丈夫かな?


2011/2/27 追記
この方法で問題発覚(未解決)
詳細は以下
posted by 白虹 at 23:42| Comment(0) | TrackBack(0) | Android開発