एक प्राथमिकता में "addPreferencesFromResource" के बजाय क्या उपयोग करें?


360

मैंने सिर्फ इस तथ्य पर ध्यान दिया है कि विधि addPreferencesFromResource(int preferencesResId)को Android के प्रलेखन ( संदर्भ प्रविष्टि ) में पदावनत किया गया है ।

दुर्भाग्य से, विधि के विवरण में कोई वैकल्पिक विधि प्रदान नहीं की गई है।

प्राथमिकता प्राथमिकतास्क्रीन कनेक्ट करने के लिए किस विधि का उपयोग किया जाना चाहिए?


2
एक बहुत ही सीधा दृष्टिकोण WannaGetHigh द्वारा stackoverflow.com/questions/23523806/…
सबिन

वहां का समाधान अभी भी उपयोग करता है addPreferencesFromResource(int preferencesResId)। क्या मैं कुछ भूल रहा हूँ ?
जम्‍मू

@ जैमो हां, लेकिन इसे करने के नए तरीके को प्रतिबिंबित करने के लिए गतिविधि से फ्रैगमेंट में ले जाया गया है -> टुकड़ा।
14

जवाबों:


332

कोई वैकल्पिक पद्धति क्योंकि वरीय दृष्टिकोण का दृष्टांत है (एपीआई स्तर 11) के रूप में विधि के विवरण में प्रदान की जाती है PreferenceFragment संसाधन फ़ाइल से अपनी प्राथमिकताएँ लोड करने के लिए वस्तुओं। यहां नमूना कोड देखें: वरीयता


उत्तर देने के लिए आपका धन्यवाद। मैं सिर्फ "Video2Brain-Android विकास" से पदावनत निर्देशों का पालन कर रहा था, जिसने मुझे विधि के वरीयता-सक्रियता संस्करण का उपयोग करने के लिए प्रेरित किया। Btw: अगर मैं केवल कर सकता तो मैं आपके उत्तर को उपयोगी बनाना पसंद करूंगा।
मुविज़

33
अब केवल अगर प्राथमिकता पैकेज में प्राथमिकता शामिल की गई थी, तो इसका उपयोग करने के लिए इसका मतलब समझ में
आएगा।

1
चूंकि मैं एक्शन बार शेरलॉक का उपयोग करता हूं, इसलिए मैंने इस समस्या को हल करने के लिए निम्न ब्लॉग का अनुसरण किया, देखें ... commonsware.com/blog/2012/10/16/…
कोई व्यक्ति

2
अगर आप चाहते हैं कि एप 11 स्तर (एंड्रॉइड 3.0) की तुलना में एपि स्तर के साथ पीछे की ओर संगत हो, तब भी आपको addPreferencesFromResource (int PreferencesID) को कॉल करने की आवश्यकता है। लेकिन मुझे लगता है कि आप उन पुराने उपकरणों पर भी विचार कर सकते हैं।
ईयोन सुंदरन

5
@EinarSundgren मैं Nexus एक मालिक हूं और मेरा अधिकतम उपलब्ध संस्करण 2.2 है: आप मुझे नहीं रोकेंगे! मैं कभी नहीं हटा दिया जाएगा! ग्रेस्कुल की शक्ति से ... मेरे पास शक्ति है!
टेकनिक्विस्ट

186

ऊपर दिए गए सही उत्तर में अधिक जानकारी जोड़ने के लिए, एंड्रॉइड-एर के एक उदाहरण को पढ़ने के बाद मैंने पाया कि आप आसानी से अपनी वरीयता गतिविधि को वरीयता खंड में बदल सकते हैं। यदि आपके पास निम्नलिखित गतिविधि है:

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
अच्छा लगा, इसके लिए धन्यवाद। जावा और इस प्रकार की सोच को अब तक मेरी अच्छी छोटी .net दुनिया से दूर कर दिया गया है :)
टॉम

44
क्यों वे addPreferencesFromResources()वरीयता के लिए व्यापार में मूल्यह्रास करेंगे ? यह शुरुआती दृष्टिकोण से अनावश्यक लगता है।
Howdy_McGee

