PreferenceActivity에서 "addPreferencesFromResource"대신 무엇을 사용해야합니까?


360

방금 메소드 addPreferencesFromResource(int preferencesResId)가 Android 설명서 ( Reference Entry ) 에서 더 이상 사용되지 않는 것으로 나타났습니다 .

불행하게도, 방법의 설명에 다른 방법이 제공되지 않습니다.

preferenceScreen.xml을 일치하는 PreferenceActivity에 연결하려면 대신 어떤 방법을 사용해야합니까?



이 솔루션은 여전히을 사용합니다 addPreferencesFromResource(int preferencesResId). 뭔가 빠졌습니까?
Jammo

@Jammo 네,하지만 새로운 방식-> 조각을 반영하기 위해 Activity에서 Fragment로 옮겨졌습니다.
WannaGetHigh

답변:


332

API 레벨 11 기준으로 선호되는 접근법은 PreferenceFragment 오브젝트를 인스턴스화 하여 자원 파일에서 환경 설정을로드 하는 것이므로 메소드 설명에 대체 방법이 제공되지 않습니다 . 여기에서 샘플 코드를보십시오 : PreferenceActivity


대답 해 주셔서 감사합니다. 방금 "Video2Brain-Android Development"의 더 이상 사용되지 않는 지침을 따르고 PreferenceActivity 버전의 메소드를 사용했습니다. Btw : 가능한 한 대답이 유용한 것으로 평가하고 싶습니다.
mweisz

33
PreferenceFragment가 호환성 패키지에 포함 된 경우에만 stackoverflow.com/questions/5501431/…
좋습니다.

1
내가 작업 표시 줄 셜록를 사용하기 때문에, 내가 볼 ...이 문제를 해결하기 위해 다음과 같은 블로그를 따라 commonsware.com/blog/2012/10/16/...
어딘가의 누군가가

2
앱이 11보다 오래된 api 수준 (Android 3.0)과 호환되도록하려면 addPreferencesFromResource (int PreferencesID)를 호출해야합니다. 그러나 오래된 장치도 이탈 된 것으로 생각할 수 있습니다.
Einar Sundgren

5
@EinarSundgren 저는 Nexus One 소유자이며 사용 가능한 최대 버전은 2.2입니다. 나는 더 이상 사용되지 않을 것입니다! Grayskull의 힘으로 ... 나는 힘이있다!
TechNyquist 2016 년

186

위의 정답에 더 많은 정보를 추가하기 위해 Android에서 예제를 읽은 후 환경 설정 활동을 환경 설정 조각으로 쉽게 변환 할 수 있음을 알았습니다. 다음 활동이있는 경우 :

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.my_preference_screen);
    }
}

다음과 같이 내부 조각 클래스를 만들고 조각으로 이동 한 addPreferencesFromResources()다음 활동에서 조각을 호출하면됩니다.

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
    }

    public static class MyPreferenceFragment extends PreferenceFragment
    {
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.my_preference_screen);
        }
    }
}

프래그먼트에서 더 복잡한 환경 설정을 만드는 데 다른 미묘한 점이있을 수 있습니다. 그렇다면 누군가가 여기에 메모하기를 바랍니다.


6
좋아, 고마워 Java와 이런 유형의 사고는 지금까지 나의 멋진 작은 .net 세계에서 제거되었습니다. :)
Tom

44
addPreferencesFromResources()PreferenceFragment의 거래에서 왜 감가 상각 됩니까? 초보자의 관점에서는 불필요 해 보입니다.
Howdy_McGee

4
전화는 API 레벨 11이 필요합니다
메 흐멧

1
API가 레벨 9에 있다면 어떨까요? @mehmet
gumuruh

2
멋진 답변! android.R.id.content를 변경하지 않고 이것을 달성 할 수있는 방법이 있습니까? (올바른 나 메신저 잘못된 경우) ... 어떤 이유로 나에게 우아 것
tomer.z

37

