最近使ったアプリに表示されないようにするには

最近使ったアプリに表示されないようにするには

最近使ったアプリ一覧に表示したくない場合
android.intent.action.Mainが指定されている
メイン画面のactivity要素へ
excludeFromRecents=”true”
を追加する

注意点として
サブ画面のactivity要素へ
excludeFromRecents=”true”
を設定しても有効にはならないので注意

回転してもActivityを破棄しないようにする

回転してもActivityを破棄しないようにする

通常は、画面回転時にはActivityは破棄されてから再生される

このとき、Activityを破棄しないようにするためには
AndroidManifest.xmlの

android:configChanges=””
を指定する

android:configChanges="orientation|screenSize"

また、回転時に処理をしたいのなら
Javaで
onConfigurationChanged()

overrideする

@Override
public void onConfigurationChanged(Configuration newConfig){
Log.i(TAG, "onConfigurationChanged");
super.onConfigurationChanged(newConfig);
}

アクションに対応するアプリの一覧を取得

アクションに対応するアプリの一覧を取得

これは、暗黙的インテントで呼び出せるアプリの一覧を表示できる

パッケージ名も取得できるため
明示的インテントのときにも使える

アクションに対応するアプリ一覧を取得するには
PackageManagerの
queryIntentActivities()を使えば、
引数に指定したIntentの情報にマッチするActivity一覧を取得できる

ACTION_VIEWアクションに対応するアプリ一覧を取得したいのなら

PackageManager pg = getPackageManager();

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);

List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

これで、一覧が表示される

インストールされているアプリ一覧の取得

インストールされているアプリ一覧の取得

アプリのバージョン取得したり
アクションに対応するアプリの一覧作成に使う

インストールされているアプリ一覧を取得するには
PackageManagerの
getInstalledApplications()
を使う

アプリ一覧を取得するソースは

PackageManager pg = context.getPackageManager();
List<ApplicationInfo> appInfoList = pm.getInstalledApplications(PackageManager.GET_META_DATA);

これで、ApplicationsInfoの中にアプリに関する様々な情報がふくまれる

そして、アプリ名の取得

アプリ名を取得するには
PackageManagerの
getApplicationLabel()の引数に
ApplicationsInfoインスタンスを渡すことで取得できる

String appLabel = pm.getApplicationLabel(appInfo).toString();

これで、インストールされているアプリ名がわかるようになる

アプリのバージョン取得

アプリのバージョン取得

インストールされているアプリ一覧を取得したり
アクションに対応するアプリ一覧を作成するときに使う

アプリのバージョンを示す
versionCode
versionName

PackageInfoクラスの
versionCode/versionNameプロパティから取得できる

なお、例外発生もあるので
try~catchで処理を行う

PackageManager pm = getPackageManager();

int versionCode =0;
String versionName="";

try{
PackageInfo packageInfo = pm.getPackageInfo(getPackageName, 0);

//AndroidManifest.xmlの versionCode
versionCode = PackageInfo.versionCode;

//AndroidManifestでのversionName
versionName = packageInfo.versionName;

}catch(NameNotFoundException e){
e.printStackTrace();
}

versionNameは自由に文字列を指定できるけど
versionCodeには数値しか入らない

また、アプリをインストールするときには
現在インストール中のアプリの
versionCodeより低い値では上書きすることができない

チェックするところは
AndroidManifest.xmlの

android:versionCode="1"
android:versionName="1.0"

のところ

スワイプで切り替わるが画面の作成

スワイプで切り替わるが画面の作成

いくつかのページがある場合
左右にスワイプで切り替えできると便利

スワイプで切り替わる画面を作成するには
ViewPagerクラスを使う

そして、表示するFragmentは
FragmentPagerAdapterを継承したクラスへ作る

まずは、レイアウト定義のファイル作成

<LinearLayout 
xmlns:android="http://scheams.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<android.support.v4.view.viewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.viewPager>

</LinearLayout>

次に、PagerAdapterを継承したクラスを作成

これは、画面が切り替るタイミングで
Fragmentを生成する FragmentPagerAdapterクラスを作成する

まずは、レイアウト定義

<LinearLayout 
xmlns:android="http://scheams.android.com/apk/res/android"
xmlns:ads="http://scheams.android.com/apk/lib/com.google.ads"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<android.support.v4.view.viewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</android.support.v4.view.viewPager>

</LinearLayout>

次に、PagerAdapterを継承したクラスの作成

