I'm trying something that would sound fairly easy to implement. However, it doesn't respond as expected. I'm using a Progressbar to draw a 5 state bar, where the user can click on any of the states to change the behavior of the application. My progressbar uses this drawable (just pay attention to the background element).
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#android:id/background">
<nine-patch
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/statusbar_thin" />
</item>
<item android:id="#android:id/secondaryProgress">
<clip>
<shape>
<gradient
android:endColor="#ffeeeeee"
android:startColor="#ffeeeeee" />
</shape>
</clip>
</item>
<item android:id="#android:id/progress">
<nine-patch
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/statusbar_thin" />
</item>
</layer-list>
This is the #drawable/statusbar_thin.
You may see they just don't look like vertically centered spots, but it doesn't matter. The problem is that, when the image is stretched (it's a 9 patch, as you may expect), the "superior black mark that expands the pixels below it" (I don't know how it's called. Anyone?) expands them randomly (By that I mean some parts expand twice more than others).
I'm not sure if there's a trick I didn't use, or it's just Android that uses indistinctly any block, instead of all of them evenly. Any ideas on that?
EDIT:
As #sandkasten suggested, I used the draw9patch application. However, as you see, it looks perfectly distributed, but on Nexus 7, it just doesn't work.
EDIT 2:
The status bar in black background. As you see, there's a big distance between the first and the second icon, while the selector is inbetween.
EDIT 3: Such an amazing world. I started playing with the top black marks, and, despite they weren't equally distributed at last, it worked.
If I understand you right, this should be the solution. Take a look at draw9patch.bat, which shows you a preview of your image and how android strech it. It's deliverd with the android sdk.
Related
I am trying to add a border to an alert dialog. I am hoping to make it look like this:
The best solution I have found thus far is to use a nine patch drawable as the background for the dialog.
The problem with this is that I have not found a way to make a nine patch background that actually gives the dialog a consistent white line around it. This has been my best attempt thus far (sorry it is a little hard to see...) :
The problem is that this produces a dialog like this:
The problems here are twofold; the lines at the sides are way too thick, and the lines at the top are kind of faded by the shadow.
My only ideas are to either find a working nine patch that gives a consistently thick border, or to find a way to get the 'main layout' of the alert dialog, so I can add a padding to that directly.
What is the best way to go about setting up a border on an Alert Dialog like this?
The answer by questioner was very close to what I wanted, but it still left a big black line around the dialog that I was not interested in.
I deleted one of the layers from the layer list, and customised the padding on the white border. I also did not set the background to transparent as suggested would be a good idea in the comments.
The shape the is inside the item is to give the background the same curved edges on a dialog (if you look really closely on 3.0+, you can see a few pixels of round corners).
In a dialog_border.xml file in the drawable folder, I had this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:top="6dp"
android:left="13dp"
android:right="13dp"
android:bottom="6dp">
<shape android:shape="rectangle" >
<solid android:color="#color/offWhite" />
<corners
android:radius="3dp"/>
</shape>
</item>
</layer-list>
And in my style I had this:
<style name="DialogTheme" parent="android:Theme.Holo.Dialog">
<item name="android:windowBackground">#drawable/dialog_border</item>
</style>
Although it could probably be set programatically rather than in the style if necessary.
In your dialog's xml set following background for top level view:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/white"/>
<item
android:bottom="1dp"
android:drawable="#color/black"
android:left="1dp"
android:right="2dp"
android:top="2dp">
</item>
</layer-list>
You can customise border width on each side.
I would like to create a ProgressBar with no background. I've been able to turn the background transparent, but there is still padding in the space where the background normally shows. Setting padding to 0 does not change this. Is it possible to achieve what I want without creating a custom drawable?
The issue is that the default 9Patch images used for ProgressBar have space around them. For example below is the standard holo_dark image used for the primary progress, secondary progress and background . As you can see, they each have areas of transparent space in their images.
progress_primary_holo_dark.9.png
progress_secondary_holo_dark.9.png
progress_bg_holo_dark.9.png
To achieve what you are after, you'll need to supply your own 9Patch images which do not have this extra space. Use setProgressDrawable() in your code or android:progressDrawable in xml, to set the Drawable for your ProgressBar.
You can combine all the necessary images in a single LayerList Drawable like the Android OS does. For example:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background"
android:drawable="#drawable/my_progress_bg" />
<item android:id="#android:id/secondaryProgress">
<scale android:scaleWidth="100%"
android:drawable="#drawable/my_progress_secondary" />
</item>
<item android:id="#android:id/progress">
<scale android:scaleWidth="100%"
android:drawable="#drawable/my_progress_primary" />
</item>
</layer-list>
You can find all the default graphic resources used by Android in the sdk/platforms/android-xx/data/res/ folder on the computer you're developing on.
in my current project I'm building an App with API 10 which should look like an ICS App.
Since my GUI is not very complex I can build this all manually, but I have some problems with button states.
I googled a lot and found nothing that would work for me so I would appreciate any help ;)
I designed an action bar with google ICS stock icons. When for example someone touches the search-loupe-icon, which has an 8dp padding around it, it's background color should change to a defined highlight-color-value.
So now you would suggest probably a selector drawable. But my case is: I have an icon-drawable which has an background-color, which I want to change. I dont want to change the icon, so since I cant change the backgroundcolor from a selector-xml this doesn't work.
(I thought I can setup multiple drawable-xml with my icon static bg colors so that I could refer with one selector to those different colored icons, but since a shape-drawable-xml cannot have a source and an bitmap-drawable-xml cannot have a background color, this is no sollution.)
If I try to change the background color in my onclick-listener (also tried onTouch) with:
ImageButton searchIcon = (ImageButton) findViewById(R.id.upper_actionbar_icon_search);
searchIcon.setBackgroundColor(R.color.android_ics_blue_light);
The Icon gets a dark grey bg color. This is also true for any other color altough nothing lies on top of the ImageButton. I also tried an ImageView.
So could someone explain to my please how the hell I can define a highlighted bg color-image without any hacks (default-gone image that lies above the icon and is set visible onclick).
Thanks so much!!
Okay the solution is simple.
Write yourself a drawable selector which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<item android:state_selected="true">
<shape android:shape="rectangle">
<solid android:color="#color/android_ics_blue_light"/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#color/android_ics_blue_light"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/light_grey"/>
</shape>
</item>
Within your ImageButton code define your icon as src and your new drawable as background, like this:
<ImageButton
<!-- ... -->
android:src="#drawable/icon_search"
android:background="#drawable/actionbar_ontouch"
/>
Works like a charm!
what I want to achieve is this:
As you can see there is are two tiny, yellow triangles (warning signs) in the EdiTtexts. I read, it's possible to achieve that by using Relative layout and simply have the images overlap the EditText. This however is not an option as I am writing a library project and can't limit the user to one particular layout type (such as RelativeLayout). Alternatively I read, it can be done in the onDraw method of a view. However, I will have no access to the onDraw method (or rather now way of overriding it). The one thing I have access to, is the Views itslef (like Spinner, EditText) or alternatively their wrapping view (Like LinearLayout etc...). I need to set this tiny icon not only on EditText but generally on Views such as Spinner, Button, EditText, etc....
One idea was to simply obtain the x/y coordinates of the View on which I want to draw that warning sign, but although I am able to get the coordinates I am quite at a loss as to how to actually do the drawing on the obtained view.
On an additional note: I am using code to generate the layout from non-android layout-xml files. That only matters in so far, that I am afraid android-layout-xml-based solutions are not an option. Furthermore I have to be able to dynamically add/remove those image overlays.
Please let me know, if there are further questions.
Thank you very much in advance & Best regards,
Ready4Android
EDIT
I had one idea but I am not sure how to carry it out: I could determine the on-screen coordinates of my Widgets (like Spinner, EditText, Button...) and then I could draw that little warning symbol on top of my canvas - without even touching the Widgets. So would it be easier to solve, if I just wanted to draw on the screen? It should be possible, non?
EDIT 2 (20.09)
I followed the advice from superM but since the Icon was stretched I tried to use a bitmap inside the item. Thing is: It places the icon at the correct place (left edge) but the skin of the button disappears - I guess because it's replaced by the bitmap...
Here is the original Button:
Here the Xml (the invisible shape is the same as in superM's post):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/sign_warning_overlay_shape"
android:top="5dip" android:right="5dip" android:bottom="5dip"
android:left="5dip" />
<item>
<bitmap android:src="#drawable/sign_warning" android:gravity="left" />
</item>
</layer-list>
and this is how it looks:
With the original posted layer list by superM - this one:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/sign_warning_overlay_shape"
android:top="5dip" android:right="5dip" android:bottom="5dip"
android:left="5dip" />
<item android:drawable="#drawable/sign_warning" android:top="5dip"
android:right="5dip" android:bottom="5dip" android:left="5dip" />
</layer-list>
the Button looks like this(seems like here too the icon replaces the button skin):
Could it be, that I am setting the layer list in a wrong way? What would be the correct code to set the layer list on a button? I am using this one:
button.setBackgroundResource(R.drawable.sign_warning_overlay_layer_list);
Edit 3 - Modified solution
This edit is based on the accepted answer - I decided to go for a bitmap embedded in an item because I had issues with the image being stretched - here is the layer_list:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:drawable/btn_default"
android:top="5dip" android:right="5dip" android:bottom="5dip"
android:left="5dip" />
<item>
<bitmap android:src="#drawable/sign_warning" android:gravity="left" />
</item>
</layer-list>
Which can be set on the button like this:
button.setBackgroundDrawable(button.getResources().getDrawable( R.drawable.layer_list));
and produces the following result:
That's it folks :) !
Thanks for all the suggestions & Cheers,
Ready4Android
In the case you mentioned, I think that what you want can be easily done by setting android:drawableLeft.
For editText it is editText.setCompoundDrawables(left, top, right, bottom) where left, top, right and bottom are either drawables or null. For buttons you can set the image as background by using a layer-list and shape, where the first layer is transparent and should "wrap" your button and the second layer is the image. This is can be done with other views too.
Here's an example of layer-list with transparent background:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="#android:drawable/btn_default" <!--any default background from android:drawable-->
android:top="5dip"
android:right="5dip"
android:bottom="5dip"
android:left="5dip" />
<item
android:drawable="#drawable/my_drawable"
android:top="0dip"
android:right="0dip"
android:bottom="0dip"
android:left="0dip" />
</layer-list>
where background_transparent is:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#android:color/transparent"/>
<padding
android:top="0dip"
android:left="3dip"
android:bottom="5dip"
android:right="3dip" />
<corners
android:radius="4dip" />
</shape>
Buttons:
Simply set the text
using code:
button.setText("<img src=\"image_location\"/>Login");
using xml:
android:text="#string/mystring"
//mystring must be a string in strings.xml
//with a value of <img src="image_location"/>Login
EditTexts:
Your question is not clear 100%...
If you want the image to be behind the text, then the best way to achieve this is by setting a background with that image to the left and let it be a 9patch image that extends the empty space.
If you want the image to move to the right with the text entered, then you have a couple of ways to achieve it, one simple would be to use a listener to the text input and always make sure there is an at the end of the text. I have not tested this approach but I guess it works fine.
If you really need to be able to place arbitrary views over anything, you can take a look at PopupWindow and use View.getLocationInWindow to get co-ordinates for the views you want to overlay. You can take a look at an android standard usage for putting a little error marker floating over a textview in TextView.setError
Using progress_horizontal.xml as a base drawable for my seekbar i was able to customize it pretty well. But unfortunately i stuck with the following problem. I need my progress to be made from two horizontal lines with different color something like this http://picasaweb.google.com/manigoad/Other#5442553107070487330 . In this case a blue line and transparent line below it.
So how can i make my progress to be made from two different colors.
Tnaks
I've had a look into creating the "stack" of shapes that you are looking for using "drawable" XML, but the padding/height values seem to be ignored.
There are two possible workarounds that I can think of:
Create a class that implements Drawable for the background and the progress and draw the custom colours/gradients yourself.
-OR-
Create a PNG of the background (on the right) and progress (on the left) from your mockups. About 30px wide should be fine (if you make them 1px wide, it will be put more pressure on the layout because it has to be repeated more times). Throw those in res/drawable/ and then load them into your styles using <bitmap>:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<bitmap android:src="#drawable/scroll_bg" />
</item>
<item android:id="#android:id/progress">
<clip>
<bitmap android:src="#drawable/scroll_progress" />
</clip>
</item>
</layer-list>