@Garret Wilson 정말 감사합니다! 안드로이드 코딩에 대한 멍청한 듯이, 나는 많은 시간 동안 기본 설정 비 호환성 문제에 갇혀 있었고, 이전 API에서 지원하지 않는 새로운 메소드에 대한 일부 메소드 / 접근 방식을 사용하지 않기 때문에 실망했습니다. 다양한 기기에서 앱이 작동하도록 모든 종류의 해결 방법을 사용해야합니다. 정말 실망 스럽습니다!

클래스는 훌륭합니다. 이전과 같은 환경 설정으로 새로운 API에서 계속 작업 할 수 있지만 이전 버전과 호환되지는 않습니다. 광범위한 장치에 도달하려고 노력하고 있기 때문에 API 11 이전 장치와 최신 API에서 작동하도록하기 위해 약간의 노력을 기울였습니다.

import android.annotation.TargetApi;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;

public class MyPrefsActivity extends PreferenceActivity
{
    private static int prefs=R.xml.myprefs;

    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        try {
            getClass().getMethod("getFragmentManager");
            AddResourceApi11AndGreater();
        } catch (NoSuchMethodException e) { //Api < 11
            AddResourceApiLessThan11();
        }
    }

    @SuppressWarnings("deprecation")
    protected void AddResourceApiLessThan11()
    {
        addPreferencesFromResource(prefs);
    }

    @TargetApi(11)
    protected void AddResourceApi11AndGreater()
    {
        getFragmentManager().beginTransaction().replace(android.R.id.content,
                new PF()).commit();
    }

    @TargetApi(11)
    public static class PF extends PreferenceFragment
    {       
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(MyPrefsActivity.prefs); //outer class
            // private members seem to be visible for inner class, and
            // making it static made things so much easier
        }
    }
}

두 개의 에뮬레이터 (2.2 및 4.2)에서 성공적으로 테스트되었습니다.

왜 내 코드가 그렇게 엉망인 것입니까?

나는 안드로이드 코딩의 멍청한 놈이며, 가장 큰 자바 팬이 아닙니다.

더 이상 사용되지 않는 경고를 피하고 Eclipse가 컴파일하도록 강제하기 위해 주석에 의존해야했지만 클래스 또는 메소드에만 영향을 미치는 것처럼 보이므로 코드를 두 가지 새로운 메소드로 옮겨야했습니다.

새 PreferenceActivity에 대한 클래스를 복사하여 붙여 넣을 때마다 xml 리소스 ID를 두 번 쓰지 않고 싶지 않으므로이 값을 저장하기 위해 새 변수를 만들었습니다.

나는 이것이 다른 누군가에게 유용하기를 바랍니다.

추신 : 저의 의견에 대해 죄송하지만, 새로 와서 그러한 장애를 발견하면 도와 드릴 수는 없습니다.


글쎄 ... 복사하고 붙여 넣을 때마다 외부 클래스 이름을 두 번 변경해야한다는 것을 알았습니다. 내부 클래스에 prefs를 전달하여 실제로 이것을 피할 수있는 방법이 있습니다. PreferenceFragment 파생 클래스에는 권장되지 않으므로 prefs를 매개 변수로 허용하는 내부 클래스 생성자를 만들 수 없습니다. 또한 super.onCreate가 호출 된 후 addPreferencesFromResource를 호출해야하고 PreferenceFragment 파생 클래스가 호출 된 후 바로 onCreate가 호출되지 않으므로 prefs를 가져오고 addPreferencesFromResource를 즉시 호출하기 위해 내부 클래스에서 메소드를 작성할 수 없습니다.
ecv

... 인스턴스화되었습니다. 따라서 내부 클래스에서 새 변수를 작성하고 내부 클래스에서 해당 변수에 대한 공용 세트 메소드를 작성하고 addPreferencesFromResource를 super.onCreate에 대한 호출 이후 위치에두고 onCreate 내에서 내부 클래스를 인스턴스화하고 prefs를 설정해야합니다. 이전과 같이 getFragmentManager ()를 호출 할 때 사용하십시오.
ecv

2
당신의 코드는 생명의 은인이었습니다! 이전 전화와 새 전화를 모두 타겟팅하려고했지만 3 일을 낭비했습니다. 답변은 매우 간단합니다. 감사합니다
Devdatta Tengshe

