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.
Related
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
Im working on an android app were you can setup your own Ring.
Now I want to give the user a preview of the ring, when they selected multiple rings.
Here a preview of how it should look like
The setup of how i thought to make it is this:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="5dp">
<ImageView
android:id="#+id/generator_ring_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#e7e7e7"/>
<FrameLayout
android:id="#+id/generator_ring_addon_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</FrameLayout>
I'm going to add the addon rings programmatically by just creating a new ImageView in the code.
Now the hard part of this is to place the image over the other ring, and have the view the same on every screen size..
Is ther anybody who can help me getting the correct code for placing the image on the correct position on every screen size?
thanks for reading
EDIT:
the moment I am selecting the addons rings the Base Rings is already visible, so I can get the height of the image
User Paint API: https://developer.android.com/reference/android/graphics/Paint.html
https://developer.android.com/reference/android/graphics/Canvas.html
Like that you can add whatever pictures you want, programatically, move them, even create animations if you want.
Also you will have just a view, which contains the canvas. So no need to have convoluted FrameLayouts into FrameLayouts.
Example on how to draw images on a canvas.
draw object/image on canvas
Using canvas you can get (x,y) coordinates of the ring.
First create canvas with ring image and than use canvas.draw() to draw another image on base image.
I have a problem with my ImageButton because it appears to be resizing together with the source image. This is quite problematic because I'm using a TableLayout with equally weighted TableRows to achieve a uniform grid layout but for some reason, that particular ImageButton is resizing itself with the image and making that entire row appear bigger than the others even if they all have the same layout weight.
empty src:
https://gyazo.com/b50ab6d7afb6608db0505d701a2a40c9
with src, adjustViewBounds=true
https://gyazo.com/e2a2dae581d1fae4503b6e130ced776d
with src, adjustViewBounds=false
https://gyazo.com/2623f08fcffea586d5b7917332ae7291
XML Tag:
<ImageButton
android:id="#+id/stat_analyze"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/sp2_calc_button"
android:onClick="btnClicked"
android:src="#drawable/statistics_white"
android:adjustViewBounds="true"
android:scaleType="fitCenter"/>
Update:
So far, I've tried replacing the source image which is a png with a smaller version and with an android vector resource replacement but so far, I've still been stuck with the same results. I guess that means the only way to do this really is to lock the layout height. I've tried programatically setting the height at runtime but I still get the same result.
Update:
I tried once again, resizing the image to a fixed value. I noticed, however, that this particular button does not take up the whole area until it reaches a height quite far beyond the intended height. What I mean by this is for example, I set it to 60dp, the entire row will already begin to take up more space even if the button itself hasn't matched the parent height yet. I don't know why this is happening as this is the first time I've seen this happen. Can someone help me with this?
Have you tried the scaleType fitXY attribute:
android:scaleType="fitXY"
I'm creating a bar at the top of my app much like the one above.
The graphics are embedded into the background and the numbers that represent the level etc is using TextViews.
As you can see the TextView has to be pixel(dp) perfect to fit in the center of the white bar thingy. With some margins or padding i can achieve that.
But how do games like that keep the same pixel perfect across all devices?
I know about resource qualifiers and such but some devices within the same bucket have different sizes.
Is there a good way or trick to achieve the perfect centering across most devices?
In general Android will handle the relative sizes across devices as long as you do everything in relative units and include 9-patch or images for each screensize.
For your question of how to handle images attached to a TextView, you can accomplish this a few ways.
A TextView will allow you to attach a drawable to it on the top, bottom, left, and right. You can do this with code using the various setCompoundDrawable* methods. For example, this will add a drawable to the right and left of the TextView.
txtScore.setCompoundDrawables(R.drawable.imageLeft, null, R.drawable.imageRight, null)
You can also do this in XML with the drawableLeft, etc properties. You may need to mess with padding and bounds for the drawables.
<TextView
android:id="#+id/txtScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="#drawable/imageLeft"
android:drawableRight="#drawable/imageRight"
android:drawablePadding="10dp"
android:singleLine="true"
android:text="125"/>
There are a number of different options in code as well if you look over those setCompoundDrawable type APIs for the TextView.
Your other option is to create your own View that does all of the work for you, but may be overkill if you only use it in one spot.
Again, you will really want to consider a 9-patch image or create an image for each screensize in the drawable folders. This will allow Android to determine which image to use for each device.
Let's say I have a LinearLayout set to vertical and i've added 100 views to it each view is 50dp high. A user is going to scroll and fling up and down on that LinearLayout.
I need to know the index numbers of the views that are on the screen. i.e if they fling down to the middle and stop, and see 5 items on their screen, i'd need to infer 50-55.
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#id/listing_main">
</LinearLayout>
I've tried a bunch of ways to infer the current visible views - like taking the scrollY position and the height of my items...doesn't seem to work out.
view.getScrollY() seems totally arbitrary compared to the other scroll mesurements
If you put them inside a list then you can use getFirstVisiblePosition() and getLastVisiblePosition() and use these to get all of them from first to last.
http://developer.android.com/reference/android/widget/AdapterView.html