Tab を作ってみた その2

XMLリソースを使わずにTabを作る場合(XMLリソース使う場合は Tab を作ってみた)
Intent を指定するか,
TabHost.TabContentFactory インターフェースを使用する.

TabContentFactory の public View createTabContent(String tag) を実装すると,
返り値の View がそのまま Tab の画面に表示される

というわけで,Tab を作ってみる

サンプルコード
public class TabSample extends TabActivity implements TabHost.TabContentFactory {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // TabHost の取得
    final TabHost tabHost = getTabHost();
    
    // アイコン付きタブ
    tabHost.addTab(tabHost.newTabSpec("tab1")
        .setIndicator("tab1", getResources().getDrawable(R.drawable.icon))
        .setContent(this));
    
    // 任意の View
    tabHost.addTab(tabHost.newTabSpec("tab2")
        .setIndicator("Views")
        .setContent(new MyTabContentFactory()));

    // Intent を起動するタブ
    tabHost.addTab(tabHost.newTabSpec("tab3")
        .setIndicator("List")
        .setContent(new Intent(this, ListViewSample.class)));
  }

  public View createTabContent(String tag) {
    final TextView tv = new TextView(this);
    tv.setText("This is " + tag);
    return tv;
  }

  // TabContentFactory を実装したクラスの作成
  class MyTabContentFactory implements TabContentFactory {
    public View createTabContent(String tag) {
      // 任意の View を設定
      View view = LayoutInflater.from(TabSample.this).inflate(R.layout.views, null);
      return view;
    }  
  }
}

プログラムを実行すると...





こんな感じ!

参考サイト
http://developer.android.com/intl/ja/reference/android/widget/TabHost.TabContentFactory.html

ListPreference を使ってみた

ListPreference は
java.lang.Object
  ↳ android.preference.Preference
    ↳ android.preference.DialogPreference
      ↳ android.preference.ListPreference
を使います

List の Dialog を表示させる Preference の一つで
String型の値を SharedPreferences に保存します

というわけで,ListPreference をいじってみた

サンプルコード
public class EditTextPreferenceSample extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // addPreferencesFromResource(R.xml.edittext_preference);

    PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(this);

    PreferenceCategory pc = new PreferenceCategory(this);
    pc.setTitle(R.string.title_category);
    ps.addPreference(pc);

    EditTextPreference editTextPreference = new EditTextPreference(this);
    editTextPreference.setKey(getString(R.string.key_edittext_preference));
    editTextPreference.setTitle(R.string.title_edittext_preference);
    editTextPreference.setSummary(R.string.summary_edittext_preference);
    editTextPreference.setDialogTitle(R.string.dialog_title_edittext_preference);
    editTextPreference.setDialogMessage(R.string.dialog_message_edittext_preference);

    pc.addPreference(editTextPreference);
    setPreferenceScreen(ps);
  }
}

プログラムを実行すると...



こんな感じ!

XML で一括で作成することもできます

サンプルコード
public class ListPreferenceSample extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // XML で Preference を設定
    addPreferencesFromResource(R.xml.list_preference);

    // ListPreference の取得
    ListPreference listPreferrence = 
      (ListPreference) findPreference(
          getString(R.string.key_list_preference));
  }  
}

List_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen 
  xmlns:android="http://schemas.android.com/apk/res/android">
  <PreferenceCategory 
    android:title="@string/title_category">
    <ListPreference 
      android:key="@string/key_list_preference"
      android:title="@string/title_list_preference" 
      android:summaryOn="@string/summary_list_preference"
      android:entries="@array/entries_list_preference" 
      android:entryValues="@array/entryvalues_list_preference"
      android:dialogTitle="@string/dialog_title_list_preference" />
  </PreferenceCategory>
</PreferenceScreen>


参考サイト
http://developer.android.com/intl/ja/reference/android/preference/ListPreference.html

EditTextPreference を使ってみた

EditTextPreference は
java.lang.Object
  ↳ android.preference.Preference
    ↳ android.preference.DialogPreference
      ↳ android.preference.EditTextPreference
を使います

EditText を Dialog 上で表示させる Preference の一つで
String型の値を SharedPreferences に保存します

というわけで,EditTextPreference をいじってみた

サンプルコード
public class EditTextPreferenceSample extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(this);

    PreferenceCategory pc = new PreferenceCategory(this);
    pc.setTitle(R.string.title_category);
    ps.addPreference(pc);

    EditTextPreference editTextPreference = new EditTextPreference(this);
    editTextPreference.setKey(getString(R.string.key_edittext_preference));
    editTextPreference.setTitle(R.string.title_edittext_preference);
    editTextPreference.setSummary(R.string.summary_edittext_preference);
    editTextPreference.setDialogTitle(R.string.dialog_title_edittext_preference);
    editTextPreference.setDialogMessage(R.string.dialog_message_edittext_preference);

    pc.addPreference(editTextPreference);
    setPreferenceScreen(ps);
  }
}

プログラムを実行すると...



こんな感じ!

XML で一括で作成することもできます

サンプルコード
public class EditTextPreferenceSample extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // XML で Preference を設定
    addPreferencesFromResource(R.xml.edittext_preference);

    // EditTextPreference の取得
    EditTextPreference editTextPreferrence = 
      (EditTextPreference) findPreference(
          getString(R.string.key_edittext_preference));
  }  
}

edittext_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen 
  xmlns:android="http://schemas.android.com/apk/res/android">
  <PreferenceCategory 
    android:title="@string/title_category">
    <EditTextPreference 
      android:key="@string/key_edittext_preference"
      android:title="@string/title_edittext_preference" 
      android:summary="@string/summary_edittext_preference"
      android:dialogTitle="@string/dialog_title_edittext_preference" />
  </PreferenceCategory>
</PreferenceScreen>


参考サイト
http://developer.android.com/intl/ja/reference/android/preference/EditTextPreference.html

CheckBoxPreference を使ってみた

CheckBoxPreference は
java.lang.Object
  ↳ android.preference.Preference
    ↳ android.preference.CheckBoxPreference
を使います

checkbox の機能を持つ Preference の一つで
boolean型の値を SharedPreferences に保存します

というわけで,CheckBoxPreference をいじってみた

サンプルコード
public class CheckBoxPreferenceSample extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    CheckBoxPreference checkBoxPreference = new CheckBoxPreference(this);

    // Key の設定
    checkBoxPreference.setKey(getString(R.string.key_checkbox_preference));
    // Title の設定
    checkBoxPreference.setTitle(R.string.title_checkbox_preference);

    // サマリーを設定
    //checkBoxPreference.setSummary(R.string.summary_checkbox_preference);
    // CheckBox が On の時のサマリーを設定
    checkBoxPreference.setSummaryOn("Summary On");
    // CheckBox が Off の時のサマリーを設定
    checkBoxPreference.setSummaryOff("Summary Off");

    // PrefenceScreen & PreferenceCategory
    PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(this);
    PreferenceCategory pc = new PreferenceCategory(this);
    // PreferenceCategory のタイトルを設定
    pc.setTitle(R.string.title_category);
    // PreferenceCategory を PreferenceScreen に追加
    ps.addPreference(pc);
    // Preference を PreferenceCategory に追加
    pc.addPreference(checkBoxPreference);
    // PreferenceScrren の設定
    setPreferenceScreen(ps);

    // Preference がチェックされているか
    checkBoxPreference.isChecked();
    // チェック状態を変更
    //checkBoxPreference.setChecked(true);

    // Preference が変更されたときに呼び出されるコールバックの登録
    checkBoxPreference.setOnPreferenceChangeListener(
        new OnPreferenceChangeListener() {
          @Override
          public boolean onPreferenceChange(
              Preference preference,
              Object newValue) {
            // Preference が変更されたときの動作
            return true;
          }    
        });
  }  
}

