目录
一、环境说明
二、项目简介
该项目是一个基于Android平台的天气预报应用,使用Android Studio开发工具和Java编程语言完成。
项目采用了SQLite数据库存储用户数据和地区信息,通过OkHttp实现网络请求获取天气数据,并结合Gson解析JSON格式的天气信息。
界面方面使用Material Design设计风格,包含抽屉导航、下拉刷新等功能,并支持后台服务定时更新天气数据。
主要功能包括:查看实时天气、未来预报、空气质量指数、生活建议等,同时实现了用户登录注册和数据缓存功能。
项目整合了第三方天气API和必应每日一图接口,是一个典型的Android移动端综合应用。
三、项目演示
网络资源模板--基于Android studio天气预报App
四、部设计详情(部分)
注册页面
package com.coolweather.android;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.coolweather.android.db.MyDBHelper;
import com.coolweather.android.util.SharePreferenceUtils;
public class RegisterActivity extends AppCompatActivity implements View.OnClickListener{
private EditText mAccount;
private EditText mPassword;
private EditText mAgain;
private MyDBHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
dbHelper = new MyDBHelper(this,"UserStore.db",null,1);
init();
}
private void init() {
mAccount = (EditText) findViewById(R.id.edit_login_phone);
mPassword = (EditText) findViewById(R.id.edit_login_password);
mAgain= (EditText) findViewById(R.id.edit_passwordAgain);
findViewById(R.id.tv_register).setOnClickListener(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (android.R.id.home == item.getItemId()) {
finish();
}
return true;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_register:
register();
break;
}
}
private void register() {
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 (!mPassword.getText().toString().equals(mAgain.getText().toString())){
Toast.makeText(this, R.string.register_same, Toast.LENGTH_SHORT).show();
}else{
if (CheckIsDataAlreadyInDBorNot(mAccount.getText().toString())) {
Toast.makeText(this,"该用户名已被注册,注册失败", Toast.LENGTH_SHORT).show();
}
else {
if (register(mAccount.getText().toString(), mPassword.getText().toString())) {
Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show();
startActivity(new Intent( RegisterActivity.this, MainActivity.class));
LoginActivity.instance.finish();
finish();
SharePreferenceUtils.writePhone( RegisterActivity.this, mAccount.getText().toString());
}
}
}
}
}
}
//向数据库插入数据
public boolean register(String username, String password){
SQLiteDatabase db= dbHelper.getWritableDatabase();
/*String sql = "insert into userData(name,password) value(?,?)";
Object obj[]={username,password};
db.execSQL(sql,obj);*/
ContentValues values=new ContentValues();
values.put("name",username);
values.put("password",password);
db.insert("userData",null,values);
db.close();
//db.execSQL("insert into userData (name,password) values (?,?)",new String[]{username,password});
return true;
}
//检验用户名是否已存在
public boolean CheckIsDataAlreadyInDBorNot(String value){
SQLiteDatabase db=dbHelper.getWritableDatabase();
String Query = "Select * from userData where name =?";
Cursor cursor = db.rawQuery(Query,new String[] { value });
if (cursor.getCount()>0){
cursor.close();
return true;
}
cursor.close();
return false;
}
}
注册功能是用户系统的核心组成部分,主要完成新用户的账号创建。本实现包含以下关键环节:
1. 用户输入账号和密码
2. 两次密码一致性验证
3. 账号唯一性检查
4. 信息存储至数据库
5. 注册成功后的页面跳转
注册界面包含三个输入框:账号输入框、密码输入框和密码确认框。当用户点击注册按钮时,系统会依次验证以下内容:
- 账号是否为空
- 密码是否为空
- 两次输入的密码是否一致
- 账号是否已被注册
每次验证不通过都会显示相应的提示信息,引导用户正确输入。所有验证通过后,用户信息才会被存入数据库。
数据操作使用了Android提供的两种方式:
1. ContentValues方式插入数据,这是Android推荐的标准做法,可以避免SQL注入风险
2. 原始SQL查询方式检查用户名是否存在,这种方式在简单查询中效率较高
首页
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg">
<ImageView
android:id="@+id/bing_pic_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
android:scaleType="centerCrop" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/weather_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<include layout="@layout/title" />
<include layout="@layout/now" />
<include layout="@layout/forecast" />
<include layout="@layout/aqi" />
<include layout="@layout/suggestion" />
</LinearLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
<fragment
android:id="@+id/choose_area_fragment"
android:name="com.coolweather.android.ChooseAreaFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
/>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
该天气应用采用标准的Android开发模式和流行开源库,实现了稳定可靠的天气查询功能。
通过合理的架构设计和细致的用户体验优化,为用户提供了直观、便捷的天气信息服务。
模块化的代码结构也为后续功能扩展和维护打下了良好基础。
天气数据请求流程
1) 检查本地是否有缓存数据
2) 无缓存则请求网络数据
3) 解析响应数据并更新UI
4) 同时缓存数据至SharedPreferences
5) 启动后台更新服务
异常处理机制
完善的网络请求错误处理:
- 请求失败时显示Toast提示
- 自动停止刷新动画
- 保留上次成功获取的数据
性能优化措施
- 使用轻量级的GSON解析JSON数据
- 图片加载采用Glide实现内存缓存
- 异步网络请求避免阻塞UI线程
- 合理使用View的可见性控制
五、项目源码
👇👇👇👇👇快捷方式👇👇👇👇👇