【问题标题】:Seekbar showing only progress color and not background color搜索栏只显示进度颜色而不是背景颜色
【发布时间】:2016-07-18 10:34:20
【问题描述】:

我正在使用自定义搜索栏可绘制并在我的 xml 中将其进度设置为 50。它在 Android Studio Preview 中显示得非常好,但在设备中,背景颜色与进度颜色相同。我正在使用带有 Android 版本的 Nexus 5:6.0.1。以下是代码和截图:

搜索栏:

 <SeekBar
     android:id="@+id/seekbar"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_below="@id/ivRepeat"
     android:indeterminate="false"
     android:maxHeight="2dp"
     android:minHeight="2dp"
     android:progress="50"
     android:progressDrawable="@drawable/progress_drawable"
     android:thumbTint="@color/seekColor" />

progress_drawable.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />
            <solid android:color="#F7CCBD" />
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <solid android:color="@color/seekColor" />
            </shape>
        </clip>
    </item>
</layer-list>

seekColor 值: #87DED5

它在 Android Studio Preview 中的显示方式:

它在我的设备中的显示方式:

任何想法为什么会发生这种情况以及如何解决它?

【问题讨论】:

  • 添加一个id为@android:id/secondaryProgress@android:id/progress内容相同的项目并再次运行
  • @Blackbelt 我以前做过,同样的问题。所以,我尝试删除它。同样的问题。
  • 如果您使用“即时运行”,请尝试将其关闭并重新构建项目。
  • 对不起,伙计们。我的 java 文件中有一行正在执行此操作。 seekbar.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.seekColor), PorterDuff.Mode.SRC_IN));我之前用它来改变颜色,但无法改变它的厚度,所以我改成了自定义drawable。但是忘记删除这一行。我觉得自己很笨......
  • @Blackbelt 对,谢谢。

标签: android android-seekbar


【解决方案1】:

这里, 清除项目后代码没有问题。

如果仍然有问题,请尝试下面的代码 sn-p。

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@android:id/background"> <!--background of seekbar--> 
            <shape>
                <corners android:radius="5dip" />
                <solid android:color="#F7CCBD" />
            </shape>
        </item>
        <item android:id="@android:id/progress"> <!--progress color-->
            <clip>
                <shape>
                    <corners android:radius="5dip" />
                    <solid android:color="#87DED5" />
                </shape>
            </clip>
        </item>
        <item android:id="@android:id/secondaryProgress"> <!--secondaryProgress color-->
            <clip>
                <shape>
                    <corners android:radius="5dip" />
                    <solid android:color="#F7CCBD" />
                </shape>
            </clip>
        </item>
    </layer-list>