プログラムを実行すると...



こんな感じ!

XML で一括で作成することもできます

サンプルコード
public class CheckBoxPreferenceSample extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // XML で Preference を設定
    addPreferencesFromResource(R.xml.checkbox_preference);

    // CheckBoxPreference の取得
    CheckBoxPreference checkBoxPreferrence = 
      (CheckBoxPreference) findPreference(
          getString(R.string.key_checkbox_preference));
  }  
}

checkbox_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen 
  xmlns:android="http://schemas.android.com/apk/res/android">
  <PreferenceCategory 
    android:title="@string/title_category">
    <CheckBoxPreference 
      android:key="@string/key_checkbox_preference"
      android:title="@string/title_checkbox_preference" 
      android:summaryOn="@string/summary_on_checkbox_preference"
      android:summaryOff="@string/summary_off_checkbox_preference" />
      <!-- android:summary="@string/summary_checkbox_preference" -->
  </PreferenceCategory>
</PreferenceScreen>


参考サイト
http://developer.android.com/intl/ja/reference/android/preference/CheckBoxPreference.html

SharedPreferences を使ってみた

Preference は Androidアプリでデータを保存する方法のひとつ
データをキーと値の組み合わせで保存します.

ファイルなどに保存するよりも非常に簡単にデータを保存できます

今回は SharedPreferences を...

SharedPreferences はまず
getSharedPreferences(String name, int mode);
でを取得してきます
name は Preference 自体の名前を指定します
mode には
  • Activity.MODE_PRIVATE
  • Activity.MODE_WORLD_READABLE
  • Activity.MODE_WORLD_WRITEABLE
などを指定します.

保存された Preference は data/data/パッケージ名/shared_prefs
の中に xmlファイルとして保存されるようです

取得する時は
  • getString(String key, String defValue);
  • getInt(String key, int defValue);
  • getLong(String key, long defValue);
  • ...
などを使って取得して着ます

というわけで,Preference を使ってみた

サンプルコード
public class PreferencesTest extends Activity implements OnClickListener {
  private static final String PREF_KEY = "preferenceTest";
  private static final String KEY_TEXT = "text";

  SharedPreferences pref;
  SharedPreferences.Editor editor;

  EditText mEditText;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.preferencestest);

    // SharedPrefernces の取得
    pref = getSharedPreferences(PREF_KEY, Activity.MODE_PRIVATE);

    mEditText = (EditText) findViewById(R.id.EditText);

    Button button;
    button = (Button) findViewById(R.id.Button);
    button.setOnClickListener(this);
    
    TextView textView;
    textView = (TextView) findViewById(R.id.TextView);
    // SharedPreferences よりデータを取得
    textView.setText(pref.getString(KEY_TEXT, "No Data"));
  }

  public void onClick(View v) {
    if (v.getId() == R.id.Button) {
      // Editor の設定
      editor = pref.edit();
      // Editor に値を代入
      editor.putString(
          KEY_TEXT,
          mEditText.getText().toString()
      );
      // データの保存
      editor.commit();
    }
  }
}

プログラムを実行すると...

保存して...

再び起動

こんな感じ!

ちなみに保存された Preference は
preferencetest.xml
<map>
<string name="text">Test</string>
</map>


参考サイト
http://developer.android.com/intl/ja/reference/android/content/SharedPreferences.html

Wallpaper を替えてみた

壁紙を替えるには WallpaperManager を使用します

替え方は
  • setBitmap(Bitmap bitmap)
  • setResource(int resid)
  • setStream(InputStream data)
の三つから指定します

まず AndroidManifest でパーミッションを設定する必要があります

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  ... >
    ・
    ・
    ・
  <uses-permission 
    android:name="android.permission.SET_WALLPAPER" />
</manifest>

サンプルコード
public class WallpaperSample extends Activity implements OnClickListener {
  WallpaperManager mWM;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.wallpaper_sample);

    Button button;
    button = (Button) findViewById(R.id.Button_Set);
    button.setOnClickListener(this);
    button = (Button) findViewById(R.id.Button_Clear);
    button.setOnClickListener(this);

    // WindowManager の取得
    mWM = WallpaperManager.getInstance(this);

    // 壁紙の最小の幅,最小の高さの取得
    int width = mWM.getDesiredMinimumWidth();
    int height = mWM.getDesiredMinimumHeight();
  }

  @Override
  public void onClick(View v) {
    switch(v.getId()) {
    case R.id.Button_Set:
      try {
        // 壁紙をリソースから設定
        mWM.setResource(R.drawable.icon);
      } catch (IOException e) {
        e.printStackTrace();
      }
      break;
    case R.id.Button_Clear:
      try {
        // 壁紙をデフォルトに戻す
        mWM.clear();
      } catch (IOException e) {
        e.printStackTrace();
      }
      break;
    }
  }
}

プログラムを実行すると...

変更前
変更後

こんな感じ!

Activity の背景を壁紙にしたいときは
<activity 
  android:name=".activity.WallpaperSample"
  android:theme="@android:style/Theme.Wallpaper">
とテーマを指定すればOK

ちなみに
API 2.0以前ではできないので注意!
下記の方法で設定するようです
int width = getWallpaperDesiredMinimumWidth();
int height = getWallpaperDesiredMinimumHeight();
setWallpaper(Bitmap or InputStream);
clearWallpaper();


参考サイト
http://developer.android.com/intl/ja/reference/android/app/WallpaperManager.html

ExpandableListView を使ってみた

ExpandableListView は
java.lang.Object
  ↳ android.view.View
    ↳ android.view.ViewGroup
      ↳ android.widget.AdapterView<T extends android.widget.Adapter>
        ↳ android.widget.AbsListView
          ↳ android.widget.ListView
            ↳ android.widget.ExpandableListView
を使用します

Group のリストがありそれぞれが Child のリストを保持しています.
Group をクリックすRと Child のリストが開き,もう一度クリックするとリストが閉じられます.

というわけで,ExpandableListView をいじってみた.

サンプルコード
public class ExpandableListViewSample extends Activity {
  private static final String KEY1 = "GROUP";
  private static final String KEY2 = "CHILD";