4
कॉल के लिए API स्तर 11
mehmet

1
तो क्या होगा अगर एपीआई स्तर 9 पर है? @mehmet
gumuruh

2
बहुत बढ़िया जवाब! क्या android.R.id.content को बदले बिना इसे प्राप्त करने का कोई तरीका है? किसी कारण से मेरे लिए
अपात्र

37

@ ग्रेट विल्सन बहुत बहुत धन्यवाद! एंड्रॉइड कोडिंग के लिए एक noob के रूप में, मैं कई घंटों के लिए वरीयताओं की असंगति के मुद्दे के साथ फंस गया हूं, और मुझे यह बहुत निराशाजनक लगता है कि उन्होंने नए तरीकों के लिए कुछ तरीकों / दृष्टिकोणों का उपयोग किया है जो पुराने एपीआई द्वारा समर्थित नहीं हैं। उपकरणों की एक विस्तृत श्रृंखला में अपने एप्लिकेशन को काम करने के लिए सभी प्रकार के वर्कआरा का सहारा लेना पड़ता है। यह वास्तव में निराशाजनक है!

आपकी कक्षा बहुत अच्छी है, इसके लिए आप नए APIs में काम करते रहने की अनुमति देते हैं। जब से मैं उपकरणों की एक विस्तृत श्रृंखला तक पहुँचने की कोशिश कर रहा हूँ मैंने इसे थोड़ा सा पूर्व एपीआई 11 उपकरणों के साथ-साथ नए एपीआई में काम करने के लिए इसके साथ थोड़ा छेड़छाड़ की:

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) में परीक्षण किया गया।

मेरा कोड इतना भद्दा क्यों दिखता है:

मैं एंड्रॉइड कोडिंग के लिए एक noob हूं, और मैं सबसे बड़ा जावा प्रशंसक नहीं हूं।

पदावनत चेतावनी से बचने और ग्रहण करने के लिए मजबूर करने के लिए मुझे एनोटेशन का सहारा लेना पड़ा, लेकिन ये केवल कक्षाओं या विधियों को प्रभावित करते हैं, इसलिए मुझे इसका लाभ उठाने के लिए कोड को दो नए तरीकों पर स्थानांतरित करना पड़ा।

मैं अपनी xml संसाधन आईडी को दो बार लिखना पसंद नहीं करूंगा, जब भी मैं एक नई वरीयता के लिए कक्षा की प्रतिलिपि बनाता हूं और पेस्ट करता हूं, इसलिए मैंने इस मूल्य को संग्रहीत करने के लिए एक नया चर बनाया।

मुझे उम्मीद है कि यह किसी और के लिए उपयोगी होगा।

पुनश्च: मेरी राय के लिए खेद है, लेकिन जब आप नए आते हैं और इस तरह के बाधाएं पाते हैं, तो आप इसे निराश होने में मदद नहीं कर सकते हैं!


ओह ठीक है ... मैंने अभी देखा कि मुझे बाहरी क्लास का नाम दो बार बदलना होगा जब भी मैं इसे कॉपी और पेस्ट करूँगा। वास्तव में इससे बचने का एक तरीका है, इनरक्लास में प्रीफ़्स पास करके। आप एक आंतरिक श्रेणी के निर्माता को एक पैरामीटर के रूप में प्रिफ़र स्वीकार करते हुए नहीं बना सकते हैं क्योंकि यह स्पष्ट रूप से वरीयता प्राप्त व्युत्पन्न वर्गों के लिए अनुशंसित नहीं है। इसके अलावा, आप Prefs पाने के लिए इनर क्लास में कोई विधि नहीं बना सकते हैं और addPreferencesFromResource को तुरंत कॉल कर सकते हैं, क्योंकि addPreferencesFromResource को super.onCreate के कॉल करने के बाद कॉल करने की आवश्यकता होती है, और वरीयता प्राप्त व्युत्पन्न वर्ग के होने के बाद onCreate को सही नहीं कहा जाता है ...
इको

