Android中使用GridLayout網(wǎng)格布局來(lái)制作簡(jiǎn)單的計(jì)算器App
關(guān)于GridLayout
在android4.0版本之前,如果想要達(dá)到網(wǎng)格布局的效果,首先可以考慮使用最常見(jiàn)的LinearLayout布局,但是這樣的排布會(huì)產(chǎn)生如下幾點(diǎn)問(wèn)題:
1、不能同時(shí)在X,Y軸方向上進(jìn)行控件的對(duì)齊。
2、當(dāng)多層布局嵌套時(shí)會(huì)有性能問(wèn)題。
3、不能穩(wěn)定地支持一些支持自由編輯布局的工具。
其次考慮使用表格布局TabelLayout,這種方式會(huì)把包含的元素以行和列的形式進(jìn)行排列,每行為一個(gè)TableRow對(duì)象,也可以是一個(gè)View對(duì)象,而在TableRow中還可以繼續(xù)添加其他的控件,每添加一個(gè)子控件就成為一列。但是使用這種布局可能會(huì)出現(xiàn)不能將控件占據(jù)多個(gè)行或列的問(wèn)題,而且渲染速度也不能得到很好的保證。
android4.0以上版本出現(xiàn)的GridLayout布局解決了以上問(wèn)題。GridLayout布局使用虛細(xì)線將布局劃分為行、列和單元格,也支持一個(gè)控件在行、列上都有交錯(cuò)排列。而GridLayout使用的其實(shí)是跟LinearLayout類似的API,只不過(guò)是修改了一下相關(guān)的標(biāo)簽而已,所以對(duì)于開(kāi)發(fā)者來(lái)說(shuō),掌握GridLayout還是很容易的事情。GridLayout的布局策略簡(jiǎn)單分為以下三個(gè)部分:
首先它與LinearLayout布局一樣,也分為水平和垂直兩種方式,默認(rèn)是水平布局,一個(gè)控件挨著一個(gè)控件從左到右依次排列,但是通過(guò)指定android:columnCount設(shè)置列數(shù)的屬性后,控件會(huì)自動(dòng)換行進(jìn)行排列。另一方面,對(duì)于GridLayout布局中的子控件,默認(rèn)按照wrap_content的方式設(shè)置其顯示,這只需要在GridLayout布局中顯式聲明即可。
其次,若要指定某控件顯示在固定的行或列,只需設(shè)置該子控件的android:layout_row和android:layout_column屬性即可,但是需要注意:android:layout_row=”0”表示從第一行開(kāi)始,android:layout_column=”0”表示從第一列開(kāi)始,這與編程語(yǔ)言中一維數(shù)組的賦值情況類似。
最后,如果需要設(shè)置某控件跨越多行或多列,只需將該子控件的android:layout_rowSpan或者layout_columnSpan屬性設(shè)置為數(shù)值,再設(shè)置其layout_gravity屬性為fill即可,前一個(gè)設(shè)置表明該控件跨越的行數(shù)或列數(shù),后一個(gè)設(shè)置表明該控件填滿所跨越的整行或整列。
計(jì)算器實(shí)例

