DialogのsetCancelableの微妙な罠
Dialogクラス内(onCreateDialogなど)で設定するときちんと設定されない。
Dialogインスタンスから呼び出せばきちんと設定される。
Uriを改めて復習
例:content://image/favorite?id=4&referer=from_ok
schemeはcontent
authorityはimage
pathは/favorite
query1はid = 4
query2はreferer = from_ok
スキームとは、「://」までの、すべての文字列を指す。
オーソリティーは、「://」から、次の「/」「?」「#」までのすべての文字列を指す。
パスは、「/」を含めた、次の「/」までを指す。
クエリは、「?」から「&」までの、「=」で分けられた部分を指す。
おばかな例として、
content:///favorite?id=4
ならば
schemeはcontent
authorityは空
pathは/favorite
query1はid = 4
となる。
ちなみにAndroidでは、authorityとは、hostを指す模様。
Manifestに記述する際には、Pathに「/」を忘れないのと同様、注意せねば。
ButterKnife(Androidライブラリ)を使う
昨今流行のView Injection Library。
findViewByIdの嵐を防ぐことができる。
インストール自体は、Android Studioであればappの方のbuild.gradleに追加するだけなので簡素。
詳細は公式ページを参照。
http://jakewharton.github.io/butterknife/
Activityで使用する場合と、Fragmentで使用する場合で使い方が微妙に違う点は注意。
Activityで使用する場合
MainActivity.java
. . . @InjectView(R.id.button) Button mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); mButton.setText("hello"); } . . .
Fragmentで使用する場合
SampleFragment.java
. . . @InjectView(R.id.button1) Button mButton1; @InjectView(R.id.button2) Button mButton2; @InjectView(R.id.button3) Button mButton3; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_sample, container, false); ButterKnife.inject(this, view); return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { mButton1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO: your logic } }); mButton2.setText("hello"); mButton3.setVisibility(View.INVISIBLE); } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.reset(this); } . . .
主な違いとしては、FragmentではButterKnife.resetを走らせる必要があることと引数が異なるという点。
AcitivityとFragmentのライフサイクルの違いが影響している模様。
Viewの生成簡略化の他に、Eventなどの記述を簡略化する方法も存在するが、個人的に微妙な気がする。
Viewの中身をLogで確認できるViewDebugのdumpCapturedViewが便利
使用例
MainActivity.java
. . . @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button b = (Button) findViewById(R.id.button1); // こいつ ViewDebug.dumpCapturedView("SAMPLE_TAG", b); } . . .
Logには
D/SAMPLE_TAG﹕ android.widget.Button: getBottom()=0; getContext()=com.tatuas.android.sample.MainActivity@425f5d20; getHint()=null; getId()=2131230720; getLeft()=0; getRight()=0; getText()=; getTop()=0;
といった感じで出力される。
JavaでPHPのimplode的なことをしたい
なさそうなので、仕方なく作った。
public String implode(List<String> values, String glue) { StringBuilder sb = new StringBuilder(); int index = 0; int size = values.size(); for (String value : values) { sb.append(value); if (index <= size - 2) { sb.append(glue); } index++; } return sb.toString(); }
Activityから特定のViewを削除する(GONEではないよ)
ViewGroup p = (ViewGroup) view.getParent(); p.removeView(view);
AndroidでTimerを実装してみる
俺のTimerTaskクラス
public class MyTimer extends TimerTask { public Context context; public Handler handler = new Handler(); public MyTimer(Context context) { this.context = context; } @Override public void run() { handler.post(new Runnable() { public void run() { try { Toast.makeText(context, "hello", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } } }); } }
俺の実行方法
public class MyActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // これ new Timer(true).schedule(new MyTimer(), 5000); } }
Javaで日付文字列からタイムスタンプを取る
SimpleDateFormat sdf = new SimpleDateFormat(); sdf.applyPattern("yyyy/MM/dd HH:mm:ss); Date d = sdf.parse("2014/01/01 11:00:22"); long timeStamp = d.getTime() / 1000;
AndroidのTextUtils.isEmptyを使う
# echo true Log.d("TextUtilsSample", String.valueOf(TextUtils.isEmpty(null))); # echo false Log.d("TextUtilsSample", String.valueOf(TextUtils.isEmpty("hello")));
Android Studioで右下にIDEのメモリ使用量を出す
Preferenceを開き、Appearanceのshow memory indicatorにチェックをつける。
Nexus 7(2013)にUbuntuから「L」を入れてみた
Google I/Oを見ていたら、入れたくなってしまった。
必要なもの
・Android SDK(fastbootへのPathを通す)
・ファクトリーイメージ(Google Developerからダウンロードする)
$ tar xvzf razor-lpv79-preview-d0ddf8ce.tgz
$ cd razor-lpv79
$ unzip image-razor-lpv79.zip
これで準備完了なのであとはアップデート。
端末の電源をOFFにし、電源ボタン+ボリュームダウンボタンを長押しでブートモードに切り替え。
ドロイドくんのお腹が開いている画面が出たら、PCに接続。
接続後、
$ adb reboot bootloader $ fastboot oem unlock $ ./flash-all.sh
を実行。SDKのインストール方法によってはsudo権限が必要。
途中でブートローダを本当に解除するか端末にYesかNoを選択する画面がでるが、ボリュームボタンでYesを選択し電源ボタンでOKする。ほかは基本的に眺めるだけ。5分かからない。完了後は端末側で自動で再起動するので、あとはアカウント設定するだけ。
なお、インストール完了後、
$ fastboot oem lock
を忘れないようにする。
端末起動時にGoogle画面で鍵マークが出る場合、ブートロックが解除されている状態なので、上記コマンドで再びロックをかける。
UbuntuのGUIが固まってしまったら
Ctrl + Alt + F6でターミナル起動。(ちなみにCtrl + Alt + F7でGUIに戻る)
ユーザ名でログインしたら
$ sudo service lightdm restart
で再起動。
LinuxでコマンドからHDDなどをマウント・アンマウント
デバイスと種類を把握する
$ sudo fdisk -l
実行
$ sudo mkdir /mnt/mountedhdd $ sudo mount -t exfat /dev/sdb1 /mnt/mountedhdd $ sudo ln -s /mnt/mountedhdd ~/hdd
アンマウント
$ sudo umount /mnt/mountedhdd
Gitでリモートブランチをローカルに取得
$ git checkout -b new-local-name origin/remote-branch
HashMapのIterator
HashMap<String, MyObject> maps = new HashMap<String, MyObject>(); Set<String> keys = maps.keySet(); Iterator<String> iterator = keys.iterator(); while (iterator.hasNext()) { String key = iterator.next(); MyObject object = maps.get(key); }