画面が切り替わったタイミングで
Fragmentを生成するFragmentPagerAdapterクラスを作成する

public static class ViewPagerAdapter extends FragmentPagerAdapter{

private String[] values = new String[]{"page1","page2"};

public ViewPagerAdapter(FragmentManager fm){
super(fm);
}

@Override
public Fragment getItem(int position){
ViewPagerFragment fragment = new ViewPagerFragment();

Bundle args= new Bundle();
args.putString("value", values[position]) ;
fragment.setArguments(args);
return fragment;

}

@Override
public int getCount(){
return values.length;
}
}

長さ取得には lengthを使うと便利

次に、ViewPagerクラスへPagerAdapterクラスをセット

最初に、部品のインスタンスを取得してセットする

今回はonCreate()の中でやる

mAdapter = new ViewPagerAdapter(getSupportFragmentManager());

mPager = (ViewPager)findViewById(R.id.pager);

mPager.setAdapter(mAdapter);

これで、スワイプで切り替わる画面ができる

もし、大量のページがあるなら
FragmentPagerAdapterの代わりに
FragmentStatePagerAdapterを使う

レスポンスは悪くなるけど
ページが表示されなくなると破棄するため
メモリ節約になる

ナビゲーションドロワーの作成

ナビゲーションドロワーの作成

YouTubeやGmail GoogleMapなどの
Googleが作っているアプリのほとんどが
画面端からメニューを引き出して操作するようになった

このような画面の端からスライドして引き出すメニューのことを
ナビゲーションドロワーという

英語だとNavigationDrawer

ちなみに、NavigationDrawerは
Android標準機能ではなく
Android Support Libraryで提供されている仕組みになる

なので、自分のプロジェクトのlibsディレクトリへ
android-support-v4.jar
を追加する

また、NavigationDrawerの実装には
NavigationDrawerがあることを示すマーク画像
スライドメニューの影画像が必要になる

とはいっても
NavigationDrawerのサンプルがあるので
それをダウンロードして自分のアプリに設置すればok

ダウンロードURLは
http://developer.android.com/training/implementing-navigation/nav-drawer.html

ここで、Download the sample app
をクリックし、ダウンロード

ダウンロードした圧縮ファイルを解凍すると
NavigationDrawerフォルダができるので

その中の
res/drawable-xhdpiディレクトリの中に
drawer_shadow.9.png

oc_drawer.png
があるので
これをプロジェクトの
res/drawable-xhdpi/
へコピーする

他の解像度のディレクトリにも入れれば
それぞれの端末画像でも綺麗に表示される

次に、レイアウトファイルへの追加

Activityのレイアウト定義の一番下へ
DrawerLayoutを書く

そして、その中に画面のメインレイアウトとなるFrameLayoutと
そこで使うスライドメニュー用のレイアウトになるListViewを設定する

<android.support.v4.widget.DrawerLayout 
xmlns:android="http://scheams.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- メインコンテンツレイアウト -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"/>
</FrameLayout>

<!-- スライドメニュー用レイアウト -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@android:color/background_light"/>

</android.support.v4.widget.DrawerLayout>

これでレイアウト定義はできたので
次にJavaでレイアウトの呼び出し

これは、通常のボタンのように
findViewById()で取得する

まずは、パーツの宣言

private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private TextView mTextView;

次にonCreate()の中で、各Viewの取得

ちなみに、setupNavigationDrawer()は
自作のユーザー関数

mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
mDrawerList = (ListView)findViewById(R.id.left_drawer);
mTextView = (TextView)findViewById(R.id.text);

setupNavigationDrawer();

そして、NavigationDrawerを使うための設定を
setupNavigationDrawer()へ書いていく

private void setupNavigationDrawer(){

//NavigationDrawerの影を指定
mDrawerLayout.setDrawerShadow(R.drawable/drawer_shadow, GravityCompat.START);
mDrawerList.setOnItemClickListener(this);

//ActionBarの左へDrawerToggleを表示
getActionBar().setDisplayHomeAsUpEnabled(true);

//ActionBarのホームボタンを有効化
getActionBar().setHomeButtonEnabled(true);

//Drawerを開閉したときのイベントを受け取る

mDrawerToggle = new ActionBarDrawerToggle(this,
mDrawerList, 
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close){

@Override
public void onDrawerClosed(View v){
}

@Override
public void onDrawerOpened(View drawerView){
}

};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}

