कस्टम अधिसूचना लेआउट और पाठ रंग


82

मेरा आवेदन कुछ सूचनाएं दिखाता है, और उपयोगकर्ता प्राथमिकताओं के आधार पर यह अधिसूचना में एक कस्टम लेआउट का उपयोग कर सकता है। यह अच्छी तरह से काम करता है, लेकिन एक छोटी समस्या है - पाठ रंग । स्टॉक एंड्रॉइड और लगभग सभी निर्माता खाल अधिसूचना पाठ के लिए एक हल्की पृष्ठभूमि के खिलाफ काले पाठ का उपयोग करते हैं, लेकिन सैमसंग ऐसा नहीं करता है: उनके अधिसूचना पुलडाउन में एक अंधेरे पृष्ठभूमि है और डिफ़ॉल्ट अधिसूचना लेआउट में पाठ सफेद है।

तो यह एक समस्या का कारण बनता है: किसी भी फैंसी लेआउट का उपयोग नहीं करने वाले नोटिफिकेशन ठीक दिखाई देते हैं, लेकिन कस्टम लेआउट का उपयोग करने वाले को पढ़ना मुश्किल है क्योंकि टेक्स्ट डिफ़ॉल्ट सफेद के बजाय काला है। यहां तक ​​कि आधिकारिक दस्तावेज़ीकरण सिर्फ एक के #000लिए एक रंग निर्धारित करता है TextView, इसलिए मुझे वहां कोई संकेत नहीं मिला।

एक उपयोगकर्ता समस्या का स्क्रीनशॉट लेने के लिए पर्याप्त था:

स्क्रीनशॉट

तो मैं अपने लेआउट में डिवाइस से डिफ़ॉल्ट अधिसूचना पाठ रंग का उपयोग कैसे करूं ? मैं इसके बजाय फ़ोन मॉडल के आधार पर टेक्स्ट कलर को गतिशील रूप से बदलना शुरू नहीं करूंगा, क्योंकि इसके लिए बहुत अपडेट करने की आवश्यकता होती है और कस्टम रोम वाले लोगों को अभी भी समस्या हो सकती है, यह उस त्वचा पर निर्भर करता है जिसका वे उपयोग कर रहे हैं।


10
छवि अब उपलब्ध नहीं है
अमीर उल

कृपया छवि को पुनः लोड करें, यदि संभव हो तो कृपया।
मैकिएज गोल

जवाबों:


63

मैल्कम द्वारा समाधान API> = 9 के साथ ठीक काम करता है। यहाँ पुराने एपीआई के लिए समाधान है:

चाल मानक अधिसूचना ऑब्जेक्ट बनाने के लिए है और फिर contentViewद्वारा बनाई गई डिफ़ॉल्ट को पीछे छोड़ती है Notification.setLatestEventInfo(...)। जब आपको सही TextView मिल जाए, तो बस प्राप्त करें tv.getTextColors().getDefaultColor()

यहां वह कोड है जो डिफ़ॉल्ट पाठ रंग और पाठ आकार (स्केल किए गए घनत्व पिक्सेल - सपा में) को निकालता है।

private Integer notification_text_color = null;
private float notification_text_size = 11;
private final String COLOR_SEARCH_RECURSE_TIP = "SOME_SAMPLE_TEXT";

private boolean recurseGroup(ViewGroup gp)
{
    final int count = gp.getChildCount();
    for (int i = 0; i < count; ++i)
    {
        if (gp.getChildAt(i) instanceof TextView)
        {
            final TextView text = (TextView) gp.getChildAt(i);
            final String szText = text.getText().toString();
            if (COLOR_SEARCH_RECURSE_TIP.equals(szText))
            {
                notification_text_color = text.getTextColors().getDefaultColor();
                notification_text_size = text.getTextSize();
                DisplayMetrics metrics = new DisplayMetrics();
                WindowManager systemWM = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
                systemWM.getDefaultDisplay().getMetrics(metrics);
                notification_text_size /= metrics.scaledDensity;
                return true;
            }
        }
        else if (gp.getChildAt(i) instanceof ViewGroup)
            return recurseGroup((ViewGroup) gp.getChildAt(i));
    }
    return false;
}

