سؤال

أود تغيير لون زر أندرويد قياسي قليلا من أجل مطابقة علامات عميل بشكل أفضل.

أفضل طريقة وجدتها للقيام بذلك حتى الآن هي تغيير Buttonجميلة جميلة في الواقعة res/drawable/red_button.xml:

<?xml version="1.0" encoding="utf-8"?>    
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/red_button_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/red_button_focus" />
    <item android:drawable="@drawable/red_button_rest" />
</selector>

لكن القيام بذلك يتطلب من أنني في الواقع إنشاء ثلاثة أشخاص مختلفين مختلفين لكل زر أريد تخصيصه (واحد للزر في الراحة، واحدة عند التركيز، وواحد عند الضغط عليه). يبدو أن أكثر تعقيدا وغير جافة مما أحتاج إليه.

كل ما أريد فعله حقا هو تطبيق نوع من تحويل اللون إلى الزر. هل هناك طريقة أسهل للذهاب حول تغيير لون زر أكثر مما أفعله؟

هل كانت مفيدة؟

المحلول

اكتشفت أن هذا يمكن القيام به كل شيء في ملف واحد بسهولة إلى حد ما. ضع شيئا مثل التعليمات البرمجية التالية في ملف يدعى custom_button.xml ثم أعد background="@drawable/custom_button" في عرض الزر الخاص بك:

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" >
        <shape>
            <gradient
                android:startColor="@color/yellow1"
                android:endColor="@color/yellow2"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <gradient
                android:endColor="@color/orange4"
                android:startColor="@color/orange5"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item>        
        <shape>
            <gradient
                android:endColor="@color/blue2"
                android:startColor="@color/blue25"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

نصائح أخرى

فيما يلي إجابة Tomasz، يمكنك أيضا تعيين الظل برمجيا من الزر بأكمله باستخدام وضع الضرب PorterDuff. سيؤدي ذلك إلى تغيير لون الزر بدلا من مجرد صبغة.

إذا بدأت مع زر مظلل رمادي قياسي:

button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

سوف تعطيك زر مظللة حمراء،

button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

سوف تعطيك زر مظللة خضراء وما إلى ذلك، حيث القيمة الأولى هي اللون بتنسيق عرافة.

إنه يعمل بضرب قيمة لون الزر الحالي حسب قيمة اللون. أنا متأكد من أن هناك أيضا الكثير يمكنك القيام به مع هذه الأوضاع.

مايك، قد تكون مهتما بمرشحات الألوان.

مثال:

button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));

جرب هذا لتحقيق اللون الذي تريده.

هذا هو الحل الذي يعمل بشكل مثالي من API 15.. وبعد يحتفظ هذا الحل بجميع تأثيرات الزر الافتراضية، مثل المواد RippleEffect. وبعد لم أختبرها في أبيس السفلي، ولكن يجب أن تعمل.

كل ما عليك القيام به، هو:

1) قم بإنشاء نمط يتغير فقط colorAccent:

<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
    <item name="colorAccent">@color/com_facebook_blue</item>
</style>

أوصي باستخدام ThemeOverlay.AppCompat أو الرئيسية الخاصة بك AppTheme كوالد، للحفاظ على بقية أنماطك.

2) إضافة هذين السطرين إلى button القطعة:

style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"

في بعض الأحيان الجديد الخاص بك colorAccent لا تظهر في معاينة Studio Android، ولكن عند تشغيل التطبيق الخاص بك على الهاتف، سيتم تغيير اللون.


عينة زر القطعة

<Button
    android:id="@+id/sign_in_with_facebook"
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/sign_in_facebook"
    android:textColor="@android:color/white"
    android:theme="@style/Facebook.Button" />

Sample Button with custom color

يمكنك الآن استخدام AppCompat-V7 AppCompatbutton. مع ال backgroundTint ينسب:

<android.support.v7.widget.AppCompatButton
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:backgroundTint="#ffaa00"/>

أنا أحب اقتراح فلتر اللون في الإجابات السابقة من @ conjugatedirection و stomasz؛ ومع ذلك، وجدت أن الكود المقدم حتى الآن لم يكن تطبيقه بسهولة كما كنت أتوقع.