  // 表示させる文字列
  private String[] GROUPS = {"Group1", "Group2", "Group3"};
  private String[][][] CHILDREN = {
      {{"Child11", "Text11"}}, 
      {{"Child21", "Text21"}, {"Child22", "Text22"}},
      {{"Child31", "Text31"}, {"Child32", "Text32"}, {"Child33", "Text33"}}, 
  };

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.expandablelistview_sample);

    // 設定する文字列のリスト
    List<Map<String, String>> groupData =
        new ArrayList<Map<String, String>>();
    List<List<Map<String, String>>> childData =
        new ArrayList<List<Map<String, String>>>();

    // リストに文字列を設定していく
    for (int i = 0; i < GROUPS.length; i++) {
      // 親要素の追加
      Map<String, String> curGroupMap =
          new HashMap<String, String>();
      groupData.add(curGroupMap);
      curGroupMap.put(KEY1, GROUPS[i]);
      curGroupMap.put(KEY2, "");

      List<Map<String, String>> children =
          new ArrayList<Map<String, String>>();
      if (CHILDREN.length > i) {
        for (int j = 0; j < CHILDREN[i].length; j++) {
          // 子要素の追加
          Map<String, String> curChildMap =
              new HashMap<String, String>();
          children.add(curChildMap);
          curChildMap.put(KEY1, CHILDREN[i][j][0]);
          curChildMap.put(KEY2, CHILDREN[i][j][1]);
        }
      }
      childData.add(children);
    }

    // ExpandbleListAdapter の作成
    ExpandableListAdapter adapter =
        new SimpleExpandableListAdapter(
            this,
            groupData,
            android.R.layout.simple_expandable_list_item_1,
            new String[] { KEY1, KEY2 },
            new int[] { android.R.id.text1, android.R.id.text2 },
            childData,
            android.R.layout.simple_expandable_list_item_2,
            new String[] { KEY1, KEY2 },
            new int[] { android.R.id.text1, android.R.id.text2 }
        );

    ExpandableListView listView = 
      (ExpandableListView) findViewById(R.id.ExpandableListView);
    // Adapter を設定
    listView.setAdapter(adapter);
    
    // グループがクリックされた時に呼び出されるコールバックを登録
    listView.setOnGroupClickListener(new OnGroupClickListener() {
      @Override
      public boolean onGroupClick(ExpandableListView parent,
          View v, int groupPosition, long id) {
        // クリックされた時の処理
        return false;
      }      
    });
    
    // グループ内の項目がクリックされた時に呼び出されるコールバックを登録
    listView.setOnChildClickListener(new OnChildClickListener() {
      @Override
      public boolean onChildClick(ExpandableListView parent, View v,
          int groupPosition, int childPosition, long id) {
        // クリックされた時の処理
        return false;
      }      
    });
  }  
}

さらに
setOnGroupCollapseListener でグループが閉じた時,
setOnGroupExpandListener でグループが開いた時
の処理もできる模様!

XMLリソース
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" 
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="ExpandableListViewSample" />
  <ExpandableListView 
    android:layout_width="fill_parent"
    android:layout_height="0dip" 
    android:layout_weight="1"
    android:id="@+id/ExpandableListView">
  </ExpandableListView>
</LinearLayout>
プログラムを実行すると...


グループを開いたとき

こんな感じ!


参考サイト http://developer.android.com/intl/ja/reference/android/widget/ExpandableListView.html

ListView で MultipleChoice モード

ListView で複数選択できるような List を作ることができます.

基本的には ListView や SingleChoice と同じ.
Adapter の作成時に Muliple Choice ようのレイアウトを設定するのと
setChoiceMode で ListView.CHOICE_MODE_MULTIPLEを設定するくらい
すると CheckBox 付きのリストが表示されます.

というわけで,MultipleChoiceList をいじってみた.

サンプルコード
public class MultipleChoiceListViewSample extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listview_sample);
    ListView listView = (ListView)findViewById(R.id.ListView);

    // アダプタの作成
    listView.setAdapter(new ArrayAdapter<String>(
        this,
        android.R.layout.simple_list_item_multiple_choice,
        DAYS)
    );

    // フォーカスが当たらないよう設定
    listView.setItemsCanFocus(false);

    // 選択の方式の設定
    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    
    for (int i = 1; i < 6; i++) {
      // 指定したアイテムがチェックされているかを設定
      listView.setItemChecked(i, true);
    }
    
    // アイテムがクリックされたときに呼び出されるコールバックを登録
    listView.setOnItemClickListener(new OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent,
              View view, int position, long id) {
          // クリックされた時の処理
      }
    });
    
    // 現在チェックされているアイテムを取得
    // チェックされてないアイテムは含まれない模様
    SparseBooleanArray checked = listView.getCheckedItemPositions();
    for (int i = 0; i < checked.size(); i++) {
      // チェックされているアイテムの key の取得
      int key = checked.keyAt(i);
      Log.v(getClass().getSimpleName(), "values: " + DAYS[key]);
    }
  }
  
  // ListView に表示させる文字列
  private static final String[] DAYS = new String[] {
    "Sunday", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday"
  };
}
XMLリソース
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" 
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="ListSample" />
  <ListView 
    android:layout_width="fill_parent"
    android:layout_height="0dip" 
    android:layout_weight="1"
    android:id="@+id/ListView">
  </ListView>
</LinearLayout>

実行すると...



こんな感じ!


参考サイト
http://developer.android.com/intl/ja/reference/android/widget/ListView.html

ListView で SingleChoice モード

ListView で一つしか選択できないような List を作ることができます.

基本的には ListView と同じ.
Adapter の作成時に Single Choice ようのレイアウトを設定するのと
setChoiceMode で ListView.CHOICE_MODE_SINGLEを設定するくらい
すると RadioButton 付きのリストが表示されます.

というわけで,SingleChoiceList をいじってみた

サンプルコード
public class SingleChoiceListViewSample extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listview_sample);
    ListView listView = (ListView)findViewById(R.id.ListView);

    // アダプタの作成
    listView.setAdapter(new ArrayAdapter<String>(
        this,
        android.R.layout.simple_list_item_single_choice,
        SIZES)
    );  
        
    // 選択の方式の設定
    listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
  
    // 指定したアイテムがチェックされているかを設定
    listView.setItemChecked(0, true);
    
    // アイテムがクリックされた時に呼び出されるコールバックを登録
    listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent,
                View view, int position, long id) {
            // クリックされた時の処理
        }
    });
  
    // 現在チェックされているアイテムの position を取得
    listView.getCheckedItemPosition();
  }
  
  // ListView に表示させる文字列
  private static final String[] SIZES = new String[] {
      "XS(eXtra Small)", "S(Small)", "M(Medium)",
   "L(Large)", "XL(eXtra Large)"
  };
}

XMLリソース
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" 
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="ListSample" />
  <ListView 
    android:layout_width="fill_parent"
    android:layout_height="0dip" 
    android:layout_weight="1"
    android:id="@+id/ListView">
  </ListView>
</LinearLayout>

実行すると...



こんな感じ!


参考サイト
http://developer.android.com/intl/ja/reference/android/widget/ListView.html

XML で Button 変化

ボタンの変化をXMLで指定するには selector というのを指定してあげます
state_pressed が true なら押されている
state_focused が true ならフォーカスがあたっている
状態になりそれぞれのイメージを指定します

というわけで, XMLでボタンを変化させてみた

XMLリソース
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 押されたときの Button -->
  <item android:drawable="@drawable/icon_pressed"
        android:state_pressed="true" />
  <!-- フォーカスがあたっているときの Button -->
  <item android:drawable="@drawable/icon_focused"
        android:state_focused="true" />
  <!-- 通常時の Button -->
  <item android:drawable="@drawable/icon" />
</selector>

んで、メインの方はただバックグラウンドに指定するだけ
XMLで指定してしまってもOK

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;