private void extractColors()
{
    if (notification_text_color != null)
        return;

    try
    {
        Notification ntf = new Notification();
        ntf.setLatestEventInfo(this, COLOR_SEARCH_RECURSE_TIP, "Utest", null);
        LinearLayout group = new LinearLayout(this);
        ViewGroup event = (ViewGroup) ntf.contentView.apply(this, group);
        recurseGroup(event);
        group.removeAllViews();
    }
    catch (Exception e)
    {
        notification_text_color = android.R.color.black;
    }
}

बुलाओ extractColorsयानी। onCreate () आपकी सेवा का। फिर जब आप कस्टम सूचना बना रहे हैं, रंग और पाठ आकार आप चाहते हैं कर रहे हैं notification_text_colorऔर notification_text_size:

Notification notification = new Notification();
RemoteViews notification_view = new RemoteViews(getPackageName(), R.layout.notification);       
notification_view.setTextColor(R.id.label, notification_text_color);
notification_view.setFloat(R.id.label, "setTextSize", notification_text_size);

1
+1 शानदार जवाब। अच्छा काम करता है। मैंने देखा कि शीर्षक और मुख्य सामग्री के लिए - दो अलग-अलग डिफ़ॉल्ट रंग प्रतीत होते हैं। मैं दोनों को लाना चाहता हूं, लेकिन केवल इस पद्धति का उपयोग करके शीर्षक रंग प्राप्त करने में सक्षम है - पुनरावृत्ति केवल 1 टेक्स्टबॉक्स ढूंढती है। कोई विचार?
हरमीत

1
मैं @Raw, केवल एक TextView के समान देखता हूं। मैंने "Utest" को दूसरे खोज टिप (और एक अलग स्ट्रिंग के साथ) से बदल दिया। यह केवल एक TextView पाता है और यह COLOR_SEARCH_RECURSE_TIP से मेल खाता है। कोई संकेत? धन्यवाद।
ciscogambo

6
इसका कारण यह है कि केवल एक बग "रिटर्न रिकरसेग्रुप ((व्यूग्रुप)) gp.getChildAt (i)) में एक बग है;" - विधि केवल तभी वापस आनी चाहिए जब भीतर का "रिकरसेग्रुप" सही हो। यह होना चाहिए: "अगर (रिक्रूसग्रेग ((ViewGroup) gp.getChildAt) (i))) सही है;) समाधान के लिए धन्यवाद - महान बॉक्स आउट सोच।
एलिकएल्ज़िन-किलाका

9
इस उत्तर के लिए धन्यवाद, यह बहुत मददगार था। रुचि रखने वाले किसी भी व्यक्ति के लिए, मैंने एक त्वरित कक्षा को एक साथ फेंक दिया, ताकि गक्कल उत्तर के आधार पर शीर्षक और पाठ रंग / आकार दोनों प्राप्त किए जा सकें। यह यहाँ पाया जा सकता है: pastebin.com/sk08QGxs
NuSkooler

3
इस वाक्य से सावधान रहें क्योंकि यह सच नहीं है (एपीआई स्तर 10 के साथ गैलेक्सी ऐस में परीक्षण किया गया है) Solution by Malcolm works fine with API>=9:। तुम्हें पता है, Android और निर्माताओं एक मुश्किल बात है। हर मंच के लिए इस समाधान का उपयोग करें।
cccrack

83

समाधान में निर्मित शैलियों का उपयोग करना है। आपके द्वारा आवश्यक शैली TextAppearance.StatusBar.EventContentको Android 2.3 और Android 4.x में कहा जाता है। Android में 5.x सामग्री सूचनाएं कई अन्य शैलियों का उपयोग: TextAppearance.Material.Notification, TextAppearance.Material.Notification.Title, और TextAppearance.Material.Notification.Line2। बस पाठ दृश्य के लिए उपयुक्त पाठ उपस्थिति सेट करें, और आपको आवश्यक रंग मिलेंगे।

यदि आप रुचि रखते हैं कि मैं इस समाधान पर कैसे पहुंचा हूं, तो यहां मेरे ब्रेडक्रंब का निशान है। कोड अंश Android 2.3 से लिए गए हैं।

  1. जब आप Notificationपाठ का उपयोग करते हैं और अंतर्निहित साधनों का उपयोग करके सेट करते हैं, तो निम्न पंक्ति लेआउट बनाती है:

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  2. उल्लिखित लेआउट में निम्नलिखित है Viewजो अधिसूचना पाठ को देखने के लिए जिम्मेदार है:

    <TextView android:id="@+id/text"
        android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:fadingEdge="horizontal"
        android:paddingLeft="4dp"
        />
    
  3. इसलिए निष्कर्ष यह है कि आवश्यक शैली है TextAppearance.StatusBar.EventContent, जो परिभाषा इस तरह दिखती है:

    <style name="TextAppearance.StatusBar.EventContent">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>
    

    आपको यहां ध्यान देना चाहिए कि यह शैली वास्तव में किसी भी निर्मित रंगों का संदर्भ नहीं देती है, इसलिए सबसे सुरक्षित तरीका कुछ अंतर्निहित रंगों के बजाय इस शैली को लागू करना है।

एक और बात: एंड्रॉइड 2.3 (एपीआई स्तर 9) से पहले, न तो स्टाइल थे, न ही रंग, केवल हार्ड-कोडेड मूल्य थे। यदि आपको किसी कारण से ऐसे पुराने संस्करणों का समर्थन करना पड़ता है, तो Gaks द्वारा उत्तर देखें ।


मुझे नहीं लगता कि मैं इस जवाब को समझता हूं। अंतिम वाक्य में कहा गया है कि ऐसा कोई रंग संदर्भ नहीं है जिसका उपयोग इसके लिए किया जा सकता है। इस मामले में किस रंग का उपयोग किया जाना चाहिए?
स्टीव पोमेरॉय

उस ने कहा, मैंने एंड्रॉइड के चैंज में देखा कि केवल एपीआई स्तर 9 के रूप में, एंड्रॉइड: textAppearance = "@ androidstyle / TextAppearance.StatusBar.EventContent" को सार्वजनिक किया गया था। इससे पहले, यह छिपा हुआ था।
स्टीव पोमेरॉय

1
यह एंड्रॉइड 2.3 से पहले छिपा नहीं था, यह बस मौजूद नहीं था। तब लेआउट में एक हार्ड-कोडित मूल्य था, और अगर डिवाइस विक्रेता ने इसे बदलने का फैसला किया, तो आप इसके बारे में कुछ भी करने में सक्षम नहीं होंगे। कोई रंग या शैली नहीं थी जिसके माध्यम से आप इस मूल्य तक पहुंच सकते थे। अभी आपके पास अभी भी कोई रंग नहीं है, लेकिन आपके पास एक शैली है, जिसे आप इस विशिष्ट पाठ रंग को प्राप्त करने के लिए आवेदन कर सकते हैं। सही बात? :)
माल्कॉम

3
क्या स्थानीय शैली? मेरे उत्तर में शैली सीधे Android स्रोत से ली गई है। आप इसे किसी अन्य अंतर्निहित शैली ( style="@android:style/TextAppearance.StatusBar.EventContent") के रूप में लागू करते हैं और पाठ के लिए आवश्यक रंग प्राप्त करते हैं। यह #ff6b6b6bवैनिला एंड्रॉइड के मामले में होने वाला है , या डिवाइस विक्रेता द्वारा इसके बजाय जो भी रंग निर्धारित किया गया था।
मैल्कम

4
बस दूसरों को बताने के लिए, यह एंड्रॉइड 6+ पर काम नहीं करता है
iGoDa

17

यहां केवल संसाधनों का उपयोग करके किसी भी एसडीके संस्करण के लिए समाधान है।

res / values ​​/ styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationTitle">
      <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
      <item name="android:textStyle">bold</item>
    </style>
    <style name="NotificationText">
      <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
    </style>
</resources>

res / values-v9 / styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent" />
    <style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title" />
</resources>

