安卓非原创--基于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);
    }

五、项目源码

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

相关推荐
情爱少有真诚13 小时前
Java集合框架:数据存储与操作的利器
java·开发语言·经验分享·课程设计·ai编程
Lv117700813 小时前
Visual Studio中的接口
ide·笔记·c#·visual studio
2501_9160074713 小时前
iOS 证书如何创建,从能生成到能长期使用
android·macos·ios·小程序·uni-app·cocoa·iphone
Just_Paranoid14 小时前
【AOSP】Android Dump 信息快速定位方法
android·adb·framework·service·aosp·dumpsys
帅得不敢出门14 小时前
MTK Android11获取真实wifi mac地址
android·mtk
成都大菠萝14 小时前
2-2-16 快速掌握Kotlin-泛型扩展函数
android
I'm Jie14 小时前
Gradle 多模块依赖集中管理方案,Version Catalogs 详解(Kotlin DSL)
android·java·spring boot·kotlin·gradle·maven
BoomHe14 小时前
Android 13 (API 33)开发自己的 Settings ,如何配置 WiFi BT 权限
android
城东米粉儿14 小时前
ConcurrentHashMap实现原理 笔记
android
若数14 小时前
vscode如何打开多个标签
ide·vscode·编辑器