public class ButtonXMLTest extends Activity {
  Button button;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.buttonxmltest);
    
    button = (Button) findViewById(R.id.Button);
    button.setBackgroundResource(R.drawable.buttonxml);
  }    
}

プログラムを実行すると...

通常時

ボタンにフォーカスがあたったとき

ボタンが押されたとき


こんな感じ!

参考サイト
http://developer.android.com/intl/ja/resources/tutorials/views/hello-formstuff.html

ソフトバンク、『X06HT HTC Desire』発売開始

2010年4月27日より、ソフトバンクモバイル初となるAndroid搭載スマートフォン「HTC Desire SoftBank X06HT」が発売されました。

詳しくはhttp://www.htc.com/jp/product/x06ht/overview.html

MediaPlayer を使ってみた

android で mp3, midi などを再生するには
MediaPlayer を使います

そして drawable/raw を作ってその中にメディアファイルを格納します

その後, MediaPlayer.create(context, resid); で作成します

というわけで, MediaPlayer をいじってみた

サンプルプログラム
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MediaPlayerTest extends Activity 
                             implements OnClickListener {
  private MediaPlayer mediaPlayer = null;
  private Button button_Play;
  private Button button_Pause;
  private Button button_Stop;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.soundtest);
    
    button_Play = (Button) findViewById(R.id.Button01);
    button_Play.setOnClickListener(this);
    button_Pause = (Button) findViewById(R.id.Button02);
    button_Pause.setOnClickListener(this);  
    button_Stop = (Button) findViewById(R.id.Button03);
    button_Stop.setOnClickListener(this);  

    // メディアプレイヤーの作成
    mediaPlayer = MediaPlayer.create(this, R.raw.sample);
    
    // ループ再生の設定
    // mediaPlayer.setLooping(true);
  }
  @Override
  public void onClick(View v) {
    if (v == button_Play) {
      // 再生してなかったら
      if (!mediaPlayer.isPlaying()) {
        // MediaPlayerの再生
        mediaPlayer.start();
      }
    } else if (v == button_Pause) {
      // MediaPlayerの一時停止
      mediaPlayer.pause();
    }
    else if (v == button_Stop) {
      // 再生してたら
      if (mediaPlayer.isPlaying()) {
        // MediaPlayerの停止
        mediaPlayer.stop();
        try {
          // MediaPlayerの準備
          mediaPlayer.prepare();
        } catch (Exception e) {}
      }
    }
  }
}

こんな感じ!

参考サイト
http://developer.android.com/intl/ja/reference/android/media/MediaPlayer.html

ToneGenerator を使ってみた

ToneGeneratorを使うと簡単にトーンを鳴らせます
コンストラクタは
ToneGenerator (int streamType, int volume);
第1引数はストリームの種類
第2引数は音量

んで、
startTone(int ToneType) or startTone(int ToneType, int durationMs)
で再生します
後者は再生する時間を指定
Toneの種類に関してはToneGeneratorから

というわけで, ToneGenarator をいじってみた

サンプルプログラム
import android.app.Activity;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ToneGeneratorTest extends Activity {
  ToneGenerator toneGenerator;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tonegeneratortest);

    // ToneGenerator の作成
    toneGenerator = new ToneGenerator(
        AudioManager.STREAM_ALARM,
        ToneGenerator.MAX_VOLUME
    );

    ((Button) findViewById(R.id.Button01))
    .setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        // Tone再生
        toneGenerator.startTone(ToneGenerator.TONE_CDMA_ABBR_ALERT);
        // toneGenarator.stratTone(ToneGenerator.TONE_CDMA_ABBR_ALERT, 1000);
      }
    });
    ((Button) findViewById(R.id.Button02))
    .setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        // Tone停止
        toneGenerator.stopTone();
      }
    });
  }
  
  @Override
  public void onDestroy() {
    super.onDestroy();
    
    // ToneGenerator の解放
    toneGenerator.release();
  }
}

こんな感じ!

参考サイト
http://developer.android.com/intl/ja/reference/android/media/ToneGenerator.html
http://developer.android.com/intl/ja/reference/android/media/AudioManager.html

Tab を作ってみた

Tab を使うには TabHost と TabWidget を使います
そして TabWidget でTabのコンテンツを表示するのに FrameLayout を使います

Tabのコンテンツとして 任意のViewを表示させるのと, Activityを起動する2種類があるようです

というわけで, Tab を作ってみた

注意するのは id として
  • TabHost は @android:id/tabhost
  • TabWidget は @android:id/tabs
  • メインの FrameLayout は @android:id/tabcotent
というのを指定してあげます

XMLリソース
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@android:id/tabhost" 
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <LinearLayout 
    android:orientation="vertical"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:padding="5dp">
    <TabWidget 
      android:id="@android:id/tabs"
      ... />
    <FrameLayout 
      android:id="@android:id/tabcontent"
      android:padding="5dp"
      ... >
      <LinearLayout
        android:id="@+id/content1" 
        android:orientation="vertical"
        ... >
        <TextView 
          ... />
      </LinearLayout>
      <LinearLayout
        android:id="@+id/content2" 
            ・
            ・
            ・
      </LinearLayout>
    </FrameLayout>
  </LinearLayout>
</TabHost>

また, Tab が切り替わったときのアイコンの切り替えもXMLで指定できます
以下のように作ってres/drawable に置きます
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 選択されたときの画像 -->
  <item android:drawable="@android:drawable/star_big_on"
        android:state_selected="true" />
  <!-- 選択されていないときの画像 -->
  <item android:drawable="@android:drawable/star_big_off" />
</selector>
んで, 本体
ここで Activity でなく TabActivity というのを継承させます

サンプルプログラム
import android.app.TabActivity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.TabHost.OnTabChangeListener;

public class TabTest extends TabActivity
                     implements OnTabChangeListener {
  private static final String TAG[] = {
    "tag1", "tag2", "tag3",
  };
  private static final String LABEL[] = {
    "Label1", "Label2", "Label3",
  };

  TabHost tabHost;
  TabHost.TabSpec spec;
  TextView textView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.tabtest);
    textView = new TextView(this);
    
    // TabHost の取得
    tabHost = getTabHost();
    // Tab が切り替わったときに呼ばれるコールバックを登録
    tabHost.setOnTabChangedListener(this);

    /********** Tab その1 **********/
    // TabSpec の作成
    spec = tabHost.newTabSpec(TAG[0]);
    // インジケーターの設定
    spec.setIndicator(LABEL[0]);
    // Tab のコンテンツの設定
    spec.setContent(R.id.content1);
    // TabHost に Tab を追加
    tabHost.addTab(spec);

    /********** Tab その2 **********/
    spec = tabHost.newTabSpec(TAG[1])
    // アイコン付きインジケーターの設定
    .setIndicator(LABEL[1], getResources().getDrawable(R.drawable.icon))
    .setContent(R.id.content2);
    tabHost.addTab(spec);

    textView.setText("Text");
    textView.setBackgroundColor(Color.DKGRAY);
    textView.setTextColor(Color.RED);
    textView.setGravity(Gravity.CENTER);

    /********** Tab その3 **********/
    // 起動したいアクティビティのIntent作成
    Intent intent = new Intent().setClass(this, TabTest.class);
    
    spec = tabHost.newTabSpec(TAG[2])
    // インジケーターに任意のビューを設定
    .setIndicator(textView)
    // Intent を設定
    .setContent(intent);
    tabHost.addTab(spec);

    // 現在の Tab を設定
    tabHost.setCurrentTab(0);
  }
  // Tab が切り替わったときの動作 (引数はTag)
  public void onTabChanged(String tabId) {
    if (tabId == TAG[2])
      textView.setBackgroundColor(Color.LTGRAY);
    else
      textView.setBackgroundColor(Color.DKGRAY);
  }
}
これでOK!

