समर्थन लाइब्रेरी v21 में अपग्रेड के बाद वरीयता में कोई ActionBar नहीं


83

मैं समर्थन लाइब्रेरी v21 में अपग्रेड करने के बाद मेरा ActionBar अपने PreferenceActivityमें चला गया है।

क्या मैंने इसे फिर से सक्रिय करने के लिए अपने विषय में कुछ विशेषताओं को याद किया? मैं एक काले ActionBar के साथ कुछ इसी तरह की परेशानी थी ।

मैंने Toolbarरूट लेआउट में इसे जोड़कर इसे थोड़ा हैकिश करने की कोशिश की , लेकिन यह उम्मीद के मुताबिक काम नहीं कर पाया।


आपको प्राथमिकता फ़्रैगमेंट का उपयोग करना चाहिए: developer.android.com/reference/android/preference/…
Jared Burrows

1
@JaredBurrows आप कैंटफ़्रैगमेंट प्री 3.0 का उपयोग नहीं कर सकते हैं
tyczj

1
मैं उनका भी उपयोग कर रहा हूं। AFIK मुझे एक वरीयताऐक्टिविटी से लिंक करने की आवश्यकता है जो कि प्राथमिकता का उपयोग करता है। हालांकि जैसा कि tyyyj बताते हैं कि मुझे विरासत समर्थन के लिए भी उनकी आवश्यकता है।
rekire

1
टूलबार केवल एक दृश्य है। आप इसे कहीं भी जोड़ सकते हैं।
जेरेड बुरो

1
आप मेरे द्वारा बनाए गए उदाहरण को देख सकते हैं: github.com/AndroidDeveloperLB/MaterialPreferenceLibrary
Android डेवलपर

जवाबों:


170

कृपया GitHub रेपो: यहां देखें


बहुत ही अपने कोड के समान है लेकिन सेट शीर्षक के लिए अनुमति देने के लिए xml जोड़ा गया है:

उपयोग करने के लिए जारी PreferenceActivity:

settings_toolbar.xml :

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    app:navigationContentDescription="@string/abc_action_bar_up_description"
    android:background="?attr/colorPrimary"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:title="@string/action_settings"
    />

SettingsActivity.java :

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
        Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
        root.addView(bar, 0); // insert at top
        bar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

}

Result :

उदाहरण


अद्यतन (जिंजरब्रेड संगतता):

जैसा कि यहां बताया गया है , जिंजरब्रेड डिवाइस इस लाइन पर NullPointerException वापस कर रहे हैं:

LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();

ठीक कर:

SettingsActivity.java :

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        Toolbar bar;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent();
            bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
            root.addView(bar, 0); // insert at top
        } else {
            ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
            ListView content = (ListView) root.getChildAt(0);

            root.removeAllViews();

            bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
            

            int height;
            TypedValue tv = new TypedValue();
            if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
                height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
            }else{
                height = bar.getHeight();
            }

            content.setPadding(0, height, 0, 0);

            root.addView(content);
            root.addView(bar);
        }

        bar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

ऊपर के साथ किसी भी मुद्दे मुझे पता है!


अद्यतन 2: टंकण कार्य

जैसा कि कई देव नोटों में बताया गया है कि PreferenceActivityतत्वों की टिनिंग का समर्थन नहीं करता है, हालांकि कुछ आंतरिक वर्गों का उपयोग करके आप इसे प्राप्त कर सकते हैं। यह तब तक है जब तक इन वर्गों को हटा नहीं दिया जाता। (AppCompat support-v7 v21.0.3 का उपयोग कर काम करता है)।

निम्नलिखित आयात जोड़ें:

import android.support.v7.internal.widget.TintCheckBox;
import android.support.v7.internal.widget.TintCheckedTextView;
import android.support.v7.internal.widget.TintEditText;
import android.support.v7.internal.widget.TintRadioButton;
import android.support.v7.internal.widget.TintSpinner;

फिर onCreateViewविधि को ओवरराइड करें :

