조각에 대한 테마 설정


117

조각에 대한 테마를 설정하려고합니다.

매니페스트에서 테마 설정이 작동하지 않습니다.

android:theme="@android:style/Theme.Holo.Light"

이전 블로그를 보면 ContextThemeWrapper를 사용해야하는 것처럼 보입니다. 누구든지 코딩 된 예제를 참조 할 수 있습니까? 아무것도 찾을 수 없습니다.

답변:


187

매니페스트의 테마 설정은 일반적으로 활동에 사용됩니다.

Fragment에 테마를 설정하려면 Fragment의 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);
}

30
이것은 나를 위해 작동하지 않습니다. 조각에는 여전히 매니페스트 파일에 지정된 동일한 테마가 있습니다.
Giorgi

1
매니페스트에서 조각이 아닌 활동에 대한 테마를 지정합니다. fragment 또는 fragmentActivity를 사용하고 있습니까?
David

1
나를 위해 일했습니다. 활동 내에서 고전적인 조각으로.
David

8
@David "매니페스트의 테마 설정은 활동에 사용됩니다". 이것은 전적으로 사실이 아닙니다. FragmentTransaction을 사용하여 런타임에 프래그먼트를 추가하면 해당 테마가 프래그먼트에도 적용됩니다.
sebster 2013 년

4
이것은 ActionBarSherlock 라이브러리의 SherlockFragmentActivity에서 작동하지 않는 것 같습니다.
toobsco42

18

Fragment는 활동에서 테마를 가져옵니다. 각 조각에는 그것이 존재하는 활동의 테마가 할당됩니다.

테마는 Fragment.onCreateView 메서드에 적용되며, 여기서 코드는 실제로 테마가 사용되는 개체 인 뷰를 생성합니다.

Fragment.onCreateView에서는 뷰를 확장하는 LayoutInflater 매개 변수를 가져오고 테마에 사용되는 컨텍스트를 보유합니다. 실제로 이것이 바로 Activity입니다. 따라서 부풀려진 뷰는 활동의 테마를 사용합니다.

테마를 재정의하려면 LayoutInflater.cloneInContext를 호출 할 수 있으며 , 이는 테마 변경에 사용될 수 있음을 문서에서 언급합니다. 여기에서 ContextThemeWrapper를 사용할 수 있습니다. 그런 다음 복제 된 팽창기를 사용하여 조각의보기를 만듭니다.


Google 문서에서 다음과 같이 설명합니다. "... 주어진 컨텍스트와 관련된 새로운 LayoutInflater 객체를 스 패킹하는 브랜드를 반환합니다 ..."- developer.android.com/reference/android/view/…
Chris

Davids 코드 솔루션에 매우 유용한 추가 기능입니다. 감사!
muetzenflo

13

단일 스타일을 적용하기 위해 방금 사용한

getContext().getTheme().applyStyle(styleId, true);

onCreateView()조각의 루트 뷰를 부풀리기 전에 조각 에서 작동합니다.


1
min api 23 forgetContext()
vigilancer

@vigilancer 최소 API 문제에 대한 수정 사항은 다음 답변을 확인하십시오. stackoverflow.com/questions/36736244/…
rm8x

1
훌륭한 솔루션입니다. onAttach (Context)에 코드를 추가했습니다.이 코드는 모든 자식 조각에도 적용됩니다
crysxd

이는 컨텍스트 (대부분의 경우 활동) 테마를 수정하므로 예상치 못한 결과를 초래할 수 있습니다. 활동의 미래 팽창 (예 : 회전 후)은 모든 곳에서 새 테마를 사용할 것입니다
Irhala

12

나는 또한 내 조각 대화 상자를 활동과 다른 테마로 표시하려고 시도 했으며이 솔루션을 따랐습니다 . 댓글에 언급 된 일부 사람들과 마찬가지로 작동하지 않았고 매니페스트에 지정된 테마로 대화가 계속 표시되었습니다. 문제는 방법 AlertDialog.Builder에서 사용하여 대화를 onCreateDialog작성하고 있으므로 onCreateView연결된 답변에 표시된 방법 을 사용하지 않는 것으로 밝혀졌습니다. 그리고 인스턴스화 할 때 인스턴스화 된 AlertDialog.Builder것을 대신 getActivity()사용해야 할 때를 사용하여 컨텍스트에서 전달했습니다 ConstextThemeWrapper.

