creating a gradient with certain effects in android - android

I understand how to create gradients using start color, end color, etc like below:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:type="radial" android:gradientRadius="260"
android:startColor="#A74171" android:endColor="#690136"/>
</shape>
But I dont understand how to bring about more complex effects. For Eg:- I am faced with a task of making a textview look like a button where it will look a little raised at the center, something like the image attached .
How can such an effect be brought by code without using images?

Here's the good news: Something like the button, shown in the picture, already exists. Maybe in other colors, but with a little painting you should get there easily. Check out the design downloads
When there're good news, than there might be some news with - lets say - more work involved. This link to Drawable Resource gives you an overview of what is possible with XML.
When you get out of XML possibilities, you must create your own Drawable, which is described here which is extremely powerful.
You can always paint your own drawings, load them as bitmap and use them. There you must be very sensitive on the size of the bitmap and the good looking (painted with enough pixels). I mysef have not found the right mix up to now.
All in all, in my experience, even the most complex XML drawables are quite efficient, whereas my own Drawables, painted at runtime are always a cause for lagging on the UI-Thread.

Related

Xamarin Android, How do you go about rotating a Vector Drawable?

Edit: see my own answer, I have added more detail as I have managed to get an animation working through XMLs, I cannot see why the code I have isn't doing the same thing.
I'm trying in Xamarin Android (not Forms) to display a couple of Vector Drawables and have one of the rotate on the other. The idea is a timer, a single hand going around a clock. I'm after the hand to appear to do a couple of full rotations then stop at a random angle. So it could stop at say 3 o'clock or 10 o'clock when it is done rotating.
I would have thought what I am trying to do would be done programmatically rather than via XMLs however I cannot find any good information to start me off on this. I'm not that familiar with base Android (I'm quite familiar with Xamarin Forms).
I can get both the face and the hand to display in an ImageView control. This I have done with both a layer-list.xml and a LayerDrawable. I have tried creating a RotateDrawable from the hand with a fromRotation and a toRotation set then applying that to LayerDrawbale. It does draw but not rotated.
The same applies in the layer-list xml, both draw, the hand is without rotation.
I have tried searching here and google, I cannot find anything solid so far to get me started. just snippets of XMLs. I feel I'm missing something very fundamental.
Any help is massively apricated.
This is the xml for the layerlist
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:drawable="#drawable/Clock"/>
<item>
<rotate
android:drawable="#drawable/Needle"
android:pivotX="50%"
android:pivotY="1%"
android:fromDegrees="0"
android:toDegrees="1080"
/>
</item>
</layer-list>
The code for the setting the layer-list to a Imageview.
ImageView clockDisplay = FindViewById<ImageView>(Resource.Id.ThreePlayers);
Drawable clock = VectorDrawableCompat.Create(Resources, Resource.Drawable.Clock, null);
clockDisplay.SetImageDrawable(clock);
/*
I have also used the following to no avail.
RotateDrawable clockRotate = new RotateDrawable();
clockRotate.Drawable = needle;
clockRotate.FromDegrees = 180;
clockRotate.ToDegrees = 180;
clockDisplay.SetImageDrawable(clockRotate);
*/
Cheers
Andy.
Edit: I've changed this answer completely from what it was.
from the suggestions in the comments of the main post, I have got the rotation working by rotating the image view.
I have created a test program here
that animates an ImageView with an AnimationSet and OhectAnimator, one using a Spring Animator and one that attempts to Animate the VectorDrawable directly in C#
The 1st two work as expected and is good enough for the project I am working on as all I need is rotation.
However is it not possible to Animate a VectorDrawable in C# without having animate the ImageView control?
If I creating a static animation in XMLs I could manipulate different layers of the VectorDrawable and Animate them Separately, surely this is possible to do in C#?
I'm starting to think it is not possible to do programmatically.|
Any advice?
Thanks.
Andy.

Create a pattern along the bottom edge of a view

I would like to have a pattern along the edge of a view. For this particular case, I would like it to be a jagged edge (like tearing parchment paper or tinfoil out of a roll). I would prefer a more general solution - perhaps at some point I would like waves along the top of a view, or a binder coil down the side. I would prefer to have some kind of repeating image rather than stretching an image.
Edit:
I would like a the pattern to occur just around the edge of the view (perhaps only on one edge). For example, a tear mark on the bottom or top of a receipt. The tear should not repeat up or down the image, just at the bottom edge.
Create a drawable (pattern_tile.xml) with the root element of a <bitmap>. Like this for instance:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:src="#drawable/bgnoise_lg"
android:tileMode="repeat" >
</bitmap>
And the drawable image used in the code above is:
Then, in your XML, you set it like you set the usual background using this attribute:
android:background="#drawable/pattern_tile"
Oh. Almost forgot, I put these two files, in the drawable-nodpi folder. I don't want Android to ever scale the image for me.
Obviously, since your question is a little vague, you will have to use your own image instead of the example I have posted, play around with it a bit till you get the result that suits your needs.
NOTE: Such a thing is typically done when you have patterns that should repeat instead of filling up the screen or stretching. So make sure the image you use is such a pattern that can repeat and not look out of place.