22

내 접근 방식은 Garret Wilson과 매우 가깝습니다 (감사합니다.

또한 Android <3과의 하위 호환성을 제공합니다.

나는 방금 내 솔루션이 Kevin Remo 의 솔루션에 더 가깝다는 것을 알았습니다 . "expection"antipattern 에 의존하지 않기 때문에 단순한 비트 클리너 입니다.

public class MyPreferenceActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            onCreatePreferenceActivity();
        } else {
            onCreatePreferenceFragment();
        }
    }

    /**
     * Wraps legacy {@link #onCreate(Bundle)} code for Android < 3 (i.e. API lvl
     * < 11).
     */
    @SuppressWarnings("deprecation")
    private void onCreatePreferenceActivity() {
        addPreferencesFromResource(R.xml.preferences);
    }

    /**
     * Wraps {@link #onCreate(Bundle)} code for Android >= 3 (i.e. API lvl >=
     * 11).
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void onCreatePreferenceFragment() {
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new MyPreferenceFragment ())
                .commit();
    }
}

"실제"(보다 복잡한) 예제는 NusicPreferencesActivityNusicPreferencesFragment 를 참조하십시오 .


@SuppressLint("NewApi")-더 정확하게 피하십시오. 당신은 낮은 API를 위해 그것을 실행 했습니까? 던질 것입니다VerifyError
Mr_and_Mrs_D 19:43에

API 레벨 10을 실행하는 에뮬레이터에서 위를 테스트합니다. APK는 SDK 버전 19를 사용하여 빌드되었습니다. 빌드에 어떤 SDK 버전을 사용 했습니까? 어떤 기기 API 수준에서 실행 했습니까? 에뮬레이터 또는 실제 장치에서 실행 했습니까? 언제 정확히 오류가 발생 했습니까? SDK <= 16으로 Ur을 빌드하는 경우이 응답을 참조하십시오 .
schnatterer 2016 년

당신은 요점을 놓치고 있습니다-당신이 나에게 통보되기를 원한다면 @Mr_and_Mrs_D를 추가하십시오. 다음은 여기를 읽어 VE stackoverflow.com/questions/20271593/...을 . 이것은 @SuppressLint("NewApi")나쁜 스타일입니다
Mr_and_Mrs_D

@M 그렇다면 @SuppressLint("NewApi")이 특정한 상황에서 피하는 방법에 대한 제안은 어떻 습니까?
schnatterer

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
-api에

6

예외 대신 다음을 사용하십시오.

if (Build.VERSION.SDK_INT >= 11)

사용

@SuppressLint("NewApi")

경고를 표시하지 않습니다.


1
그것은 충돌 이외의 다른 일이 없기 때문에 : D
Ishtiaq

1
그것이 충돌하는 경우 ... 다음 시도하고 잡아 : D
gumuruh

0

a PreferenceActivity를 사용하여 환경 설정을 직접로드 하는 대신 환경 설정 AppCompatActivity을로드하는 a PreferenceFragmentCompat를로드 하는 동등한 기능을 사용 하십시오. 지원 라이브러리 (현재 Android Jetpack)의 일부이며 API 14와의 호환성을 다시 제공합니다.

build.gradle에서 환경 설정 지원 라이브러리에 대한 종속성을 추가 하십시오 .

dependencies {
    // ...
    implementation "androidx.preference:preference:1.0.0-alpha1"
}

참고 : 기본 설정 XML이 이미 생성되었다고 가정합니다.

활동의 경우 새 활동 클래스를 작성하십시오. 머티리얼 테마를 사용하는 경우을 확장해야 AppCompatActivity하지만 다음과 같이 유연하게 사용할 수 있습니다.

public class MyPreferencesActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_preferences_activity)
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, MyPreferencesFragment())
                    .commitNow()
        }
    }
}

이제 중요한 부분 : XML에서 환경 설정을로드하는 단편을 작성하십시오.

public class MyPreferencesFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.my_preferences_fragment); // Your preferences fragment
    }
}

자세한 내용은에 대한 Android 개발자 문서 를 참조하십시오 PreferenceFragmentCompat.

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