寒川アクアブログ

美容師しながらアプリ開発していて水草が趣味の私のブログです

SearchViewを使って検索のインテントを発行する

SearchViewを使って検索のインテントを発行する方法です。

ウィジェットとして任意の位置に配置できるほうのSearchViewです。
画面上部に現れる検索ダイアログや、アクションバーに組み込まれている検索ボックスではありません。

SearchView searchView = (SearchView)baseV.findViewById(R.id.searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String query) {
        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
        intent.putExtra(SearchManager.QUERY,query);
        startActivity(intent);
        return true;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        return false;
    }
 });

検索開始のボタン(虫眼鏡のアイコン)が押された時は、
onQueryTextSubmitが呼ばれ、検索ボックスに入力されたテキストは(String型)queryとして渡されます。
黙示的インテントを発行し、外部アプリで検索を行います。

サーチビューに文字列をセットするときは、
setQuery(CharSequence query,boolean submit)
を使い、第二引数には、すぐに検索するかどうかをboolean型で指定します。

最後にボタンを押してから数秒後に一回だけ処理をする

最後にボタンを押してから数秒後に一回だけ処理をする方法です。

たとえばフローティングアクションボタン(FAB)を設置していて、
ユーザーが何かをしているときはFABは隠しておき、操作が終わった後にちょっと間を置いて再び表示したいときなどに。

private Handler handler;

    //    Handlerのインスタンスをフィールドに宣言

private void doSomethingLater(){

    if (handler != null) {
        handler.removeCallbacksAndMessages(null);

        //    既に予定があればそれはキャンセルする

    }

    handler = new Handler();

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {

            Toast.makeText(getApplicationContext(),"HELLO!",Toast.LENGTH_SHORT).show();

        }
    },3000l);    //    処理を予約します
}

doSomethingLater()を呼び出してから3秒後にトーストを表示します。
トーストが出る前に、再度 doSomethingLater() が呼ばれた場合は、
そこから3秒後に初めてトーストを表示します。

画面の向きを取得する

現在の画面の向きを取得する方法です。

Configuration configuration = getResources().getConfiguration();
switch(configuration.orientation) {
    case Configuration.ORIENTATION_PORTRAIT:   

    //    縦向き
       
        break;
    case Configuration.ORIENTATION_LANDSCAPE:

    //    横向き

        break;
}

Configurationクラスのorientationフィールドを調べることで、画面の現在の向きを知ることができます。

テキストサイズをButtonに収まるように調整する

テキストサイズをButtonに収まるように調整するためのメソッドです。
TextViewでテキストサイズを自動調整する方法は検索すると多数出てきます。
こちらを参考にさせていただきました。ありがとうございます。
TextViewのフォントサイズを自動調整する。 - monaka android memo

今回はボタンのように、テキストをあまり変えることがないViewでテキストサイズを調整する場合に便利なメソッドを定義しました。

private float resize(Button button) {

        final float MIN_TEXT_SIZE = 10f;//最小サイズを決める

        String text = button.getText().toString();
        int padding = button.getPaddingLeft();//
        Paint paint = new Paint();

        int viewWidth = button.getWidth() - (padding * 2);//Viewのコンテンツ領域を取得
        int viewHeight = button.getHeight() - (padding * 2);//パディングは左右同じとして
        
        float textSize = 200f;//テキストサイズの初期値を適当に決める

        paint.setTextSize(textSize);//テキストサイズをセット

        Paint.FontMetrics fm = paint.getFontMetrics();
        float textHeight = (Math.abs(fm.top)) + (Math.abs(fm.descent));//テキストの高さを取得

        float textWidth = paint.measureText(text);//テキストの幅を取得

        while (viewWidth < textWidth || viewHeight < textHeight) {//ボタンに収まるまでループ

            if (MIN_TEXT_SIZE >= textSize) {//最小サイズを下回ったら最小サイズに設定
                textSize = MIN_TEXT_SIZE;

                break;
            }

            textSize -= 8f;//テキストサイズをデクリメント(間隔は適当に)

            paint.setTextSize(textSize);

            fm = paint.getFontMetrics();
            textHeight = (Math.abs(fm.top)) + (Math.abs(fm.descent));
            textWidth = paint.measureText(text);//テキストの縦横サイズを再取得
        }

        button.setTextSize(TypedValue.COMPLEX_UNIT_PX,textSize);//収まるサイズに設定

        return textSize;

    }

ButtonのプロパティのSingleLineにチェックを入れて下さい。
引数にButtonを渡すと、Buttonのテキストを取得し、サイズを調整します。
調整したサイズをリターンするので、他の同じようなButtonのテキストサイズを調整するには、その値を使えます。
(例:電卓の数字キーなど)
オンクリエイト内等で実行すると、Viewのサイズが0なので文字が小さくなってしまいます。
Viewのサイズと、文字列がわかった時点で実行してください。

ご注意。独自フォントを設定していると、フォントによってはテキストサイズがはみ出してしまったり、
期待通りの結果にならないことがあるようです。
その場合の解決策は、まだ自分で試していないので、確認したら追記します。

EditTextの指定位置にカーソルを移動

EditText備忘録

指定位置にカーソルを移動する

エディットテキストのsetSelection(int型)メソッドの引数にカーソルの位置を指定します。
0で、文字列の先頭になります。

EditText editText;
editText.setSelection(3);
文字列の最後にカーソルを移動する
editText.setSelection(editText.getText().toString().length());

EditText等で、バックスペースの入力を検出する

EditTextの入力中に、ソフトキーボードのバックスペースキーが押されたときのイベントの検出は、以下のようにします。

mEditText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {

        if (event.getAction() == KeyEvent.ACTION_DOWN){

            if (keyCode == KeyEvent.KEYCODE_DEL){
                       
            //    バックスペースが押された

            }
        }
        return false;
    }
});

単純に、「押された時」を知るための方法です。
KeyEvent.ACTION_DOWNまたはACTION_UPのどちらかを判別しないと、
タップした時と指を離した時の2回、イベントが呼ばれてしまいます。

EditText等で、Enterキーの入力イベントを検出する

ユーザーがEditTextで文字を入力中に、ソフトキーボードのEnterキーが押されたときのイベントを検出する方法です。

EditTextに以下のようにリスナーをセットします。

mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE){
        
        //    Enterが押されたときに行いたい処理

        }
        return false;
    }
});

ただし、EditTextが複数ある場合だと、Enterを押したときに次のEditTextにフォーカスが移ってしまい、
このイベントが呼ばれません。

ちょっと強引ですが、if分に以下の条件を追加することで、イベントを検出できます。

if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_NEXT){
}

 ソフトキーボードの右下のEnterの位置にあるボタンは、ユーザーの入力の状況によってアクションが「GO」、「次へ」、「検索」のように変化します。
本来ならば、それぞれのアクションに応じた振る舞いを検討するのが良いのかもしれません。