IT박스

PreferenceFragment가 호환성 패키지에서 의도적으로 제외 되었습니까?

itboxs 2020. 6. 8. 21:17
반응형

PreferenceFragment가 호환성 패키지에서 의도적으로 제외 되었습니까?


3.0 및 3.0 이전 장치 모두에 적용 할 수있는 환경 설정을 작성하려고합니다. PreferenceActivity더 이상 사용되지 않는 메소드 포함되어 있음을 발견 한 경우 (동봉 된 샘플 코드에서 사용되지만) PreferenceFragement문제를 해결하기 위해 호환성 패키지를 살펴 보았습니다 .

그러나 PreferenceFragment호환성 패키지에없는 것으로 보입니다 . 누구든지 이것이 의도적인지 말해 줄 수 있습니까? 그렇다면 다양한 기기를 쉽게 타겟팅 할 수 있습니까 (예 : <3.0 및> = 3.0) 후프를 뛰어 넘어야합니까? 의도적으로 제외되지 않은 경우 호환성 패키지의 새로운 릴리스를 기대할 수 있습니까? 또는 사용하기에 안전한 다른 해결 방법이 있습니까?

건배

제임스


PreferenceActivity에 더 이상 사용되지 않는 메소드가 포함되어 있음을 발견 (이는 첨부 된 샘플 코드에서 사용됨)

더 이상 사용되지 않는 메소드는 Android 3.0부터 더 이상 사용되지 않습니다. 모든 Android 버전에서 완벽하게 작동하지만 PreferenceFragmentAndroid 3.0 이상 에서 사용 하는 것이 좋습니다 .

누구든지 이것이 의도적인지 말해 줄 수 있습니까?

내 생각 엔 엔지니어링 시간의 문제이지만 그것은 추측 일뿐입니다.

그렇다면 다양한 기기를 쉽게 타겟팅 할 수 있습니까 (예 : <3.0 및> = 3.0) 후프를 뛰어 넘어야합니까?

나는 그것이 "쉽게"행해진다고 생각한다. PreferenceActivity하나는 기본 설정 헤더를 PreferenceFragments사용하고 다른 하나는 원래 접근 방식을 사용하는 두 가지 별도의 구현이 있습니다. 필요한 시점 (예 : 사용자가 옵션 메뉴 항목을 클릭 할 때)에서 올바른 것을 선택하십시오. 이것을 보여주는 샘플 프로젝트가 있습니다. 또는 이 샘플 프로젝트PreferenceActivity 에서와 같이 두 경우를 모두 처리 하는 싱글 보유하십시오 .

의도적으로 제외되지 않은 경우 호환성 패키지의 새로운 릴리스를 기대할 수 있습니까?

당신은 우리의 나머지 사람들이 언제, 언제 배송하는지 알아낼 것입니다.

또는 사용하기에 안전한 다른 해결 방법이 있습니까?

위 참조.


@CommonsWare의 대답의 미묘한 의미는 앱이 호환성 API 또는 내장 조각 API (SDK 11 이후부터) 중에서 선택해야한다는 것입니다. 실제로 "쉽게"권장 사항이 수행 한 것입니다. 즉, PreferenceFragment를 사용하려면 앱에서 기본 제공 조각 API를 사용하고 PreferenceActivity에서 더 이상 사용되지 않는 메서드를 처리해야합니다. 반대로, 앱이 compat을 사용하는 것이 중요하다면. API PreferenceFragment 클래스가 전혀 없을 때 직면하게 될 API입니다. 따라서 장치 타겟팅은 문제가되지 않지만 하나 또는 다른 API를 선택하여 예기치 않은 해결 방법으로 디자인을 제출해야 할 때 후프 점핑이 발생합니다. 나는 동료가 필요하다. API를 사용하여 PreferenceFragment 클래스를 직접 만들고 작동 방식을 살펴 보겠습니다. 최악의 시나리오에서 나는

편집 : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/preference/PreferenceFragment.java 에서 코드를보고 시도한 후 ? av = h- 내 자신의 PreferenceFragment를 만들 수 없습니다. 기본 설정은 'protected'대신 PreferenceManager에서 package-private를 자유롭게 사용하는 것 같습니다. 실제로 보안이나 동기 부여가없는 것처럼 보이지 않으며 단위 테스트에는 좋지 않지만 오 입력은 적습니다.

편집 v2 : 실제로 발생했고 작동했습니다. 호환성 API JAR로 코드를 작동시키는 것은 분명히 골치 아픈 일이었습니다. com.android.preference 패키지를 SDK에서 내 앱으로 약 70 % 복사 한 다음 일반적으로 Android에서 평범한 품질의 Java 코드로 씨름했습니다. SDK v14를 사용했습니다. 일부 Android 엔지니어가이 주제에 대해 말한 것과는 달리 Goog 엔지니어는 내가 한 일을 훨씬 쉽게 수행 할 수있었습니다.