プログラムを実行すると...


こんな感じ!

今回は Intent で自分自身を読んでます
当たり前ですが何回も呼ぶとオーバーフローして落ちます

Tab で TabActivity を呼べば多段の Tab ができそう!

参考サイト
http://developer.android.com/intl/ja/resources/tutorials/views/hello-tabwidget.html
http://developer.android.com/intl/ja/reference/android/widget/TabHost.html
http://developer.android.com/intl/ja/reference/android/widget/TabWidget.html

HorizontalScrollView を使ってみた

横方向にスクロールさせるには
HorizontalScrollView を使います
java.lang.Object
  ↳ android.view.View
    ↳ android.view.ViewGroup
      ↳ android.widget.FrameLayout
        ↳ android.widget.HorizontalScrollView

その名の通り ScrollView の横バージョンです

HorizontalScrollView は ScrollView と同様一つしか子ビューを持てないので
LineaLayout などにまとめて入れてやります

というわけで, HorizontalScrollView をいじってみた

XMLリソース
<HorizontalScrollView
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" 
  android:id="@+id/HorizontalScrollView">
  <LinearLayout 
    android:id="@+id/LinearLayout"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content">
    <TextView 
      android:id="@+id/TextView" 
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" 
      android:text="HorizontalScrollViewTest">
    </TextView>
        ・
        ・
        ・
  </LinearLayout>
</HorizontalScrollView>
アクティビティー側で setContentView で設定

プログラムを実行すると...


こんな感じ!

一番下にスクロールバーが表示されています

参考サイト
http://developer.android.com/intl/ja/reference/android/widget/HorizontalScrollView.html

XML で Menu

Menu を XML で作成したいときは
/res に menu というフォルダを作成し、その中にxmlファイルを作成します


XML は以下のようにすればOKです
submenu を作りたいときは item の中に menu を入れてあげます。

XML リソース
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item 
    android:id="@+id/menu_item01" 
    android:title="Menu01"/>
  <group 
    android:id="@+id/menu_group01">
    <item 
      android:icon="@drawable/icon" 
      android:id="@+id/menu_item02" 
      android:title="Menu02"/>
  </group>
  <item 
    android:id="@+id/menu_item03" 
    android:title="Menu03">
    <menu>
      <item 
        android:id="@+id/submenu_item01" 
        android:title="Sub_Menu01"/>
      <item 
        android:id="@+id/submenu_item02" 
        android:title="Sub_Menu02/">
    </menu>
  </item>
</menu>

そして,
MenuInflater というクラスを使ってXMLを取得します

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class MenuXMLTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }

  // Option Menu が最初に表示される時に1度だけ呼び出される
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    // MenuInflater の取得
    MenuInflater menuInflater = getMenuInflater();
    // MenuInflater から XML の取得  
    menuInflater.inflate(R.menu.menutest, menu);
    return true;
  }
}

あとは普通に onOptionsItemSelected(MenuItem item) などをオーバーライドすればアイテムが選択された際の処理などもできます

プログラムを実行すると...

こんな感じ!

参考サイト
http://developer.android.com/intl/ja/guide/topics/resources/available-resources.html#menus
http://developer.android.com/intl/ja/reference/android/view/MenuInflater.html

Eclipse で Xperia用アプリ開発準備

EclipseでXperia用のアプリを開発するためには、

まず、以下のソニーエリクソンのページ(http://developer.sonyericsson.com/wportal/devworld/downloads)
から, Android の部分にある [All Android Downloads] をクリックし
『Sony Ericsson Xperia X10 add-on for the Android SDK』というのをダウンロード

ダウンロードしたファイルを解凍して [Android SDK]を保存してあるディレクトリを開いて、その中にある [add-ons]ディレクトリの中に置く

そしたら、次は Eclipse を開く

普通のAVDの作成と同じで
[Window] -> [Android SDK and AVD Manager] 移動して [New] をクリック
すると [Target] に『X10 (Sony Erricsson ...』というのがあるのでそれを選択

Skin も『X10』を選択(たぶんデフォルトでなってる)



んで [Create AVD]

そして、プロジェクトの作成

Android 1.6 用のものがあるならわざわざ新しいのを作らなくても大丈夫

こちらも [Target Name] のところに『X10』が現れるので選択



これでOK!

そして、[Run Configurations] で Tagetをさっき作った『X10』のAVDを選んで実行すると...


こんな感じ!

やっぱ Xperia かっこいいですね!

XML で Animation

Animation を XML で作成したいときは

/res に anim というフォルダを作成し、その中にxmlファイルを作成します

アニメーションの要素としては以下のようなものがあります
  • set
  • alpha
  • scale
  • translate
  • rotate
  • interpolator

サイズを指定するものでViewサイズに対する比率を指定できるわけですが
以下の2種類で指定します
%   : View のサイズに対する比率
%p  : 親View のサイズに対する比率

というわけで、アニメーションを作ってみた

下からズームインしてくるアニメーション
zoom_in_from_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <scale
    android:fromXScale="0.0"
    android:toXScale="1.0"
    android:fromYScale="0.0"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:duration="1000">
  </scale>
  <translate
    android:fromYDelta="100%p"
    android:toYDelta="0.0"
    android:duration="1000">
  </translate>
</set>

こんな感じで作成します

作成したら
AnimationUtilsクラスの
loadAnimation(context, id) メソッドを使ってアニメーションを取得

例えば
AnimationUtils.loadAnimation(context, R.anim.zoom_in_from_bottom);
というふうにすれば取得できます!


参考サイト
http://developer.android.com/intl/ja/guide/topics/resources/available-resources.html#animation
http://developer.android.com/intl/ja/reference/android/view/animation/AnimationUtils.html

XML でカスタムView

既存の View を拡張して新たに自分だけの View を作成したいときは

まず、res/values に attrs.xml を作成します

attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <!-- name : custom view class name -->
  <declare-styleable name="CustomView">
    <attr name="text" format="string" />
    <attr name="color" format="color" />
    <attr name="size" format="dimension" />
  </declare-styleable>
</resources>

declare-styleable の name属性は作成するカスタムビューのクラス名を指定する

次に、レイアウトを作成します

xmlns:app="http://schemas.android.com/apk/res/パッケージの名前"
というのを追加します
app は勝手につけた名前

attrs.xml で作成した属性を指定します

XMLリソース
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res/androidtest.app"
  android:id="@+id/LinearLayout"
  android:layout_height="fill_parent"
  android:layout_width="fill_parent"> 
  <androidtest.app.CustomView
    android:id="@+id/CustomView" 
    android:layout_height="fill_parent"
    android:layout_width="fill_parent" 
    app:text="CustomViewTest" 
    app:color="#FFFF0000"
    app:size="32sp" />
</LinearLayout>

そしたら、カスタムビューの作成

サンプルプログラム(CustomView)
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidtest.app.R;

public class CustomView extends View {
  String str;
  int color;
  int size;

  public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);

    // styleable から TypedArray の取得
    TypedArray tArray = 
      context.obtainStyledAttributes(
        attrs,
        R.styleable.CustomView
      );
  
    // TypedArray から String を取得
    str = tArray.getString(R.styleable.CustomView_text);
    // TypedArray から Color を取得
    color = tArray.getColor(R.styleable.CustomView_color, 0xFFFFFFFF);
    // TypedArray から Dimension を取得
    size = tArray.getDimensionPixelSize(R.styleable.CustomView_size, 12);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint paint = new Paint();
    paint.setColor(color);
    paint.setTextSize(size);
    canvas.drawText(str, 32, 64, paint);
  }
}

