I'm trying to create a "fill-up" animation on a shape in Android. It should start being completely invisible and then gradually "fill up" from the bottom like this:
What I am specifically trying to animate is a circle such as this one:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#666666"/>
<size
android:width="120dp"
android:height="120dp"/>
</shape>
I have checked out the AlphaAnimation, RotateAnimation, ScaleAnimation and TranslateAnimation (sublasses of Animation) but I can't find a way to use them for this.
Here is how I eventually solved it:
I included this library from github https://github.com/lzyzsd/CircleProgress which contains a circular progress bar (CircleProgress). I added a countdowntimer to gradually increase the "progress" it is displaying
Here is the code:
final CircleProgress circularProgress =(CircleProgress)findViewById(R.id.circleProgress);
//Hides the text and the part of the circle which should not be shown
circularProgress.setUnfinishedColor(Color.parseColor("#00000000"));
circularProgress.setTextColor(Color.parseColor("#00000000"));
//Makes the circle red
circularProgress.setFinishedColor("#FF0000");
final int timeToCountDownMilis = 10000;
circularProgress.setMax(timeToCountDownMilis);
//Initiates and starts the countdowntimer which gradually increases the "progress" in the progress bar
new CountDownTimer(timeToCountDownMilis,70){
onTick(long milisUntilFinished){
circularProgress.setProgress(timeToCountDownMilis-(int)milisUntilFinished);
}
onFinish(){
}
}.start();
Thanks to Stan for pointing me to circular progress bars!
You could dig deep in Animations, like drawPath etc. What I should do in this case is simplier a bit:
-place a full red circle on a screen
-put a View with white bg over it (like a square), covering all the circle
-animate that white square View moving up revealing your circle
You could use a simple transition animation to do it.
That way it gonna looks like a filling animation you want.
Well, my answer was given following images you provide and it covers the target good enough. But if you wish something like a progress bar looking so, you should visit https://github.com/snowdream/awesome-android and check circular progress bar libs there, at least you'll maybe lern how to achieve your goal Or find out its already done.
Related
I have a button and I want to make an animation of going down. I made it but the functionality is left at the previous position(like the button moves but if I click on it, it doesn't work, but if I click its previous position it will work)
Animation logbtn = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.logbtnanim);
button.startAnimation(logbtn);
And the animation code is this.
P.S. Parent is the constraint layout.
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate
android:fromYDelta="0"
android:toYDelta="100"
android:duration="1000"/>
</set>
First of all you don't need the AnimatorSet Tag if you only have one animation. This is used if you want to play multiple animations together.
Second you are using TranslateAnimation which does not animate the Buttons property, it only moves the pixels on the screen, so after the animation, Android still thinks the view is at the old position, that is why it is still clickable there.
I suggest doing it in Java code using ViewPropertyAnimator something like :
button.animate().translationY(...f).duration(1000);
Or ObjectAnimator which is a little more flexible since you can also do it in xml.
I'm developing an application that has an embedded chat on it.
In order to draw the bubbles* where the text is displayed, I'm using a custom view which extends from FrameLayout, just like in here:
https://github.com/florent37/ShapeOfView/blob/master/shapeofview/src/main/java/com/github/florent37/shapeofview/ShapeOfView.java
or here:
https://github.com/MasayukiSuda/BubbleLayout/blob/master/bl/src/main/java/com/daasuu/bl/BubbleLayout.java
*bubbles -> you know: the rounded corner rectangle with a little arrow at the left or right, depending on who wrote the message
The thing is that, if the message to be shown is long enough (a couple of thousands of characters depending on the phone's memory) the background drawable is not shown anymore.
I found that this is expected because I'm exceeding the maximum canvas size (the maximum height, in this case)
I know that the canvas maximum size in android depends on the phone on which you are measuring it.
For example, this is the limit for an old phone (Moto G 1st gen):
And this is the limit for a newer phone, with more memory:
Question: Is there another way you can think of, to define a view with an arbitrary shape as the background which overcomes this limitation?
PD: Yes, the code looks strange because I'm using xamarin to develop, but the question is general enough, and I don't care the language of the solution if it does exist :)
UPDATE
Added example code to reproduce this issue.
You just have to create any background in xml, let's say that we call it "bubble_background.xml":
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
And then use it as background for a TextView, like in :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/cell_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:autoLink="all"
android:linksClickable="true"
android:textSize="#dimen/atlas_text_size_message_item"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
android:background="#drawable/bubble_background" />
</LinearLayout>
Now, if your text is long enough, the background won't be visible (it is a good idea to wrap the TextView in a ScrollView...)
UPDATE
This is the result of testing the background that was suggested by #cherryBu
Of course, I've got the same result because it is exactly what I was doing, but still, I had to test it, just in case, you know how this is.... :)
The top and bottom thin rectangles with round corners and the little triangle at the right (all in blue) are part of my current solution (one which doesn't make me happy but works: I'm "drawing" the bubble by composing it using those 3 partial images and setting the background of the text to the same color). The text is white, that's why you can't really see much of it. In the current code I'm setting the background to blue (not an image, because it can't be drawn -again :) -, only a plain color; the same as you can see in the other parts of the "bubble")
bubble_background.xml:
<?xml version="1.0" encoding="utf-8" ?>
<!-- For all properties see: http://developer.android.com/guide/topics/resources/menu-resource.html -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />
<padding
android:bottom="50dp"
android:left="50dp"
android:right="50dp"
android:top="50dp" />
<stroke android:width="10dp" android:color="#B2F7FE"/>
<solid android:color="#ffffff" />
</shape>
I use this as TextView background, I add very long text in it, but the shape still exist.
Update:
In case anyone is struggling with this issue: there is no solution and the maximum canvas size cannot be changed nor exceeded if you want to display a background like in this case.
Workaround solution, for my particular case:
Each bubble is composed using 4 items and a relative layout:
an image at the top, a thin blue/green rectangle with round top corners
an image at the bottom, a thin blue/green rectangle with round bottom corners
the text itself, with the same blue/green color set as background
a little blue/green triangle located at the right or left, according to who is sending the message to complete the chat bubble
I did not find any other solution and this one is working.
Of course, this won't work for you if you want to use an image instead of a plain color or simple pattern as backgournd
I'm the one who originally posted the question and the same which suggests the hacky and ugly solution from below.
I found a better and proper solution to this issue: the canvas size limit is only a problem when you have the Hardware acceleration turned on; so once I turned it off, I was able to render bubbles of any size.
The hardware acceleration can be customized in different ways and at different levels: Application, Activity, Window, or even at the View level, with some limitations.
For more information about what can and can't be done, please refer to the Goggle's documentation about this topic: https://developer.android.com/guide/topics/graphics/hardware-accel
We are making a quiz app as a school project where we are supposed to display a question and show 4 answers. For 8 seconds we are supposed to show 4 buttons with different geometric shapes of different colors(and text for the answer). Then when the timer hits zero the geometric shapes will change colors and switch positions. Then the buttons should be clickable and we can hit the correct answer.
My problem is that I can't find a way to draw these objects on a button, or anything clickable. I could have just used images of triangles, circles etc. on ImageButton, but as the objects need to change colors, it will be difficult. Here is a photo of what it is supposed to look like:
(edit) https://i.stack.imgur.com/05Far.png
Hope someone can help me with this, thanks.
Step 1
For creating geometrical shapes you will have to create a different xml file in the drawable folder for each shape. [for drawing circle you need to oval]. XML file should be like this:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="any_shape_name*" >
<stroke
//optional: for setting border.
android:dashGap="4dp"
android:dashWidth="10dp"
android:width="6dp"
android:color="#color/black" />
<solid android:color="#color/white" />
<padding
android:bottom="20dp"
android:left="20dp"
android:right="20dp"
android:top="20dp" /></shape>
Step 2
Create a button in main layout file and add this xml as the background
android:background = "#drawable/shape_file_name"
This was just a simple 2 step method.
Note:- You can also draw shapes dynamically and set them as the background of the button.
For this way please refer to this beautiful link.
Hope this helps.
--> a number of circles will be drawn over a period of time but only one will be shown on screen at a time.
--> user will click on the circle when the program registers the click, it will show the next circle.
--> the position of each circle is known, only they will appear randomly at different execution.
I have considered a linear layout filled with a lot of imageview(30 of them), every imageview has the same source, a small red dot, generated and stored in the res/drawable folder. code for the dot is:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Large red circle -->
<item>
<shape
android:shape="oval">
<stroke
android:width="0dp"
android:color="#000000" />
<solid android:color="#FF0000" />
<size
android:width="30dp"
android:height="30dp"/>
</shape>
</item>
I am thinking about using isVisible() on these imageviews to hide and show them at different times. this doesn't seem very efficient to me. any suggestions?
The best way to achieve that is to create a single custom View with onDraw overridden.
Then, inside onDraw you can simply draw as many circles as you want on the Canvas object. There are thousands of threads here on StackOverflow describing how to do that. E.g. this one.
Remember that you will have to call setWillNotDraw(false) on your View to cause your custom onDraw to be executed.
When the user clicks on the circle, simply record that even and call invalidate(). onDraw will be called once again and you can draw proper number of circles for the updated state.
Problem & Question:
I currently have a view pager, with just 2 pages/views inside it, which are next to each other horizontally.
My views are custom ones which draw a two-color gradient and an image over the top of it at a low opacity/alpha value.
I'm finding that when I swipe across the screen to move from the first view/page to the second or vice-versa, the images are getting squashed. How can I stop this from happening, and draw them normally?
Example:
The left image shows the first view that is visible, pre-swipe; the right image shows the two views, midway through swipe.
Code:
I have a Drawable variable I set earlier, overlayImage, that I have not done anything to other than setting opacity.
#Override
protected void onDraw(Canvas canvas) {
p.setShader(new LinearGradient(0, 0, 0, getHeight(), startColor, endColor, Shader.TileMode.MIRROR));
canvas.drawPaint(p);
//Pretty sure the mistake is around these two next lines
overlayImage.setBounds(canvas.getClipBounds());
overlayImage.draw(canvas);
}
I actually think it is in your
overlayImage.setBounds(canvas.getClipBounds());
line of code. When you are getting the clip bounds of the left most (swiping in the right most) view, it is getting the size of the viewable area (i.e. the smaller shrinking area) and thus the image is being drawn into that shrinking space.
You probably want to be setting the bounds by the overall size of the view it is being overlayn on, not the clipped bounds. Use instead getHeight() and getWidth() of the canvas and build up your own bounds.
I actually think that you really should setup the overlayImage bounds ONLY ONCE in your setup code. The draw code shouldnt necessarily need to set that up at all, then when the view begins to go off screen the drawing of the overlayImage will naturally move with the rest of the drawing canvas.
I think that you need to make a xml in the drawable-hdpi folder.
Which will contain your shader/linear gradiant.. (for options look here)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:startColor="#474946"
android:endColor="#181818"
android:angle="270"/>
</shape>
And then you can set the xml as background.. which should fix the problem i think.
(If it doesn't work try without the android:shape="rectangle", that might help)