다음은 내 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빌더에 전달되는 컨텍스트를 확인하십시오. 도움이 되었기를 바랍니다! :)


9

android:minSdkVersion="11"매니페스트에 설정 했는지 확인하십시오 . 이것이 David의 모범이 당신에게 효과가 없었던 이유 일 수 있습니다.

또한, 설정 android:theme="@android:style/Theme.Holo.Light"에 대한 속성 <application>태그와 NOT<activity> 태그를.

또 다른 가능한 문제는 ContextThemeWrapper(). 같은 것을 사용하는 경우 대신 getActivity().getApplicationContext()교체하십시오 getActivity().

일반적으로 Theme.Holo는 MainActivity에 연결된 Fragments에 적용되어야합니다.

Fragment에 다른 테마 를 적용하려면 ContextThemeWrapper를 사용합니다 . MainActivity에서 Fragments를 추가하는 코드 조각을 제공하면 도움이 될 수 있습니다.


유용한 링크 :

Fragment의 Custom ListView가 상위 테마를 준수하지 않습니다.


8

나는 David가 제안한 솔루션을 시도했지만 모든 시나리오에서 작동하지는 않았습니다.
1. 스택에 추가 된 첫 번째 조각에는 onCrateView에 정의 된 것이 아니라 활동의 테마가 있지만 두 번째 조각에는 스택에 추가하면 조각에 적용되었습니다.

2. 올바르게 표시된 두 번째 조각에서 다음을 수행했습니다. 메모리를 정리하여 앱을 강제로 닫고 앱을 다시 열고 조각으로 활동이 다시 생성되었을 때 조각이 잘못 변경되었습니다. 조각의 onCrateView에 설정된 것과 동일하지 않습니다.

문제를 해결하기 위해 작은 변경을 수행하고 inflater.inflate의 컨테이너 인수를 null로 대체했습니다.

나는 inflater가 컨테이너 뷰의 컨텍스트를 일부 시나리오에서 사용하는 방법을 모르겠습니다.

참고-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);
} 

감사합니다. 귀하의 솔루션이 저를 구해줍니다. 내 DialogFragment의 테마는 다른 조각과는 다소 달랐습니다. 제공된 인플레이터를 사용했기 때문에 EditText가 이상해졌습니다. ContextThemeWrapper에 대한 도움을 찾았지만 어떻게 수행되는지 보여주지 않았습니다. 귀하의 솔루션이 저에게 효과적입니다. 감사합니다.
Phuong Dao

4

조금 늦었지만 도움이 되었기 때문에 다른 사람에게 도움이 될 수 있습니다. 조각의 onCreatView 함수 안에 아래 코드 줄을 추가해 볼 수도 있습니다.

    inflater.context.setTheme(R.style.yourCustomTheme)

2

자바 클래스를 생성 한 다음 onCreate 메소드에서 테마를 변경하려는 레이아웃을 사용한 다음 매니페스트에서 정상적으로 언급합니다.


1

특정 조각에 스타일을 적용하려면 호출하기 전에 onCreateView()또는 onAttach()조각 에이 줄을 추가하십시오 .

getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);

투명 상태 표시 줄을 설정 하려면 루트 레이아웃의 속성에 false 를 설정 fitsSystemWindows합니다.

android:fitsSystemWindows="false"

1

인플레이터를 호출하기 전에 조각 컨텍스트에 테마를 설정하여 작동하도록했습니다.

참고 : 이것은 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);
}

나는 이것이 일부 사람들을 돕기를 바랍니다.


1

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>

-1

onAttach에서 롤리팝을 시도해 볼 수 있습니다.

최종 창 창 = activity.getWindow (); window.setStatusBarColor (myStatusBarColor)

ondettach에서 기본값으로 다시 설정하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.