テーマをアプリケーションから分離する方法

Androidアプリケーションの外観をカスタマイズ(カスタマイズ)する問題は、開発者の前にしばしば発生します。 その理由は、企業スタイルへのインターフェイスに従う必要があるか、または標準要素のセットのようにではなく、アプリケーションを特別な方法で見たい顧客の要件にある可能性があります。



これらの目的(テーマ、スタイル)のためにプラットフォームに組み込まれたツールがありますが、アプリケーション自体のコードを変更せずにアプリケーションインターフェイスを変更するための明確なメカニズムを提供しません。



アプリケーションとは別にダウンロードできる新しい「テーマ」をインストールすることにより、Androidアプリケーションの外観を動的に変更できる技術を提案します。 この記事で説明されている開発は、記事の著者が勤務している会社「Mera-NN」( www.meranetworks.com )のモバイルアプリケーション部門でのパイロットプロジェクトとして実施されました。



図書館



検討中のメカニズムは、開発者のサイトからダウンロードし、通常のAndroidアプリケーションとしてデバイスにインストールできる個別の.apkファイルの形式でトピックの配布を提供します。 プラットフォームの基本要素と新しく作成された(カスタム)UI要素の両方のテーマを変更することができます。



この考え方は、Android APIを使用すると、あるアプリケーションから別のアプリケーションのリソースにアクセスできるという事実に基づいています。



別のアプリケーションのリソースにアクセスするためのサンプルコード:



PackageManager pm = context.getPackageManager(); Resources res = pm.getResourcesForApplication ("package name"); Resources.Theme rstheme = res.newTheme();
      
      





ここで、パッケージ名はデバイスにインストールされた任意のパッケージです。



個々のアクティビティのテーマの変更は、作成の直前にのみ行うことができます。 これを行わないために、onCreate()メソッドが再定義されるBaseActivityクラスを作成するたびに。 また、別のアプリケーションのリソースを使用する場合は、これらのリソースからリソースおよびトピックにアクセスするために使用されるメソッドを再定義する必要があります。



BaseActivityクラスのソースコードを以下に示します。



 package com.mera.detachedthemeslib; import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; public abstract class BaseActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { ActivityManager.setThemeForActivity(this); super.onCreate(savedInstanceState); } @Override public Resources getResources() { return ActivityManager.getResourcesForActivity(this, super.getResources()); } @Override public Resources.Theme getTheme() { return ActivityManager.getThemeForActivity(this, super.getTheme()); } }
      
      





アプリケーションの現在の構成を管理するために、ThemeManagerクラスが作成されました。

次の機能を実装します。



 static List<Theme> getThemes(Context ctx, ThemesConfiguration cfg)
      
      







 static void setTheme(Context ctx, Theme theme)
      
      





ThemeManagerの使用例は、個別のテーマを使用するアプリケーションのサンプルコードで以下に示します。



これらのクラス(BaseActivityおよびThemeManager)、および一連の補助クラスは、 githubで利用可能なライブラリに結合されました。



ライブラリを使用したアプリケーション開発:



アプリケーションでトピックの動的な切り替えを有効にするには、いくつかの条件を満たしている必要があります。



まず、開発中のアプリケーションでテーマを動的に変更できるようにするには、このアプリケーションのすべてのアクティビティをBaseActivity(BaseListActivity、BasePreferenceActivity)から継承する必要があります。



次に、アプリケーションに「MainTheme」という名前のテーマを含める必要があります。

開発したアプリケーションの例:



 <style name="MainTheme" parent="android:Theme"> <item name="custButtonStyle">@android:style/Widget.Button</item> </style>
      
      





アプリケーションに他の標準テーマが組み込まれており、必要に応じてユーザーが使用できるようにする場合は、ThemeManagerに連絡するときにそれらを指定する必要があります。 これがどのように行われるかの例を、グリーンテーマを追加するときに以下に示します。



別のトピックを提供する追加のアプリケーションには制限もあります。



以下は、個別のトピックを使用するアプリケーションのサンプルコードです。



アプリケーションのメイン画面:



 package com.mera.detachedthemesapp; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Spinner; import com.mera.detachedthemeslib.BaseActivity; public class MainActivity extends BaseActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String[] items = new String[] {"One", "Two", "Three"}; Spinner spinner = (Spinner) findViewById(R.id.spinner1); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, items); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); this.findViewById(R.id.switch_button).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { startActivity(new Intent(MainActivity.this, SwitchThemeActivity.class)); } }); } }
      
      





それらを切り替えるためのトピックのリストを含む画面:



 package com.mera.detachedthemesapp; import java.util.List; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.TextView; import com.mera.detachedthemeslib.BaseListActivity; import com.mera.detachedthemeslib.ThemesConfiguration; import com.mera.detachedthemeslib.ThemeManager; public class SwitchThemeActivity extends BaseListActivity { private LayoutInflater mInflater; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); List<ThemeManager.Theme> themes = ThemeManager.getThemes(this, new ThemesConfiguration() .addInnerTheme(R.style.CustomTheme2, "Green")); ArrayAdapter<ThemeManager.Theme> adapter = new ArrayAdapter<ThemeManager.Theme>( this, android.R.layout.simple_list_item_1, themes) { @Override public View getView(int position, View convertView, ViewGroup parent) { View row; if (null == convertView) { row = mInflater.inflate( android.R.layout.simple_list_item_1, null); } else { row = convertView; } TextView tv = (TextView) row.findViewById(android.R.id.text1); tv.setText(((ThemeManager.Theme) getItem(position)).mTitle); return row; } }; getListView().setAdapter(adapter); getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ThemeManager.Theme theme = (ThemeManager.Theme) getListView() .getAdapter().getItem(position); ThemeManager.setTheme(SwitchThemeActivity.this, theme); Intent intent = new Intent(); intent.setClass(SwitchThemeActivity.this, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); SwitchThemeActivity.this.startActivity(intent); } }); } }
      
      





それはどのように見えますか...



開発したアプリケーションでは、2つの組み込みテーマを使用してアプリケーションの外観を変更できます。



このアプリケーションでは、通常のAndroidアプリケーションとして個別にダウンロードおよびインストールされた新しいテーマをインストールして使用することもできます。



ライブラリと別のテーマのサンプルアプリケーションのコードはgithubで入手できます。

DetachedThemesLib-ライブラリ

DetachedThemesApp-アプリケーション

DetachedThemesTheme-分離されたテーマ



All Articles