◎위챗 : speedseoul
http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/
http://stackoverflow.com/questions/15643483/how-to-get-the-numpad-layout
http://www.techotopia.com/index.php/Using_the_Android_GridLayout_Manager_in_the_Graphical_Layout_Tool
http://rushabh138.blogspot.jp/2013/09/onscreen-number-pad-in-android.html
http://web.gccaz.edu/~dsmith9/CSC110AB/CSC110%20Course%20Materials/Minilabs/Minilab12/Calculator.java
At first glance, you might wonder why the new GridLayout class even exists in Android 4.0 (aka Ice Cream Sandwich). It sounds a lot like TableLayout. In fact, it’s a very useful new layout control. We’ll create a simple numeric keypad using GridLayout to demonstrate a small taste of its power and elegance.
GridLayout (android.widget.GridLayout) initially seems like it’s a way to create tables much like TableLayout (android.widget.TableLayout). However, it’s much more flexible than the TableLayout control. For instance, cells can span rows, unlike with TableLayout. Its flexibility, however, comes from the fact that it really helps to line up objects along the virtual grid lines created while building a view with GridLayout.
We provide the full source code for the sample application discussed in this tutorial. You can download the sample source code we provide for review.
The following shows a rough sketch of the keypad we will build.
Some things of note for the layout:
When designing a layout like this before GridLayout existed, we’d know that TableLayout use wouldn’t be feasible because of the row span. We’d likely resort to using a nested combination of LinearLayout controls—not the most efficient design. But in Android 4.0, there’s a more efficient control that suits our purposes: GridLayout.
GridLayout controls, like LinearLayout controls, can have horizontal and vertical orientations. That is, setting a vertical orientation means the next cell will be down a row from the current one and possibly moving right to the next column. Horizontal orientation means the next cell is to the right, and also possibly wrapping around to the next row, starting on the left.
For this keypad, if we start on the forward slash cell (/), and use horizontal orientation, no cells need be skipped. Choosing horizontal means we have to limit the number of columns to get the automatic wrapping to the next row at the correct location. In this example, there are 4 columns.
Finally, we want the View control in each cell (in this case, these are Button controls) to be centered and we want the whole layout to size itself to the content.
The following XML defines the GridLayout container we’ll need:
1 2 3 4 5 6 7 | android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_gravity = "center" android:columnCount = "4" android:orientation = "horizontal" > </ GridLayout > |
The child controls of the GridLayout control are defined a little differently than you might be used to. Instead of explicitly declaring a size (width & height) to a control with wrap_content or match_parent, the default is wrap_content for all children, and match_parent behaves the same as wrap_content as the sizing is controlled by different rules (which you can read all about in the GridLayout docs for creating more complex grid-aligned layouts).
Each cell will contain a single Button control with a text label. Therefore, each of the simple cells is merely defined as follows:
1 2 3 | < Button android:text = "1" /> < Button android:text = "2" /> <!-- and so on... --> |
If you just left that as-is, you’d end up with a layout looking like this:
Clearly, there’s more we can do here.
The current layout isn’t exactly what we want. The /, +, 0, and = Button controls are all special when it comes to laying them out properly. Let’s look at them:
Applying these subtle changes to the GridLayout results in the following XML definition:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?xml version= "1.0" encoding= "utf-8" ?> <GridLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_gravity= "center" android:columnCount= "4" android:orientation= "horizontal" > <Button android:layout_column= "3" android:text= "/" /> <Button android:text= "1" /> <!-- Other numbers --> <Button android:text= "9" /> <Button android:layout_rowSpan= "3" android:text= "+" /> <Button android:layout_columnSpan= "2" android:text= "0" /> <Button android:text= "00" /> <Button android:layout_columnSpan= "3" android:text= "=" /> </GridLayout> |
Are we there yet? You decide:
We’re getting there, but it’s not quite what we want yet, is it? The spanning is in place, but the cell content sizing isn’t quite right now.
The width and height values of the Button controls are not yet correct. You might immediately think that the solution is to adjust the layout_width and layout_height. But remember, the values for automatic scaling, just as wrap_content and match_parent, both behave the same and are already applied.
The solution is simple. In a GridLayout container, the layout_gravity attribute adjusts how each view control should be placed in the cell. Besides just controlling drawing centered or at the top, and other positioning values, the layout_gravity attribute can also adjust the size. Simply set layout_gravity to fill so each special case view control expands to the size of the container it’s in. In the case of GridLayout, the container is the cell.
Here’s our final layout XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_gravity = "center" android:columnCount = "4" android:orientation = "horizontal" > < Button android:layout_column = "3" android:text = "/" /> < Button android:text = "1" /> < Button android:text = "2" /> < Button android:text = "3" /> < Button android:text = "*" /> < Button android:text = "4" /> < Button android:text = "5" /> < Button android:text = "6" /> < Button android:text = "-" /> < Button android:text = "7" /> < Button android:text = "8" /> < Button android:text = "9" /> < Button android:layout_gravity = "fill" android:layout_rowSpan = "3" android:text = "+" /> < Button android:layout_columnSpan = "2" android:layout_gravity = "fill" android:text = "0" /> < Button android:text = "00" /> < Button android:layout_columnSpan = "3" android:layout_gravity = "fill" android:text = "=" /> </ GridLayout > |
And here’s the final result:
Finally, that’s exactly what we’re looking for!
While GridLayout isn’t just for use with items that line up in a regular sized table-like layout, it may be easier to use than TableLayout for such designs. Here you saw how it can provide a lot of flexibility and functionality with minimal configuration. However, any layout that can be defined in terms of grid lines — not just cells — can likely be done with less effort and better performance in a GridLayout than other container types. The new GridLayout control for Android 4.0 is very powerful and we’ve just scratched the surface of what it can do.
Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development, Second Edition and Sams Teach Yourself Android Application Development in 24 Hours, Second Edition. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to androidwirelessdev+mt@gmail.com, via their blog atandroidbook.blogspot.com, and on Twitter @androidwireless.