通過(guò)Android4.0 網(wǎng)格布局GridLayout來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的計(jì)算器界面布局 源碼如下(歡迎大家指導(dǎo) 批評(píng) ):
package com.android.xiong.gridlayoutTest;
import java.math.BigDecimal;
import java.util.regex.Pattern;
import com.android.xiong.gridlayoutTest.R.id;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
private EditText print;
private static String fistNumber = "0";// 第一次輸入的值
private static String secondNumber = "0";// 第二次輸入的值
private static String num = "0";// 顯示的結(jié)果
private static int flg = 0;// 結(jié)果累加一次
public Counts take = null;
private int[] btidTake = { R.id.txtdivide, R.id.txtx, R.id.txtmin,
R.id.txttakesum };
private Button[] buttonTake = new Button[btidTake.length];
private int[] btidNum = { R.id.txt0, R.id.txt1, R.id.txt2, R.id.txt3,
R.id.txt4, R.id.txt5, R.id.txt6, R.id.txt7, R.id.txt8, R.id.txt9,
R.id.txtspl };
private Button[] buttons = new Button[btidNum.length];
private int[] btcl = { R.id.chars, R.id.charx, R.id.txtb, R.id.txtv };
private Button[] btcls = new Button[btcl.length];
private GridLayout gly;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gly=(GridLayout)findViewById(R.id.gly);
print = (EditText) findViewById(R.id.print);
print.setText("0");
print.setEnabled(false);
GetNumber get = new GetNumber();
for (int i = 0; i < btidNum.length; i++) {
buttons[i] = (Button) findViewById(btidNum[i]);
buttons[i].setOnClickListener(get);
}
Compute cm = new Compute();
for (int i = 0; i < btidTake.length; i++) {
buttonTake[i] = (Button) findViewById(btidTake[i]);
buttonTake[i].setOnClickListener(cm);
}
Button eq = (Button) findViewById(R.id.txteq);
eq.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (flg == 0) {
secondNumber = print.getText().toString();
if (take == Counts.DIVIDE && secondNumber.equals("0")) {
print.setText("0不能為被除數(shù)");
} else {
num = take.Values(fistNumber, secondNumber);
fistNumber = num;
secondNumber = "0";
print.setText(num);
flg = 1;
gly.setBackgroundResource(R.drawable.jz);
}
}
}
});
Button cleargo = (Button) findViewById(R.id.cleargo);
cleargo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (num.length() > 1) {
num = num.substring(0, num.length() - 1);
} else {
num = "0";
}
print.setText(num);
}
});
Button clear = (Button) findViewById(R.id.clear);
clear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
num = "0";
fistNumber = secondNumber = num;
print.setText(num);
flg = 0;
}
});
for (int i = 0; i < btcl.length; i++) {
btcls[i] = (Button) findViewById(btcl[i]);
btcls[i].setOnClickListener(new OnTake());
}
}
// 給 EditText賦值
class GetNumber implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (flg == 1)
num = "0";
if (num.equals("0")) {
print.setText("");
num = v.getId() == R.id.txtspl ? "0" : "";
}
String txt = ((Button) v).getText().toString();
boolean s = Pattern.matches("-*(\\d+).?(\\d)*", num + txt);
num = s ? (num + txt) : num;
gly.setBackgroundResource(R.drawable.js);
print.setText(num);
}
}
// 根據(jù)條件計(jì)算
class Compute implements OnClickListener {
@Override
public void onClick(View arg0) {
fistNumber = print.getText().toString();
// TODO Auto-generated method stub
switch (arg0.getId()) {
case R.id.txttakesum:
take = Counts.ADD;
break;
case R.id.txtmin:
take = Counts.MINUS;
break;
case R.id.txtx:
take = Counts.MULTIPLY;
break;
case R.id.txtdivide:
take = Counts.DIVIDE;
break;
}
num = "0";
flg = 0;
gly.setBackgroundResource(R.drawable.js);
}
}
class OnTake implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.chars:
num = "-" + num;
break;
case R.id.charx:
if(!num.equals("0"))
num = BigDecimal.valueOf(1).divide(new BigDecimal(num),12,BigDecimal.ROUND_UP).stripTrailingZeros()
.toString();
break;
case R.id.txtb:
num = new BigDecimal(num).divide(BigDecimal.valueOf(100),12,BigDecimal.ROUND_UP).stripTrailingZeros()
.toString();
break;
case R.id.txtv:
Double numss = Math.sqrt(new BigDecimal(num).doubleValue());
int stratindex=numss.toString().contains(".")?numss.toString().indexOf("."):0;
num = numss.toString().length()>13?numss.toString().substring(0, 12+stratindex):numss.toString();
}
print.setText(num);
flg=0;
num = "0";
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
package com.android.xiong.gridlayoutTest;
import java.math.BigDecimal;
public enum Counts {
ADD, MINUS, MULTIPLY, DIVIDE, MARK, ROOT;
public String Values(String num1, String num2) {
BigDecimal number1 = new BigDecimal(num1);
BigDecimal number2 = new BigDecimal(num2);
BigDecimal number = BigDecimal.valueOf(0);
switch (this) {
case ADD:
number = number1.add(number2);
break;
case MINUS:
number = number1.subtract(number2);
break;
case MULTIPLY:
number = number1.multiply(number2);
break;
case DIVIDE:
number = number1.divide(number2,20,BigDecimal.ROUND_UP);
break;
}
return number.stripTrailingZeros().toString();
}
}
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40px"
android:columnCount="5"
android:rowCount="6"
tools:context=".MainActivity" >
<EditText
android:id="@+id/print"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="5"
android:layout_marginLeft="2px"
android:layout_marginRight="2px"
android:layout_row="0"
android:background="#eee" />
<Button
android:id="@+id/cleargo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_row="1"
android:text="《--" />
<Button
android:id="@+id/clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:layout_columnSpan="2"
android:layout_row="1"
android:layout_gravity="fill_horizontal"
android:text="清屏" />
<Button
android:id="@+id/chars"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_row="1"
android:text="-/+" />
<Button
android:id="@+id/charx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_row="1"
android:text="1/x" />
<Button
android:id="@+id/txt7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_row="2"
android:text="7" />
<Button
android:id="@+id/txt8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_row="2"
android:text="8" />
<Button
android:id="@+id/txt9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_row="2"
android:text="9" />
<Button
android:id="@+id/txtdivide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:layout_row="2"
android:text="÷" />
<Button
android:id="@+id/txtb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="4"
android:layout_row="2"
android:text="%" />
<Button
android:id="@+id/txt4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_row="3"
android:text="4" />
<Button
android:id="@+id/txt5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_row="3"
android:text="5" />
<Button
android:id="@+id/txt6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_row="3"
android:text="6" />
<Button
android:id="@+id/txtx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:layout_row="3"
android:text="X" />
<Button
android:id="@+id/txtv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="4"
android:layout_row="3"
android:text="√" />
<Button
android:id="@+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_row="4"
android:text="1" />
<Button
android:id="@+id/txt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_row="4"
android:text="2" />
<Button
android:id="@+id/txt3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_row="4"
android:text="3" />
<Button
android:id="@+id/txtmin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:layout_row="4"
android:text="-" />
<Button
android:id="@+id/txteq"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="4"
android:layout_gravity="fill_vertical"
android:layout_row="4"
android:layout_rowSpan="2"
android:text="=" />
<Button
android:id="@+id/txt0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_gravity="fill_horizontal"
android:layout_row="5"
android:text="0" />
<Button
android:id="@+id/txtspl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_row="5"
android:text="." />
<Button
android:id="@+id/txttakesum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:layout_row="5"
android:text="+" />
</GridLayout>
- 從零開(kāi)始學(xué)android實(shí)現(xiàn)計(jì)算器功能示例分享(計(jì)算器源碼)
- Android開(kāi)發(fā)實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器功能【附完整demo源碼下載】
- android計(jì)算器簡(jiǎn)單實(shí)現(xiàn)代碼
- Android計(jì)算器編寫(xiě)代碼
- android計(jì)時(shí)器,時(shí)間計(jì)算器的實(shí)現(xiàn)方法
- Android Studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器
- Android實(shí)現(xiàn)簡(jiǎn)易計(jì)算器小程序
- android studio實(shí)現(xiàn)計(jì)算器
- Android studio設(shè)計(jì)簡(jiǎn)易計(jì)算器
- Android簡(jiǎn)單實(shí)現(xiàn)計(jì)算器功能
相關(guān)文章
Android shell命令行中過(guò)濾adb logcat輸出的幾種方法
本文主要介紹Android shell命令行中過(guò)濾adb logcat輸出的方法,這里整理了幾種方法,并詳細(xì)的說(shuō)明,有需要的朋友可以參考下2016-08-08
Android編程之頁(yè)面切換測(cè)試實(shí)例
這篇文章主要介紹了Android編程之頁(yè)面切換測(cè)試,實(shí)例分析了Android實(shí)現(xiàn)頁(yè)面點(diǎn)擊切換的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
Android開(kāi)發(fā)之DOM解析xml文件的方法
這篇文章主要介紹了Android開(kāi)發(fā)之DOM解析xml文件的方法,涉及Android中DOM工廠對(duì)象的創(chuàng)建,文檔的獲取及節(jié)點(diǎn)的遍歷技巧,需要的朋友可以參考下2015-12-12
Compose?for?Desktop?鼠標(biāo)事件示例demo
這篇文章主要為大家介紹了Compose?for?Desktop?鼠標(biāo)事件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Android百度地圖實(shí)現(xiàn)搜索和定位及自定義圖標(biāo)繪制并點(diǎn)擊時(shí)彈出泡泡
這篇文章主要介紹了Android百度地圖實(shí)現(xiàn)搜索和定位及自定義圖標(biāo)繪制并點(diǎn)擊時(shí)彈出泡泡的相關(guān)資料,需要的朋友可以參考下2016-01-01
詳解Android 利用Iptables實(shí)現(xiàn)網(wǎng)絡(luò)黑白名單(防火墻)
這篇文章主要介紹了詳解Android 利用Iptables實(shí)現(xiàn)網(wǎng)絡(luò)黑白名單(防火墻),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Android viewpager自動(dòng)輪播和小圓點(diǎn)聯(lián)動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android viewpager自動(dòng)輪播和小圓點(diǎn)聯(lián)動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
Android Studio+MAT實(shí)戰(zhàn)內(nèi)存泄漏
這篇文章主要介紹了Android Studio+MAT實(shí)戰(zhàn)內(nèi)存泄漏的相關(guān)技術(shù)內(nèi)容,并在需要注意的地方做了提示,需要參考學(xué)習(xí)下吧。2017-12-12
Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解
這篇文章主要介紹了Android中使用socket通信實(shí)現(xiàn)消息推送的方法,文中舉了一個(gè)消息發(fā)送端和一個(gè)消息接收端以及服務(wù)器端的例子來(lái)說(shuō)明原理并且展示了客戶端的實(shí)現(xiàn),需要的朋友可以參考下2016-04-04