रेस / लेआउट / my_notification.xml

...
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="title"
    style="@style/NotificationTitle"
    />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="text"
    style="@style/NotificationText"
    />
...

पुनश्च: हार्ड कोडित मान 2.2- के लिए उपयोग किए जाते हैं। तो कुछ दुर्लभ पुरानी कस्टम फर्मों के साथ समस्याएं हो सकती हैं।


सुनिश्चित करें कि पाठ रंग की आवश्यकता है? माता-पिता पहले से ही इसे सेट करते हैं, नहीं?
Android डेवलपर

13

2.3+ के लिए ( Android प्रलेखन से ):

android:TextAppearance.StatusBar.EventContent.Titleप्राथमिक पाठ के लिए शैली का उपयोग करें ।

android:TextAppearance.StatusBar.EventContentद्वितीयक पाठ के लिए शैली का उपयोग करें ।

२.२- के लिए, इस सूत्र के एक अन्य उत्तर में Gaks ने जो सुझाव दिया , वह करें।

यदि आप 2.2 के विरुद्ध संकलन करना चाहते हैं और 2.3+ का समर्थन करना चाहते हैं, और सभी प्रकार के उपकरणों का समर्थन करना चाहते हैं, तो गक्स का समाधान केवल वही है जो मैं जानता हूं।

BTW, Google ने ?android:attr/textColorPrimary2.2- के लिए मान का उपयोग करने के बारे में जो सुझाव दिया है , वह काम नहीं कर रहा है। बस इसे एमुलेटर का उपयोग करके देखें। गक्स का रास्ता ही एकमात्र रास्ता है।

अधिक संसाधन: यह और यह काम नहीं करता है।


5
आपके 2.3+ निर्देशों ने Android के लिए काम नहीं किया। यह एक सफेद पृष्ठभूमि पर सफेद पाठ का उत्पादन करता था।
सैम

6

मैं प्रश्न में TextView पर इसका उपयोग करता हूं:

style="@style/TextAppearance.Compat.Notification.Title"

अगर बैकग्राउंड सफेद है तो बैकग्राउंड ब्लैक है और ब्लैक टेक्स्ट है तो यह मुझे व्हाइट टेक्स्ट देता है। और यह एपीआई 19 के रूप में कम से कम वापस काम करता है।


2

आपको निर्दिष्ट रंगों का उपयोग करना चाहिए android.R.color

उदाहरण के लिए: android.R.color.primary_text_light

कस्टम रॉम डेवलपर्स और एंड्रॉइड स्किन डिज़ाइनर इनको अपडेट करने वाले हैं इसलिए आपके ऐप के रंग बाकी सिस्टम के अनुरूप हो सकते हैं। इसमें यह सुनिश्चित करना शामिल है कि आपका पाठ पूरे सिस्टम में ठीक से दिखाई दे।


मुझे किस रंग का उपयोग करना चाहिए android.R.color? सभी टेक्स्ट रंगों में "डार्क" और "लाइट" दोनों विविधताएं हैं।
वीटी

1
मेरे पास इस पर कस्टम थीम वाला कोई उपकरण नहीं है, इसलिए मैं वास्तव में परीक्षण नहीं कर सकता कि किसका उपयोग करना है। मैं कहता हूँ कि दोनों को आज़माएँ और देखें कि आपके लिए कौन सा काम करता है।
ऑस्टिन महोनी

1

इस निर्देश पर देख रहा: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView आप LinearLayout कंटेनर के लिए अपने पृष्ठभूमि रंग की स्थापना की है, तो आप पाठ के लिए अधिसूचना में अपने रंग में हो सकता है और पृष्ठ - भूमि।

यदि अधिसूचना पाठ के लिए डिफ़ॉल्ट रंग लांचर एप्लिकेशन द्वारा परिभाषित किया गया है, तो आप इसे एंड्रॉइड डिफॉल्ट सेटिंग्स से पुनर्प्राप्त नहीं कर सकते हैं जब तक कि लांचर इस जानकारी को तेज नहीं कर रहा है।