... तत्काल किया गया। इसलिए आपको इनर क्लास में एक नया वैरिएबल बनाने की जरूरत है, इनर क्लास में इसके लिए एक पब्लिक सेट मेथड बनाएं, ऐडपायरिफायरफ्रॉम को छोड़ दें। जहां यह सुपर.ऑनक्रीट को कॉल करने के बाद है, ऑनक्रिएट के अंदर, इनर क्लास को इंट्रस्ट करें, इनर क्लास को सेट करें। , और पहले की तरह GetFragmentManager () ... के लिए कॉल में इसका उपयोग करें।
इकोव

2
आपका कोड एक लाइफसेवर रहा है !! मैं दोनों पुराने और नए फोन को लक्षित करने की कोशिश कर रहा था, और 3 दिन बर्बाद कर दिया..और जवाब इतना आसान है। धन्यवाद
देवदत्त तेंग्शे

22

मेरा दृष्टिकोण गैरेट विल्सन के बहुत करीब है (धन्यवाद, मैंने आपको वोट दिया;)

इसके अलावा यह एंड्रॉइड <3 के साथ डाउनवर्ड संगतता प्रदान करता है।

मैंने अभी पहचाना कि मेरा समाधान केविन रेमो द्वारा एक के करीब है । यह सिर्फ एक मूत सा क्लीनर है (क्योंकि यह "एक्सपेंशन" एंटीपैटर्न पर निर्भर नहीं करता है )।

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();
    }
}

एक "वास्तविक" (लेकिन अधिक जटिल) उदाहरण के लिए NusicPreferencesActivity और NusicPreferencesFragment देखें


@SuppressLint("NewApi")- बचना - अधिक सटीक होना। क्या आपने इसे कम एपिस के लिए चलाया है? यह फेंक देंगेVerifyError
Mr_and_Mrs_D

मैं एपीआई स्तर 10 पर चलने वाले एमुलेटर पर उपरोक्त परीक्षण करता हूं, एपीके को एसडीके संस्करण 19 का उपयोग करके बनाया गया था। आपने भवन के लिए एसडीके संस्करण का क्या उपयोग किया है? आपने किस उपकरण API स्तर पर इसे चलाया? क्या आपने इसे एमुलेटर पर या किसी भौतिक उपकरण पर चलाया? वास्तव में त्रुटि कब हुई? यदि एसडी एसडीके <= 16 के साथ उर बिल्डिंग, यह प्रतिक्रिया देखें ।
श्नाटरर

आप बिंदु याद कर रहे हैं - और @Mr_and_Mrs_D जोड़ें यदि आप चाहते हैं कि मुझे सूचित किया जाए। वीईए के लिए यहां पढ़ें: stackoverflow.com/questions/20271593/…@SuppressLint("NewApi")सिर्फ बुरा शैली है
Mr_and_Mrs_D

@ अच्छी तरह से, तो @SuppressLint("NewApi")इस विशेष स्थिति में कैसे बचें पर एक प्रस्ताव के बारे में?
श्नाटर

@TargetApi(Build.VERSION_CODES.HONEYCOMB)- किसी भी एपीआई के लिए सभी चेतावनियाँ नहीं :)
Mr_and_Mrs_D

6

अपवादों के बजाय, बस उपयोग करें:

if (Build.VERSION.SDK_INT >= 11)

और उपयोग करें

@SuppressLint("NewApi")

चेतावनियों को दबाने के लिए।


1
क्योंकि यह दुर्घटना के अलावा और कुछ नहीं करता है: D
इश्तियाक

1
अगर यह दुर्घटनाग्रस्त है ... तो कोशिश करें और इसे
पकड़ें

0

PreferenceActivityसीधे-सीधे लोड वरीयताओं का उपयोग करने के बजाय , एक AppCompatActivityया समकक्ष का उपयोग करें जो PreferenceFragmentCompatआपकी वरीयताओं को लोड करता है। यह सपोर्ट लाइब्रेरी (अब एंड्रॉइड जेटपैक) का हिस्सा है और एपीआई 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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.