Nine-Patch Drawable vs Shape Drawable. Which should be preferred?

My co-worker and I developed two apps in parallel, each with similar styling. The main view background of these apps is a radial gradient. He implemented his as a nine-patch image and I did it with a shape drawable. Both generate similar and acceptable results.
So my question is, which should we use? Are there are trade-offs between memory consumption and performance? I imagine that the image could take time to load, but that the shape drawable takes more time to draw (due to calculations). Are these then stored in a cache and those penalties only happen the first time they are displayed or are these issues on-going???
Shape Drawable:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:startColor="#003472"
android:endColor="#000034"
android:gradientRadius="350"
android:type="radial"/>
</shape>
Nine Patch:
Shape drawable is great for gradient kind of images with simple constant color changes.
On the other hand, 9-patch images are great for images with lots of detail, constant color in streching regions.
Was just bumping into this problem earlier.
DO NOT USE SHAPE IN XML IF YOU HAVE ANIMATION THAT INVOLVES IT. The reason is that the caching (especially if you are using hardware acceleration on) will make it really seem "laggy" as the screen will not refresh as often.
Take a look at the answer given by #Ivan Bartsov. But through careful code analysis he concludes that for most general cases, using a 9 patch requires less process uses less memory than generated gradients. Therefore for most cases it's best to use 9 patches.
Take a look at his answer for mode details: What should i use for better performance, nine-patch or drawable xml resource?

Create Tiled Background from Image or <LinearLayout> / <GridView> etc

I am wondering as a new Android developer (10+ years C# OOP) which would be the better way to create a simple repeating background. The background will be consistent no matter the screen size, density, or orientation. I've read the Android Developers Dev Guide about things such as supporting multiple screens, nine patch drawables etc. I have seen tutorials such as this one (http://androidforbeginners.blogspot.com/2010/06/how-to-tile-background-image-in-android.html) telling you how you can use an image and get it to repeat.
Of course using an image then you have to provide multiple images for multiple densities or risk bitmap scaling and pixelation. For a complex background pattern I can see how this might be the way to go. But my pattern is a simple grid pattern so isn't there a better way using just xml?
I looked at GridView and TableLayout and both allowed me to set a background color, specify cell width / height, but I did not see a way to specify the grid line color.
For now I am using the slightly older 2.3.3 api as that is the largest version currently in use.
I don't suspect I'll need much hand holdong just some good solid advise from those who know better than I.
Thank You
JB
You can create a drawable like this:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="AndroidPuzzlesSolver/#drawable/bg_tile"
android:tileMode="repeat"
android:dither="true" />
Place the above in a "background.xml" file at the drawable folder. Then you can use it in your layout like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/background">
You can use a background with all Layouts.
I don't think there is an out-of-the-box way to do an alternate repeat, e.g. show one image at some places and another one in some others. If you want something like this, then you would probably need to implement your own View and override the onDraw method. You could use a FrameLayout to combine this background View with any other elements.

Is it possible to dither a gradient drawable?

I'm using the following drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<gradient
android:startColor="#color/content_background_gradient_start"
android:endColor="#color/content_background_gradient_end"
android:angle="270"
/>
</shape>
The problem is that I get severe banding on hdpi devices (like the Nexus One and Droid) since the gradient goes from the top of the screen to the very bottom.
According to http://idunnolol.com/android/drawables.html#shape_gradient there isn't a "dither" attribute for a gradient. Is there anything I can do to smooth the gradient?
Note: adding dither="true" to shape doesn't seem to work.
I wrote the documentation you referenced. I've taken another look at the code and unfortunately there's no way to enable dithering on a GradientDrawable except by explicitly calling GradientDrawable.setDither() in code.
(The way the codes looks, technically you could include the Gradient as the only child of a <selector>, and enable dithering on the entire selector; however, it's definitely a hack.)
I'm not convinced enabling dithering will actually solve your problem, as dithering (at least as it's noted in the official Android docs) are for solving banding problems when the device has too small of a color palette. This seems to be a banding problem due to the size of the gradient.
Hi all i have the same problem, there is one solution which works but it's not very good.
getWindow().setFormat(PixelFormat.RGBA_8888);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);
It works for me but the problem is that the whole windows is dithered. I was looking to find a way to dither only the gradient but i couldn't find anything. android:dither="true" in xml is not working and GradientDrawable.setDither(true) is also not working. So any ideas how can i dither only the gradient ?
I faced a very similar problem last year and came to no useful conclusion on the android-developers list.
However, a while ago I discovered — after trying <gradient> and all sorts of Drawables with various dither attributes and manually creating dithered PNGs — that if I manually create a new image using GIMP, and specify the density at this point (i.e. explicitly entering 120, or 240 etc) when creating the image, it looks great, even on hdpi devices. And this is despite it being a grayscale gradient, with not so many colours.
The PNG when saved ends up being comparatively large (at least for 240dpi), but it looks great.

Categories

Resources