Android開発してて思った

Android開発をしていて思ったことを書いていきます

戻るボタンのイベントを取得する方法

場合によって戻るボタンを押したときに画面を戻りたくない場合があると思います。

戻るボタンのイベントを取得するにはActivity.onKeyDown()で処理を行います。

引数のkeyCodeに何のボタンが押したのか入っているので
戻るボタン(KeyEvent.KEYCODE_BACK)で分岐して処理を加えます。

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK) {
        // 戻るボタンの処理
        if(mCurrentMode == MainActivity.MEMO_EDIT) {
            // 編集しているときにメモボタンを押したときは警告をする
            Toast.makeText(this, "編集中は戻れません", Toast.LENGTH_SHORT).show();
            return false;
        }
       return super.onKeyDown(keyCode, event);
    } else {
        return super.onKeyDown(keyCode, event);
    }
}

ActionBarのメニューアイテムを消すには

メニューを消すには
onCreateOptionsMenu()の引数MenuのfindItem()メソッドを使い
メニューアイテムを取得して、そのアイテムを表示をsetVisible()でfalseにします

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.menu_memo_edit, menu);
    menu.findItem(R.id.action_memo_edit_new).setVisible(false);
}

ListFragmentから子ビューを取得して変更する

ListFragmentで子Viewを取得する方法です。

リストから選択してタップした場合にはOnClickListenerでViewを取得しているので
そこから取得すればいいのですが、ActionBarのメニューを押したときに
リストの見た目を変更したい場合にはどのようにViewを取得すればよいのでしょうか。

まずはじめにListFragmentのgetListView()で自身のListViewを取得します。
そして、getChildAt(position)でpositionで指定した位置にあるViewが取得できます。

下のサンプルコードではリストにあるViewの数だけループしてすべてのViewを設定しています。

ListView listView = getListView();
for(int i=0;i<listView.getCount();i++) {
    // リストの子ノードを取得して編集する
    View view = listView.getChildAt(i);
    // Viewの中にあるImageViewの背景を変更する
    ImageView imageView = (ImageView)view.findViewById(R.id.imageView1);
    imageView.setBackgroundColor(Color.RED);
}

eclipseでインデントを一発で揃える方法

A型人間なので、ソースコードを見ていても
インデントが揃ってないとなんとなく気持ちが悪い気してました。

だからいままでは手作業でインデントを揃えてましたけど、
さすがに嫌になってきたのでeclipseでそういった機能がないが探してみました。

ありました!
それも一瞬でできました。

エディタの領域で右クリック
[Source] -> [Format]
でできました。

ログを出力する

今回はいまさらながらAndroidでログを出力する方法について書きたいと思います。
アプリ開発をしているときにバグを検査するときに、
これってどんな値が入っていたんだろうってのを調べるのに役立ちます。

さて、ログを出力する方法は一般的にこのように書きます。

Log.v(TAG, "index=" + i);

TAGの部分はどこから出力されているのかを見分けるため識別用文字列です。
クラスのはじめの辺に書いておきましょう。
一般的にはクラス名を入れます。

private static final String TAG = "一般的にはクラス名をいれます";

こんな感じです。

private static final String TAG = "MyActivity";


ログ出力において、デバッグ用や致命的なエラー用など、
発生するログによって使い分けることもできます。
具体的にはLog.v()、Log.d()、Log.i()、Log.w()、Log.e()といったメソッドを使います。



ASSERTLog.println(Log.ASSERT, TAG, message)前提条件チェック用
DEBUGLog.d()デバッグ
ERRORLog.e()エラー発生用
INFOLog.i()情報用
VERBOSELog.v()詳細情報用
WARNLog.w()警告用

public class MainActivity extends Activity {
	
	private static final String TAG = "MainActivity";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Log.println(Log.ASSERT, TAG, "ASSERT MESSAGE");
		Log.e(TAG, "ERROR MESSAGE");
		Log.d(TAG, "DEBUG MESSAGE");
		Log.w(TAG, "WORN MESSAGE");
		Log.i(TAG, "INFO MESSAGE");
		Log.v(TAG, "VERBOSE MESSAGE");
	}
}

これを実行するとLogCatには、このように色分けされて表示されます。
f:id:rikisha-blog:20140501200839p:plain

例えば、エラーメッセージ以外は表示しないようにする場合
LogCat右側のリストを選択すると選択したものより重要でないエラーは出力されません。
f:id:rikisha-blog:20140501201122p:plain


Log | Android Developers

レイアウトの変更をアニメーション

Viewを追加してレイアウトを変更するときにアニメーションのように動きながら切り替える方法を紹介します。

変更予定のレイアウトに以下のコードを追加します。

android:animateLayoutChanges="true"

例えば、GridLayoutが変更される予定の場合は以下のように書きます。

<GridLayout
  android:columnCount="4"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/gridContainer"
  android:animateLayoutChanges="true"
/>

透明な画面を作成する

大手が作成するアプリには操作説明として通常の画面の上に
操作説明が表示されることがある。

アプリでさきのような操作説明画面を表示したい場合は、
透明なActivityを作成して透明な画面を本来の画面の手前に配置するとよい。

方法

AndroidManifest.xml

android:theme="@android:style/Theme.Translucent"  

を追加すればよい。

タイトルバーを非表示にしたい場合は

android:theme="@android:style/Theme.Translucent.NoTitleBar"

を使用する

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.clearactivitysample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.clearactivitysample.MainActivity"
            android:label="@string/app_name" 
            android:theme="@android:style/Theme.Translucent.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

半透明の画面を作成する

styles.xml

<drawable name="translucent_background">#44FF0000</drawable>
<style name="Theme.MyTrans" parent="android:style/Theme.Translucent.NoTitleBar">
  <item name="android:windowBackground">@drawable/translucent_background</item>
</style>

AndroidManifest.xml

<activity
  android:name="com.example.clearactivitysample.MainActivity"
  android:label="@string/app_name" 
  android:theme="@style/Theme.MyTrans" >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>