BTW- "타겟팅 장치가 문제가되지 않는다"고 말했습니까? com.android.preference를 사용하면 주요 리팩토링없이 호환성 API로 교체 할 수 없습니다. 재미있는 로그!


CommonsWare의 답변과 Tenacious의 관찰을 바탕으로 최소한의 번거 로움없이 코드 또는 리소스 중복없이 모든 현재 Android API 버전을 대상으로 할 수있는 단일 하위 클래스 솔루션을 고안했습니다. PreferenceActivity Android 4.0 및 이전 버전 의 관련 질문에 대한 답변을 참조하십시오

또는 내 블로그 : http://www.blackmoonit.com/2012/07/all_api_prefsactivity/

4.0.3 및 4.0.4를 실행하는 두 태블릿과 4.0.4 및 2.3.3을 실행하는 전화기와 1.6을 실행하는 에뮬레이터에서 테스트되었습니다.


Machinarius의 Preferencement-Compat참조하십시오 . gradle을 사용하여 쉽게 넣을 수 있었고 심지어 거기에 있다는 것을 잊었습니다.

compile 'com.github.machinarius:preferencefragment:0.1.1'

중요 업데이트 : 최신 버전v7 support library지금은 기본이 PreferenceFragmentCompat을 .


2015 년 8 월 Google은 새로운 환경 설정 지원 라이브러리 v7을 출시했습니다 .

이제 사용할 수 있습니다 PreferenceFragmentCompat을 하나와 ActivityAppCompatActivity

public static class PrefsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
}

preferenceTheme테마 를 설정 해야합니다.

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  ...
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

이러한 방식으로 preferenceTheme활동의 다른 부분에 영향을주지 않고 각 환경 설정 유형에 사용되는 레이아웃 스타일을 사용자 정의 할 수 있습니다 .


Tenacious의 답변은 정확하지만 자세한 내용은 다음과 같습니다.

The reason you can't "create a normal layout and bind the view components to the sharedprefs manually" is that there are some surprising omissions in the android.preferences API. PreferenceActivity and PreferenceFragment both have access to critical non-public PreferenceManager methods, without which you can't implement a preference UI of your own.

In particular, to construct a Preference hierarchy from an XML file you need to use a PreferenceManager, but all of PreferenceManager's constructors are either package-private or hidden. The method of attaching the Preference onClick listeners to your activity is also package-private.

And you can't work around this by sneakily putting your implementation in the android.preferences package, because non-public methods in Android APIs are actually omitted from the SDK. With a bit of creativity involving reflection and dynamic proxies, you can still get at them. The only alternative, as Tenacious says, is to fork the entire android.preference package, including at least 15 classes, 5 layouts, and a similar number of style.xml and attrs.xml elements.

So to answer the original question, the reason Google didn't include PreferenceFragment in the compatibility package is that they would have had exactly the same difficulty as Tenacious and myself. Even Google can't go back in time and make those methods public in the old platforms (though I hope they do that in future releases).


My app target is API +14 but due to using support library for some fancy navigation, I couldn't use the android.app.Fragment and had to use android.support.v4.app.Fragment, but I also needed to have PreferenceFragment in place without large changes to code behind.

So my easy fix for having both worlds of support library and PreferenceFragment:

private android.support.v4.app.Fragment fragment;
private android.app.Fragment nativeFragment = null;

private void selectItem(int position) {
    fragment = null;
    boolean useNativeFragment = false;
    switch (position) {
    case 0:
        fragment = new SampleSupprtFragment1();
        break;
    case 1:
        fragment = new SampleSupprtFragment2();
        break;
    case 2:
        nativeFragment = new SettingsFragment();
        useNativeFragment = true;
        break;
    }
    if (useNativeFragment) {
        android.app.FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
            .replace(R.id.content_frame, nativeFragment).commit();
    } else {
        if (nativeFragment != null) {
            getFragmentManager().beginTransaction().remove(nativeFragment)
                .commit();
            nativeFragment = null;
        }
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
            .replace(R.id.content_frame, fragment).commit();
    }
}

I needed integrate Preferences into application's design and keep support for 2.3 android. So I still needed PreferencesFragment.

After some search I found android-support-v4-preferencefragment lib. This lib save a lot of time for copying and refactoring original PreferencesFragment as Tenacious said. Works fine and users enjoy preferences.

참고URL : https://stackoverflow.com/questions/5501431/was-preferencefragment-intentionally-excluded-from-the-compatibility-package

반응형