Activity では setContentView で作成した layout を指定するだけ

サンプルプログラム(Activity)
import android.app.Activity;
import android.os.Bundle;
import androidtest.app.R;

public class CustomViewTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.customviewtest);
  }
}

プログラムを実行すると...


こんな感じ!


参考サイト
http://developer.android.com/intl/ja/guide/topics/resources/available-resources.html#customresources

ToggleButton を使ってみた

ToggleButton は
java.lang.Object
  ↳ android.view.View
    ↳ android.widget.TextView
      ↳ android.widget.Button
        ↳ android.widget.CompoundButton
          ↳ android.widget.ToggleButton
を使います

というわけで、ToggleButton を使ってみた

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.ToggleButton;

public class ToggleButtonTest extends Activity {
  ToggleButton toggleButton;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.togglebuttontest);
  
    toggleButton = (ToggleButton) findViewById(R.id.ToggleButton01);
  
    // ToggleButton が On のときのテキストを設定
    toggleButton.setTextOn("Toggle ON");
    // ToggleButton が Off のときのテキストを設定
    toggleButton.setTextOff("Toggle OFF");
  
    // ToggleButton が On かどうかを設定
    toggleButton.setChecked(true);
  
    // ToggleButton が On かどうかを取得
    boolean checked = toggleButton.isChecked(); 
  }
}

XMLリソースで設定もできます

XMLリソース
<ToggleButton
  android:id="@+id/ToggleButton"
  android:layout_height="wrap_content"
  android:layout_width="wrap_content"
  android:textOff="Toggle Off"
  android:textOn="Toggle On">
</ToggleButton>

プログラムを実行すると...



こんな感じ!

参考サイト
http://developer.android.com/intl/ja/reference/android/widget/ToggleButton.html

いろいろな AlertDialog

AlertDialog.Builderクラスを使っていろいろな AlertDialog を作ってみた

サンプルプログラム
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class AlertDialogTest2 extends Activity implements View.OnClickListener {
  AlertDialog.Builder alertDialogBuilder;
  Button button[];

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.alertdialogtest2);

    button = new Button[3];
    for (int i = 0; i < 3; i++) { d.Button01 + i);
      button[i].setOnClickListener(this);
    }
  }

  public void onClick(View v) {
    if (v == button[0]) {
      setEditAlertDialog();
    } else if (v == button[1]) {
      setSingleChoiceDialog();
    } else if (v == button[2]) {
       setMultiChoiceDialog();
    }
  }

  /* AlertDialog(EditText) */
  public void setEditAlertDialog() {
    EditText editText = new EditText(this);
    editText.setText("Please fill your name!");

    alertDialogBuilder = new AlertDialog.Builder(this);
    alertDialogBuilder.setTitle("EditTextDialog");

    // AlertDialog に View を設定
    alertDialogBuilder.setView(editText);

    // Positive Button を設定
    alertDialogBuilder.setPositiveButton(
      "Positive", 
      new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          // Positive Button がクリックされた時の動作
        }
      }
    );
    alertDialogBuilder.show();
  }
 
  /* SingleChoiceDialog */
  public void setSingleChoiceDialog() {
    // 表示させるアイテム名
    final String[] str_items = {
      "One",
      "Two",
      "Three"
    };

    alertDialogBuilder = new AlertDialog.Builder(this);
    alertDialogBuilder.setTitle("SingleChoiceDialog");

    // 初めに選ばれているアイテム
    final int default_item = 0;

    // SingleChoiceDialog の作成
    alertDialogBuilder.setSingleChoiceItems(
      str_items, 
      default_item,
      new OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          // アイテムが選ばれたときの動作
        }
      }
    );
    // Positive Button を設定
    alertDialogBuilder.setPositiveButton(
      "Positive", 
      new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          // Positive Button がクリックされた時の動作
        }
      }
    );
    alertDialogBuilder.show();
  }

  /* MultiChoiceDialog */
  public void setMultiChoiceDialog() {
    // 表示させるアイテム名
    final String[] str_items = {
      "Red",
      "Green",
      "Blue"
    };
    // 各アイテムがチェックされている状態かどうか
    final boolean[] flag_items = {
      false,
      true,
      false
    };

    alertDialogBuilder = new AlertDialog.Builder(this);
    alertDialogBuilder.setTitle("MultiChoiceDialog");

    // MultiChoiceDialog の作成
    alertDialogBuilder.setMultiChoiceItems(
      str_items, 
      flag_items,
      new OnMultiChoiceClickListener() {
        public void onClick(
            DialogInterface dialog, 
            int which, 
            boolean isChecked) {
          // アイテムが選ばれたときの動作
        }
      }
    );
    // Positive Button を設定
    alertDialogBuilder.setPositiveButton(
      "Positive", 
      new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          // Positive Button がクリックされた時の動作
        }
      }
    );
    alertDialogBuilder.show();
  }
}
プログラムを実行すると...

AlertDialog(EditText)

SingleChoiceDialog

MultiChoiceDialog

こんな感じ!


参考サイト
http://developer.android.com/intl/ja/reference/android/app/AlertDialog.html
http://developer.android.com/intl/ja/reference/android/app/AlertDialog.Builder.html

Spannable で文字のマークアップ

Spannable はテキストをマークアップするためのインターフェースです

CharacterStyleなどのクラスを使って文字列の一部を
下線を引いたり、下付き文字にしたり、
上付き文字にしたり、URLを付けたり...
と様々なことができます

CharacterStyle のサブクラスには
  • UnderlineSpan
  • SubscriptSpan
  • SuperscriptSpan
  • URLSpan
  • ScaleXSpan
  • RelativeSizeSpan
  • etc...
といろいろあります

