简体   繁体   中英

Change background colour dynamically

I am using RangeSeekBar to set some values for 3 conditions (ie Green=OK,Amber=Warning, Red=evacuate)... I am using xml drawable to set the backgroung like this

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient 
        android:startColor="#27F70C" 
        android:centerColor="#FFBF00"
        android:endColor="#FC0505" 
        android:angle="0" />

    <corners android:radius="0px" />

    <stroke 
        android:width="2dp" 
        android:color="#70555555" />

    <stroke 
            android:width="0dp" 
            android:color="#70555555" />
</shape>

which results like this 在此输入图像描述

Now I want to change the background colour according to the seekbar values so that If I change the range it should change the background colour something like this 在此输入图像描述

I know I can change the gradient programmatically but how to narrow down start color and increase end colour ? Anyone has a solution for this ?

Thanks

Try creating three View s underneath the RangeSeekBar , and updating the widths of each as the sliders are moved.

Very roughly, this might look like:

<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
     <View
         android:id="@+id/green"
         android:layout_width="100dp"
         android:layout_height="match_parent"
         android:background="#00FF00"/>
     <View
         android:id="@+id/orange"
         android:layout_toRightOf="@id/green"
         android:layout_width="100dp"
         android:layout_height="match_parent"
         android:background="#FFFF00"/>
     <View
         android:id="@+id/red"
         android:layout_toRightOf="@id/orange"
         android:layout_width="100dp"
         android:layout_height="match_parent"
         android:background="#FF0000"/>
     <RangeSeekBar android:layout_width="300dp" android:layout_height="wrap_content">
</RelativeLayout>

In this example, you would update the widths of the three colour views so that they add up to 300dp, as the sliders are moved.

You can either use solid colours for the backgrounds of the three views, which would look like your second image, or create three gradients (green to green-yellow, yellow-orange, orange-red).

The LinearGradient has an optional parameter called positions - these positions tell how long the different sections of colors will be.

@miroslavign posted a function here which seems to set gradient background for a view by code (not XML) - I haven't tried it, but it looks promising. Simply change it to your colors and set the gradient positions according to the Seekbar.

Copy pasted here for people who don't like following links:

private void FillCustomGradient(View v) {
    final View view = v;
    Drawable[] layers = new Drawable[1];

    ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
        @Override
        public Shader resize(int width, int height) {
            LinearGradient lg = new LinearGradient(
                    0,
                    0,
                    0,
                    view.getHeight(),
                    new int[] {
                             getResources().getColor(R.color.color1), // please input your color from resource for color-4
                             getResources().getColor(R.color.color2),
                             getResources().getColor(R.color.color3),
                             getResources().getColor(R.color.color4)},
                    new float[] { 0, 0.49f, 0.50f, 1 },  // positions
                    Shader.TileMode.CLAMP);
            return lg;
        }
    };
    PaintDrawable p = new PaintDrawable();
    p.setShape(new RectShape());
    p.setShaderFactory(sf);
    p.setCornerRadii(new float[] { 5, 5, 5, 5, 0, 0, 0, 0 });
    layers[0] = (Drawable) p;

    LayerDrawable composite = new LayerDrawable(layers);
    view.setBackgroundDrawable(composite);
} 

This is how I did it, in case anyone looking for a complete solution... Thanks to @Dave Morrissey for the help :)

XML code will be

<RelativeLayout
    android:id="@+id/layout4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center">

    <LinearLayout
        android:id="@+id/colorsLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <View
            android:id="@+id/bgGreen"
            android:layout_width="100dp"
            android:layout_height="25dp"
            android:background="#27F70C"/>
        <View
            android:id="@+id/bgAmber"
            android:layout_width="100dp"
            android:layout_height="25dp"
            android:background="#FFBF00"/>
        <View
            android:id="@+id/bgRed"
            android:layout_width="100dp"
            android:layout_height="25dp"
            android:background="#FC0505"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/seekBarLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    </LinearLayout>

</RelativeLayout>

Java code will be like

LinearLayout ll = (LinearLayout)findViewById(R.id.colorsLayout);
View viewGreen = (View)findViewById(R.id.bgGreen);
View viewAmber = (View)findViewById(R.id.bgAmber);
View viewRed = (View)findViewById(R.id.bgRed);

int sbMaxVal = 4999;
//Create RangeSeekBar as Integer range between 0 and sbMaxVal
seekBar = new RangeSeekBar(0, sbMaxVal, this);
seekBar.setNotifyWhileDragging(true);

//Add RangeSeekBar to Pre-defined layout
ViewGroup layout = (ViewGroup) findViewById(R.id.seekBarLayout);
layout.addView(seekBar);


//Set the onRangeChangeListener for the seekBar
seekBar.setOnRangeSeekBarChangeListener(new RangeSeekBar.OnRangeSeekBarChangeListener<Integer>() {
    @Override
    public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {

        int width = ll.getWidth();
        int minVal = (int) Math.floor((Integer.parseInt(amberValue)*width)/sbMaxVal);
        int maxVal = (int) Math.floor((Integer.parseInt(redValue)*width)/sbMaxVal);

        int wg = minVal;
        int wy = maxVal-minVal;
        int wr = ll.getWidth()-wg-wy;

        //Change the length of background views green,amber,red
        LinearLayout.LayoutParams paramsGreen = (LinearLayout.LayoutParams)
        viewGreen.getLayoutParams();
        paramsGreen.width = wg;
        viewGreen.setLayoutParams(paramsGreen);

        LinearLayout.LayoutParams paramsAmber = (LinearLayout.LayoutParams)
        viewAmber.getLayoutParams();
        paramsAmber.width = wy;
        viewAmber.setLayoutParams(paramsAmber);

        LinearLayout.LayoutParams paramsRed = (LinearLayout.LayoutParams)
        viewRed.getLayoutParams();
        paramsRed.width = wr ;
        viewRed.setLayoutParams(paramsRed);
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM