Adsenseバナー

ラベル Android Tips の投稿を表示しています。 すべての投稿を表示
ラベル Android Tips の投稿を表示しています。 すべての投稿を表示

2015年3月19日木曜日

AndroidのTextViewにHTMLを表示するのは意外と厳しいお話

StickyText 1.4では、ノートのテキストをHTML形式で表示できるようにしました。
情報もそこそこあるし楽勝と思いきや、悪戦苦闘になったため、ハマった点を書いておきます。

主に Html#fromHtml() の話です。

2010年12月30日木曜日

子Activityからアプリを終了する方法

各画面ごとにActivityを作って問題になったのが、子Activityからアプリを終了するときどうする?ということでした。
Activity#finish()を呼んでも、それを呼び出したActivityしか終了しないので、Backキーと同じことになる。
子Activityから親Activityが簡単に取得できないようで、やり方が見つかりませんでした。

で、どうしたかというと、Activityの呼び出しにActivity#startActivity()ではなく、Activity#startActivityForResult()で子Activityの終了コードを見ることにしました。
子の終了コードが「終了」なら、自分もfinish()する。
さらに、自分に親がいることも考えて、自分の終了コードを「終了」にする。
つまり、以下のようなコード。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_CLOSE) {
        setResult(RESULT_CLOSE);
        finish();
    }
}

これを全部のActivityに仕込んでおけばOK。
これを仕込んだBaseActivityを作ろうかとも思ったけど、TabActivityを継承してるやつとかもあって、そういった拡張Activityごとに用意するのが面倒だったので、とりあえず今回は見送りました。

Activity間を行ったり来たりするときのActivityの呼び方

例えば、「今僕たちに必要な買い物」では買い物リスト画面とカタログ編集画面はそれぞれ別Activityで作っていて、お互いボタンにより行き来が可能です。
つまり、買い物リスト画面(画面A)にはカタログ編集ボタンがあって、それを押せばカタログ編集画面(画面B)に移る。
カタログ編集画面(画面B)には買い物リストボタンがあって、それを押せば買い物リスト画面(画面A)に移る。

そこで、「メニュー→画面A→画面B→画面A→画面B→画面A→…」と、交互に繰り返し画面を切り替えたとき、Backキーを押したらどうなるのが一番自然でしょうか。
「…→画面A→画面B→画面A」の状態で、Backキーを押していくと、次のようになってほしいと僕は思います。

「メニュー←画面B←画面A」

でも、デフォルトのままだと「メニュー←画面A←画面B←…←画面A←画面B←画面A」になります。
これは良くないということで、いろいろ調べて試したところ、次のようにしてIntentにフラグを追加すればいいということがわかった。

intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

Intentにフラグを追加することで画面遷移の仕方を制御可能で、上述のような遷移はFLAG_ACTIVITY_REORDER_TO_FRONTで実現できます。
これは、すでに存在するActivityを呼び出したときは、履歴スタックの一番上に持ってくるといった動きをします。
存在しない場合は、新しくActivityを作り、やはり履歴スタックの一番上にセットします。

ネットで検索したとき、この情報があまりなかったので、それほど使われてないのでしょうか?
僕は一番自然だと思うのですが。。。

ListViewで奇数行/偶数行での色分け

「今僕たちに必要な買い物」のListViewは奇数行/偶数行で色を変えています。
毎回そのロジックを入れるのも馬鹿らしいので、それ用のAdapterを作成しています。
以下にコードを載せるので、よろしかったら使ってください。
継承したAdapterクラスを作って、それをListViewにセットすればOKです。
ネーミングセンスが気に入らないときはリファクタリングをどうぞ。

import java.util.List;

import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

abstract public class EvenOddArrayAdapter<t> extends ArrayAdapter<t> {

    private int listOddColor;
    private int listEvenColor;
    protected LayoutInflater inflater;

    public EvenOddArrayAdapter(Context context, int textViewResourceId, List<t> objects, int oddColor, int evenColor) {
        super(context, textViewResourceId, objects);
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Resources resources = context.getResources();
        listOddColor = resources.getColor(oddColor);
        listEvenColor = resources.getColor(evenColor);
    }

    public EvenOddArrayAdapter(Context context, List<t> objects, int oddColor, int evenColor) {
        this(context, 0, objects, oddColor, evenColor);
    }

    /**
     * @see android.widget.ArrayAdapter#getView(int, android.view.View,
     *      android.view.ViewGroup)
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView != null) {
            convertView.setBackgroundColor((position & 1) == 1 ? listOddColor : listEvenColor);
        }

        return convertView;
    }
}

注意事項
  1. コンストラクタの引数 oddColorとevenColorはリソースIDです。
  2. getView()ではsuper.getView()を呼び出していないため、行にフォーカスが当たったときなどに表示が変えられないという欠点があります。(うまいやり方がないものか。。。)

Alert Dialogの標準ボタン操作

Alert Dialogは3つのボタンを持っています。

  1. Positive Button(主にOKボタンとして)
  2. Neutral Button(主に…なんだろう?Noボタンがあった場合のキャンセルボタンとか?)
  3. Negative Button(主にNoボタンやキャンセルボタン)

で、これらを使いたいときは、AlertDialog.Builder#set~~Button()を使えばいい。
それはいいんですが、今回、このボタンの有効/無効を制御したかったのに、すんなりできなかったのでメモ。

2010年12月29日水曜日

ListViewで独自の行レイアウトを使ったときのContextMenu表示

Androidでは一覧において、行に対するコンテキストメニュー(ポップアップメニュー)を表示させたい場合、その行を長押し(Long Click)する方法が標準的です。

で、プログラミングではどうやるのかは、ネットで探せば親切なサイトがたくさんあって、苦労せず実装できます。
…が、しかし、苦労しないはずが、なぜか苦労してしまったので、ハマったところのメモ。

タブ表示を独自のものにする

「今僕たちに必要な買い物」のカタログ編集画面では、左の画像のように、カテゴリごとにタブを分けて表示しています。
このタブ表示は独自に定義したレイアウトで行っていますが、その方法がなかなかネット上で見つからなかったので、ここに記録。
タブ表示はTabActivityを使うのが一般的のようです。
その方法は検索したらいっぱい出てきました。
が、しかし、それらのサンプルは「タブの背景画像が標準のまま」であって、文字列やアイコンは設定できるものの、タブの背景画像を自分の好きな表示に変える方法がなかなか見つからなかった。
デフォルトのままだと、全体の雰囲気と合わないし、表示領域がでかすぎるので、どうしても変えたい。

世の中に出回っているアプリはよく、タブの背景を変えている。
絶対変えられるはずだと、APIリファレンスを見て試したところ、怪しいのがあったので試したら成功。
以下、やり方。