Androidのアプリ開発関連のブログ

次はどんなアプリを作ろうか・・・

公開から連日バージョンアップしていたブログエディターだが、
現在ソフトキーボードで変換候補が出た際にキャレット位置によっては一時的に隠れる問題を把握しているが、解決困難なんで放置。
ブログエディターに必要な機能は十分実装されていると思うんで、更なる機能追加はユーザーが獲得できてからでいいかなと考えてる。
アプリ内購入で広告非表示オプションを導入したいとも思ってるが、それもユーザー獲得が先だね。
というわけで、ブログエディターのアップは落ち着いた感じ。


で、次何作ろうか・・・
というわけだが、

ブログエディターみたいなツール系アプリなら利用者がいれば広告効果が期待できると思うが、
設定系アプリみたいに滅多に使わないアプリじゃ広告つけてもほぼ無駄だね。
有料アプリやるより、無料アプリでユーザー獲得するのが先だと思うんで、
設定系みたいな広告つけても無駄ぽいのや、ウィジェットみたいに広告つけたら邪魔すぎるアプリは当面除外かな。
無広告の定番アプリがあって機能的にも勝てそうにないのも除外。
メモ帳みたいに作っても埋もれると思われるのも除外。

って感じかな。
難しいね・・・


Google Playで配信されてるアプリ眺めたりして考えたが、
FTP接続でリモートファイルを編集するアプリを作ろうかなーという方向に傾いてる。
WEB制作やってるからWEB系ツールしか思いつかないのかな。

単純にFTPクライアントだとアプリ多数あるから埋もれちゃいそうなんだが、
同期用アプリじゃなくて編集に特化した感じで。

そうすると、FTPクライアントとしての機能を作らなきゃだから、まず単純なFTPクライアントを作成。
HTMLファイルの編集にHTMLエディタを実装しなきゃだから、まずローカル用HTMLエディタを作成。
とか個別にアプリを作成することも考えたが、一つのアプリに機能追加していく感じの方が良いのかな。

まあ、そっち方向で考えてる。

キーボード出現時にキャレットが隠れる

公開から連日アップデートしてるブログエディターだが、
今回は、ソフトウェアキーボード出現時に、キャレットが下の方にあるとキーボードで隠れちゃう。
改善したい・・・

というわけなんだが、
android.view.ViewにonSizeChangedがあって、Viewのリサイズ時に呼び出される。
が、イベントリスナの登録はできないんで、カスタムViewを作ってイベントリスナを登録できるようにしてみた。
今回問題のViewはWebViewなんで、カスタムWebView。

CustomWebView.java
import android.webkit.WebView;
import android.content.Context;
import android.util.AttributeSet;

public class CustomWebView extends WebView{
    public CustomWebView(Context context,AttributeSet attrs){
        super(context,attrs);
    }
    public interface customOnSizeChangedListener{
        public void customOnSizeChanged(int w,int h,int oldw,int oldh);
    }
    private customOnSizeChangedListener listener;
    public void customSetOnSizeChangedListener(customOnSizeChangedListener listener){
        this.listener=listener;
    }
    protected void onSizeChanged(int w,int h,int oldw,int oldh){
        super.onSizeChanged(w,h,oldw,oldh);
        listener.customOnSizeChanged(w,h,oldw,oldh);
    }
}

MainActivity.java
((CustomWebView)view).customSetOnSizeChangedListener(new CustomWebView.customOnSizeChangedListener(){
            public void customOnSizeChanged(int w,int h,int oldw,int oldh){
                処理
           }
});

てな感じで、Viewのリサイズ時にMainActivity側で処理することができた。
layoutの.xmlファイルでカスタムViewを配置する場合は、(Context context,AttributeSet attrs)のコンストラクタが使われるみたいなんでOverride。
で、.xmlファイルには、<パッケージ名.クラス名>でカスタムViewが設置できる。
javaファイルで設置するなら、ほとんどの場合(Context context)で設置するから、そっちのコンストラクタをOverrideだね。

MainActivity側で処理できるように、イベントリスナのinterfaceを定義して、リスナ登録用のメソッドを用意。
onSizeChangedに追加でリスナを実行するようにする感じだね。


で、今回はWebViewのcontenteditable要素への入力でソフトキーボードが出現する時に問題が生じるんだが、
元々「改行→<br>」変換処理で要素が拡大してViewからはみ出した場合にスクロールする処理を入れてあるんだが、
その処理はrangeに一時的に<span>を入れて、<span>の座標がはみ出した場合にスクロールするようにしてある。

同じようにやろうとしたんだが、改行時処理と違って文字入力時処理だと、処理によってキーボードが消えちゃうって問題が発生した。
文字入力中にjavascriptでrangeに変更加えるのは問題生じそうな気もするし、javascript側で処理するのはやめたほうが良さそう・・・


Java側での処理を考えて、onSizeChangeddから元のサイズと新しいサイズが取得できるから、差をスクロールさせればできるとも思ったんだが、
View中のキャレット位置が上の方にあるって場合も考えられるし、その場合にスクロールさせちゃうと逆に消えちゃうね・・・

Java側でキャレット座標の取得ができないか調べたが、どうもできなそう。
android.view.ViewにあるgetBaseline()が怪しいかとも思ったが、WebViewでは常に-1ぽい・・・

AndroidManifest.xmlで「android:windowSoftInputMode="adjustResize"」を設定するとソフトウェアキーボード出現時にアクティビティが伸縮するらしいんだが、
うちの場合layoutで対応できてるのか、そもそもこれ設定しなくても伸縮してる。
問題はActivityのサイズじゃなくてView内のスクロール量だから、これは関係無さそう。


お手上げぽいんで、この問題は放置することにした。


EditTextでキーボード出現した場合どうなるのか試したが、EditTextの場合、何もせずに良い動きしてくれる。
WebViewの方の挙動を再度よく確認してみたが、キーボード出現時自体は自動で位置調整してくれるんだが、
1文字入力して変換候補がでた時に位置調整してくれない。EditTextなら問題ない。
WebViewでも、1文字入力で変換候補が出てキャレットが隠れるが、そのまま2文字目を入力すると再度位置調整してくれて画面内にキャレットが入る。
変換候補出現時の処理にWebViewはバグがあるっぽいな。

キャレットの座標が取得できないと位置調整できないと思うが、WebViewでもキーボード出現時と2文字目入力時は位置調整してくれるってことは、どこかで座標取得できそうな気はするが・・・