というわけで, Spannable でテキストをいじってみた

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.text.Spannable;
import android.text.Spannable.Factory;
import android.text.style.RelativeSizeSpan;
import android.text.style.ScaleXSpan;
import android.text.style.SubscriptSpan;
import android.text.style.SuperscriptSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class SpannableTest extends Activity {
  Spannable spannable;

  UnderlineSpan underline;
  SubscriptSpan subscript;
  SuperscriptSpan superscript;
  URLSpan url;
  ScaleXSpan scaleX;
  RelativeSizeSpan relative;

  TextView textView[];

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.spannabletest);

    textView = new TextView[4];
    for (int i = 0; i < 4; i++) {
      textView[i] = (TextView) findViewById(R.id.TextView01 + i);
    }

    // UnderlineSpan
    underline = new UnderlineSpan();
    // SubscriptSpan
    subscript = new SubscriptSpan();
    // SuperscriptSpan
    superscript = new SuperscriptSpan();
    // URLSpan
    url = new URLSpan("http://weide-dev.blogspot.com/");
    // ScaleXSpan
    scaleX = new ScaleXSpan(0.5f);
    // RelativeSizeSpan
    relative = new RelativeSizeSpan(0.5f);

    // Factory の取得
    Factory factory = Spannable.Factory.getInstance();

    /* アンダーラインが引かれた文字列 */
    // Spannable の取得
    spannable = factory.newSpannable(textView[0].getText());
    // 0からテキストの長さ分まで下線を引く
    spannable.setSpan(
        underline,
        0,
        textView[0].getText().length(),
        spannable.getSpanFlags(underline)
    );
    // TextView にテキストを設定
    textView[0].setText(spannable, TextView.BufferType.SPANNABLE);

    /* 後ろ4文字が下付きの文字列 */
    spannable = factory.newSpannable(textView[1].getText());
    // 後ろ4文字を下付き文字にする
    spannable.setSpan(
        subscript,
        textView[1].getText().length() - 4,
        textView[1].getText().length(),
        spannable.getSpanFlags(subscript)
    );
    // 後ろ4文字のXのスケールを0.5倍する
    spannable.setSpan(
        scaleX,
        textView[1].getText().length() - 4,
        textView[1].getText().length(),
        spannable.getSpanFlags(scaleX)
    );
    textView[1].setText(spannable, TextView.BufferType.SPANNABLE);

    /* 後ろ4文字が上付きの文字列 */
    spannable = factory.newSpannable(textView[2].getText());
    // 後ろ4文字を上付き文字にする
    spannable.setSpan(
        superscript,
        textView[2].getText().length() - 4,
        textView[2].getText().length(),
        spannable.getSpanFlags(superscript)
    );
    // 後ろ4文字のサイズを0.5倍する
    spannable.setSpan(
        relative,
        textView[2].getText().length() - 4,
        textView[2].getText().length(),
        spannable.getSpanFlags(relative)
    );
    textView[2].setText(spannable, TextView.BufferType.SPANNABLE);

    /* URL文字列 */
    spannable = factory.newSpannable(textView[3].getText());
    // 0からテキストの長さ分までURLタイプにする
    spannable.setSpan(
        url,
        0,
        textView[3].getText().length(),
        spannable.getSpanFlags(url)
    );
    textView[3].setText(spannable, TextView.BufferType.SPANNABLE);
    textView[3].setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        // URLを開く
        url.onClick(textView[3]);
      }
    });
  }
}
プログラムを実行すると...


こんな感じ!


参考サイト
http://developer.android.com/intl/ja/reference/android/text/Spannable.html
http://developer.android.com/intl/ja/reference/android/text/style/CharacterStyle.html

Menu を使ってみた

Menu は
android.view.Menu
を使用します

さらに、Activity クラスの
  • public boolean onCreateOptionsMenu(Menu menu)
  • public boolean onPrepareOptionsMenu(Menu menu)
  • public boolean onOptionsItemSelected(MenuItem item)
  • public boolean onMenuOpened(int featureId, Menu menu)
などのメソッドを Override することで使用できます

というわけで、Menu をいじってみた

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MenuTest extends Activity {
  private static final int MENU_ID1 = Menu.FIRST;
  private static final int MENU_ID2 = Menu.FIRST + 1;
  private static final int MENU_ID3 = Menu.FIRST + 2;
  private static final int SUBMENU_ID1 = Menu.FIRST + 21;
  private static final int SUBMENU_ID2 = Menu.FIRST + 22;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 
  
    ((Button) findViewById(R.id.Button)).setOnClickListener(
      new OnClickListener() {
        public void onClick(View v) {
          // Menu の表示
          openOptionsMenu();
        }
      }
    );
  }

  // Option Menu が最初に表示される時に1度だけ呼び出される
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    boolean ret = super.onCreateOptionsMenu(menu);

    // Menu にアイテムを追加
    menu.add(Menu.NONE, MENU_ID1, Menu.NONE, "Menu1");
    // Menu に Icon 付きアイテムを追加
    menu.add(Menu.NONE, MENU_ID2, Menu.NONE, "Menu2").setIcon(R.drawable.icon);

    // SubMenu を追加
    SubMenu sMenu = menu.addSubMenu(Menu.NONE, MENU_ID3, 3, "Menu3");
    sMenu.add(Menu.NONE, SUBMENU_ID1, Menu.NONE, "SubMenu1");
    sMenu.add(Menu.NONE, SUBMENU_ID2, Menu.NONE, "SubMenu2");

    // Menu にショートカットキーを設定
    menu.findItem(MENU_ID1).setAlphabeticShortcut('a');
    menu.findItem(MENU_ID2).setAlphabeticShortcut('1');
    menu.findItem(MENU_ID3).setAlphabeticShortcut('s');

    return ret;
  }

  // Option Menu が表示される時の動作
  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    return super.onPrepareOptionsMenu(menu);
  }

  // Option Menu のアイテムが選択された時の動作
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    boolean ret = super.onOptionsItemSelected(item);
    // 選ばれたアイテムの ID を取得
    switch(item.getItemId()) {
    case MENU_ID1:   // Menu1
      return true;
    case MENU_ID2:   // Menu2
      return true;
    case SUBMENU_ID1:   // Submenu1
      return true;
    default:
    }
    return ret;
  }

  // Option Menu が開かれた時の動作
  @Override
  public boolean onMenuOpened(int featureId, Menu menu) {
    return super.onMenuOpened(featureId, menu);
  }
}

プログラムを実行すると...


SubMenu は...

こんな感じ!

参考サイト
http://developer.android.com/intl/ja/reference/android/view/Menu.html
http://developer.android.com/intl/ja/reference/android/app/Activity.html

EditText を使ってみた

EditText は
java.lang.Object
   ↳ android.view.View
     ↳ android.widget.TextView
       ↳ android.widget.EditText
を使います

というわけで, EditText を使ってみた

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.text.InputType;
import android.widget.EditText;

public class EditTextTest extends Activity {
  EditText editText;
 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edittexttest);
  
    editText = (EditText) findViewById(R.id.EditText01);
  
    // EditText にテキストを設定
    editText.setText("EditTextTest");
  
    // EditText のインプットタイプを設定
    editText.setInputType(InputType.TYPE_CLASS_TEXT);
  
    // EditText の最大行の設定
    editText.setMaxLines(1);
  
    // EditText が空のときに表示させるヒントを設定
    editText.setHint("This is Hint");
  
    // EditText のカーソル位置を設定
    editText.setSelection(3);
    // EditText のテキストを全選択
    // editText.selectAll();
  
    // EditText のテキストを取得
    String str = editText.getText().toString();
  }
}

InputType には
  • 数字入力
  • アドレス入力
  • パスワード入力
  • オートコンプリート
  • 入力不可
  • etc...
といろいろあります
詳しくは InputTypeクラス を参照してください

XMLリソースで指定することもできます

XMLリソース
<EditText 
  android:hint="This is Hint"
  android:id="@+id/EditText" 
  android:inputType="text" 
  android:layout_height="wrap_content" 
  android:layout_width="wrap_content"  
  android:text="EditTextTest">