हालाँकि, क्या आपने अपने लेआउट से इस लाइन को हटाने का प्रयास किया है android: textColor = "# 000" ताकि यह स्वचालित रूप से डिफ़ॉल्ट रंग प्राप्त कर सके?


1
पाठ रंग हटाने से कोई सहायता नहीं मिलती - डिफ़ॉल्ट अधिसूचना रंगों से मेल नहीं खाता है।
वीटी

क्या आपने पृष्ठभूमि बदलने की कोशिश की? मुझे लगता है कि यह एक गंभीर समस्या है और यह अच्छा है कि आपने इसे लाया। क्या आपने Google डेवलपर फ़ोरम / समूह आज़माए हैं?
लुमिस

1

मैंने एंड्रॉइड द्वारा प्रदान की गई विशेषता के नाम को सीधे बदलकर एक बहुत ही सरल समाधान पाया है।

जैसा कि आप इस ट्यूटोरियल में देख सकते हैं: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/

आपको केवल एक अलग विशेषता का उपयोग करने की आवश्यकता है:

<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>

आशा है इससे आपको सहायता मिलेगी!


1

मुझे पता है कि यह एक पुराना सवाल है, लेकिन यह किसी और की मदद कर सकता है; ) मैं अपने ऐप में ऐसा करता हूं और जो कुछ लाइनों में सही काम करता है:

    RemoteViews notificationView = new RemoteViews(context.getPackageName(), R.layout.notification_layout);

    if (SDK >= LOLLIPOP) {

            TextView textView = new TextView(context);
            textView.setTextAppearance(context, android.R.style.TextAppearance_Material_Notification_Title);

            notificationView.setTextColor(R.id.title, textView.getCurrentTextColor());
            notificationView.setFloat(R.id.title, "setTextSize", textView.getTextSize());

            textView.setTextAppearance(context,android.R.style.TextAppearance_Material_Notification_Line2);

            notificationView.setTextColor(R.id.contentText,textView.getCurrentTextColor());
            notificationView.setFloat(R.id.contentText,"setTextSize",textView.getTextSize());

            textView = null;

    }

0

TextMearance.Material.Notification.Title की वजह से डार्क नोटिफिकेशन बैकग्राउंड के साथ @Malckom के सॉल्यूशन ने लॉलीपॉप पर मेरी मदद नहीं की। यह एक सिस्टम हार्डकोड कलर है। @Grzaks से समाधान हुआ, लेकिन अधिसूचना बनाने की प्रक्रिया में कुछ बदलावों के साथ:

NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(this)
                          .setContentTitle(NOTIFICATION_TITLE_TIP)
                          .setContentText(NOTIFICATION_TEXT_TIP);
Notification ntf = mBuilder.build();
// ...
if (NOTIFICATION_TEXT_TIP.equals(szText)) {
    notification_text_color = text.getTextColors().getDefaultColor();
} else {
    if (NOTIFICATION_TITLE_TIP.equals(szText)) {
        notification_title_color = text.getTextColors().getDefaultColor();
    }
}
// ...

0

यहाँ इस त्रुटि को हल करने के लिए मेरे लिए क्या काम किया गया है। निम्नलिखित को style.xml में जोड़ें

    <style name="TextAppearance">
    </style>
    <style name="TextAppearance.StatusBar">
    </style>
    <style name="TextAppearance.StatusBar.EventContent">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>
    <style name="TextAppearance.StatusBar.EventContent.Info">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>

0

अपने एक्सपेंडेबल या कोलाज़ लेआउट android:backgroundमें एक सेट के रूप में "@android:color/transparent"क्योंकि यह स्वचालित रूप से आपके डिवाइस की अधिसूचना थीम का रंग लेता है और पृष्ठभूमि के रूप में सेट होता है

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_margin="0dp"
android:background="@android:color/transparent"
android:orientation="vertical">
          <TextView

            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/colorSecondary"
            android:textStyle="bold" />

और आपका टेक्स्टव्यू रंग काले और सफेद को Resource/colorसरल रंग फ़ाइल में फ़ाइल के साथ-साथ रात मोड रंग फ़ाइल के रूप में परिभाषित करता है

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