How to draw geometric shapes on buttons - java

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.

Related

Android custom views not being draw and canvas maximum size

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

Best way generate small solid circle on a blank screen in a specific position?

--> 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.

How to create a "fill-up" animation in Android

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.

Changing XML color from java code

I want a button shaped as a circle which i can change the background color of from my .java file.
I dont want to use circular images which change to accomplish this because i want to potentially use any hex color and i would need far too many images.
I have created an XML file called roundbutton which displays a round button by using 45 corner radius, but i need to be able to change the colour attribute(android:color="#ff0000" for instance)
from my .java
The round button displays ok right now but only displaying the colour i have set in the xml file, If I use buttonname.setBackgroundColor(Color.rgb(0, 255, 0)); the circle will be replaced by a square, so using the XML colour attribute would work if only i could change it from .java!
By the way im changing the colour of this round button on the press of another button.
hope this makes sense, thanks in advance!
XML circle:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ff0000" /> <<<<NEED TO CHANGE THE COLOUR CODE HERE FROM WITHIN .JAVA
<corners android:bottomRightRadius="45dp"
android:bottomLeftRadius="45dp"
android:topRightRadius="45dp"
android:topLeftRadius="45dp"/>
</shape>
Create another shape xml which have different color and access file using .setBackgroundColor(getResources().getColor(R.color.your_color_in_xmlfile));
use .setBackgroundColor(getResources().getColor(R.color.your_color_in_xmlfile)); in onClickListener() on button which you want to press for changing color else use
View.setBackgroundColor(Color.parseColor("#E7FC3A"));
and if you are using .java file i.e dunamically than dont set color from .xml file else it will not show effect on Orientation change

How to create a 10x10 grid in Android?

I am creating a small Battleship game and for the Android UI I was hoping to create a 10x10 grid of image buttons or something (anything easy).
I was following the tutorial provided at this link
My problem is that I can't get the images to display in a proper 10x10 format. Using the GridView, I set the num_columns to "10" in the XML but there is no such attribute for the number of rows.
As phone sizes differ, is there a way to have a 10x10 grid auto fit any screen?
By following the steps in the above link I can display 100 clickable images but my problem is with the formatting. Here's a screenshot of said result:
I've tried changing values in XML to scale the images down but cannot figure out how to. Apologies for lack of code snippets but I really haven't altered much from the sample given in the above link other than the vertical and horizontal spacing.
Would appreciate any enlightenment, even if it's just to say I am I going about this the wrong way completely.
You can achieve this with a table layout : http://www.mkyong.com/android/android-tablelayout-example/
GridViews, just as ListViews have been designed to contain any number of rows.
But I really doubt you want to use views in your game and not only use a canvas, draw anything and detect clicks without relying on views built-in mechanisms. It's more work but you end with something that will make you much more free to do what you want (for instance not having to deal with the number of rows of a container...)
go to this link and try 2nd example Custom Adapter example.
just change android:numColumns="auto_fit" to android:numColumns="10".
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridView1"
android:numColumns="10"
android:gravity="center"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</GridView>
You can probably do what you want with a GridLayout, but not with a GridView (which automatically scrolls vertically). Using a GridLayout, set all the buttons to have 0dp layout width and height, and set their layout gravity to fill.

Categories

Resources