アレアレ

お役立ち情報、お悩み解決情報を発信!

visual studio for mac

Visual Studio for MacのAndroid開発でPreferenceFragmentを使うときの注意点

Visual Studio for MacのAndroid開発でPreferenceFragmentを使うときの注意点

今回は、Visual Studio for MacのAndroid Appプロジェクト(Xamarin.Formではなく)で、Androidアプリを開発したい人に伝えたいお役立ち情報です。

Androidでは、Preferences APIというライブラリを利用して、そのアプリにおけるユーザー設定情報を簡単に管理することができます。

ただ、Visual Studio for MacからこのAPIで提供されるPreferenceFragmentクラスを利用して、設定画面を作るときには、Android StudioでJavaで開発した場合には起きない問題が起きます。

PreferenceFragment継承クラスにはRegisterアトリビュートでクラス名を設定する必要がある

その問題とは、「PreferenceFragment継承して自作したPreferenceFragmentに、ある設定をしないと正しく呼び出せない」という問題です。ちなみに、その設定をしないと単純に自作のPreferenceFragmentを呼び出すところで、例外が発生しアプリが落ちます。

では、どのような設定が必要になると言いますと。その説明のために、具体的なコードを示しながらご紹介します。

まず、自作のユーザー設定画面の大元のレイアウトを設定するActivityとして、MyPreferenceActivityというクラスを作るとします。そのクラスのコードは次の通りです。

MyPreferenceActivity.cs

using System.Collections.Generic;

using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Preferences;

namespace MyGreatApp
{
    [Activity(Label = "MyPreferenceActivity")]
    public class MyPreferenceActivity : PreferenceActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Create your application here
        }

        public override void OnBuildHeaders(IList<Header> target)
        {
            LoadHeadersFromResource(Resource.Xml.preference_headers, target);
        }
    }
}

で、MyPreferenceActivityは、ユーザーに入力させる設定項目を「Resource.Xml.preference_headers」というXMLから読み込んでいます。そのXMLがどうなっているかというと、次の通りです。

Resources/xml/preference_headers.xml

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
  <header android:fragment="com.companyname.MyGreatApp.MyPreferenceFragment"
      android:title="ユーザー設定1" />
</preference-headers>

つまり、MyPreferenceActivityを表示すると、「ユーザー設定1」という設定項目が表示される状況です。

そして、その「ユーザー設定1」をタップすると、「com.companyname.MyGreatApp.MyPreferenceFragment」という自作のPreferenceFragmentが呼び出されるわけですが、その時に上述した「ある注意」が必要となります。

その注意点を説明するために、自作のMyPreferenceFragmentのコードを示すと次の通りです。

MyPreferenceFragment.cs

using System.Collections.Generic;

using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Preferences;

namespace MyGreatApp
{
  [Register("com.companyname.MyGreatApp.MyPreferenceFragment")]
  public class MyPreferenceFragment : PreferenceFragment
  {
    public override void OnCreate(Bundle savedInstanceState)
    {
      //省略
    }
  }
}

で、以上のソースにおいて、MyPreferenceFragmentのクラスの宣言の上に、「[Register(“com.companyname.MyGreatApp.MyPreferenceFragment”)]」というコードがありますよね。

ここがポイントです。このようにRegisterアトリビュートを利用して、そのクラス名をパッケージ名、プロジェクト名も含めた文字列で、ちゃんと指定する必要があるわけです。ちなみに、これは、preference_headers.xml内で「ユーザー設定1」向けに指定した値と同じものとなります。

逆に、このRegisterアトリビュートの設定を忘れると、MyPreferenceActivity画面で「ユーザー設定1」をタップした瞬間にアプリが落ちます。

なので、面倒ですが、この設定をする必要があります。

普通のFragmentをLayoutから読み込むときも同じ問題が発生する

ちなみに、今回は、PreferenceFragmentを利用するときの例をご紹介していますが、同じ問題が、普通のFragmentをLayoutのXMLから指定するときにも起きます。

次のように、自作のFragmentを読み込む場合ですね。

<fragment
    android:id="@+id/my_fragment"
    android:name="com.companyname.appname.MyFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

このようにしてFragmentを利用したい場合、MyFragmentにRegisterの設定が必要になります。そうしないと例外でアプリが落ちます。

Return Top