2013/12/15

Android で 円をきりとる。

タイトル微妙。
なんて表現していいかわからないがこんな感じの円を切り取ってつくる

2013/12/05

TextView の フォントを変えると中国っぽさがでる。フォントによっては・・・。

端末のフォントが気に食わないことも多々あるかと思います。そこで TextView フォントを変えましょうということに。ただ普通のフォントがいいのでいいものないかなーと探していたら、Android SDK のなかにフォントが入ってた。ソレを使ってみます。

/path/to/sdk/platforms/android-[xx]/data/fonts/
にたくさん入ってます。
※ [xx] はバージョン番号


2013/11/30

Android で隙間なく Button を並べる。

ボーダー付きのカスタムボタンをびっちり隙間なく並べると、カッコ悪い。連続したボーダーがあるもんだからボーダーが太くなる。こんな感じ。


結論からだと。ボーダーは定義しないで、隙間開けて背景色を見せることでボーダーっぽく見せる。なんか昔のhtmlみたいだ・・・。

なんやかんやでこうなる。一番上のはボーダーありだから太い箇所がある。
縦線だけ、ヨコ線だけ、あと最初と最後の要素だけ角丸も。角丸がちょっと微妙かも・・・。内と外の radius がなかなかビッタリいかない。悩みどころ。まあ許容範囲内?


もうちょっとスマートな方法ないものかしら?

style="?android:attr/buttonBarStyle"
style="?android:attr/buttonBarButtonStyle"

あたりをちゃんと理解すればいいのかな?

とりあえず今回のサンプルプロジェクトは githunb にあげておきます。
drawable と layout の中身見ればまあそれなりに。

2013/11/15

こんな Android コードは嫌だ

public class SomeActivity extends Activity {
ArrayList<String> list_items;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_some);
this.list_items = new ArrayList<String>();
this.list_items.add("one");
this.list_items.add("two");
this.list_items.add("three");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.some, menu);
return true;
}
private class ListAdapter extends BaseAdapter {
@Override
public int getCount() {
return list_items.size();
}
@Override
public Object getItem(int position) {
return list_items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.list_item, null);
}
String item = list_items.get(position);
// do something
return convertView;
}
}
}
view raw gistfile1.java hosted with ❤ by GitHub


うん。やだ。

2013/11/08

DialogFragment のイベントを Activity とか Fragment に伝えたい。

削除しますか?「はい/いいえ」の確認ダイアログ出して、「はい」したらもとの画面からも消えてるみたいな。ダイアログのイベントを元々の画面伝えたい。そんな感じのよくある話。

DialogFragment になにか渡したいときは Fragment の特徴である DialogFragment#setArguments() で渡さないといけない。でもリスナー渡したいときは一筋縄ではいかない。DialogFragment#setOnDoSomethingListener() なんかを生やしても大人の事情でダメ。ここでこうやってみる。

まずはなんにせよ Listener を作る。
public class ConfirmDialogFragment extends DialogFragment {
public interface OnButtonClickListener {
public void onPositiveClick();
public void onNegativeClick();
}
}
view raw gistfile1.java hosted with ❤ by GitHub

こんな感じ。

Activity に通知する場合。


Activity にリスナーを implements するの忘れない。Dialog 側は onAttach(Activity activity) をオーバーライドする。ライフサイクルに組み込まれてるこのメソッドでは Activity が渡されるので、そのアクティビティが Listener を implements してるかチェックできる。なので DialogFragment#setArguments() で渡さなくてもいい。
// DialogFragment
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
this.mOnDialogButtonClickListener = (OnDialogButtonClickListener)activity;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
view raw gistfile3.java hosted with ❤ by GitHub

こんな感じ。あとは必要なところでthis.mOnDialogButtonClickListenerのメソッド使えばいい。

Fragment に通知する場合。


DialogFragment にいつもの newInstance() を生やす。ここで引数に Fragment をとるようにして、DialogFragment#setTargetFragment() を使って Fragment を保持。必要なときに DialogFragment#getTargetFragment() から Fragment を取ってきてリスナーにキャストして使う。ちょっと回りくどい。

public class ConfirmDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
public interface OnDialogButtonClickListener {
public void onPositiveClick();
public void onNegativeClick();
}
public static ConfirmDialogFragment newInstance(Fragment fragment) {
ConfirmDialogFragment dialog = new ConfirmDialogFragment();
dialog.setTargetFragment(fragment, 0);
return dialog;
}
@Override
public void onClick(DialogInterface dialog, int which) {
OnDialogButtonClickListener listener;
try {
listener = (OnDialogButtonClickListener) this.getTargetFragment();
} catch (ClassCastException e) {
// リスナーなし
return;
}
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
listener.onPositiveClick();
break;
case DialogInterface.BUTTON_NEGATIVE:
listener.onNegativeClick();
break;
}
}
view raw gistfile4.java hosted with ❤ by GitHub

こんな感じでいいんじゃまいか。

2013/11/06

DialogFragment#dismiss() で NullPointerException がたまにでる。

「たまにでる」ここぽいんと。

ローディングのくるくるダイアログとか DialogFragment とかって出すことは、まあよくあると思う。そんな感じで出してたら NullPointerException でた。
こんな感じのとこ。

// ダイアログ出すとこは
// this.mLoadingDialog = LoadingDialog.newInstance("ちょっとまってねっ!");
// っていう感じでメンバ変数に入れといてる。
if (this.mLoadingDialog != null) {
this.mLoadingDialog.dismiss(); // ここでぬるぽ
}
view raw gistfile1.java hosted with ❤ by GitHub


いやいや、null じゃなければって言ってるでしょ?どうも DialogFragment の中で何かが null っぽい(例外メッセージ忘れた)なので、こう変えた。

// ダイアログ出す時
FragmentManager fragmentManager = this.getSupportFragmentManager();
LoadingDialog dialogFragment = LoadingDialog.newInstance("ちょっとまってねっ!");
dialogFragment.show(fragmentManager, LoadingDialog.DIALOG_TAG);
// ダイアログ消す時
FragmentManager fragmentManager = this.getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(LoadingDialog.DIALOG_TAG);
if (fragment != null && fragment instanceof DialogFragment) {
((DialogFragment)fragment).dismiss();
}
view raw gistfile2.java hosted with ❤ by GitHub


TAG を指定して生成、消すときも TAG 指定で取得、fragment が帰ってくるから一応 null チェックとそいつが DialogFragment かどうかを見て、dismiss() 呼び出す。これで一応 NullPointerException はなくなりました。ここらへんどうなんだろうかっていうのはある。ドキュメント見てもshow() の例は書いてるけど dismiss() の例もないものね。

追記


12-03 17:57:12.331: E/AndroidRuntime(5279): java.lang.NullPointerException
12-03 17:57:12.331: E/AndroidRuntime(5279): at android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:184)
12-03 17:57:12.331: E/AndroidRuntime(5279): at android.support.v4.app.DialogFragment.dismiss(DialogFragment.java:155)


こんなかんじの例外でした。

2013/07/21

Android でクラスを作るときに TAG も一緒につくる。

Log.d(TAG, "hogehoge")
とか何かと物入りな TAG という代物。

クラスを作成するたびに
private static final String TAG = "hoge";
とかやっていたけど、まあめんどいし忘れるし。
うまいことできんかと思ったらテンプレート機能が Eclipse さんには備わっておる。