أولا، لم يتم ذكرها أين لتطبيق ومسح مرشح اللون. من الممكن أن هناك أماكن جيدة أخرى للقيام بذلك، ولكن ما جاء إلى الذهن بالنسبة لي كان ontouchlistener..

من قراءتي للسؤال الأصلي، سيكون الحل المثالي هو واحد لا ينطوي على أي صور. الإجابة المقبولة باستخدام custom_button.xml من @ @ ammby هي مناسبة أفضل من مرشحات الألوان إذا كان ذلك هدفك. في حالتي، بدأت مع صورة PNG من مصمم UI من ما يفترض أن يبدو الزر. إذا قمت بتعيين "خلفية الزر" لهذه الصورة، فقد تضيع ملاحظات العرض الافتراضي بالكامل. يحل هذا الرمز محل هذا السلوك مع تأثير سواد برنامجي.

button.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 0x6D6D6D sets how much to darken - tweak as desired
                setColorFilter(v, 0x6D6D6D);
                break;
            // remove the filter when moving off the button
            // the same way a selector implementation would 
            case MotionEvent.ACTION_MOVE:
                Rect r = new Rect();
                v.getLocalVisibleRect(r);
                if (!r.contains((int) event.getX(), (int) event.getY())) {
                    setColorFilter(v, null);
                }
                break;
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                setColorFilter(v, null);
                break;
        }
        return false;
    }

    private void setColorFilter(View v, Integer filter) {
        if (filter == null) v.getBackground().clearColorFilter();
        else {
            // To lighten instead of darken, try this:
            // LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
            LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
            v.getBackground().setColorFilter(darken);
        }
        // required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
        v.getBackground().invalidateSelf();
    }
});

لقد استخراجت هذا كصف منفصل للتطبيق على أزرار متعددة - يظهر كطبقة داخلية مجهولة فقط للحصول على الفكرة.

إذا كنت تقوم بعمل أزرار اللون مع XML، فيمكنك إنشاء الكود منظف بعض الشيء من خلال تحديد الحالة المركزة والضغط في ملف منفصل وإعادة استخدامها. زر أخضر يشبه هذا:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_focused="true" android:drawable="@drawable/button_focused"/>
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>

    <item>
        <shape>
            <gradient android:startColor="#ff00ff00" android:endColor="#bb00ff00" android:angle="270" />
            <stroke android:width="1dp" android:color="#bb00ff00" />
            <corners android:radius="3dp" />
            <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
        </shape>
    </item>

</selector>

أقصر حلا يعمل مع أي إصدار يعمل بنظام Android:

<Button
     app:backgroundTint="@color/my_color"

الملاحظات / المتطلبات:

  • استخدم ال app: مساحة الاسم و ليس ال android: مساحة الاسم!
  • إصدار AppCompat> 24.2.0

    التبعيات {compile 'com.android.support:apmpat-v7:25.3.1'}

تفسير: enter image description here

أنا أستخدم هذا النهج

style.xml.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:colorPrimaryDark">#413152</item>
    <item name="android:colorPrimary">#534364</item>
    <item name="android:colorAccent">#534364</item>
    <item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>

<style name="MyButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">#534364</item>
    <item name="android:textColor">#ffffff</item>
</style>

كما ترون من الأعلى، فأنا أستخدم نمط مخصص للزر الخاص بي. لون زر يتوافق مع اللون لهجة. أجد هذا نهج أفضل بكثير من الإعداد android:background كما لن أفقد تأثير تموج Google.

هناك طريقة أسهل بكثير الآن: Android-olo-colors.com

سوف يتيح لك تغيير ألوان كل Holo Prables (أزرار، المغازل، ...) بسهولة. يمكنك تحديد اللون ثم قم بتنزيل ملف zip الذي يحتوي على رسمية لجميع القرارات.

استخدامه بهذه الطريقة:

buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);

في <Button> استعمال android:background="#33b5e5". وبعد أو أفضل android:background="@color/navig_button"

ال Droidux. مكتبة المكونات لديها ColorButton القطعة التي يمكن تغيير لونها بسهولة، سواء من خلال تعريف XML وقم برمجيا في وقت التشغيل، حتى تتمكن من السماح للمستخدم بتعيين لون الزر / سمة الزر إذا كان تطبيقك يسمح بذلك.