次に、DrawerToggleでオプションメニューの選択を検知可能にする

@Override
public boolean onOptionsItemSelected(MenuItem item){
if(mDrawerToggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}

次に、DrawerToggleでオプションメニューの制御

@Override
protected void onPostCreate(Bundle savedInstanceState){
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}

そして、DrawerToggleで上下の変更の制御

@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}

そして、ボタンを押したときの処理

@Override
public void onItemClick(AdapterView<?> adapterView, View parent, int position, long id){
selectItem(position);
}

次に、アイテム選択時の処理

@Override
public void selectItem(int position){
ListAdapter adapter = mDrawerList.getAdapter();
String item = (String)adapter.
getItem(position);

mTextView.setText("選択したアイテム: "+item);

mDrawerLayout.closeDrawer(mDrawerList);
}

これで、NavigationDrawerが作成できる

Androidでタブ画面の作成

Androidでタブ画面の作成

画面でタブ画面を作成すると用途ごとの切り替えができてみやすくなる

クックパッドとか
楽天証券のiSpeedなどがタブ画面をつかっている

画面でタブを使うには
TabWidgetクラス
FragmentTabHostクラス
を使う

まずは、レイアウトファイル作成

<android.support.v4.app.FragmentTabHost xmlns:android="http://scheams.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal"/>

<FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

</LinearLayout>

</android.support.v4.app.FragmentTabHost>

次に、Javaで
TabWidgetクラス
FragmentTabHostクラスを使い、
画面でタブを使うように
onCreate()へ追記する

mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabhost.setUp(this,  getSupportFragmentManager(), R.id.realtabcontent);

for(String tag:tags){
Bundle bundle = new Bundle();
bundle.putString("value",tag);
mTabhost.addTab(mTabhost.newTabSpec(tag).setIndicator(tag),
TabFragment.class, bundle);
}

これで、タブ追加できる

FragmentTabhostクラスは、
setup()で初期化後、Fragmentをタブコンテンツへ追加できる
そして、setIndicator()でタブのテキストを指定する

AndroidでViewで使える数値の単位

AndroidでViewで使える数値の単位

dp
画面密度の基準単位

sp
OSのフォントサイズを基準にする単位

pt
1/72インチを1ptとする単位

px
画面のピクセルを基準にする

mm
ミリメートル単位

in
インチ単位

基本的には
Viewのサイズ設定にはdp

フォントサイズ設定ならspを使う

書籍ではよく
50dpとかで指定しているけど
これはわかりやすさ重視のため

Androidは、機種ごとのディスプレイサイズや解像度がかなり異なるため
dimens
xml
のリソースを準備して数値を定義して
マルチデバイス対応にするほうがベター


から送られてきた高速メモ帳

Androidの背景設定

Androidの背景設定

背景設定は
android:background=””
で設定する

設定できるのは
通常の画像
shapeリソース
9patch

まずはShapeの場合

これには、まず背景用のShapeリソースを作成する

ソースは
/res/drawable/shape.xml

<shape
xmlns:android="http://scheams.android.com/apk/res/android">
<gradient
android:angle="270"
android:endColor="#FF2A68"
android:startColor="#FF53A"/>

<corners android:radius="10dp"/>
</shape>

次に、作成したレイアウトファイルを
背景に設定するので
android:background=””
で指定する

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/padding_xlarge"
android:background="@drawable/shape"
android:padding="@dimen/padding_large"
android:text="shapeを使った背景"/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/padding_xlarge"
android:background="@drawable/normal"
android:text="普通の背景画像"/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/padding_xlarge"
android:background="@drawable/9patch"
android:text="9patchでの画像"/>

今回は一緒に
普通の場合と9patchの場合も追加

shapeリソースのメリットは
XMLなのでファイルが軽いこと
そして、Viewのサイズに依存しないので画質が一定になること

これは、グラデーション背景とか
角丸ボタンの作成に使われる

そして、9patchのメリットは
伸縮するのが前提なので、小さい画像ファイルでできるため
こちらもファイルサイズを小さくできる
またshapeみたいにViewのサイズに依存しないので画質が一定になる
さらに、コンテンツの表示領域の指定も可能

これは、画像こ一部だけをのばしたり
EditTextで特定の場所だけ入力欄にするときに使う

9patchリソースは
Android SDK の中の toolsディレクトリの中にあるツールの
draw9patch
を使うことで作成できる