安卓非原创--基于Android Studio 实现的天气预报App

一、测试环境说明

电脑环境

Windows 11

编写语言

JAVA

开发软件

Android Studio (2020)

开发软件只要大于等于测试版本即可(近几年官网直接下载也可以),若是版本低于测试版本请自行测试。项目需要根据你的软件自行适配

二、项目简介

该项目简介来自网络,具体内容需要自行测试

本项目是一个基于Android平台的天气预报应用程序,采用Java语言开发,使用SQLite数据库进行用户数据存储。

系统实现了用户注册登录、地区选择和天气信息展示等核心功能。应用程序通过调用第三方天气API获取实时天气数据,并使用LitePal框架进行本地数据管理。

用户界面包含登录页面、注册页面和主天气展示页面,支持滑动刷新和自动更新功能。数据持久化方面,系统采用sp存储用户偏好设置和缓存数据,通过OkHttp进行网络通信。

服务层实现了后台自动更新天气数据的功能,通过AlarmManager定时触发数据更新。整体架构采用分层设计,将用户界面、业务逻辑和数据访问进行分离,保证了代码的可维护性和扩展性。

该应用不仅提供了准确的天气信息查询,还具有良好的用户体验和稳定的性能表现。

API地址:http://guolin.tech/api/weather......

三、项目演示

安卓非原创--基于Android studio 气预报App

四、部设计详情(部分)

登陆页

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f5f5f5"
    android:orientation="vertical"
    android:padding="20dp">

    <!-- 顶部标题区域 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp"
        android:layout_marginBottom="60dp"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:text="@string/login_title"
            android:textColor="#0077C2"
            android:textSize="28sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="欢迎回来,请登录您的账户"
            android:textColor="#5c5c5c"
            android:textSize="14sp" />
    </LinearLayout>

    <!-- 登录卡片 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:background="@drawable/rounded_card"
        android:backgroundTint="#FFFFFF"
        android:elevation="4dp"
        android:orientation="vertical"
        android:padding="24dp">

        <!-- 账号输入区域 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:background="@drawable/rounded_input"
            android:backgroundTint="#f5f5f5"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="16dp">

            <EditText
                android:id="@+id/edit_login_phone"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@null"
                android:hint="@string/login_hint_phone"
                android:inputType="number"
                android:padding="8dp"
                android:textColor="#333333"
                android:textColorHint="#5c5c5c"
                android:textSize="16sp" />
        </LinearLayout>

        <!-- 密码输入区域 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:background="@drawable/rounded_input"
            android:backgroundTint="#f5f5f5"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="16dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="12dp"
                android:text="@string/login_password"
                android:textColor="#333333"
                android:textSize="16sp" />

            <View
                android:layout_width="1dp"
                android:layout_height="20dp"
                android:layout_marginRight="12dp"
                android:background="#cccccc" />

            <EditText
                android:id="@+id/edit_login_password"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@null"
                android:hint="@string/login_hint_password"
                android:inputType="textPassword"
                android:padding="8dp"
                android:textColor="#333333"
                android:textColorHint="#5c5c5c"
                android:textSize="16sp" />
        </LinearLayout>

        <!-- 选项区域 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <CheckBox
                android:id="@+id/check_login_remember"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:buttonTint="#0077C2"
                android:text="@string/login_rememberPassword"
                android:textColor="#333333" />

          
        </LinearLayout>
    </LinearLayout>

    <!-- 登录按钮 -->
    <TextView
        android:id="@+id/tv_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/rounded_button"
        android:elevation="2dp"
        android:gravity="center"
        android:padding="16dp"
        android:text="立 即 登 录"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        android:textStyle="bold" />

</LinearLayout>

1.页面的结构

该登录页面采用经典的线性布局结构,整体分为三个主要功能区域。顶部区域包含账号和密码两个输入框,分别用于接收用户输入的手机号和密码信息。中部区域设计了一个记住密码的复选框选项,通过颜色变化直观反馈选中状态。底部区域并列放置了两个交互按钮,左侧是执行登录操作的主按钮,右侧则提供跳转至注册页面的入口链接。

页面布局层次分明,遵循用户习惯的视觉动线设计。输入区域占据页面显眼位置,确保用户能够快速定位核心操作。功能按钮区域通过色彩对比和间距控制,形成清晰的视觉分区。整个界面采用简洁明了的设计风格,避免过多装饰元素干扰用户操作流程。

2.使用到的技术

该页面基于Android原生开发框架,采用Java语言实现核心业务逻辑。数据持久化方面综合运用了SQLite数据库和SharedPreferences轻量级存储方案。数据库组件负责用户凭证的验证工作,通过预编译SQL语句实现安全的登录查询。本地偏好设置则用于保存用户登录状态和自动填充信息。

界面交互部分采用事件监听机制,通过实现点击监听接口统一处理用户操作。输入验证模块集成Android原生文本工具类,对空值情况进行实时检测。页面跳转通过显式意图实现组件间通信,并配合动画过渡效果提升用户体验。此外还运用资源颜色管理机制,实现复选框状态变化的动态视觉反馈。

3.页面详细介绍

该登录页面是典型的用户认证入口,主要承担身份验证和权限控制功能。页面启动时自动检测本地存储的登录偏好设置,若用户曾选择记住密码,则自动填充历史账号信息。核心登录流程包含三重验证机制:首先检测输入框非空校验,其次验证账户信息与数据库记录是否匹配,最后根据用户选择更新本地存储策略。

交互设计方面,记住密码功能提供个性化登录体验,复选框选中状态通过文字颜色变化提供明确视觉反馈。登录失败时会通过浮动提示框告知用户,成功认证则自动跳转至主界面并销毁当前页面。辅助功能设计考虑周全,提供注册入口降低新用户使用门槛,整体流程形成完整的用户认证闭环。

安全机制方面采用参数化查询防止SQL注入攻击,密码信息经过本地加密存储。页面生命周期内维护静态实例引用,便于其他组件获取当前认证状态。通过组合使用多种Android系统组件,在保证安全性的同时提供流畅的用户体验。

java 复制代码
    private void login() {
        if (TextUtils.isEmpty(mAccount.getText().toString())) {
            Toast.makeText(this, R.string.register_toast_noPhone, Toast.LENGTH_SHORT).show();
        } else {
            if (TextUtils.isEmpty(mPassword.getText().toString())) {
                Toast.makeText(this, R.string.register_toast_noPassword, Toast.LENGTH_SHORT).show();
            } else {

                if (mRemember.isChecked()) {
                    SharePreferenceUtils.writeRememder(  LoginActivity.this, true);
                    SharePreferenceUtils.writePassword(  LoginActivity.this, mPassword.getText().toString());
                } else {
                    SharePreferenceUtils.writeRememder(  LoginActivity.this, false);
                }
                SharePreferenceUtils.writePhone(  LoginActivity.this, mAccount.getText().toString());
                String userName = mAccount.getText().toString();
                String passWord = mPassword.getText().toString();
                if (login(userName, passWord)) {
                    Toast.makeText(  LoginActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();
                    startActivity(new Intent(  LoginActivity.this, MainActivity.class));
                    finish();
                } else {
                    Toast.makeText(  LoginActivity.this, "登陆失败", Toast.LENGTH_SHORT).show();
                }
            }

        }


    }

天气页

  1. 页面的结构

该天气应用页面采用经典的侧滑抽屉布局结构,整体分为三个主要部分。顶部是状态栏区域,通过透明化设计实现了沉浸式体验,让天气内容能够延伸到屏幕顶端。主体部分包含天气信息展示区,采用垂直滚动布局来容纳丰富的天气数据,包括当前温度、天气状况、未来多日预报以及生活指数建议等。左侧隐藏的导航抽屉可通过滑动或点击按钮唤出,用于切换城市或其他功能导航。

信息展示区内部采用分层组织方式,当前天气信息以突出形式显示在顶部,包含城市名称、更新时间和核心气象数据。中部区域为未来天气预报,以横向排列的卡片形式展示日期、天气图标和温度区间。底部区域专门显示空气质量指数和各类生活建议,包括舒适度、洗车指数和运动建议等实用信息。整个布局注重信息的层次感和可读性,通过合理的空间分配让用户能够快速获取关键天气信息。

  1. 使用到的技术

该应用采用了现代化的Android开发技术栈。数据获取方面基于OkHttp网络库实现异步HTTP请求,通过回调机制处理服务器响应,确保网络操作不会阻塞主线程。数据解析使用自定义的Utility工具类处理JSON格式的天气数据,将其转换为实体对象供界面使用。数据持久化通过SharedPreferences实现本地缓存,存储天气数据和背景图片URL,提升用户体验并减少网络请求次数。

界面交互方面集成多种Material Design组件,包括SwipeRefreshLayout实现下拉刷新功能,让用户能够手动更新天气数据。DrawerLayout管理侧滑菜单,提供导航功能。后台服务通过Intent启动自动更新服务,实现定时获取最新天气信息。图片加载方面虽然相关代码被注释,但预留了Glide库的集成接口用于加载必应每日一图。同时应用还处理了不同Android版本的兼容性问题,针对Android 5.0以上系统设置了透明状态栏。

  1. 页面详细介绍

天气主页面提供全面的气象信息服务,核心功能是展示当前和未来的天气状况。页面启动时会优先检查本地缓存,存在历史数据则立即显示,否则根据传入的城市编号从网络获取最新天气。数据显示方面,当前天气区域突出展示温度、天气状况和更新时间,让用户一眼就能获取最重要的信息。预报部分提供多日天气趋势,包括最高最低温度和天气状况图标,帮助用户规划未来活动。

页面还提供丰富的扩展功能,下拉刷新手势让用户能够随时手动更新数据,侧滑菜单为城市切换提供入口。生活指数建议基于实时气象数据给出实用指导,包括穿衣舒适度、洗车适宜度和运动建议等。空气质量数据显示让用户了解环境状况,特别是PM2.5指数的展示对健康防护具有参考价值。后台自动更新服务确保天气信息的时效性,而必应每日一图功能虽然暂时禁用,但为界面美化预留了扩展空间。整个页面设计以用户体验为中心,通过清晰的信息架构和流畅的交互操作,为用户提供专业可靠的天气查询服务。

java 复制代码
private void showWeatherInfo(Weather weather) {
        String cityName = weather.basic.cityName;
        String updateTime = weather.basic.update.updateTime.split(" ")[1];
        String degree = weather.now.temperature + "℃";
        String weatherInfo = weather.now.more.info;
        titleCity.setText(cityName);
        //titleUpdateTime.setText(updateTime);
        degreeText.setText(degree);
        weatherInfoText.setText(weatherInfo);
        forecastLayout.removeAllViews();
        for (Forecast forecast : weather.forecastList) {
            View view = LayoutInflater.from(this).inflate(R.layout.forecast_item, forecastLayout, false);
            TextView dateText = (TextView) view.findViewById(R.id.date_text);
            TextView infoText = (TextView) view.findViewById(R.id.info_text);
            TextView maxText = (TextView) view.findViewById(R.id.max_text);
            TextView minText = (TextView) view.findViewById(R.id.min_text);
            dateText.setText(forecast.date);
            infoText.setText(forecast.more.info);
            maxText.setText(forecast.temperature.max);
            minText.setText(forecast.temperature.min);
            forecastLayout.addView(view);
        }
        if (weather.aqi != null) {
            aqiText.setText(weather.aqi.city.aqi);
            pm25Text.setText(weather.aqi.city.pm25);
        }
        String comfort = "舒适度:" + weather.suggestion.comfort.info;
        String carWash = "洗车指数:" + weather.suggestion.carWash.info;
        String sport = "运行建议:" + weather.suggestion.sport.info;
        comfortText.setText(comfort);
        carWashText.setText(carWash);
        sportText.setText(sport);
        weatherLayout.setVisibility(View.VISIBLE);
        Intent intent = new Intent(this, AutoUpdateService.class);
        startService(intent);
    }

五、项目源码

👇👇👇👇👇快捷方式👇👇👇👇👇

相关推荐
清风6666663 小时前
基于单片机的智能收银机模拟系统设计
数据库·单片机·毕业设计·nosql·课程设计
大熊的瓜地5 小时前
Android automotive 框架
android·android car
私人珍藏库6 小时前
[Android] Alarm Clock Pro 11.1.0一款经典简约个性的时钟
android·时钟
非得登录才能看吗?6 小时前
VScode 入门(设置篇)
ide·vscode·编辑器
珹洺7 小时前
Java-Spring入门指南(二十七)Android Studio 第一个项目搭建与手机页面模拟器运行
java·spring·android studio
消失的旧时光-19438 小时前
ScheduledExecutorService
android·java·开发语言
小糖学代码8 小时前
MySQL:14.mysql connect
android·数据库·mysql·adb
Costrict9 小时前
解锁新阵地!CoStrict 现已支持 JetBrains 系列 IDE
大数据·ide·人工智能·深度学习·自然语言处理·ai编程·visual studio
AlphaFinance9 小时前
Windows下Vscode连接到WSL的方法
ide·vscode·编辑器