フラグメントのテーマを設定しようとしています。
マニフェストでテーマを設定しても機能しません。
Android:theme="@Android:style/Theme.Holo.Light"
以前のブログを見ると、ContextThemeWrapperを使用する必要があるように見えます。誰でも私にコード例を紹介できますか?何も見つかりません。
マニフェストでテーマを設定することは、通常アクティビティに使用されます。
テーマをフラグメントに設定する場合は、フラグメントのonCreateView()に次のコードを追加します。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create ContextThemeWrapper from the original Activity Context with the custom theme
final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.yourCustomTheme);
// clone the inflater using the ContextThemeWrapper
LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
// inflate the layout using the cloned inflater, not default inflater
return localInflater.inflate(R.layout.yourLayout, container, false);
}
フラグメントは、アクティビティからテーマを取ります。各フラグメントには、そのフラグメントが存在するアクティビティのテーマが割り当てられます。
テーマはFragment.onCreateViewメソッドで適用されます。このメソッドでは、コードがビューを作成します。ビューは、実際にはテーマが使用されるオブジェクトです。
Fragment.onCreateViewでは、ビューを拡張するLayoutInflaterパラメーターを取得し、テーマに使用されるコンテキストを保持します。実際はこれがアクティビティです。そのため、膨らんだビューはアクティビティのテーマを使用します。
テーマをオーバーライドするには、 LayoutInflater.cloneInContext を呼び出します。これは、テーマの変更に使用できることをドキュメントに記載しています。ここでContextThemeWrapperを使用できます。次に、クローンされたインフレータを使用して、フラグメントのビューを作成します。
また、フラグメントダイアログをそのアクティビティとは異なるテーマで表示するようにしようとしており、 このソリューション に従いました。コメントで言及された一部の人々のように、私はそれを動作させておらず、ダイアログはマニフェストで指定されたテーマで表示され続けました。問題は、onCreateDialog
メソッドでAlertDialog.Builder
を使用してダイアログを構築しているため、リンクした回答に示されているonCreateView
メソッドを使用していないことでした。そして、AlertDialog.Builder
をインスタンス化するときに、代わりにインスタンス化されたConstextThemeWrapper
を使用すべきだったときに、getActivity()
を使用してコンテキストを渡していました。
OnCreateDialogのコードは次のとおりです。
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Create ContextThemeWrapper from the original Activity Context
ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(getActivity(), Android.R.style.Theme_DeviceDefault_Light_Dialog);
LayoutInflater inflater = getActivity().getLayoutInflater().cloneInContext(contextThemeWrapper);
// Now take note of the parameter passed into AlertDialog.Builder constructor
AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
View view = inflater.inflate(R.layout.set_server_dialog, null);
mEditText = (EditText) view.findViewById(R.id.txt_server);
mEditText.requestFocus(); // Show soft keyboard automatically
mEditText.setOnEditorActionListener(this);
builder.setView(view);
builder.setTitle(R.string.server_dialog);
builder.setPositiveButton(Android.R.string.ok, this);
Dialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
当初、次のようにインスタンス化されるAlertDialog.Builder
がありました。
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
変更後:
AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
この変更後、フラグメントダイアログが正しいテーマで表示されました。したがって、他の誰かが同様の問題を抱えており、AlertDialog.Builder
を使用している場合は、ビルダーに渡されるコンテキストを確認してください。お役に立てれば! :)
マニフェストにAndroid:minSdkVersion="11"
が設定されていることを確認してください。これが David's の例がうまくいかなかった原因かもしれません。
また、Android:theme="@Android:style/Theme.Holo.Light"
タグに<application>
属性を設定し、NOT<activity>
タグを設定します。
別の考えられる問題は、ContextThemeWrapper()
を使用するときにコンテキストを取得する方法です。 getActivity().getApplicationContext()
のようなものを使用する場合は、代わりにgetActivity()
に置き換えてください。
通常、Theme.HoloはMainActivityにリンクされたフラグメントに適用する必要があります。
フラグメントにdifferentテーマを適用する場合は、ContextThemeWrapperを使用することに注意してください。フラグメントを追加するMainActivityからコードを提供すると役立つ場合があります。
便利なリンク:
私が使用した単一のスタイルを適用するために
getContext().getTheme().applyStyle(styleId, true);
フラグメントのonCreateView()
でbeforeフラグメントのルートビューを膨らませてくれます。
Davidが提案した解決策を試しましたが、すべてのシナリオでは機能しませんでした:
1。スタックに追加された最初のフラグメントにはアクティビティのテーマがあり、onCrateViewで定義されたものではなく、スタックに追加する2番目のフラグメントでフラグメントに修正が適用されました。
2。それらが正しく表示された2番目のフラグメントで、私は次のことを行いましたメモリをきれいにしてアプリを閉じ、アプリを再起動し、フラグメントでアクティビティが再作成されたときにフラグメントはアクティビティの間違ったものを変更しましたフラグメントのonCrateViewで設定されたものと同じではありません。
この問題を修正するために、小さな変更を行い、inflater.inflateのコンテナー引数をnullに置き換えました。
私はインフレータがいくつかのシナリオでコンテナビューからのコンテキストを使用する方法を知りません。
注-Android.support.v4.app.FragmentとAndroid.support.v7.app.AppCompatActivityを使用しています。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create ContextThemeWrapper from the original Activity Context with the custom theme
final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.yourCustomTheme);
// clone the inflater using the ContextThemeWrapper
LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
// inflate the layout using the cloned inflater, not default inflater
return localInflater.inflate(R.layout.yourLayout, null, false);
}
Javaクラスを作成し、onCreateメソッドでテーマを変更するレイアウトを使用します。その後、通常どおりマニフェストでそれを言及します
フラグメントのレイアウトファイルでAndroid:theme = "@style/myTheme"
を使用して問題を解決しました。たとえば、これはLinearLayout
のスタイルを変更しますが、その内容はLinearLayout
以外のものではありません。したがって、フラグメント全体を任意のスタイルで装飾するには、テーマをその最も外側の親レイアウトに適用します。
注:まだ解決策が見つからない場合に備えて、試してみてください
<LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:theme = "@style/myTheme" >
<TextView
Android:id="@+id/tc_buttom_text1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Time elapsed"/>
<TextView
Android:id="@+id/tc_buttom_text2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginTop="10dp"
Android:text="00:00:00 00"/>
</LinearLayout>
特定のフラグメントにスタイルを適用する場合は、フラグメントのonCreateView()
またはonAttach()
を呼び出す前にこの行を追加するだけです。
getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);
透明なステータスバーを設定する場合は、ルートレイアウトのfitsSystemWindows
プロパティにfalseを設定します。
Android:fitsSystemWindows="false"
インフレータを呼び出す前に、フラグメントコンテキストにテーマを設定することで動作するようにしました。
注:これは、MvvmCrossと組み合わせたXamarin.Androidの例です。これがJavaプログラマーでも機能するかどうかは100%わかりません。しかし、あなたは試すことができます:)
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Context.SetTheme(Theme);
base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(FragmentLayoutId, container, false);
// Doing some other stuff
return view;
}
SetTheme拡張メソッドコード
public static void SetTheme(this Context context, AppThemeStyle themeStyle)
{
var themeStyleResId = themeStyle == AppThemeStyle.Dark ? Resource.Style.AppTheme : Resource.Style.AppTheme_Light;
context.SetTheme(themeStyleResId);
}
これが何人かの人々の助けになることを願っています!