</EditText>

XMLリソースで
InputTypeを指定するときは android:InputType を使います

プログラムを実行すると...



こんな感じ!

また、ヒントは


こんな感じで表示されます!

参考サイト
http://developer.android.com/intl/ja/reference/android/widget/EditText.html

ScrollView を使ってみた

ScrollView を使うには
java.lang.Object
  ↳ android.view.View
    ↳ android.view.ViewGroup
      ↳ android.widget.FrameLayout
        ↳ android.widget.ScrollView
を使います

というわけで、ScrollView をいじってみた

サンプルプログラム
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;

public class ScrollViewTest extends Activity {
  ScrollView scrollView;
  LinearLayout linearLayout;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    scrollView = new ScrollView(this);
    linearLayout = new LinearLayout(this);
    linearLayout.setOrientation(LinearLayout.VERTICAL);
  
    for (int i = 0; i < 12; i++) {
      Button button = new Button(this);
      button.setText("Button" + (i+1));
      linearLayout.addView(button);
    }

    // ScrollView に View を追加
    scrollView.addView(linearLayout);

    setContentView(scrollView);
  }
}

ScrollView は1つしか View を設定できないので LinearLayout などにまとめる必要があります XMLでまとめて設定することもできます XMLリソース
<ScrollView
  android:id="@+id/ScrollView"
  android:layout_height="fill_parent"
  android:layout_width="fill_parent">
  <LinearLayout 
    android:id="@+id/LinearLayout"
    android:orientation="vertical"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent">
    <!-- 追加したいView -->
    <Button .../>
        ・
        ・
        ・
  </LinearLayout>
</ScrollView>

プログラムを実行すると...



こんな感じ!

右にスクロールバーが表示されて、上下に続きがあると少し暗くなっています

参考サイト
http://developer.android.com/intl/ja/reference/android/widget/ScrollView.html

SurfaceView を使ってみた

SurfaceView は
java.lang.Object
  ↳ android.view.View
    ↳ android.view.SurfaceView
を使用します

また、Surfaceの変更などを取得するために
SurfaceHolder.Callback
を使用します
このインターフェースは
  • public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
  • public void surfaceCreated(SurfaceHolder holder)
  • public void surfaceDestroyed(SurfaceHolder holder)
の3つのメソッドを実装する必要があります

というわけで、SurfaceView をいじってみた

サンプルプログラム
import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SurfaceViewTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(new SurfaceTestView(this));
  }
 
  class SurfaceTestView extends SurfaceView 
        implements SurfaceHolder.Callback, Runnable {
    private Thread thread;
    private BitmapDrawable bitmapDrawable;
  
    public SurfaceTestView(Context context) {
      super(context);
   
      // SurfaceHolder の取得
      SurfaceHolder holder = getHolder();
   
      // SurfaceHolder に コールバックを設定
      holder.addCallback(this);
      holder.setFixedSize(getWidth(), getHeight());
   
      // フォーカスをあてる
      setFocusable(true);
   
      bitmapDrawable = new BitmapDrawable(
        context.getResources(),
        BitmapFactory.decodeResource(
          context.getResources(), 
          R.drawable.icon)
      );
    }

    // Surface が変更されたときの動作
    public void surfaceChanged(SurfaceHolder holder,
        int format, int width, int height) {
    }

    // Surface が作成されたときの動作
    public void surfaceCreated(SurfaceHolder holder) {
      thread = new Thread(this);
      thread.start();
    }

    // Surface が削除されたときの動作
    public void surfaceDestroyed(SurfaceHolder holder) {
      thread = null;
    }

    public void run() {
      while (thread != null) {
        // 描画の開始
        Canvas canvas = getHolder().lockCanvas();
    
        draw(canvas);
    
        // 描画の終了
        getHolder().unlockCanvasAndPost(canvas);
      }
    }

    @Override
    public void draw(Canvas canvas) {
      // 現在の状態を保存
      canvas.save();
   
      Paint paint = new Paint();
      paint.setColor(Color.RED);
      paint.setTextSize(32);
   
      bitmapDrawable.setBounds(0, 0, 96, 96);
      bitmapDrawable.draw(canvas);
      canvas.drawText("SurfaceViewTest", 0, 128, paint);

      paint.setAntiAlias(true);
      bitmapDrawable.setBounds(0, 160, 96, 256);
      bitmapDrawable.draw(canvas);
      canvas.drawText("SurfaceViewTest2", 0, 288, paint);

      // 現在の状態の変更
      canvas.restore();
    }
  }
}

プログラムを実行すると...


こんな感じ!(上:アンチエイリアスなし, 下:あり)

アンチエイリアスは時間がかかるが場合によってはかけた方が良さそう

参考サイト
http://developer.android.com/intl/ja/reference/android/view/SurfaceView.html
http://developer.android.com/intl/ja/reference/android/view/SurfaceHolder.Callback.html

Drawable を使ってみた

Drawableクラスは abstract class で
サブクラスには
  • BitmapDrawable
  • ColorDrawable
  • RotateDrawable
  • ScaleDrawable
  • etc...
といろいろあります

今回は BitmapDrawable クラスを使ってみた

BitmapDrawable は
java.lang.Object
  ↳ android.graphics.drawable.Drawable
    ↳ android.graphics.drawable.BitmapDrawable
を使用します

というわけで BitmapDrawable をいじってみた

サンプルプログラム
import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;

public class DrawableTest extends Activity {
  BitmapDrawable bitmapDrawable;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new DrawableTestView(this));
  }

  class DrawableTestView extends View {
    public DrawableTestView(Context context) {
      super(context);
      // BitmapDrawable を作成
      bitmapDrawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.icon);
    }
    @Override
    public void onDraw(Canvas canvas) {
      // BitmapDrawable の範囲を設定
      bitmapDrawable.setBounds(0, 0, 48, 48);
      // BitmapDrawable の描画
      bitmapDrawable.draw(canvas);
   
      // BitmapDrawable のアルファ値を設定
      bitmapDrawable.setAlpha(128);
      bitmapDrawable.setBounds(48, 0, 96, 48);
      bitmapDrawable.draw(canvas);
      bitmapDrawable.setAlpha(255);   

      // BitmapDrawable にアンチエイリアスを設定
      bitmapDrawable.setAntiAlias(true);
      bitmapDrawable.setBounds(0, 48, 240, 288);
      bitmapDrawable.draw(canvas);
   
      bitmapDrawable.setAntiAlias(false);
      bitmapDrawable.setBounds(240, 48, 480, 288);
      bitmapDrawable.draw(canvas);
   
      bitmapDrawable.setBounds(0, 0, getWidth(), getHeight());
      // BitmapDrawable にグラビティを設定
      bitmapDrawable.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
      bitmapDrawable.draw(canvas);
    }
  }
}

プログラムを実行してみると...


こんな感じ!(左:アンチエイリアスあり, 右:なし)

この画像だとアンチエイリアスの違いはよく分からないですね
状況によって使い分けるのが良さそう

参考サイト
http://developer.android.com/intl/ja/reference/android/graphics/drawable/Drawable.html
http://developer.android.com/intl/ja/reference/android/graphics/drawable/BitmapDrawable.html