I am trying to, somewhat clone the design of an activity from a set of slides on Android UI design. However I am having a problem with a very simple task.
I have created the layout as shown in the image, and the header is a TextView in a RelativeLayout. Now I wish to change the background colour of the RelativeLayout, however I cannot seem to figure out how.
I know I can set the android:background property in the RelativeLayout tag in the XML file, but what do I set it to? I want to define a new colour that I can use in multiple places. Is it a drawable or a string?
Additionally I would expect there to be a very simple way to this from within the Eclipse Android UI designer that I must be missing?
I am a bit frustrated currently, as this should be an activity that is performed with a few clicks at maximum. So any help is very appreciated. :)
You can use simple color resources, specified usually inside res/values/colors.xml.
<color name="red">#ffff0000</color>
and use this via android:background="#color/red". This color can be used anywhere else too, e.g. as a text color. Reference it in XML the same way, or get it in code via getResources().getColor(R.color.red).
You can also use any drawable resource as a background, use android:background="#drawable/mydrawable" for this (that means 9patch drawables, normal bitmaps, shape drawables, ..).
The above answers are nice.You can also go like this programmatically if you want
First, your layout should have an ID. Add it by writing following +id line in res/layout/*.xml
<RelativeLayout ...
...
android:id="#+id/your_layout_id"
...
</RelativeLayout>
Then, in your Java code, make following changes.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.your_layout_id);
rl.setBackgroundColor(Color.RED);
apart from this, if you have the color defined in colors.xml, then also you can do programmatically :
rl.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.red));
You can use android:background="#DC143C", or any other RGB values for your color. I have no problem using it this way, as stated here
The
res/values/colors.xml.
<color name="red">#ffff0000</color>
android:background="#color/red"
example didn't work for me, but the
android:background="#(hexidecimal here without these parenthesis)"
worked for me in the relative layout element as an attribute.
If you want to change a color quickly (and you don't have Hex numbers memorized) android has a few preset colors you can access like this:
android:background="#android:color/black"
There are 15 colors you can choose from which is nice for testing things out quickly, and you don't need to set up additional files.
Setting up a values/colors.xml file and using straight Hex like explained above will still work.
4 possible ways, use one you need.
1. Kotlin
val ll = findViewById<LinearLayout>(R.id.your_layout_id)
ll.setBackgroundColor(ContextCompat.getColor(this, R.color.white))
2. Data Binding
<LinearLayout
android:background="#{#color/white}"
OR more useful statement-
<LinearLayout
android:background="#{model.colorResId}"
3. XML
<LinearLayout
android:background="#FFFFFF"
<LinearLayout
android:background="#color/white"
4. Java
LinearLayout ll = (LinearLayout) findViewById(R.id.your_layout_id);
ll.setBackgroundColor(ContextCompat.getColor(this, R.color.white));
Android studio 2.1.2 (or possibly earlier) will let you pick from a color wheel:
I got this by adding the following to my layout:
android:background="#FFFFFF"
Then I clicked on the FFFFFF color and clicked on the lightbulb that appeared.
Kotlin
linearLayout.setBackgroundColor(Color.rgb(0xf4,0x43,0x36))
or
<color name="newColor">#f44336</color>
-
linearLayout.setBackgroundColor(ContextCompat.getColor(vista.context, R.color.newColor))
The answers above all are static. I thought I would provide a dynamic answer. The two files that will need to be in sync are the relative foo.xml with the layout and activity_bar.java which corresponds to the Java class corresponding to this R.layout.foo.
In foo.xml set an id for the entire layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/foo" .../>
And in activity_bar.java set the color in the onCreate():
public class activity_bar extends AppCompatActivty {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.foo);
//Set an id to the layout
RelativeLayout currentLayout =
(RelativeLayout) findViewById(R.id.foo);
currentLayout.setBackgroundColor(Color.RED);
...
}
...
}
I hope this helps.
Related
I've recently updated my phone to Android Marshmallow and ran my existing app on it, but noticed a difference in color behavior: When applying changes to the background of a view (drawable), all views that share the same background (reference) will also the same changes applied. While previously, this was not the case.
Example
In this example, I have a two views with the same background color, and I want to change the alpha level of one of both views.
First we define the views in the layout:
<LinearLayout
android:id="#+id/test1"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor2">
</LinearLayout>
<LinearLayout
android:id="#+id/test2"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor1"
android:layout_marginLeft="5dp">
</LinearLayout>
Both views share the same background color or drawable:
<color name="testColor1">#3F51B5</color>
<color name="testColor2">#3F51B5</color>
The result looks like this:
Now we are going to change one of the two background, like this:
LinearLayout test1 = (LinearLayout) findViewById(R.id.test1);
LinearLayout test2 = (LinearLayout) findViewById(R.id.test2);
test1.getBackground().setAlpha(80);
Which results in this:
However, the desired and expected result is obviously this:
Download the sample project here.
A few thoughs:
When setting the Alpha level trough XML, this behavior does not apply.
It does not matter if both views refer to a different color definition in colors.xml (like in the example), refer to the same color definition of both have the same color (hex) directly in the view's xml file.
Question
How can I make changes to a view's background without this affecting other views that share the same background. Preferably while still being able to use a background that directly refers to a color defined in the color's xml file
Most likely the class of each view's background and constantstate are
the same object. It seems as if the two color resources have been
"merged" somewhere -- meaning they have shared ConstantState. Maybe in
the Resources class' caching? I would've expected them to stay
separate since they're different resources (albeit with the same color
value), but apparently not.
– Snild Dolkow
The ColorDrawable's state stores alpha, so any changes to one will change the others. To prevent this, you can first call mutate() on the drawable, separating the two drawables (by making a copy of the state).
In the example, this would result in using test1.getBackground().mutate().setAlpha(80); instead of directly applying the alpha.
I've recently updated my phone to Android Marshmallow and ran my existing app on it, but noticed a difference in color behavior: When applying changes to the background of a view (drawable), all views that share the same background (reference) will also the same changes applied. While previously, this was not the case.
Example
In this example, I have a two views with the same background color, and I want to change the alpha level of one of both views.
First we define the views in the layout:
<LinearLayout
android:id="#+id/test1"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor2">
</LinearLayout>
<LinearLayout
android:id="#+id/test2"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor1"
android:layout_marginLeft="5dp">
</LinearLayout>
Both views share the same background color or drawable:
<color name="testColor1">#3F51B5</color>
<color name="testColor2">#3F51B5</color>
The result looks like this:
Now we are going to change one of the two background, like this:
LinearLayout test1 = (LinearLayout) findViewById(R.id.test1);
LinearLayout test2 = (LinearLayout) findViewById(R.id.test2);
test1.getBackground().setAlpha(80);
Which results in this:
However, the desired and expected result is obviously this:
Download the sample project here.
A few thoughs:
When setting the Alpha level trough XML, this behavior does not apply.
It does not matter if both views refer to a different color definition in colors.xml (like in the example), refer to the same color definition of both have the same color (hex) directly in the view's xml file.
Question
How can I make changes to a view's background without this affecting other views that share the same background. Preferably while still being able to use a background that directly refers to a color defined in the color's xml file
Most likely the class of each view's background and constantstate are
the same object. It seems as if the two color resources have been
"merged" somewhere -- meaning they have shared ConstantState. Maybe in
the Resources class' caching? I would've expected them to stay
separate since they're different resources (albeit with the same color
value), but apparently not.
– Snild Dolkow
The ColorDrawable's state stores alpha, so any changes to one will change the others. To prevent this, you can first call mutate() on the drawable, separating the two drawables (by making a copy of the state).
In the example, this would result in using test1.getBackground().mutate().setAlpha(80); instead of directly applying the alpha.
I want to customize Buttons for my application. The application has a color picker where the user will select color and I have to set that particular start/end color to the buttons. These colro values will be stored in an object "Utility".
Basically from start only, I want to use "Utility" object to set colors for background, text color, font, etc. And again when the color is changed by the user I got to change it to the buttons and refresh them. And also to save colors in a file, so next time user starts app, it comes up with the last color selected.
I couldn't find <selector> to be the best option, as I wont be able to change the color in xml. What can be the best option for such requirement ?
UPDATIONS :
#jitendra, from your answer I got somethign helpful. I use GradientDrawable to set colors of my buttons. In my onCreate() of the Activity, I call a method RefreshComponents() that sets the background of root, text color/size of buttons and gradient colors of the buttons. It works properly, but the only problem I see is the on applying GradientDrawable to the button the gap between 2 buttons is lost.
This is the image WITHOUT applying GradientDrawable :
On applying GradientDrawable the output is :
You see the size of button is increased a bit from all the sides. If I apply to next button also, they both touch eachother. My xml for the above is :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainroot" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical"
android:paddingTop="35dip" android:paddingBottom="35dip"
android:paddingLeft="35dip" android:paddingRight="35dip"android:gravity="center" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainrow1" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal"
android:layout_marginBottom="15dip" android:gravity="center_horizontal" >
<Button android:text="Accounting" android:id="#+id/accBtn" android:layout_width="80dip" style="#style/TileButtonStyle" />
<Button android:text="Data" android:id="#+id/dataBtn" android:layout_width="80dip" android:layout_height="fill_parent"></Button>
<Button android:text="Information" android:id="#+id/infoBtn" android:layout_width="80dip" android:layout_height="fill_parent" android:ellipsize="end"></Button>
</LinearLayout>
..... Other lineasr layout with same parameters as above child
And the GradientDrawable that I create is :
public static GradientDrawable getButtonDrawable(Button btn) {
int colors[] = {getStartColor(), getEndColor()};
GradientDrawable grad = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
grad.setCornerRadius(5f);
return grad;
}
And finally in my onCreate(), I add :
GradientDrawable btnGradient = Utility.getButtonDrawable(btn1);
btn1.setBackgroundDrawable(btnGradient);
What is going wrong here ? Is the margin around the button becoming 0 ? Do I have to set bounds for the grad, or again set LayoutParams for the button ?
Any help is appreciative to help me achieve my goal.
Thanks
You can Create StateListDrawable Object dynamically in java file and set as background and sources of applcation components.
Android has Themes and Styles, but they are a development-time feature and can't be manipulated at runtime. However, different predefined themes can be applied at runtime.
So you can have a set of predefined themes, with fixed view properties (colors, fonts, etc..) and give user an option to choose a theme at runtime.
But, if you need to change every particular view property, then you will need to roll your own "theme" system. Which means you will need to have properties stored somewhere and applied each time a view is built.
Tvd! I incline to agree with Peter Knego and Jitender Sharma. Furthermore, I think/believe you can setOnClickListener on those buttons of yours and perform your color changing stuff with the code that rests inside the setOnClickListenermethod assigned to every button. In addition to this, you'll have to configure your color.xml file and custom themes. There's a lot of work to be done. I'm not really sure which is the best way though. I strongly suggest you to go through the android learning stuff I'd provided to you in my previous answer. Only they can give you a detailed insight and a solid idea to go ahead. All the best!
Oh I got the solution :
I added layout_marginRight attribute to buttons and that did the work.
Though I am still concerned, without GradientDrawable the buttons had margin betweenthem then after applying GradientDrawable why is the default margin lost ? Why is the need of additional layout_marginRight to be added ?
If anyone yet has answer for this, please let me know.
Thanks
I have looked and tried a lot of different things but no matter what I end up doing the screen is always blank and I'm sure it's something really dumb I'm doing and I'm hoping someone will catch it.
I'm trying to alternate background colors but before I even get to that I need to get it so that even one background color will display properly.
First, my xml layout works fine and when I got to the layout view it displays the color just as I want it to. When I go to setContentView() in the activity that calls the xml it is never displayed and I only get a blank screen.
Second, since this initial issue described above I have tried several fixes and have numbered them accordingly. As I did a fix I usually only bothered to comment it out instead of deleting it after it didn't work. After certain lines there is a number, so if three lines have 1's behind them then those were the three lines used in attempt #1.
Third, while trying these fixes I added a colors xml file while I'll display as well.
Finally, I'll show my main activity first, xml file second, and colors file last. As you can see my ultimate goal would be to change the background dynamically but I can't even to get it to work normally right now. And FYI my splash screen works fine. But that's an image.
Thanks for you help.
public class Blink extends Activity {
long startTime= System.currentTimeMillis();
long now=0;//the current time in millis
public void OnCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//TextView backgroundColor=new TextView(this);2,3,4,5,6
//backgroundColor.setBackgroundColor(0xFFFF0000);5
//backgroundColor.setBackgroundResource(R.color.royalBlue);2,3,4
//backgroundColor.setVisibility(0);//make visible 3
setContentView(R.layout.blank);1
//setContentView(backgroundColor);4,5,6
//backgroundColor.setBackgroundColor(Color.argb(255, 255, 255, 255));6
//setContentView(R.layout.blink_blue);
//blink from royal blue to blank
/*while(true){
startTime= System.currentTimeMillis();
do{
now=System.currentTimeMillis();
setContentView(R.layout.blink_blue);
}while((-(startTime-now))>1000);
do{
now=System.currentTimeMillis();
setContentView(R.layout.blank);
}while((-(startTime-now))>1000);
}*/
}
This begins the xml file
//it is formatted properly but for some reason stack overflow doesn't like it so I'm only posting relevant lines.
//This is a Linear layout
android:id="#+id/blinkBlue"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/royalBlue"
This begins the colors file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="royalBlue">#4169e1</color>//Yes I have tried #FF4169e1 instead
<color name="plainBlue">#ff000000</color>
<color name="darkBlue">#ff000000</color>
<color name="black">#00000000</color>
<!-- I also know that the blues here aren't those colors... I'll change that when I fix this thing. -->
</resources>
You don't set colors that way, You specify colors of your Layouts that are defined in your XMLs and then you setContentView() to that XML file.
For example, lets pretend that your XML file has the name as my_layout.xml, then you have specified the color in my_color.xml so you go this way:
You write a layout in my_layout.xml
Now you write a resource XML for color as you have written above, and save it in the /res/values/my_color.xml
Set the layout (defined in my_layout.xml) background to be `android:background="#color/my_color"
in your code, use setContentView(R.layout.my_layout)
This will make my_layout.xml to be your content's layout and further the background color thing will be handled by the layout inside my_layout.xml file.
I hope that helps.
Take a look at using a state list drawable as a background. Each item can point to a shape drawable that specifies a different background color. Alternatively, use a shape drawable as a background that points to a color state list as the solid color.
If the built-in attributes available for defining a state list drawable or a color state list are not right for your application, you can use the technique shown in this thread to define your own.
I've got a custom drawable resource to display my items in a ListView, actually two because I wanted my results to have alternating background colors but both to respond to clicks by changing their color. The problem is even when assigning even one of these drawables to my LinearLayout container via the layout XML, it works fine, but via Java code it doesn't. So to be exact, this works:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/result_white"
android:id="#+id/result"
>
but this (in my ResultAdapter which extends ArrayAdapter) doesn't:
LinearLayout result = (LinearLayout) v.findViewById(R.id.result);
result.setBackgroundColor(R.drawable.result_white);
My final objective is of course to have alternating 'result_white' and 'result_ltgray' drawables for results so the first XML solution does not really satisfy my needs. What am I missing in the Java code please?
Well, assuming you are only using one-color backgrounds, you should use Colors instead since drawables can be shapes, gradients and more. Now, to actually use color, your code will look something like:
result.setBackgroundColor(mContext.getResources.getColor(R.color.result_white));
where mContext is the context, and you have a color (such as 0xFFFFFFFF) in your res/values/colors.xml file.
Also take a look at Color State Lists for changing colors when pressed / selected / etc
Thanks for your help guys, but what I needed to do is this:
result.setBackgroundResource(R.drawable.result_white);
This way I could easily implement this into my ResultAdapter for alternating results reacting to clicks with changing backgrounds:
LinearLayout result = (LinearLayout) v.findViewById(R.id.result);
if (position % 2 == 0)
result.setBackgroundResource(R.drawable.result_white);
else
result.setBackgroundResource(R.drawable.result_ltgray);
Make sure you imported the right reference for R (android.R for android drawables, your_app_path.R for your own).