【BMI指数计算器V2.0】项目实战

【BMI指数计算器V2.0】是建立在【BMI指数计算器V1.0】的基础上进行功能的增加,以版本迭代的方式循序渐进的进行Android核心技术的练习。

更新列表:
1.BMI计算标准选择
2.体重状态表情
3.输入框数据范围限制与判断
4.按钮点击效果,输入框背景效果
5.欢迎界面

项目效果图

静态效果图:

【BMI指数计算器V2.0】项目实战_第1张图片

【BMI指数计算器V2.0】项目实战_第2张图片

动态效果图:

项目结构

【BMI指数计算器V2.0】项目实战_第3张图片
注意:此项目是在依赖appcompat_v7_9项目下创建的,需要导入appcompat_v7_9并依赖此项目。

图片资源

按钮正常背景按钮按下时的背景

正常状态图标偏胖状态图标肥胖图标重度肥胖图标极重度肥胖图标

输入框背景图

【BMI指数计算器V2.0】项目实战_第4张图片

标题栏背景单选框未选中时的背景

界面开发

注册文件:AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kedi.bmi" android:versionCode="2" android:versionName="2.0" >
    <!-- 配置SDK的最小版本号为14,最大版本号为19 -->
    <uses-sdk  android:minSdkVersion="14" android:targetSdkVersion="19" />

    <application  android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >

        <!-- 注册主界面Activity -->
        <activity android:name=".MainActivity" >
        </activity>
        <!-- 注册欢迎界面Activity -->
        <activity android:name=".WelcomeActivity" >

            <!-- 配置action,category,使得WelcomeActivity成为第一启动界面 -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

字符串资源文件:values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- 字符串资源文件 -->
    <string name="app_name">BMI指数计算器</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="title">BMI指数计算器</string>
    <string name="height">您的身高</string>
    <string name="cm">(厘米)cm</string>
    <string name="weight">您的体重</string>
    <string name="kg">(千克)kg </string>
    <string name="cala">计算</string>
    <string name="clear">清除</string>
    <string name="weight_bmi">您的体重指数:</string>
    <string name="weight_state">您的体重状况:</string>
    <string name="tip1">身高不能为空</string>
    <string name="tip2">输入格式不正确</string>
    <string name="tip3">体重不能为空</string>
    <string name="standard_who">WHO标准</string>
    <string name="standard_area">亚洲标准</string>
    <string name="height_round">身高范围100~200</string>
    <string name="weight_round">体重范围30~150</string>

</resources>

尺寸资源文件:values/dimens.xml

<resources>

    <!-- 尺寸资源文件 -->
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="text_22">22sp</dimen>
    <dimen name="text_16">16sp</dimen>
    <dimen name="text_18">18sp</dimen>
    <dimen name="margin_40">40dp</dimen>
    <dimen name="margin_16">16dp</dimen>
    <dimen name="margin_14">14dp</dimen>
     <dimen name="padding_16">16dp</dimen>
    <dimen name="w_50">50dp</dimen>
     <dimen name="h_25">25dp</dimen>
</resources>

颜色资源文件:values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 颜色资源文件 -->
    <color name="white" >#ffffff</color>

</resources>

欢迎界面布局文件:layout/activity_welcome.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/welcome" >

</RelativeLayout>

主界面布局文件:layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/main" android:orientation="vertical" >

    <!-- 标题栏 -->

    <RelativeLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/title_bg" >

        <!-- 标题文本控件 -->

        <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/title" android:textColor="@color/white" android:textSize="@dimen/text_22" android:textStyle="bold" />
    </RelativeLayout>

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin_40" android:orientation="vertical" >

        <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="vertical" >

            <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" >

                <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/height" android:textColor="@color/white" android:textSize="@dimen/text_16" />

                <EditText  android:id="@+id/et_height" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/input_bg" android:gravity="center_horizontal" android:inputType="numberDecimal" android:singleLine="true" android:textSize="@dimen/text_16" >
                </EditText>

                <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/cm" android:textColor="@color/white" android:textSize="@dimen/text_16" />
            </LinearLayout>

            <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:baselineAligned="true" android:gravity="center_horizontal" android:orientation="horizontal" >

                <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/weight" android:textColor="@color/white" android:textSize="@dimen/text_16" />

                <EditText  android:id="@+id/et_weight" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/input_bg" android:gravity="center_horizontal" android:inputType="numberDecimal" android:singleLine="true" android:textSize="@dimen/text_16" />

                <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/kg" android:textColor="@color/white" android:textSize="@dimen/text_16" />
            </LinearLayout>
        </LinearLayout>
        <!-- 标准可选组布局 -->

        <RadioGroup  android:id="@+id/rg_standard" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="@dimen/margin_14" android:orientation="horizontal" >

            <!-- WHO标准单选按钮 -->

            <RadioButton  android:id="@+id/rb_who" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@drawable/rb_standard_bg" android:checked="true" android:text="@string/standard_who" android:textColor="@color/white" android:textSize="@dimen/margin_14" >
            </RadioButton>
            <!-- 亚洲标准单选按钮 -->

            <RadioButton  android:id="@+id/rb_area" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@drawable/rb_standard_bg" android:text="@string/standard_area" android:textColor="@color/white" android:textSize="@dimen/margin_14" >
            </RadioButton>
        </RadioGroup>

        <Button  android:id="@+id/btn_cala" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="@dimen/margin_16" android:background="@drawable/btn_cala_bg" android:text="@string/cala" android:textColor="@color/white" android:textSize="@dimen/text_18" />

        <LinearLayout  android:id="@+id/ll_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin_16" android:gravity="center_horizontal" android:orientation="vertical" >

            <LinearLayout  android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" >

                <ImageView  android:id="@+id/iv_state" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/r1" />

                <LinearLayout  android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/info" android:padding="@dimen/padding_16" android:layout_marginLeft="@dimen/margin_14" android:orientation="vertical" >

                    <TextView  android:id="@+id/tv_bmi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/weight_bmi" android:textColor="@color/white" android:textSize="@dimen/text_16" />

                    <TextView  android:id="@+id/tv_state" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/weight_state" android:textColor="@color/white" android:layout_marginTop="@dimen/margin_14" android:textSize="@dimen/text_16" />
                </LinearLayout>
            </LinearLayout>

            <Button  android:id="@+id/btn_clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="@dimen/margin_16" android:background="@drawable/btn_cala_bg" android:text="@string/clear" android:textColor="@color/white" android:textSize="@dimen/text_18" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

功能开发

欢迎界面:WelcomeActivity.java

package com.kedi.bmi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Window;

/** * 欢迎姐界面类 * * @author 科弟 * */
public class WelcomeActivity extends Activity {
    // 控制界面显示2秒执行界面挑转的类
    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //去掉系统标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //关联XML界面
        setContentView(R.layout.activity_welcome);
        //postDelayed()方法的作用:2000毫秒后执行某操作
        mHandler.postDelayed(new Runnable() {

            @Override
            public void run() {
                //意图类,指定界面跳转的源界面与目标界面
                Intent intent = new Intent(WelcomeActivity.this,
                        MainActivity.class);
                //执行跳转
                startActivity(intent);
                //关闭欢迎界面
                finish();
            }
        }, 2000);
    }
}

主界面:MainActivity.java

package com.kedi.bmi;

import java.text.DecimalFormat;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;

/** * BMI指数计算器主界面管理类 * * @author 科弟 * */
@SuppressLint("ShowToast")
public class MainActivity extends Activity implements OnClickListener, OnCheckedChangeListener {
    private EditText mHeightInputEt;// 身高输入框
    private EditText mWeightInputEt;// 体重输入框
    private Button mCalaBtn;// 计算按钮
    private LinearLayout mResultLl;// 计算结果布局
    private TextView mWeightBmiTv;// 体重指数文本
    private TextView mWeightStateTv;// 体重状态文本
    private Button mClearBtn;// 清除按钮
    private double height;// 身高
    private double weight;// 体重
    private double bmi;// bmi指数值
    private String state;// 体重状态
    private String weightBmi;// 您的体重指数:
    private String weightState;// 您的体重状况:
    private ImageView mStateIv;// 体重状态图标
    // 可取体重状态值数组
    private String[] states = { "偏瘦", "正常", "偏胖", "肥胖", "重度肥胖", "极重度肥胖" };
    private int[] state_imageIds = { R.drawable.r1, R.drawable.r2,
            R.drawable.r3, R.drawable.r4, R.drawable.r5, R.drawable.r6 };
    // 标准相关布局或控件
    private RadioGroup mStandardRg;// 标准可选组布局
    private RadioButton mWhoStandardRb;// WHO标准单选按钮
    private RadioButton mAreaStandardRb;// 亚洲标准单选按钮
    private static final int WHO_STANDARD = 0x1;// WHO标准
    private static final int AREA_STANDARD = 0x2;// 亚洲标准
    private int mCurrentStandard = WHO_STANDARD;// 当前标准
    private SharedPreferences sp;// 保存小量数据的类,数据会保存到指定文件名的XML文件中
    private static final String FILE_NAME = "data.xml";// 文件名

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 去掉系统标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 关联布局文件
        setContentView(R.layout.activity_main);
        // 初始化布局或控件
        initView();
        // 注册控件点击事件
        setViewListener();
        weightBmi = getResources().getString(R.string.weight_bmi);// 您的体重指数:
        weightState = getResources().getString(R.string.weight_state);// 您的体重状况:

    }

    /** * 初始化布局或控件的方法 */
    private void initView() {
        mHeightInputEt = (EditText) this.findViewById(R.id.et_height);// 身高输入框
        mWeightInputEt = (EditText) this.findViewById(R.id.et_weight);// 体重输入框
        mCalaBtn = (Button) this.findViewById(R.id.btn_cala);// 计算按钮
        mResultLl = (LinearLayout) this.findViewById(R.id.ll_result);// 计算结果布局
        mWeightBmiTv = (TextView) this.findViewById(R.id.tv_bmi);// 体重指数文本
        mWeightStateTv = (TextView) this.findViewById(R.id.tv_state);// 体重状态文本
        mStateIv = (ImageView) this.findViewById(R.id.iv_state);
        mClearBtn = (Button) this.findViewById(R.id.btn_clear);// 清除按钮
        // 默认显示计算按钮(VISIBLE),隐藏结果布局(GONE)
        mCalaBtn.setVisibility(View.VISIBLE);
        mResultLl.setVisibility(View.GONE);
        mStandardRg = (RadioGroup) this.findViewById(R.id.rg_standard);// 标准可选组布局
        mWhoStandardRb = (RadioButton) this.findViewById(R.id.rb_who);// WHO标准单选按钮
        mAreaStandardRb = (RadioButton) this.findViewById(R.id.rb_area);// 亚洲标准单选按钮
    }

    /** * 注册控件点击事件的方法 */
    private void setViewListener() {
        // 注册点击事件
        mCalaBtn.setOnClickListener(this);
        mClearBtn.setOnClickListener(this);
        // 注册选择事件
        mStandardRg.setOnCheckedChangeListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
        case R.id.btn_cala:
            // 计算逻辑
            // 获取身高输入框数据
            String heightStr = mHeightInputEt.getText().toString().trim();
            // 判断身高输入框数据是否为空
            if ("".equals(heightStr) || heightStr.length() == 0) {
                Toast.makeText(this, getResources().getString(R.string.tip1), 0)
                        .show();
            } else {
                try {
                    // 将String类型转化成Double类型
                    height = Double.valueOf(heightStr);
                    // 对身高数据范围进行判断(100.0~200.0)
                    if (height < 100.0 || height > 200.0) {
                        Toast.makeText(
                                this,
                                getResources().getString(R.string.height_round),
                                Toast.LENGTH_SHORT).show();
                    } else {
                        String weightStr = mWeightInputEt.getText().toString()
                                .trim();
                        // 体重数据非空判断
                        if ("".equals(weightStr) || weightStr.length() == 0) {
                            Toast.makeText(this,
                                    getResources().getString(R.string.tip3),
                                    Toast.LENGTH_SHORT).show();
                        } else {
                            try {
                                weight = Double.valueOf(weightStr);

                                // 体重数据范围判断(30.0~150.0)
                                if (weight < 30.0 || weight > 150.0) {
                                    Toast.makeText(
                                            this,
                                            getResources().getString(
                                                    R.string.weight_round),
                                            Toast.LENGTH_SHORT).show();
                                } else {
                                    // 计算bmi值
                                    calaBmi(mCurrentStandard);
                                    // 隐藏计算按钮(GONE),显示结果布局(VISIBLE)
                                    setViewVisible(false);
                                }

                            } catch (Exception e) {
                                Toast.makeText(
                                        this,
                                        getResources().getString(R.string.tip2),
                                        Toast.LENGTH_SHORT).show();
                            }

                        }
                    }

                } catch (Exception e) {
                    Toast.makeText(this,
                            getResources().getString(R.string.tip2),
                            Toast.LENGTH_SHORT).show();

                }

            }

            break;

        case R.id.btn_clear:
            // 清除
            setViewVisible(true);
            break;
        }
    }

    /** * 计算bmi值 */
    private void calaBmi(int standard) {
        // height/100.0 cm换算成m
        height = height / 100.0;
        bmi = weight / (height * height);
        if (standard == WHO_STANDARD) {

            if (bmi < 18.5) {
                state = states[0];
                mStateIv.setImageResource(state_imageIds[0]);
            } else if (bmi >= 18.5 && bmi <= 24.9) {
                state = states[1];
                mStateIv.setImageResource(state_imageIds[1]);
            } else if (bmi > 24.9 && bmi <= 29.9) {
                state = states[2];
                mStateIv.setImageResource(state_imageIds[2]);
            } else if (bmi > 29.9 && bmi <= 34.9) {
                state = states[3];
                mStateIv.setImageResource(state_imageIds[3]);
            } else if (bmi > 34.9 && bmi <= 39.9) {
                state = states[4];
                mStateIv.setImageResource(state_imageIds[4]);
            } else {
                state = states[5];
                mStateIv.setImageResource(state_imageIds[5]);
            }
        } else {
            if (bmi < 18.5) {
                state = states[0];
                mStateIv.setImageResource(state_imageIds[0]);
            } else if (bmi >= 18.5 && bmi <= 22.9) {
                state = states[1];
                mStateIv.setImageResource(state_imageIds[1]);
            } else if (bmi > 22.9 && bmi <= 24.9) {
                state = states[2];
                mStateIv.setImageResource(state_imageIds[2]);
            } else if (bmi > 24.9 && bmi <= 29.9) {
                state = states[3];
                mStateIv.setImageResource(state_imageIds[3]);
            } else if (bmi > 29.9 && bmi <= 39.9) {
                state = states[4];
                mStateIv.setImageResource(state_imageIds[4]);
            } else {
                state = states[5];
                mStateIv.setImageResource(state_imageIds[5]);
            }
        }

    }

    /** * 控制计算按钮与结果布局的显示与隐藏 * * @param visible */
    private void setViewVisible(boolean visible) {
        if (visible) {
            mCalaBtn.setVisibility(View.VISIBLE);
            mResultLl.setVisibility(View.GONE);
            // 清空数据
            mWeightBmiTv.setText("");
            mWeightStateTv.setText("");
            mHeightInputEt.setText("");
            mWeightInputEt.setText("");
            height = 0.0;
            weight = 0.0;
        } else {
            // 获得焦点
            mHeightInputEt.requestFocus();
            // 格式化数据的类
            DecimalFormat format = new DecimalFormat("0.0");
            mCalaBtn.setVisibility(View.GONE);
            mResultLl.setVisibility(View.VISIBLE);
            mWeightBmiTv.setText(weightBmi + format.format(bmi));
            mWeightStateTv.setText(weightState + state);

        }
    }

    @Override
    public void onCheckedChanged(RadioGroup rg, int arg1) {
        int id = rg.getCheckedRadioButtonId();
        switch (id) {
        case R.id.rb_who:
            // 选中Who单选按钮
            mCurrentStandard = WHO_STANDARD;
            break;

        case R.id.rb_area:
            // 选中亚洲单选按钮
            mCurrentStandard = AREA_STANDARD;
            break;

        default:
            mCurrentStandard = WHO_STANDARD;
            break;
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        // 获取当前用户选择的标准
        sp = this.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        mCurrentStandard = sp.getInt("standard", WHO_STANDARD);
        // 根据用户上次选择的标准初始化单选框的选择状态
        switch (mCurrentStandard) {
        case WHO_STANDARD:
            mWhoStandardRb.setChecked(true);
            mAreaStandardRb.setChecked(false);
            break;

        case AREA_STANDARD:
            mWhoStandardRb.setChecked(false);
            mAreaStandardRb.setChecked(true);
            break;

        default:
            mWhoStandardRb.setChecked(true);
            mAreaStandardRb.setChecked(false);
            break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 保存当前用户选择的标准
        sp = this.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        Editor editor = sp.edit();
        editor.putInt("standard", mCurrentStandard);
        editor.commit();
    }
}

源码下载

下载地址:http://download.csdn.net/detail/kedi_study/8935445

你可能感兴趣的:(android,迭代)