【讨论】:

    【解决方案2】:

    自定义搜索栏以更改搜索栏进度的颜色、进度背景和拇指颜色。

    下面是自定义的搜索栏类。

    package com.customseekbar;
    
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.res.ColorStateList;
    import android.content.res.TypedArray;
    import android.graphics.Color;
    import android.graphics.PorterDuff;
    import android.graphics.drawable.Drawable;
    import android.graphics.drawable.GradientDrawable;
    import android.graphics.drawable.LayerDrawable;
    import android.graphics.drawable.NinePatchDrawable;
    import android.graphics.drawable.ScaleDrawable;
    import android.os.Build;
    import android.support.annotation.IntRange;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewTreeObserver;
    import android.widget.SeekBar;
    
    import com.customseekbar.R;
    
    import java.util.concurrent.Callable;
    
    
    public class CustomSeekBar extends SeekBar implements View.OnTouchListener {
    
    private static final String TAG = "CustomSeekbar";
    private int mActualBackgroundColor;
    
    /***
     * Thumb and Progress colors
     */
    int mThumbColor, mProgressColor, mProgressBackgroundColor;
    
    /***
     * Thumb drawable
     */
    Drawable mThumb;
    /***
     * States for Lollipop ColorStateList
     */
    int[][] states = new int[][]{
            new int[]{android.R.attr.state_enabled}, // enabled
            new int[]{android.R.attr.state_pressed},  // pressed
            new int[]{-android.R.attr.state_enabled}, // disabled
            new int[]{} //everything else
    };
    
    /***
     * Default colors to be black for Thumb ColorStateList
     */
    int[] colorsThumb = new int[]{
            Color.BLACK,
            Color.BLACK,
            Color.LTGRAY,
            Color.BLACK
    };
    
    /***
     * Default colors to be black for Progress ColorStateList
     */
    int[] colorsProgress = new int[]{
            Color.BLACK,
            Color.BLACK,
            Color.LTGRAY,
            Color.BLACK
    };
    
    /***
     * Default colors to be black for Progress ColorStateList
     */
    int[] colorsProgressBackground = new int[]{
            Color.BLACK,
            Color.BLACK,
            Color.LTGRAY,
            Color.BLACK
    
    };
    
    /***
     * ColorStateList objects
     */
    ColorStateList mColorStateListThumb, mColorStateListProgress, mColorStateListProgressBackground;
    
    /***
     * Used for APIs below 21 to determine height of the seekBar as well as the new thumb drawable
     */
    private int mOriginalThumbHeight;
    private int mThumbAlpha = 255;
    private boolean mIsEnabled = true;
    
    /***
     * Updates the thumbColor dynamically
     *
     * @param thumbColor Color representing thumb drawable
     */
    public void setThumbColor(final int thumbColor) {
        mThumbColor = thumbColor;
        if (lollipopAndAbove()) {
            setupThumbColorLollipop();
        } else {
            gradientDrawable.setColor(mIsEnabled ? thumbColor : Color.LTGRAY);
        }
        invalidate();
        requestLayout();
    }
    
    /***
     * Method called for APIs 21 and above to setup thumb Color
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setupThumbColorLollipop() {
        if (lollipopAndAbove()) {
            colorsThumb[0] = mThumbColor;
            colorsThumb[1] = mThumbColor;
            colorsThumb[2] = Color.LTGRAY;
            mColorStateListThumb = new ColorStateList(states, colorsThumb);
            setThumbTintList(mColorStateListThumb);
        } else {
    
        }
    }
    
    /***
     * Updates the progressColor dynamically
     *
     * @param progressColor Color representing progress drawable
     */
    public void setProgressColor(final int progressColor) {
        mProgressColor = progressColor;
        if (lollipopAndAbove()) {
            setupProgressColorLollipop();
        } else {
            setupProgressColor();
        }
    
        invalidate();
        requestLayout();
    }
    
    /***
     * Checks if the device is running API greater than 21
     *
     * @return true if lollipop and above
     */
    private boolean lollipopAndAbove() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    }
    
    /***
     * Method called from APIs below 21 to setup Progress Color
     */
    private void setupProgressColor() {
        try {
            //load up the drawable and apply color
            LayerDrawable ld = (LayerDrawable) getProgressDrawable();
            ScaleDrawable shape = (ScaleDrawable) (ld.findDrawableByLayerId(android.R.id.progress));
            shape.setColorFilter(mProgressColor, PorterDuff.Mode.SRC_IN);
    
            //set the background to transparent
            NinePatchDrawable ninePatchDrawable = (NinePatchDrawable) (ld.findDrawableByLayerId(android.R.id.background));
            ninePatchDrawable.setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_IN);
        } catch (NullPointerException e) {
            //TODO: Handle exception
        }
    }
    
    /***
     * Method called from APIs >= 21 to setup Progress Color
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setupProgressColorLollipop() {
        colorsProgress[0] = mProgressColor;
        colorsProgress[1] = mProgressColor;
        mColorStateListProgress = new ColorStateList(states, colorsProgress);
        setProgressTintList(mColorStateListProgress);
    }
    
    /***
     * Updates the progressBackgroundColor dynamically
     *
     * @param progressBackgroundColor Color representing progress drawable
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setProgressBackgroundColor(final int progressBackgroundColor) {
        mProgressBackgroundColor = progressBackgroundColor;
        if (lollipopAndAbove()) {
            setupProgressBackgroundLollipop();
        } else {
            setupProgressBackground();
        }
        invalidate();
        requestLayout();
    }
    
    /***
     * Method called from APIs 21 and above to setup the Progress-background-line Color
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setupProgressBackgroundLollipop() {
        colorsProgressBackground[0] = mProgressBackgroundColor;
        colorsProgressBackground[1] = mProgressBackgroundColor;
        mColorStateListProgressBackground = new ColorStateList(states, colorsProgressBackground);
        setProgressBackgroundTintList(mColorStateListProgressBackground);
    }
    
    /***
     * Method called from APIs below 21 to setup the Progress-background-line Color
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void setupProgressBackground() {
        //load up the drawable and apply color
        SeekbarBackgroundDrawable seekBarBackgroundDrawable = new SeekbarBackgroundDrawable(getContext(),
                mProgressBackgroundColor, mActualBackgroundColor, getPaddingLeft(), getPaddingRight());
        if (belowJellybean())
            setBackgroundDrawable(seekBarBackgroundDrawable);
        else
            setBackground(seekBarBackgroundDrawable);
    }
    
    /***
     * Constructor for creating CustomSeekbar through code
     *
     * @param context Context object
     */
    public SeekBar(final Context context) {
        super(context);
    }
    
    GradientDrawable gradientDrawable = new GradientDrawable();
    
    /***
     * Constructor for creating CustomSeekbar through XML
     *
     * @param context Context Object
     * @param attrs   Attributes passed through XML
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CustomSeekBar(final Context context, final AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme()
                .obtainStyledAttributes(
                        attrs,
                        R.styleable.SeekBarCompat,
                        0, 0);
        int array[] = {android.R.attr.background, android.R.attr.enabled};
        TypedArray b = context.getTheme()
                .obtainStyledAttributes(attrs, array, 0, 0);
        try {
            mThumbColor = a.getColor(R.styleable.SeekBarCompat_thumbColor, getPrimaryColorFromSelectedTheme(context));
            mProgressColor = a.getColor(R.styleable.SeekBarCompat_progressColor, getPrimaryColorFromSelectedTheme(context));
            mProgressBackgroundColor = a.getColor(R.styleable.SeekBarCompat_progressBackgroundColor, Color.BLACK);
            mThumbAlpha = (int) (a.getFloat(R.styleable.SeekBarCompat_thumbAlpha, 1) * 255);
            mActualBackgroundColor = b.getColor(0, Color.TRANSPARENT);
            mIsEnabled = b.getBoolean(1, true);
            if (lollipopAndAbove()) {
                setSplitTrack(false);
                setupThumbColorLollipop();
                setupProgressColorLollipop();
                setupProgressBackgroundLollipop();
                getThumb().setAlpha(mThumbAlpha);
            } else {
                Log.e(TAG, "CustomSeekbar isEnabled? " + mIsEnabled);
                setupProgressColor();
                setOnTouchListener(this);
                gradientDrawable.setShape(GradientDrawable.OVAL);
                gradientDrawable.setSize(50, 50);
                gradientDrawable.setColor(mIsEnabled ? mThumbColor : Color.LTGRAY);
                triggerMethodOnceViewIsDisplayed(this, new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        ViewGroup.LayoutParams layoutParams = getLayoutParams();
                        mOriginalThumbHeight = mThumb.getIntrinsicHeight();
                        gradientDrawable.setSize(mOriginalThumbHeight / 3, mOriginalThumbHeight / 3);
                        gradientDrawable.setAlpha(mThumbAlpha);
                        setThumb(gradientDrawable);
                        if (layoutParams.height < mOriginalThumbHeight)
                            layoutParams.height = mOriginalThumbHeight;
                        setupProgressBackground();
                        return null;
                    }
                });
            }
        } finally {
            a.recycle();
            b.recycle();
        }
    }
    
    private boolean belowJellybean() {
        return Build.VERSION.SDK_INT < 16;
    }
    
    /***
     * Gets the Primary Color from theme
     *
     * @param context Context Object
     * @return Primary Color
     */
    public static int getPrimaryColorFromSelectedTheme(Context context) {
        int[] attrs = {R.attr.colorPrimary, R.attr.colorPrimaryDark};
        TypedArray ta = context.getTheme()
                .obtainStyledAttributes(attrs);
        int primaryColor = ta.getColor(0, Color.BLACK); //1 index for primaryColorDark
        //default value for primaryColor is set to black if primaryColor not found
        ta.recycle();
        return primaryColor;
    }
    
    /***
     * Utility method for ViewTreeObserver
     *
     * @param view   View object
     * @param method Method to be called once View is displayed
     */
    public static void triggerMethodOnceViewIsDisplayed(final View view, final Callable<Void> method) {
        final ViewTreeObserver observer = view.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT < 16) {
                    view.getViewTreeObserver()
                            .removeGlobalOnLayoutListener(this);
                } else view.getViewTreeObserver()
                        .removeOnGlobalLayoutListener(this);
                try {
                    method.call();
                } catch (Exception e) {
                    Log.e(TAG, "onGlobalLayout " + e.toString());
                }
            }
        });
    }
    
    /***
     * Touch listener for changing Thumb Drawable
     *
     * @param v     View Object
     * @param event Motion Event
     * @return
     */
    @Override
    public boolean onTouch(final View v, final MotionEvent event) {
        if (!lollipopAndAbove())
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    gradientDrawable = new GradientDrawable();
                    gradientDrawable.setShape(GradientDrawable.OVAL);
                    gradientDrawable.setSize(mOriginalThumbHeight / 2, mOriginalThumbHeight / 2);
                    gradientDrawable.setColor(mIsEnabled ? mThumbColor : Color.LTGRAY);
                    gradientDrawable.setDither(true);
                    gradientDrawable.setAlpha(mThumbAlpha);
                    setThumb(gradientDrawable);
                    break;
                case MotionEvent.ACTION_UP:
                    gradientDrawable = new GradientDrawable();
                    gradientDrawable.setShape(GradientDrawable.OVAL);
                    gradientDrawable.setSize(mOriginalThumbHeight / 3, mOriginalThumbHeight / 3);
                    gradientDrawable.setColor(mIsEnabled ? mThumbColor : Color.LTGRAY);
                    gradientDrawable.setDither(true);
                    gradientDrawable.setAlpha(mThumbAlpha);
                    setThumb(gradientDrawable);
                    break;
                default:
                    break;
            }
        return false;
    }
    
    
    /***
     * Called to substitute getThumb() for APIs below 16
     *
     * @param thumb
     */
    @Override
    public void setThumb(final Drawable thumb) {
        super.setThumb(thumb);
        mThumb = thumb;
    }
    
    /***
     * Sets the thumb alpha (Obviously)
     *
     * @param alpha
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setThumbAlpha(@IntRange(from = 0, to = 255) int alpha) {
        mThumbAlpha = alpha;
        if (!belowJellybean())
            getThumb().setAlpha(mThumbAlpha);
        setLayoutParams(getLayoutParams());
    }
    
    /***
     * Enables or disables the whole seekBar!
     *
     * @param enabled
     */
    @Override
    public void setEnabled(final boolean enabled) {
        mIsEnabled = enabled;
        triggerMethodOnceViewIsDisplayed(this, new Callable<Void>() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public Void call() throws Exception {
                if (!lollipopAndAbove()) {
                    gradientDrawable = new GradientDrawable();
                    gradientDrawable.setShape(GradientDrawable.OVAL);
                    gradientDrawable.setSize(mOriginalThumbHeight / 3, mOriginalThumbHeight / 3);
                    gradientDrawable.setColor(mIsEnabled ? mThumbColor : Color.LTGRAY);
                    gradientDrawable.setDither(true);
                    gradientDrawable.setAlpha(mThumbAlpha);
                    setThumb(gradientDrawable);
                    //load up the drawable and apply color
                    LayerDrawable ld = (LayerDrawable) getProgressDrawable();
                    ScaleDrawable shape = (ScaleDrawable) (ld.findDrawableByLayerId(android.R.id.progress));
                    shape.setColorFilter(mIsEnabled ? mProgressColor : Color.LTGRAY, PorterDuff.Mode.SRC_IN);
                    //set the background to transparent
                    NinePatchDrawable ninePatchDrawable = (NinePatchDrawable) (ld.findDrawableByLayerId(android.R.id.background));
                    ninePatchDrawable.setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_IN);
                    //background
                    //load up the drawable and apply color
                    SeekbarBackgroundDrawable seekBarBackgroundDrawable = new SeekbarBackgroundDrawable(getContext(),
                            mIsEnabled ? mProgressBackgroundColor : Color.LTGRAY, mActualBackgroundColor, getPaddingLeft(), getPaddingRight());
                    if (belowJellybean())
                        setBackgroundDrawable(seekBarBackgroundDrawable);
                    else
                        setBackground(seekBarBackgroundDrawable);
                }
                CustomSeekBar.super.setEnabled(enabled);
                return null;
            }
        });
    
    }
    }
    

    使用以下方法更改搜索栏的颜色:

    CustomSeekBar mSeekbar =    (CustomSeekBar)findViewById(R.id.video_fragment_seekbar);
    mSeekbar.setThumbColor(AppTheme.getInstance(activity).getSeekbarThumbColor());      
    
     mSeekbar.setProgressColor(AppTheme.getInstance(activity).getColor());           
    
     mSeekbar.setProgressBackgroundColor(ContextCompat.getColor(activity, R.color.seekbar_progress_bg));
    

    【讨论】:

    • 你能告诉我为什么 xml 中的 drawable 不起作用吗?我确信它有效,但发生了一些意想不到的事情。
    • 也提供 styleableDrawable 文件
    【解决方案3】:

    把这个放在progress_drawable.xml:不要用那个

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="line">
    
        <stroke android:width="1dp" android:color="#EDA216"/>
        <corners android:radius="1dp" />
    
    </shape>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 2021-10-19
      • 1970-01-01
      • 2014-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-31
      相关资源
      最近更新 更多