يمكنك أيضا استخدام هذه الأداة عبر الإنترنت لتخصيص الزر http://angrytools.com/android/button/ واستخدام android:background="@drawable/custom_btn" لتحديد الزر المخصص في التصميم الخاص بك.

يمكنك تعيين موضوع الزر الخاص بك لهذا

<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
 <item name="colorButtonNormal">@color/HEXColor</item>
 <item name="android:textColor">@color/HEXColor</item>
</style>

طريقة سهلة هي تحديد فئة زر مخصصة تقبل جميع الخصائص التي تريدها مثل RADIUS، اللون التدرج، اللون المضغوط، اللون العادي وما إلى ذلك، ثم استخدم ذلك في تخطيطات XML الخاصة بك بدلا من إعداد الخلفية باستخدام XML. عينة هنا

هذا مفيد للغاية إذا كان لديك الكثير من الأزرار التي تحتوي على نفس الخصائص مثل دائرة نصف قطرها، واللون المحدد وما إلى ذلك. يمكنك تخصيص زر موروث الخاص بك للتعامل مع هذه الخصائص الإضافية.

النتيجة (لم يتم استخدام محدد الخلفية).

زر طبيعي

Normal Image

زر مضغوط

enter image description here

الطريقة التي أقوم بها زر مصمم مختلف يعمل بشكل جيد للغاية هي الفئة الفرعية كائن الزر وتطبيق مرشح اللون. يتعامل هذا أيضا مع الدول التي تم تمكينها وتعطيلها من خلال تطبيق ألفا على الزر.

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Button;

public class DimmableButton extends Button {

    public DimmableButton(Context context) {
        super(context);
    }

    public DimmableButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DimmableButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setBackgroundDrawable(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackgroundDrawable(layer);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void setBackground(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackground(layer);
    }

    /**
     * The stateful LayerDrawable used by this button.
     */
    protected class DimmableButtonBackgroundDrawable extends LayerDrawable {

        // The color filter to apply when the button is pressed
        protected ColorFilter _pressedFilter = new LightingColorFilter(Color.LTGRAY, 1);
        // Alpha value when the button is disabled
        protected int _disabledAlpha = 100;
        // Alpha value when the button is enabled
        protected int _fullAlpha = 255;

        public DimmableButtonBackgroundDrawable(Drawable d) {
            super(new Drawable[] { d });
        }

        @Override
        protected boolean onStateChange(int[] states) {
            boolean enabled = false;
            boolean pressed = false;

            for (int state : states) {
                if (state == android.R.attr.state_enabled)
                    enabled = true;
                else if (state == android.R.attr.state_pressed)
                    pressed = true;
            }

            mutate();
            if (enabled && pressed) {
                setColorFilter(_pressedFilter);
            } else if (!enabled) {
                setColorFilter(null);
                setAlpha(_disabledAlpha);
            } else {
                setColorFilter(null);
                setAlpha(_fullAlpha);
            }

            invalidateSelf();

            return super.onStateChange(states);
        }

        @Override
        public boolean isStateful() {
            return true;
        }
    }

}

القيم Styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="RedAccentButton" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">#ff0000</item>
</style>

ومن بعد:

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text"
    android:theme="@style/RedAccentButton" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text"
    android:theme="@style/RedAccentButton" />

result

لكل إرشادات تصميم المواد، تحتاج إلى استخدام النمط مثل التعليمات البرمجية أدناه

<style name="MyButton" parent="Theme.AppCompat.Light>
    <item name="colorControlHighlight">#F36F21</item>
    <item name="colorControlHighlight">#FF8D00</item>
</style>

وفي التصميم أضف هذه الخاصية إلى الزر

    android:theme="@style/MyButton"

بسيطة .. أضف هذه التبعية في مشروعك وإنشاء زر مع 1. أي شكل 2. أي لون 3. أي حدود 4. مع تأثيرات المواد

https://github.com/manojbhadane/qbutton.

<com.manojbhadane.QButton
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="OK"
       app:qb_backgroundColor="@color/green"
       app:qb_radius="100"
       app:qb_strokeColor="@color/darkGreen"
       app:qb_strokeWidth="5" />
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top