@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
    // Allow super to try and create a view first
    final View result = super.onCreateView(name, context, attrs);
    if (result != null) {
        return result;
    }

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        // If we're running pre-L, we need to 'inject' our tint aware Views in place of the
        // standard framework versions
        switch (name) {
            case "EditText":
                return new TintEditText(this, attrs);
            case "Spinner":
                return new TintSpinner(this, attrs);
            case "CheckBox":
                return new TintCheckBox(this, attrs);
            case "RadioButton":
                return new TintRadioButton(this, attrs);
            case "CheckedTextView":
                return new TintCheckedTextView(this, attrs);
        }
    }

    return null;
}

Result:

उदाहरण 2


AppCompat 22.1

AppCompat 22.1 ने नए टिंटेड तत्वों को पेश किया, जिसका अर्थ है कि अंतिम अद्यतन के समान प्रभाव प्राप्त करने के लिए आंतरिक कक्षाओं का उपयोग करने की आवश्यकता नहीं है। इसके बजाय इसका अनुसरण करें (अभी भी ओवरराइड कर रहे हैं onCreateView):

@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
    // Allow super to try and create a view first
    final View result = super.onCreateView(name, context, attrs);
    if (result != null) {
        return result;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        // If we're running pre-L, we need to 'inject' our tint aware Views in place of the
        // standard framework versions
        switch (name) {
            case "EditText":
                return new AppCompatEditText(this, attrs);
            case "Spinner":
                return new AppCompatSpinner(this, attrs);
            case "CheckBox":
                return new AppCompatCheckBox(this, attrs);
            case "RadioButton":
                return new AppCompatRadioButton(this, attrs);
            case "CheckedTextView":
                return new AppCompatCheckedTextView(this, attrs);
        }
    }

    return null;
}

NESTED PREFERENCE SCREENS

बहुत से लोग नेस्टेड <PreferenceScreen />एस में टूलबार सहित मुद्दों का सामना कर रहे हैं , हालांकि, मुझे एक समाधान मिल गया है !! - बहुत परीक्षण और त्रुटि के बाद!

निम्नलिखित को अपने में जोड़ें SettingsActivity:

@SuppressWarnings("deprecation")
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    super.onPreferenceTreeClick(preferenceScreen, preference);

    // If the user has clicked on a preference screen, set up the screen
    if (preference instanceof PreferenceScreen) {
        setUpNestedScreen((PreferenceScreen) preference);
    }

    return false;
}

public void setUpNestedScreen(PreferenceScreen preferenceScreen) {
    final Dialog dialog = preferenceScreen.getDialog();

    Toolbar bar;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        LinearLayout root = (LinearLayout) dialog.findViewById(android.R.id.list).getParent();
        bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
        root.addView(bar, 0); // insert at top
    } else {
        ViewGroup root = (ViewGroup) dialog.findViewById(android.R.id.content);
        ListView content = (ListView) root.getChildAt(0);

        root.removeAllViews();

        bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);

        int height;
        TypedValue tv = new TypedValue();
        if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
            height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
        }else{
            height = bar.getHeight();
        }

        content.setPadding(0, height, 0, 0);

        root.addView(content);
        root.addView(bar);
    }

    bar.setTitle(preferenceScreen.getTitle());

    bar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dialog.dismiss();
        }
    });
}

कारण यह है कि PreferenceScreenइस तरह के एक दर्द है क्योंकि वे एक आवरण संवाद के रूप में आधारित हैं, इसलिए हमें टूलबार को इसमें जोड़ने के लिए संवाद लेआउट पर कब्जा करने की आवश्यकता है।


टूलबार छाया

डिज़ाइन आयात करके Toolbarपूर्व-v21 उपकरणों में ऊँचाई और छाया देने की अनुमति नहीं देता है, इसलिए यदि आप इसे अपने ऊपर उठाना चाहते हैं, तो आपको Toolbarइसे इसमें लपेटना होगा AppBarLayout:

`settings_toolbar.xml:

<android.support.design.widget.AppBarLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

   <android.support.v7.widget.Toolbar
       .../>

</android.support.design.widget.AppBarLayout>

build.gradleफ़ाइल में निर्भरता के रूप में डिज़ाइन समर्थन लाइब्रेरी जोड़ना न भूलें :

compile 'com.android.support:support-v4:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:design:22.2.0'

Android 6.0

मैंने रिपोर्ट की गई ओवरलैपिंग समस्या की जांच की है और मैं इस मुद्दे को पुन: पेश नहीं कर सकता।

उपरोक्त के रूप में उपयोग में पूर्ण कोड निम्नलिखित उत्पन्न करता है:

यहाँ छवि विवरण दर्ज करें

अगर मुझे कुछ याद आ रहा है तो कृपया मुझे इस रेपो के माध्यम से बताएं और मैं जांच करूंगा।


अच्छा एक: मैंने पहले दृष्टिकोण का उपयोग किया है (जिंजरब्रेड मेरे लक्ष्य पर नहीं है)। धन्यवाद!
JJ86

ऐसा प्रतीत होता है कि इस उदाहरण का उपयोग करके जिंजरब्रेड पर अप बटन टूट गया है।
idunnololz

1
आपके महान जवाब के लिए धन्यवाद, मैंने आपको कुछ दिन पहले स्वीकृत राज्य दिया था। मैंने सिर्फ
टिनिंग

1
मुझे खुद को सही करना होगा। android:themeवैकल्पिक हल केवल Android 5.0+ के लिए उपकरण पट्टी पर काले पाठ रंग ठीक करता है। यह नए समर्थन पुस्तकालय के साथ कुछ बदला हुआ प्रतीत होता है (मैं 22.2.0 का उपयोग कर रहा हूं)।
tony

4
android.R.id.list का जनक, Android N में
फ्रेम -आउट है

45

समस्या को हल करने के लिए AppCompatActivity और वरीयता का उपयोग करें:

AppCompatActivity:

public class SettingsActivity extends AppCompatActivity {

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
}}

PreferenceFragment:

public class SettingsFragment extends PreferenceFragment {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.settings_preferences);
}}

1
ActionBarActivity को हटा दिया गया है।
18

@ ट्रेक अपने android.support.v7.app.ActionBarActivity
अब्दुल्ला

4
केवल ActionBarActivity के बजाय AppCompatActivity का विस्तार करें।
सैमीटी

1
मेरे लिए काम किया है, और ऊपर से बहुत सरल है।
आरोन ब्लेनकुश

1
सरल वरीयता स्क्रीन के लिए, यह अब तक लागू करने का सबसे आसान समाधान है।
क्रिस क्रेफ़िस

7

मैंने इस सरल कोड के साथ स्वयं टूलबार को जोड़ने का कार्य समाप्त किया:

// get the root container of the preferences list
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
Toolbar bar = (Toolbar)LayoutInflater.from(this).inflate(R.layout.preferences_toolbar, root, false);
root.addView(bar, 0); // insert at top
bar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        finish();
    }
});

यहां मेरी प्राथमिकताएं हैं_toolbar.xml:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    app:navigationContentDescription="@string/abc_action_bar_up_description"
    android:background="?attr/colorPrimary"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:theme="@style/Theme.Toolbar" />

मुझे लगता है कि मैं इसे
onCreate

6

"अपने स्वयं के" एक्शन बार को रोल करने से बेहतर उपाय है AppCompatDelegate वर्ग का उपयोग करना , जो आपको समर्थन लाइब्रेरी से वास्तविक-वास्तविक एक्शन बार में लाने देता है। इस सवाल का जवाब exampleubomír Kučera से लिया गया है, इसका उपयोग करने के लिए उदाहरण कोड है ।

...
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
...

public class SettingsActivity extends PreferenceActivity {

    private AppCompatDelegate mDelegate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getDelegate().installViewFactory();
        getDelegate().onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        getDelegate().onPostCreate(savedInstanceState);
    }

    public ActionBar getSupportActionBar() {
        return getDelegate().getSupportActionBar();
    }

    public void setSupportActionBar(@Nullable Toolbar toolbar) {
        getDelegate().setSupportActionBar(toolbar);
    }

    @Override
    public MenuInflater getMenuInflater() {
        return getDelegate().getMenuInflater();
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        getDelegate().setContentView(layoutResID);
    }

    @Override
    public void setContentView(View view) {
        getDelegate().setContentView(view);
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        getDelegate().setContentView(view, params);
    }

    @Override
    public void addContentView(View view, ViewGroup.LayoutParams params) {
        getDelegate().addContentView(view, params);
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        getDelegate().onPostResume();
    }

    @Override
    protected void onTitleChanged(CharSequence title, int color) {
        super.onTitleChanged(title, color);
        getDelegate().setTitle(title);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getDelegate().onConfigurationChanged(newConfig);
    }

    @Override
    protected void onStop() {
        super.onStop();
        getDelegate().onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getDelegate().onDestroy();
    }

    public void invalidateOptionsMenu() {
        getDelegate().invalidateOptionsMenu();
    }

    private AppCompatDelegate getDelegate() {
        if (mDelegate == null) {
            mDelegate = AppCompatDelegate.create(this, null);
        }
        return mDelegate;
    }
}

4
आधिकारिक v7 नमूने से उर्फ AppCompatPreferenceActivity
अविनाश आर।

4

नमस्ते मैं नहीं हूँ अगर आप अभी भी यह मुद्दा है। लेकिन मुझे लगता है कि मैंने इसे हल करने के लिए क्या किया है और मुझे उम्मीद है कि यह किसी की मदद करेगा।

1) सबसे पहले, आपने देखा होगा कि प्राथमिकता सक्रियता सूचीबध्दता का विस्तार करती है, जो गतिविधि से फैली हुई है।

डेवलपर्स ब्लॉग पर टिप्पणियों के अनुसार ( http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html ) , v21 का उपयोग करने के लिए आपकी सभी गतिविधियों को ActionararActivity से विरासत में प्राप्त करना चाहिए। । तो आपका मुद्दा है।

2) मेरे द्वारा हल करने के लिए उपयोग किए जाने वाले चरण हैं:

a) Make sure that you set the Theme of your PreferenceActivity to inherits one ot the Theme.AppCompat Themes.

b) Make your class PreferenceActivity extends ActionBarActivity.

c) Use the PreferenceFragment as your container for all your preferences.

इसका हल निकालना चाहिए।

चीयर्स!


4
"अपनी कक्षा को बनाएं सक्रियता एक्शनबेरक्टिविटी बढ़ाती है" - लेकिन कैसे?
vbence

इस लिंक को यहाँ देखें: code.hootsuite.com/…
AfrikAndroid 18

1
धन्यवाद, मुझे लगता है कि यह संभव के रूप में करीब आता है। असली दर्द यह है कि वरीयता- सक्रियता में लोडहेडर्स के माध्यम से नेविगेशन का निर्माण किया गया है। स्रोत , उन टुकड़ों के साथ, जिन्हें आपको स्वयं नेविगेशन का निर्माण करना है।
vbence

0

मैंने स्वीकार किए गए प्रश्न के समान कुछ किया, लेकिन मैं अपने लेआउट का उपयोग अन्य गतिविधियों ( MainActivityभी) में कर रहा हूं, इसलिए मैं इसमें केवल एक तीर को हार्ड-कोड नहीं कर सकता।

मेरे लिए क्या काम किया:

private void setupActionBar() {
    LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
    Toolbar toolbar = (Toolbar)LayoutInflater.from(this).inflate(R.layout.app_bar, root, false);
    root.addView(toolbar, 0);
    setSupportActionBar(toolbar);
    ActionBar ab = getSupportActionBar();
    ab.setDisplayHomeAsUpEnabled(true);
}

0

मेरी भी यही समस्या थी। केवल उस गतिविधि का थीम बदलने का प्रयास करें जिसमें कोई ActionBar है। सेटिंग की गतिविधि टैग में निम्नलिखित पंक्ति जोड़ना मेरे लिए काम करता है:

android:theme="Theme.AppCompat.DayNight.DarkActionBar"


-1

एक आसान तरीका जो मुझे लगा कि वह ओवरराइडिंग है:

@android:style/Theme.Material.Light.DarkActionBar

अपनी शैली में:

<style name="SettingsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
    <item name="android:colorPrimary">@color/sunshine_blue</item>
    <item name="android:colorPrimaryDark">@color/sunshine_dark_blue</item>
</style>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.