Mono Androidを開始するには、インストールする必要があります。
- Visual Studio Professional以上またはMonoDevelop 2.6ベータ1
- Java SDK
- Android SDK
- WindowsまたはMac用のAndroidプラグイン用Mono
また、xmlレイアウトを作成するには(マークアップと呼びましょう)、グラフィカルツールの1つが必要です。 私はDroidDrawを使用していますが、ネット上には多くの選択肢があります。 だから誰もが自分の好みに合わせて何かを選択できます。
上記のすべてをインストールしたら、1つ(または複数)のAndroidデバイスエミュレーターを作成して構成する必要があります。 これは、アプリケーションを最初に起動したときにも実行できます。 この例では、Androidバージョン2.1.1のエミュレーターを使用しています。
これで、最初のMono Androidプロジェクトを作成できます。
最初のMono Androidプロジェクト
新しいプロジェクトを作成する
そして、それをMyFirstMonoAndroidApplicationと呼びましょう。
新しいプロジェクトには、Assets and ResourcesディレクトリとActivity1というクラスのいくつかの要素が含まれています。
この例のアセットは影響を受けません。 残りの要素についてもう少し詳しく説明します。
リソースがあれば、すべてが非常に簡単です。 Drawableディレクトリには、アプリケーションで使用される画像が保存されます。 Layoutディレクトリには、一連のxmlレイアウトが含まれています。 また、Valuesディレクトリには、アプリケーションで使用するさまざまな定義済みの文字列値が格納されています。
アプリケーションで使用されるすべてのリソースは、プロパティでAndroidResourceとしてマークする必要があります。
Activity1クラスに進みましょう。 ご覧のとおり、基本クラスActivityを継承しています。 アクティビティとは何ですか? アクティビティは、ユーザーが実行できる特定のタスクの1つです。 ほとんどすべてのアクティビティは、グラフィカルインターフェイス(xmlマークアップ)を介してユーザーと対話します。
SetContentView行(Resource.Layout.Main)に注意してください。
この場所でマークアップがロードされ、現在のアクティビティ用に設定されます。
アクティビティ自体のマークアップとコードを少し変更しましょう。
それぞれが別のアクティビティの実行を処理する2つのボタンを持つ単純なフォームとします。
マークアップ:
<? xml version ="1.0" encoding ="utf-8" ? >
< LinearLayout
android:layout_width ="fill_parent"
android:layout_height ="fill_parent"
xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation ="vertical" >
< Button
android:id ="@+id/FirstExample"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:text ="First Example" ></ Button >
< Button
android:id ="@+id/SecondExample"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:text ="Second Example" ></ Button >
</ LinearLayout >
* This source code was highlighted with Source Code Highlighter .
アプリケーションのメインクラス。 これは、起動時に表示されるものです。
[Activity(Label = "My first mono android activity" , MainLauncher = true , Icon = "@drawable/icon" )]
public class MyMainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base .OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Button firstExample = FindViewById<Button>(Resource.Id.FirstExample);
firstExample.Click += firstExample_Click;
Button secondExample = FindViewById<Button>(Resource.Id.SecondExample);
secondExample.Click += secondExample_Click;
}
void firstExample_Click( object sender, EventArgs e)
{
Intent titlesIntent = new Intent( this , typeof (TitlesListActivity));
StartActivity(titlesIntent);
}
void secondExample_Click( object sender, EventArgs e)
{
Intent friendlyListIntent = new Intent( this , typeof (MoreFriendlyRssFeedActivity));
StartActivity(friendlyListIntent);
}
}
* This source code was highlighted with Source Code Highlighter .
新しいIntentクラスを使用することを除いて、コードは非常にシンプルで簡単です。
意図とは何ですか? これは、実行されている操作の抽象的な説明です。 言い換えると、特定のことを行うのはユーザーの意図です。 この場合、ボタンをクリックすると、ユーザーは別のアクティビティに切り替わります。
コードをコンパイルするには、参照するクラスを追加する必要があります。 プロジェクトのコンテキストメニューから、TitlesListActivityおよびMoreFriendlyRssFeedActivityという名前の2つの新しいアクティビティを追加します。
Mono Androidの学習に役立つ簡単な例をいくつか紹介します。 プログラマが直面する主なものの1つはリストです。
RSSフィードの見出しのリストにします。 RSSを読み取るための簡単なクラスを作成しましょう。
public class RssReader
{
private const string _title = "title" ;
private const string _link = "link" ;
private const string _item = "item" ;
private const string _channel = "channel" ;
private static Func< XElement , RssListItem> GetTitlesAndLinksFunc = (x => new RssListItem { Title = x.Element(_title).Value, Link = x.Element(_link).Value });
public static IList<RssListItem> GetRssListItems( params string [] rssUris)
{
List <RssListItem> fullList = new List <RssListItem>();
IEnumerable < XElement > itemsFromConcreteIteration;
foreach ( string rssUri in rssUris)
{
itemsFromConcreteIteration = GetRssFeedChannel(rssUri).Elements(_item);
fullList.AddRange(itemsFromConcreteIteration.Select(GetTitlesAndLinksFunc));
}
return fullList;
}
public static IEnumerable < string > GetTitles( string rssUri)
{
IEnumerable < XElement > items = GetRssFeedChannel(rssUri).Elements(_item);
return items.Select(x => x.Element(_title).Value);
}
public static XElement GetRssFeedChannel( string rssUri)
{
XElement feed = XElement .Load(rssUri);
return feed.Element(_channel);
}
}
public class RssListItem
{
public string Title { get ; set ; }
public string Link { get ; set ; }
}
* This source code was highlighted with Source Code Highlighter .
次に、このリストをTitlesListActivityという名前のアクティビティに表示します。
これを行うには、ListActivityを使用します。その主な(そして唯一の)目的は、リストを表示することです。
xmlマークアップを指定してSetContentViewを呼び出す必要がないことに注意してください。
[Activity(Label = "List" )]
public class TitlesListActivity : ListActivity
{
protected override void OnCreate(Bundle bundle)
{
base .OnCreate(bundle);
var titles = RssReader.GetTitles( "http://habrahabr.ru/rss/blogs/mono/" );
ListAdapter = new ArrayAdapter< string >( this , Android.Resource.Layout.SimpleListItem1, titles.ToArray());
}
}
* This source code was highlighted with Source Code Highlighter .
特に興味深いのは、Android.Resource.Layout.SimpleListItem1というリソースです。 これは事前定義されたリソースの1つであり、その完全なリスト(マークアップとともに)はここにあります 。
そのマークアップ:
< TextView xmlns:android ="http://schemas.android.com/apk/res/android"
android:id ="@android:id/text1"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:textAppearance ="?android:attr/textAppearanceLarge"
android:gravity ="center_vertical"
android:paddingLeft ="6dip"
android:minHeight ="?android:attr/listPreferredItemHeight"
/>
* This source code was highlighted with Source Code Highlighter .
アプリケーションを起動します。
最初のボタンをクリックすると、RSSフィードにヘッダーのリストが表示された新しいアクティビティが開きます。
いいね! すべてうまくいきますが、もちろん、もっと複雑なものが欲しいです。
タスクを複雑にしましょう
リストから特定のRSSフィードを選択し、ブラウザーのフィードからエントリを開く機能を追加します。
まず、リソースを少し操作してみましょう。DrawableディレクトリにMonoと.NETのロゴを含む2つの画像を追加します(リソースのタイプを指定することを忘れないでください!)。 また、Strings.xmlファイル(Valuesディレクトリ)で、ドロップダウンリストに値の配列を追加します。
<? xml version ="1.0" encoding ="utf-8" ? >
< resources >
< string name ="ApplicationName" > MyFirstMonoAndroidApplication </ string >
< string-array name ="frameworks" >
< item > Mono </ item >
< item > .Net </ item >
< item > Mono and .Net </ item >
</ string-array >
</ resources >
* This source code was highlighted with Source Code Highlighter .
次に、新しいマークアップMoreFriendlyRssFeed.xmlを作成する必要があります
<? xml version ="1.0" encoding ="utf-8" ? >
< LinearLayout
android:layout_width ="fill_parent"
android:layout_height ="fill_parent"
xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation ="vertical" >
< Spinner
android:id ="@+id/FrameworkSelector"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content" >
</ Spinner >
< ListView
android:id ="@+id/RssEntries"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content" >
</ ListView >
</ LinearLayout >
* This source code was highlighted with Source Code Highlighter .
すべてが非常に簡単です。リボンを選択するスピナーとリストを表示するListView。 現在の段階では、ListView(または彼のアダプター)内の要素をマークアップすることについて何も知らないことを理解することが重要です。 このマークアップに基づいて、ListViewは単に「一部の」リストを表示すると言うことができます。
リストアイテムのマークアップも作成する必要があります。 RssRow.xmlと呼びましょう。 リストの各要素に、画像とテキスト(記事のタイトル)が付いたボタンを含めるようにします。
<? xml version ="1.0" encoding ="utf-8" ? >
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:padding ="6dip" >
< ImageButton
android:id ="@+id/LogoButton"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:src ="@drawable/mono" >
</ ImageButton >
< TextView
android:id ="@+id/Title"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content" >
</ TextView >
</ LinearLayout >
* This source code was highlighted with Source Code Highlighter .
最も重要なこと、アクティビティの実装に移りましょう。アクティビティの実装は、すべてのパーツをリンクします。
[Activity(Label = "Friendly List" )]
public class MoreFriendlyRssFeedActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base .OnCreate(bundle);
SetContentView(Resource.Layout.MoreFriendlyRssFeed);
Spinner spinner = FindViewById<Spinner>(Resource.Id.FrameworkSelector);
spinner.ItemSelected += spinner_ItemSelected;
ArrayAdapter adapter = ArrayAdapter.CreateFromResource( this , Resource.Array.frameworks, Android.Resource.Layout.SimpleSpinnerItem);
adapter.SetDropDownViewResource(
Android.Resource.Layout.SimpleSpinnerDropDownItem);
spinner.Adapter = adapter;
}
void spinner_ItemSelected( object sender, ItemEventArgs e)
{}
}
* This source code was highlighted with Source Code Highlighter .
もう1つの定義済みリソースAndroid.Resource.Layout.SimpleSpinnerItemに注目しましょう。 便宜上、マークアップも示します。
< TextView xmlns:android ="http://schemas.android.com/apk/res/android"
android:id ="@android:id/text1"
style ="?android:attr/spinnerItemStyle"
android:singleLine ="true"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content" />
* This source code was highlighted with Source Code Highlighter .
リストにテキストを表示するには、ArrayAdapterクラスを使用します。 もっと複雑なものを表示する必要がある場合は、GetViewメソッドをオーバーライドする独自のクラスであるArrayAdapterの継承クラスを実装する必要があります。 RssListItemAdapterクラスを作成して、データをバインドおよび表示します。
public class RssListItemAdapter: ArrayAdapter<RssListItem>
{
private IList <RssListItem> Items;
public RssListItemAdapter(Context context, int textViewResourceId, IList<RssListItem> items)
: base (context, textViewResourceId, items)
{
Items = items;
}
public override View GetView( int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null )
{
LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
// , .
view = inflater.Inflate(Resource.Layout.RssRow, null );
}
//
RssListItem item = Items[position];
//
//
ImageButton btnLogo = (ImageButton)view.FindViewById(Resource.Id.LogoButton);
btnLogo.Click += delegate
{
Intent browserIntent = new Intent( "android.intent.action.VIEW" , Android.Net. Uri .Parse(item.Link));
Context.StartActivity(browserIntent);
};
// ( )
btnLogo.SetImageResource(item.Title.StartsWith( "Mono" ) ? Resource.Drawable.mono : Resource.Drawable.net);
//
TextView txtTitle = (TextView)view.FindViewById(Resource.Id.Title);
txtTitle.Text = item.Title;
//
return view;
}
}
* This source code was highlighted with Source Code Highlighter .
これで、データをリストにバインドし、必要な形式で表示することができます。 リストから項目を選択するために、イベントハンドラーのデータにバインドする機能を追加します。
void spinner_ItemSelected( object sender, ItemEventArgs e)
{
ListView view = FindViewById<ListView>(Resource.Id.RssEntries);
switch (e.Position)
{
case 0:
view.Adapter = new RssListItemAdapter( this , Resource.Layout.RssRow, RssReader.GetRssListItems( "http://habrahabr.ru/rss/blogs/mono/" ));
break ;
case 1:
view.Adapter = new RssListItemAdapter( this , Resource.Layout.RssRow, RssReader.GetRssListItems( "http://habrahabr.ru/rss/blogs/net/" ));
break ;
case 2:
view.Adapter = new RssListItemAdapter( this , Resource.Layout.RssRow, RssReader.GetRssListItems( "http://habrahabr.ru/rss/blogs/mono/" , "http://habrahabr.ru/rss/blogs/net/" ));
break ;
}
}
* This source code was highlighted with Source Code Highlighter .
アプリケーションを実行し、2番目の例を開きます。 RSSフィード(またはフィードのセット)を選択できるようになりました。
リストは次のようになります。
見出しの横にあるボタンをクリックすると、対応する記事がブラウザーで開きます。
Androidデバイスでのアプリケーションの実行
ポイントは小さい:特定のAndroidデバイスでアプリケーションを実行します。 今すぐこれを行おうとすると、apk(Android Package)ファイルをビルドしようとしたときにエラーが発生します。 また、Mono Androidの試用版では、エミュレータ上でのみアプリケーションを実行できることを指摘したいと思います。 幸いなことに、私のバージョンはもう試用版ではないので、例を論理的な結論に導くことができます。
インストールパッケージを正しくアセンブリするには、AndroidManifest.xmlを作成する必要があります。 このファイルには、アプリケーションに関する重要な情報が含まれています。この情報がないと、デバイスでアプリケーションを起動できません。
プロジェクトプロパティを使用してAndroidManifest.xmlを作成することができます。
しかし、あなたの手でそれを書く方がはるかに興味深いでしょう:
<? xml version ="1.0" encoding ="utf-8" ? >
< manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="First.MonoApp" android:versionCode ="1" android:versionName ="1.0" >
< application android:label ="MyMonoApp" >
</ application >
< uses-sdk android:minSdkVersion ="4" />
< uses-permission android:name ="android.permission.INTERNET" />
</ manifest >
* This source code was highlighted with Source Code Highlighter .
これでapkファイルを収集できます。 ビルド-> MyFirstMonoAndroidApplication for Android(.apk)パッケージ
Androidデバイスにコピーして起動します。 インストール中に、警告が表示されます:
このアプリケーションの許可:インターネットへのフルアクセス。
つまり、マニフェストからの必要な要件はすべて、インストールの前にユーザーに表示されます。 インストールが完了するのを待っています。 そして...
ご清聴ありがとうございました。
アプリケーションのソースコードへのリンク