@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
@ -0,0 +1 @@
|
||||
My Application
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AppInsightsSettings">
|
||||
<option name="selectedTabId" value="Android Vitals" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-04-26T03:56:00.783649800Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=XWWGOZSCIRHYYHYL" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,61 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewParameterProviderOnFirstParameter" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="2.0.21" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings" defaultProject="true" />
|
||||
</project>
|
@ -0,0 +1,4 @@
|
||||
kotlin version: 2.0.21
|
||||
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
|
||||
1. Kotlin compile daemon is ready
|
||||
|
@ -0,0 +1 @@
|
||||
/build
|
@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,24 @@
|
||||
package com.example.myapplication
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.myapplication", appContext.packageName)
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.MinimalistWeather"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".WeatherActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".SettingsActivity"
|
||||
android:exported="false"
|
||||
android:label="设置"
|
||||
android:launchMode="singleTop"
|
||||
android:configChanges="uiMode|orientation|screenSize"
|
||||
android:theme="@style/Theme.MinimalistWeather"
|
||||
android:parentActivityName=".WeatherActivity" />
|
||||
<activity
|
||||
android:name=".CityManagerActivity"
|
||||
android:exported="false"
|
||||
android:label="城市管理"
|
||||
android:parentActivityName=".WeatherActivity" />
|
||||
<activity
|
||||
android:name=".OkhttpActivity"
|
||||
android:exported="false"
|
||||
android:label="OkHttp天气查询" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.MyApplication.Compose">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,252 @@
|
||||
package com.example.myapplication;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.myapplication.model.City;
|
||||
import com.example.myapplication.utils.CityManager;
|
||||
import com.example.myapplication.utils.SettingsManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 城市管理活动
|
||||
* 用于显示、添加、删除和选择城市
|
||||
*/
|
||||
public class CityManagerActivity extends AppCompatActivity {
|
||||
private static final String TAG = "CityManagerActivity";
|
||||
|
||||
private EditText etNewCity;
|
||||
private Button btnAddCity;
|
||||
private RecyclerView rvCities;
|
||||
private CityAdapter cityAdapter;
|
||||
private List<City> cityList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// 应用主题设置
|
||||
SettingsManager.applyThemeSetting(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_city_manager);
|
||||
|
||||
// 设置工具栏
|
||||
Toolbar toolbar = findViewById(R.id.city_manager_toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setTitle(R.string.city_favorites);
|
||||
}
|
||||
|
||||
// 初始化控件
|
||||
initViews();
|
||||
|
||||
// 设置监听器
|
||||
setupListeners();
|
||||
|
||||
// 加载城市列表
|
||||
loadCities();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
private void initViews() {
|
||||
etNewCity = findViewById(R.id.et_new_city);
|
||||
btnAddCity = findViewById(R.id.btn_add_city);
|
||||
rvCities = findViewById(R.id.rv_cities);
|
||||
|
||||
// 设置RecyclerView
|
||||
rvCities.setLayoutManager(new LinearLayoutManager(this));
|
||||
cityAdapter = new CityAdapter();
|
||||
rvCities.setAdapter(cityAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置监听器
|
||||
*/
|
||||
private void setupListeners() {
|
||||
btnAddCity.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String cityName = etNewCity.getText().toString().trim();
|
||||
if (cityName.isEmpty()) {
|
||||
Toast.makeText(CityManagerActivity.this, "请输入城市名称", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加城市到收藏列表
|
||||
boolean added = CityManager.addCity(CityManagerActivity.this, cityName, false);
|
||||
if (added) {
|
||||
Toast.makeText(CityManagerActivity.this,
|
||||
getString(R.string.city_added_to_favorites, cityName),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
etNewCity.setText("");
|
||||
|
||||
// 刷新城市列表
|
||||
loadCities();
|
||||
} else {
|
||||
Toast.makeText(CityManagerActivity.this,
|
||||
getString(R.string.city_already_in_favorites, cityName),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载城市列表
|
||||
*/
|
||||
private void loadCities() {
|
||||
cityList = CityManager.getAllCities(this);
|
||||
cityAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回按钮处理
|
||||
*/
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
// 返回主活动并刷新数据(使用平滑过渡)
|
||||
Intent intent = new Intent(this, WeatherActivity.class);
|
||||
intent.putExtra("refresh_settings", true);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(intent);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回键处理
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
// 返回主活动并刷新数据(使用平滑过渡)
|
||||
Intent intent = new Intent(this, WeatherActivity.class);
|
||||
intent.putExtra("refresh_settings", true);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(intent);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* 城市适配器
|
||||
*/
|
||||
private class CityAdapter extends RecyclerView.Adapter<CityAdapter.CityViewHolder> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public CityViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_city, parent, false);
|
||||
return new CityViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull CityViewHolder holder, int position) {
|
||||
City city = cityList.get(position);
|
||||
holder.tvCityName.setText(city.getName());
|
||||
|
||||
// 检查是否为暗黑模式
|
||||
boolean isDarkMode = SettingsManager.isDarkModeEnabled(CityManagerActivity.this);
|
||||
|
||||
// 设置选中状态
|
||||
if (city.isSelected()) {
|
||||
holder.tvCityName.setTextColor(getResources().getColor(R.color.colorPrimary));
|
||||
holder.tvCurrentCity.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
// 根据模式选择文字颜色
|
||||
if (isDarkMode) {
|
||||
holder.tvCityName.setTextColor(getResources().getColor(android.R.color.white));
|
||||
} else {
|
||||
holder.tvCityName.setTextColor(getResources().getColor(android.R.color.black));
|
||||
}
|
||||
holder.tvCurrentCity.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// 设置点击事件
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// 设置当前城市
|
||||
CityManager.setCurrentCity(CityManagerActivity.this, city.getName());
|
||||
|
||||
// 刷新列表
|
||||
loadCities();
|
||||
|
||||
Toast.makeText(CityManagerActivity.this,
|
||||
getString(R.string.set_as_current_city, city.getName()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
// 设置删除按钮点击事件
|
||||
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// 检查是否是最后一个城市
|
||||
if (cityList.size() <= 1) {
|
||||
Toast.makeText(CityManagerActivity.this,
|
||||
R.string.must_keep_one_city,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// 删除城市
|
||||
CityManager.deleteCity(CityManagerActivity.this, city.getName());
|
||||
|
||||
// 刷新列表
|
||||
loadCities();
|
||||
|
||||
Toast.makeText(CityManagerActivity.this,
|
||||
getString(R.string.city_deleted, city.getName()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cityList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 城市ViewHolder
|
||||
*/
|
||||
class CityViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvCityName;
|
||||
TextView tvCurrentCity;
|
||||
ImageButton btnDelete;
|
||||
|
||||
CityViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvCityName = itemView.findViewById(R.id.tv_city_name);
|
||||
tvCurrentCity = itemView.findViewById(R.id.tv_current_city);
|
||||
btnDelete = itemView.findViewById(R.id.btn_delete_city);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.example.myapplication.model;
|
||||
|
||||
/**
|
||||
* 城市信息数据模型
|
||||
*/
|
||||
public class City {
|
||||
private int id; // 城市ID
|
||||
private String name; // 城市名称
|
||||
private boolean isSelected; // 是否选中
|
||||
|
||||
// 构造方法
|
||||
public City() {
|
||||
}
|
||||
|
||||
public City(int id, String name, boolean isSelected) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.isSelected = isSelected;
|
||||
}
|
||||
|
||||
// getter和setter方法
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
isSelected = selected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "City{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", isSelected=" + isSelected +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package com.example.myapplication.model;
|
||||
|
||||
/**
|
||||
* 天气预报数据模型
|
||||
*/
|
||||
public class Forecast {
|
||||
private String date; // 预报日期
|
||||
private String week; // 星期
|
||||
private String dayWeather; // 白天天气
|
||||
private String nightWeather; // 夜间天气
|
||||
private int dayTemperature; // 白天温度
|
||||
private int nightTemperature; // 夜间温度
|
||||
private String dayWind; // 白天风向
|
||||
private String nightWind; // 夜间风向
|
||||
private String dayPower; // 白天风力
|
||||
private String nightPower; // 夜间风力
|
||||
|
||||
// 构造方法
|
||||
public Forecast() {
|
||||
}
|
||||
|
||||
public Forecast(String date, String week, String dayWeather, String nightWeather,
|
||||
int dayTemperature, int nightTemperature, String dayWind,
|
||||
String nightWind, String dayPower, String nightPower) {
|
||||
this.date = date;
|
||||
this.week = week;
|
||||
this.dayWeather = dayWeather;
|
||||
this.nightWeather = nightWeather;
|
||||
this.dayTemperature = dayTemperature;
|
||||
this.nightTemperature = nightTemperature;
|
||||
this.dayWind = dayWind;
|
||||
this.nightWind = nightWind;
|
||||
this.dayPower = dayPower;
|
||||
this.nightPower = nightPower;
|
||||
}
|
||||
|
||||
// getter和setter方法
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getWeek() {
|
||||
return week;
|
||||
}
|
||||
|
||||
public void setWeek(String week) {
|
||||
this.week = week;
|
||||
}
|
||||
|
||||
public String getDayWeather() {
|
||||
return dayWeather;
|
||||
}
|
||||
|
||||
public void setDayWeather(String dayWeather) {
|
||||
this.dayWeather = dayWeather;
|
||||
}
|
||||
|
||||
public String getNightWeather() {
|
||||
return nightWeather;
|
||||
}
|
||||
|
||||
public void setNightWeather(String nightWeather) {
|
||||
this.nightWeather = nightWeather;
|
||||
}
|
||||
|
||||
public int getDayTemperature() {
|
||||
return dayTemperature;
|
||||
}
|
||||
|
||||
public void setDayTemperature(int dayTemperature) {
|
||||
this.dayTemperature = dayTemperature;
|
||||
}
|
||||
|
||||
public int getNightTemperature() {
|
||||
return nightTemperature;
|
||||
}
|
||||
|
||||
public void setNightTemperature(int nightTemperature) {
|
||||
this.nightTemperature = nightTemperature;
|
||||
}
|
||||
|
||||
public String getDayWind() {
|
||||
return dayWind;
|
||||
}
|
||||
|
||||
public void setDayWind(String dayWind) {
|
||||
this.dayWind = dayWind;
|
||||
}
|
||||
|
||||
public String getNightWind() {
|
||||
return nightWind;
|
||||
}
|
||||
|
||||
public void setNightWind(String nightWind) {
|
||||
this.nightWind = nightWind;
|
||||
}
|
||||
|
||||
public String getDayPower() {
|
||||
return dayPower;
|
||||
}
|
||||
|
||||
public void setDayPower(String dayPower) {
|
||||
this.dayPower = dayPower;
|
||||
}
|
||||
|
||||
public String getNightPower() {
|
||||
return nightPower;
|
||||
}
|
||||
|
||||
public void setNightPower(String nightPower) {
|
||||
this.nightPower = nightPower;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Forecast{" +
|
||||
"date='" + date + '\'' +
|
||||
", week='" + week + '\'' +
|
||||
", dayWeather='" + dayWeather + '\'' +
|
||||
", nightWeather='" + nightWeather + '\'' +
|
||||
", dayTemperature=" + dayTemperature +
|
||||
", nightTemperature=" + nightTemperature +
|
||||
", dayWind='" + dayWind + '\'' +
|
||||
", nightWind='" + nightWind + '\'' +
|
||||
", dayPower='" + dayPower + '\'' +
|
||||
", nightPower='" + nightPower + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取温度范围字符串表示
|
||||
* @return 格式如"25°C ~ 18°C"
|
||||
*/
|
||||
public String getTemperatureRange() {
|
||||
return dayTemperature + "°C ~ " + nightTemperature + "°C";
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.example.myapplication.model;
|
||||
|
||||
/**
|
||||
* 天气预警信息数据模型
|
||||
*/
|
||||
public class WeatherAlert {
|
||||
private String title; // 预警标题
|
||||
private String content; // 预警内容
|
||||
private String level; // 预警级别 (红色,橙色,黄色,蓝色)
|
||||
private String type; // 预警类型
|
||||
private String publishTime; // 发布时间
|
||||
private String city; // 所属城市
|
||||
|
||||
// 构造方法
|
||||
public WeatherAlert() {
|
||||
}
|
||||
|
||||
public WeatherAlert(String title, String content, String level, String type,
|
||||
String publishTime, String city) {
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
this.level = level;
|
||||
this.type = type;
|
||||
this.publishTime = publishTime;
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
// getter和setter方法
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPublishTime() {
|
||||
return publishTime;
|
||||
}
|
||||
|
||||
public void setPublishTime(String publishTime) {
|
||||
this.publishTime = publishTime;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeatherAlert{" +
|
||||
"title='" + title + '\'' +
|
||||
", content='" + content + '\'' +
|
||||
", level='" + level + '\'' +
|
||||
", type='" + type + '\'' +
|
||||
", publishTime='" + publishTime + '\'' +
|
||||
", city='" + city + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package com.example.myapplication.model;
|
||||
|
||||
/**
|
||||
* 天气信息数据模型
|
||||
*/
|
||||
public class WeatherInfo {
|
||||
private String city; // 城市名称
|
||||
private String weather; // 天气状况
|
||||
private int temperature; // 温度
|
||||
private String windDirection; // 风向
|
||||
private String windPower; // 风力
|
||||
private int humidity; // 湿度
|
||||
private String reportTime; // 发布时间
|
||||
|
||||
// 构造方法
|
||||
public WeatherInfo() {
|
||||
}
|
||||
|
||||
public WeatherInfo(String city, String weather, int temperature,
|
||||
String windDirection, String windPower, int humidity,
|
||||
String reportTime) {
|
||||
this.city = city;
|
||||
this.weather = weather;
|
||||
this.temperature = temperature;
|
||||
this.windDirection = windDirection;
|
||||
this.windPower = windPower;
|
||||
this.humidity = humidity;
|
||||
this.reportTime = reportTime;
|
||||
}
|
||||
|
||||
// getter和setter方法
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getWeather() {
|
||||
return weather;
|
||||
}
|
||||
|
||||
public void setWeather(String weather) {
|
||||
this.weather = weather;
|
||||
}
|
||||
|
||||
public int getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(int temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
public String getWindDirection() {
|
||||
return windDirection;
|
||||
}
|
||||
|
||||
public void setWindDirection(String windDirection) {
|
||||
this.windDirection = windDirection;
|
||||
}
|
||||
|
||||
public String getWindPower() {
|
||||
return windPower;
|
||||
}
|
||||
|
||||
public void setWindPower(String windPower) {
|
||||
this.windPower = windPower;
|
||||
}
|
||||
|
||||
public int getHumidity() {
|
||||
return humidity;
|
||||
}
|
||||
|
||||
public void setHumidity(int humidity) {
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
public String getReportTime() {
|
||||
return reportTime;
|
||||
}
|
||||
|
||||
public void setReportTime(String reportTime) {
|
||||
this.reportTime = reportTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeatherInfo{" +
|
||||
"city='" + city + '\'' +
|
||||
", weather='" + weather + '\'' +
|
||||
", temperature=" + temperature +
|
||||
", windDirection='" + windDirection + '\'' +
|
||||
", windPower='" + windPower + '\'' +
|
||||
", humidity=" + humidity +
|
||||
", reportTime='" + reportTime + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
package com.example.myapplication.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.myapplication.R;
|
||||
import com.example.myapplication.model.WeatherAlert;
|
||||
import com.example.myapplication.utils.SettingsManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 天气预警适配器
|
||||
*/
|
||||
public class AlertAdapter extends RecyclerView.Adapter<AlertAdapter.AlertViewHolder> {
|
||||
|
||||
private Context context;
|
||||
private List<WeatherAlert> alertList;
|
||||
|
||||
public AlertAdapter(Context context, List<WeatherAlert> alertList) {
|
||||
this.context = context;
|
||||
this.alertList = alertList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AlertViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_alert, parent, false);
|
||||
return new AlertViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull AlertViewHolder holder, int position) {
|
||||
WeatherAlert alert = alertList.get(position);
|
||||
|
||||
// 设置预警标题
|
||||
holder.tvAlertTitle.setText(alert.getTitle());
|
||||
|
||||
// 设置预警内容
|
||||
holder.tvAlertContent.setText(alert.getContent());
|
||||
|
||||
// 设置预警时间
|
||||
holder.tvAlertTime.setText(alert.getPublishTime());
|
||||
|
||||
// 设置预警级别和图标
|
||||
String level = alert.getLevel();
|
||||
setAlertLevelIndicator(holder, level);
|
||||
|
||||
// 设置点击事件
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
Toast.makeText(context, alert.getTitle() + "\n" + alert.getContent(),
|
||||
Toast.LENGTH_LONG).show();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据预警级别设置不同的颜色和图标
|
||||
*/
|
||||
private void setAlertLevelIndicator(AlertViewHolder holder, String level) {
|
||||
int colorRes;
|
||||
int iconRes;
|
||||
|
||||
if (level.contains("红")) {
|
||||
colorRes = R.color.alert_red;
|
||||
iconRes = R.drawable.ic_alert_red;
|
||||
} else if (level.contains("橙")) {
|
||||
colorRes = R.color.alert_orange;
|
||||
iconRes = R.drawable.ic_alert_orange;
|
||||
} else if (level.contains("黄")) {
|
||||
colorRes = R.color.alert_yellow;
|
||||
iconRes = R.drawable.ic_alert_yellow;
|
||||
} else if (level.contains("蓝")) {
|
||||
colorRes = R.color.alert_blue;
|
||||
iconRes = R.drawable.ic_alert_blue;
|
||||
} else {
|
||||
colorRes = R.color.alert_default;
|
||||
iconRes = R.drawable.ic_alert_default;
|
||||
}
|
||||
|
||||
// 根据是否为暗黑模式获取适当的颜色
|
||||
int color = SettingsManager.getDarkModeColor(context, colorRes);
|
||||
|
||||
// 将颜色转换为80%不透明度(与主预警容器保持一致)
|
||||
int alpha = 204; // Alpha值为204表示80%不透明度
|
||||
int red = android.graphics.Color.red(color);
|
||||
int green = android.graphics.Color.green(color);
|
||||
int blue = android.graphics.Color.blue(color);
|
||||
int semiTransparentColor = android.graphics.Color.argb(alpha, red, green, blue);
|
||||
|
||||
holder.vAlertLevel.setBackgroundColor(semiTransparentColor);
|
||||
|
||||
// 设置图标(如果有图标资源)
|
||||
if (iconRes != 0) {
|
||||
holder.ivAlertIcon.setImageResource(iconRes);
|
||||
holder.ivAlertIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.ivAlertIcon.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return alertList == null ? 0 : alertList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 预警ViewHolder
|
||||
*/
|
||||
public static class AlertViewHolder extends RecyclerView.ViewHolder {
|
||||
View vAlertLevel; // 预警级别颜色指示器
|
||||
ImageView ivAlertIcon; // 预警图标
|
||||
TextView tvAlertTitle; // 预警标题
|
||||
TextView tvAlertContent; // 预警内容
|
||||
TextView tvAlertTime; // 预警时间
|
||||
|
||||
public AlertViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
vAlertLevel = itemView.findViewById(R.id.vAlertLevel);
|
||||
ivAlertIcon = itemView.findViewById(R.id.ivAlertIcon);
|
||||
tvAlertTitle = itemView.findViewById(R.id.tvAlertTitle);
|
||||
tvAlertContent = itemView.findViewById(R.id.tvAlertContent);
|
||||
tvAlertTime = itemView.findViewById(R.id.tvAlertTime);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.example.myapplication.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val Purple80 = Color(0xFFD0BCFF)
|
||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||
val Pink80 = Color(0xFFEFB8C8)
|
||||
|
||||
val Purple40 = Color(0xFF6650a4)
|
||||
val PurpleGrey40 = Color(0xFF625b71)
|
||||
val Pink40 = Color(0xFF7D5260)
|
@ -0,0 +1,58 @@
|
||||
package com.example.myapplication.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Purple80,
|
||||
secondary = PurpleGrey80,
|
||||
tertiary = Pink80
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Purple40,
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40
|
||||
|
||||
/* Other default colors to override
|
||||
background = Color(0xFFFFFBFE),
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onTertiary = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
*/
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun MyApplicationTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
// Dynamic color is available on Android 12+
|
||||
dynamicColor: Boolean = true,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
val context = LocalContext.current
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
}
|
||||
|
||||
darkTheme -> DarkColorScheme
|
||||
else -> LightColorScheme
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = Typography,
|
||||
content = content
|
||||
)
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.example.myapplication.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography = Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
/* Other default text styles to override
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
letterSpacing = 0.sp
|
||||
),
|
||||
labelSmall = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
*/
|
||||
)
|
@ -0,0 +1,33 @@
|
||||
package com.example.myapplication.utils;
|
||||
|
||||
/**
|
||||
* 天气API相关常量
|
||||
*/
|
||||
public class WeatherApiConstants {
|
||||
// 高德地图Web服务API的Key值 - 使用新的有效密钥
|
||||
public static final String AMAP_WEB_API_KEY = "3d9386dc59dc3b913037b7f67aa5d576";
|
||||
|
||||
// 天气查询API的基础URL
|
||||
public static final String WEATHER_BASE_URL = "https://restapi.amap.com/v3/weather/weatherInfo";
|
||||
|
||||
// 天气预警API的基础URL
|
||||
public static final String WEATHER_ALERT_URL = "https://restapi.amap.com/v3/weather/weatherInfo/alert";
|
||||
|
||||
// 请求参数名
|
||||
public static final String PARAM_KEY = "key"; // API密钥
|
||||
public static final String PARAM_CITY = "city"; // 城市编码
|
||||
public static final String PARAM_EXTENSIONS = "extensions"; // 气象类型
|
||||
public static final String PARAM_OUTPUT = "output"; // 返回格式
|
||||
|
||||
// 请求参数值
|
||||
public static final String VALUE_EXTENSIONS_BASE = "base"; // 返回实况天气
|
||||
public static final String VALUE_EXTENSIONS_ALL = "all"; // 返回预报天气
|
||||
public static final String VALUE_OUTPUT_JSON = "JSON"; // 返回JSON格式
|
||||
public static final String VALUE_OUTPUT_XML = "XML"; // 返回XML格式
|
||||
|
||||
// 预警级别常量
|
||||
public static final String ALERT_LEVEL_RED = "红色"; // 红色预警
|
||||
public static final String ALERT_LEVEL_ORANGE = "橙色"; // 橙色预警
|
||||
public static final String ALERT_LEVEL_YELLOW = "黄色"; // 黄色预警
|
||||
public static final String ALERT_LEVEL_BLUE = "蓝色"; // 蓝色预警
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 蓝天背景 -->
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#4A90E2"
|
||||
android:centerColor="#87CEEB"
|
||||
android:endColor="#1E90FF"
|
||||
android:type="linear" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 远处的山脉 -->
|
||||
<item android:top="250dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#478563"
|
||||
android:endColor="#224433"
|
||||
android:type="linear" />
|
||||
<corners
|
||||
android:topLeftRadius="120dp"
|
||||
android:topRightRadius="100dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 中间高耸的山峰 -->
|
||||
<item android:top="200dp" android:left="150dp" android:right="150dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#2E8B57"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners android:topLeftRadius="150dp" android:topRightRadius="30dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 右侧山峰 -->
|
||||
<item android:top="180dp" android:left="350dp" android:right="50dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#3CB371"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners android:topLeftRadius="100dp" android:topRightRadius="70dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 左侧较低的山 -->
|
||||
<item android:top="230dp" android:left="50dp" android:right="320dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#2E8B57"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners android:topLeftRadius="80dp" android:topRightRadius="120dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 水面 -->
|
||||
<item android:top="400dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#3d8a76"
|
||||
android:endColor="#70B8A9"
|
||||
android:type="linear" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 传统亭子/建筑 -->
|
||||
<item android:top="360dp" android:left="180dp" android:right="180dp" android:bottom="350dp">
|
||||
<shape>
|
||||
<solid android:color="#8B4513" /> <!-- 棕色 -->
|
||||
<corners android:radius="5dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 建筑屋顶 -->
|
||||
<item android:top="350dp" android:left="170dp" android:right="170dp" android:bottom="370dp">
|
||||
<shape>
|
||||
<solid android:color="#2F4F4F" /> <!-- 深灰绿色 -->
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵1 -->
|
||||
<item android:top="570dp" android:left="30dp" android:right="320dp" android:bottom="320dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵2 -->
|
||||
<item android:top="580dp" android:left="60dp" android:right="300dp" android:bottom="310dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵3 -->
|
||||
<item android:top="570dp" android:left="100dp" android:right="280dp" android:bottom="320dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵中心 -->
|
||||
<item android:top="575dp" android:left="35dp" android:right="325dp" android:bottom="325dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFF00" /> <!-- 黄色花心 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:top="585dp" android:left="65dp" android:right="305dp" android:bottom="315dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFF00" /> <!-- 黄色花心 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:top="575dp" android:left="105dp" android:right="285dp" android:bottom="325dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFF00" /> <!-- 黄色花心 -->
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 底层是景观图像 -->
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#87CEEB"
|
||||
android:endColor="#4682B4"
|
||||
android:type="linear" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 山脉 -->
|
||||
<item android:top="150dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#228B22"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners
|
||||
android:topLeftRadius="100dp"
|
||||
android:topRightRadius="70dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 右侧山峰 -->
|
||||
<item android:top="100dp" android:left="250dp" android:right="30dp">
|
||||
<shape>
|
||||
<solid android:color="#2E8B57" /> <!-- 海绿色 -->
|
||||
<corners android:topLeftRadius="80dp" android:topRightRadius="50dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 左侧山峰 -->
|
||||
<item android:top="130dp" android:left="50dp" android:right="200dp">
|
||||
<shape>
|
||||
<solid android:color="#3CB371" /> <!-- 中绿色 -->
|
||||
<corners android:topLeftRadius="60dp" android:topRightRadius="90dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 水面 -->
|
||||
<item android:top="350dp">
|
||||
<shape>
|
||||
<solid android:color="#5F9EA0" /> <!-- 淡蓝绿色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 传统建筑 -->
|
||||
<item android:top="300dp" android:left="150dp" android:right="150dp" android:bottom="200dp">
|
||||
<shape>
|
||||
<solid android:color="#8B4513" /> <!-- 棕色 -->
|
||||
<corners android:topLeftRadius="10dp" android:topRightRadius="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 屋顶 -->
|
||||
<item android:top="280dp" android:left="130dp" android:right="130dp" android:bottom="230dp">
|
||||
<shape>
|
||||
<solid android:color="#2F4F4F" /> <!-- 深灰绿色 -->
|
||||
<corners android:topLeftRadius="20dp" android:topRightRadius="20dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵1 -->
|
||||
<item android:top="450dp" android:left="30dp" android:right="320dp" android:bottom="450dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵2 -->
|
||||
<item android:top="470dp" android:left="70dp" android:right="290dp" android:bottom="430dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 半透明渐变层,确保数据能够显示 -->
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="#70FFFFFF" /> <!-- 更改为44%透明白色,确保数据清晰可见 -->
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 蓝天背景 -->
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#4A90E2"
|
||||
android:centerColor="#87CEEB"
|
||||
android:endColor="#1E90FF"
|
||||
android:type="linear" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 远处的山脉 -->
|
||||
<item android:top="250dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#478563"
|
||||
android:endColor="#224433"
|
||||
android:type="linear" />
|
||||
<corners
|
||||
android:topLeftRadius="120dp"
|
||||
android:topRightRadius="100dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 中间高耸的山峰 -->
|
||||
<item android:top="200dp" android:left="150dp" android:right="150dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#2E8B57"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners android:topLeftRadius="150dp" android:topRightRadius="30dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 右侧山峰 -->
|
||||
<item android:top="180dp" android:left="350dp" android:right="50dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#3CB371"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners android:topLeftRadius="100dp" android:topRightRadius="70dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 左侧较低的山 -->
|
||||
<item android:top="230dp" android:left="50dp" android:right="320dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#2E8B57"
|
||||
android:endColor="#006400"
|
||||
android:type="linear" />
|
||||
<corners android:topLeftRadius="80dp" android:topRightRadius="120dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 水面 -->
|
||||
<item android:top="400dp">
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#3d8a76"
|
||||
android:endColor="#70B8A9"
|
||||
android:type="linear" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 传统亭子/建筑 -->
|
||||
<item android:top="360dp" android:left="180dp" android:right="180dp" android:bottom="350dp">
|
||||
<shape>
|
||||
<solid android:color="#8B4513" /> <!-- 棕色 -->
|
||||
<corners android:radius="5dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 建筑屋顶 -->
|
||||
<item android:top="350dp" android:left="170dp" android:right="170dp" android:bottom="370dp">
|
||||
<shape>
|
||||
<solid android:color="#2F4F4F" /> <!-- 深灰绿色 -->
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵1 -->
|
||||
<item android:top="570dp" android:left="30dp" android:right="320dp" android:bottom="320dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵2 -->
|
||||
<item android:top="580dp" android:left="60dp" android:right="300dp" android:bottom="310dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵3 -->
|
||||
<item android:top="570dp" android:left="100dp" android:right="280dp" android:bottom="320dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF69B4" /> <!-- 粉红色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 粉色花朵中心 -->
|
||||
<item android:top="575dp" android:left="35dp" android:right="325dp" android:bottom="325dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFF00" /> <!-- 黄色花心 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:top="585dp" android:left="65dp" android:right="305dp" android:bottom="315dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFF00" /> <!-- 黄色花心 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:top="575dp" android:left="105dp" android:right="285dp" android:bottom="325dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FFFF00" /> <!-- 黄色花心 -->
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19.36,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.64,-4.96z"/>
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#B8D0E6"
|
||||
android:centerColor="#9AB9D3"
|
||||
android:endColor="#7A9CBE"
|
||||
android:type="linear" />
|
||||
</shape>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#60FFFFFF" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#40CCCCCC" />
|
||||
<padding
|
||||
android:left="8dp"
|
||||
android:top="8dp"
|
||||
android:right="8dp"
|
||||
android:bottom="8dp" />
|
||||
</shape>
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M17.66,8L12,8l-1.88,-2L4,6l1.88,2L4,10l1.88,2L4,14l1.88,2L4,18l1.88,2L4,22h12c3.31,0 6,-2.69 6,-6L22,12C22,9.79 20.21,8 18,8h-0.34zM18,16h-4v-2h4v2zM18,12h-4v-2h4v2z"/>
|
||||
<path
|
||||
android:fillColor="#0000CD"
|
||||
android:pathData="M7,13l2,6 2,-6h-4z"/>
|
||||
<path
|
||||
android:fillColor="#0000CD"
|
||||
android:pathData="M11,13l2,6 2,-6h-4z"/>
|
||||
<path
|
||||
android:fillColor="#0000CD"
|
||||
android:pathData="M15,13l2,6 2,-6h-4z"/>
|
||||
</vector>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/alert_blue">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||
</vector>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/alert_default">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||
</vector>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/alert_orange">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||
</vector>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/alert_red">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||
</vector>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/alert_yellow">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||
</vector>
|
@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M17.66,8L12,8l-1.88,-2L4,6l1.88,2L4,10l1.88,2L4,14l1.88,2L4,18l1.88,2L4,22h12c3.31,0 6,-2.69 6,-6L22,12C22,9.79 20.21,8 18,8h-0.34zM18,16h-4v-2h4v2zM18,12h-4v-2h4v2z"/>
|
||||
<path
|
||||
android:fillColor="#00BFFF"
|
||||
android:pathData="M8,14l2,6 2,-6h-4z"/>
|
||||
</vector>
|
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M17.66,8L12,8l-1.88,-2L4,6l1.88,2L4,10l1.88,2L4,14l1.88,2L4,18l1.88,2L4,22h12c3.31,0 6,-2.69 6,-6L22,12C22,9.79 20.21,8 18,8h-0.34zM18,16h-4v-2h4v2zM18,12h-4v-2h4v2z"/>
|
||||
<path
|
||||
android:fillColor="#1E90FF"
|
||||
android:pathData="M8,13l2,6 2,-6h-4z"/>
|
||||
<path
|
||||
android:fillColor="#1E90FF"
|
||||
android:pathData="M14,13l2,6 2,-6h-4z"/>
|
||||
</vector>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#A9A9A9"
|
||||
android:pathData="M19.36,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.64,-4.96z"/>
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#546A7B"
|
||||
android:centerColor="#465C6D"
|
||||
android:endColor="#38485A"
|
||||
android:type="linear" />
|
||||
</shape>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#60FFFFFF" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#40CCCCCC" />
|
||||
<padding
|
||||
android:left="16dp"
|
||||
android:top="8dp"
|
||||
android:right="16dp"
|
||||
android:bottom="8dp" />
|
||||
</shape>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M17.66,8L12,8l-1.88,-2L4,6l1.88,2L4,10l1.88,2L4,14l1.88,2L4,18l1.88,2L4,22h12c3.31,0 6,-2.69 6,-6L22,12C22,9.79 20.21,8 18,8h-0.34zM18,16h-4v-2h4v2zM18,12h-4v-2h4v2z"/>
|
||||
<path
|
||||
android:fillColor="#000080"
|
||||
android:pathData="M6,13l2,6 2,-6h-4z"/>
|
||||
<path
|
||||
android:fillColor="#000080"
|
||||
android:pathData="M10,13l2,6 2,-6h-4z"/>
|
||||
<path
|
||||
android:fillColor="#000080"
|
||||
android:pathData="M14,13l2,6 2,-6h-4z"/>
|
||||
<path
|
||||
android:fillColor="#FFFF00"
|
||||
android:pathData="M12,15l-3,6h3l-2,5 7,-8h-4l3,-3z"/>
|
||||
</vector>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFF00"
|
||||
android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2L12,4C6.48,4 2,8.48 2,14s4.48,10 10,10 10,-4.48 10,-10c0,-5.52 -4.48,-10 -10,-10zM12,22c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#71C3FF"
|
||||
android:centerColor="#55a4e9"
|
||||
android:endColor="#3387d5"
|
||||
android:type="linear" />
|
||||
</shape>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 底层是我们的中国风景图片 -->
|
||||
<item>
|
||||
<bitmap
|
||||
android:src="@drawable/china_landscape"
|
||||
android:gravity="center"
|
||||
android:tileMode="disabled" />
|
||||
</item>
|
||||
|
||||
<!-- 上层是半透明的白色覆盖层,确保数据能够清晰显示 -->
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="#70FFFFFF" /> <!-- 44%透明白色 -->
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#03A9F4"
|
||||
android:endColor="#2196F3"
|
||||
android:angle="45"/>
|
||||
</shape>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 底层是我们的中国风景图片 -->
|
||||
<item>
|
||||
<bitmap
|
||||
android:src="@drawable/vertopal_com_china_landscape_img"
|
||||
android:gravity="center"
|
||||
android:tileMode="disabled" />
|
||||
</item>
|
||||
|
||||
<!-- 上层是半透明的白色覆盖层,确保数据能够清晰显示 -->
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="#70FFFFFF" /> <!-- 44%透明白色 -->
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M13.127,0.688c-3.804,0.011 -7.149,2.527 -8.26,6.123 -3.309,0.333 -5.867,3.132 -5.867,6.522 0,3.624 2.945,6.569 6.569,6.569h15.748c3.624,0 6.569,-2.945 6.569,-6.569 0,-3.39 -2.558,-6.189 -5.867,-6.522 -1.111,-3.596 -4.456,-6.112 -8.26,-6.123zM10.973,15.368c0,0 -0.709,1.543 -1.397,3.214 -0.344,0.835 -0.652,1.731 -0.891,2.451 -0.119,0.36 -0.212,0.673 -0.273,0.891 -0.061,0.218 -0.041,0.288 -0.063,0.333 -0.002,0.004 -0.029,0.043 -0.063,0.063 -0.068,0.041 -0.166,0.063 -0.273,0.063 -0.214,0 -0.433,-0.095 -0.633,-0.209 -0.201,-0.115 -0.389,-0.253 -0.569,-0.4 -0.36,-0.294 -0.695,-0.643 -0.992,-1.003 -0.594,-0.721 -1.079,-1.508 -1.333,-2.179 -0.127,-0.335 -0.212,-0.647 -0.231,-0.912 -0.019,-0.265 0.019,-0.456 0.147,-0.631 0.077,-0.104 0.186,-0.193 0.326,-0.252 0.14,-0.059 0.306,-0.085 0.505,-0.084 0.111,0.001 0.233,0.011 0.357,0.031 0.249,0.042 0.518,0.114 0.798,0.21 0.559,0.192 1.17,0.465 1.73,0.765 1.119,0.599 2.084,1.301 2.084,1.301zM15.431,15.368c0,0 -0.709,1.543 -1.397,3.214 -0.344,0.835 -0.652,1.731 -0.891,2.451 -0.119,0.36 -0.212,0.673 -0.273,0.891 -0.061,0.218 -0.041,0.288 -0.063,0.333 -0.002,0.004 -0.029,0.043 -0.063,0.063 -0.068,0.041 -0.166,0.063 -0.273,0.063 -0.214,0 -0.433,-0.095 -0.633,-0.209 -0.201,-0.115 -0.389,-0.253 -0.569,-0.4 -0.36,-0.294 -0.695,-0.643 -0.992,-1.003 -0.594,-0.721 -1.079,-1.508 -1.333,-2.179 -0.127,-0.335 -0.212,-0.647 -0.231,-0.912 -0.019,-0.265 0.019,-0.456 0.147,-0.631 0.077,-0.104 0.186,-0.193 0.326,-0.252 0.14,-0.059 0.306,-0.085 0.505,-0.084 0.111,0.001 0.233,0.011 0.357,0.031 0.249,0.042 0.518,0.114 0.798,0.21 0.559,0.192 1.17,0.465 1.73,0.765 1.119,0.599 2.084,1.301 2.084,1.301z"/>
|
||||
</vector>
|
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/city_manager_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:elevation="4dp"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<!-- 添加城市区域 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="#F5F5F5"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_new_city"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:background="@android:color/white"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"
|
||||
android:hint="输入城市名称"
|
||||
android:maxLines="1"
|
||||
android:inputType="text" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_add_city"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="@string/add_to_favorites"
|
||||
android:textColor="#FFFFFF"
|
||||
android:backgroundTint="?attr/colorPrimary" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 分割线 -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#DDDDDD" />
|
||||
|
||||
<!-- 城市列表 -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="已保存的城市"
|
||||
android:textColor="#666666"
|
||||
android:textStyle="bold"
|
||||
android:background="#F5F5F5" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_cities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,48 @@
|
||||
<?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:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_city"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入城市名称"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_real_time"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="获取实时天气" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_forecast"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="获取天气预报" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_result"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp" />
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
@ -0,0 +1,327 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 背景图 - 移至最顶层,覆盖整个屏幕 -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 背景层 -->
|
||||
<ImageView
|
||||
android:id="@+id/background_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/timg"/>
|
||||
|
||||
<!-- 内容层 - 半透明UI -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 半透明工具栏 -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="#80000000"
|
||||
android:elevation="4dp"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
|
||||
|
||||
<!-- 添加Spinner到Toolbar -->
|
||||
<Spinner
|
||||
android:id="@+id/spinner_cities"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="#FFFFFF"
|
||||
android:popupBackground="#FFFFFF" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
<!-- 搜索栏 - 半透明背景 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/search_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:background="#80000000"
|
||||
android:elevation="2dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/cityname"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:textColor="#000000"
|
||||
android:textStyle="bold"
|
||||
android:hint="输入城市名称"
|
||||
android:textColorHint="#80666666"
|
||||
android:shadowColor="#40000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="1"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/search"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#000000"
|
||||
android:textStyle="bold"
|
||||
android:background="@drawable/rounded_button_background"
|
||||
android:text="查询"
|
||||
android:shadowColor="#40FFFFFF"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:elevation="2dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 天气内容 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/weather_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="#20000000">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="160dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:src="@drawable/sunny"/>
|
||||
|
||||
<!-- 城市名称和收藏按钮 -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/city"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="城市:"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="32sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="3"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btn_favorite"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@null"
|
||||
android:src="@android:drawable/btn_star_big_off"
|
||||
android:contentDescription="@string/favorite_button_desc"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="天气:"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="26sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/temp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="温度:"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="34sp"
|
||||
android:textStyle="bold"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="3"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/wind"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="风力风向:"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="18sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/humidity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="湿度:"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="18sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 天气预警容器 - 美化 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/alertContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="#60000000"
|
||||
android:visibility="gone"
|
||||
android:padding="8dp"
|
||||
android:elevation="4dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="天气预警信息"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:padding="4dp"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvAlerts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:visibility="gone"
|
||||
android:padding="4dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNoAlerts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="当前无预警信息"
|
||||
android:textColor="#FFFFFF"
|
||||
android:padding="8dp"
|
||||
android:gravity="center"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 预报栏 - 美化 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="#60000000"
|
||||
android:orientation="horizontal"
|
||||
android:elevation="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forcast1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="未来天气"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:padding="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forcast2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="未来天气"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:padding="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forcast3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="未来天气"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:padding="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forcast4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="未来天气"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:shadowColor="#80000000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="2"
|
||||
android:padding="4dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- 城市名称 -->
|
||||
<TextView
|
||||
android:id="@+id/tv_city_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@id/btn_delete_city"
|
||||
android:text="北京"
|
||||
android:textColor="#333333"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<!-- 当前城市标记 -->
|
||||
<TextView
|
||||
android:id="@+id/tv_current_city"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/tv_city_name"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="当前城市"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- 删除按钮 -->
|
||||
<ImageButton
|
||||
android:id="@+id/btn_delete_city"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="删除城市"
|
||||
android:padding="8dp"
|
||||
android:src="@android:drawable/ic_menu_delete" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#333333"
|
||||
android:padding="12dp"
|
||||
android:gravity="start"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end" />
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:padding="10dp"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end" />
|
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_refresh"
|
||||
android:orderInCategory="100"
|
||||
android:title="刷新"
|
||||
android:icon="@android:drawable/ic_popup_sync"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_gallery"
|
||||
android:orderInCategory="101"
|
||||
android:title="设置天气背景"
|
||||
android:icon="@android:drawable/ic_menu_gallery"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reset_background"
|
||||
android:orderInCategory="102"
|
||||
android:title="恢复天气默认背景"
|
||||
android:icon="@android:drawable/ic_menu_revert"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_city_manager"
|
||||
android:orderInCategory="103"
|
||||
android:title="城市管理"
|
||||
android:icon="@android:drawable/ic_dialog_map"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_share"
|
||||
android:orderInCategory="104"
|
||||
android:title="@string/share"
|
||||
android:icon="@android:drawable/ic_menu_share"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="105"
|
||||
android:title="设置"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 982 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 暗黑模式下的颜色设置 - 更暗的颜色值 -->
|
||||
<color name="colorPrimary">#1A4559</color>
|
||||
<color name="colorPrimaryDark">#0A1B24</color>
|
||||
<color name="colorAccent">#B32D59</color>
|
||||
|
||||
<color name="dark_background">#080808</color>
|
||||
<color name="dark_text_primary">#BBBBBB</color>
|
||||
<color name="dark_text_secondary">#888888</color>
|
||||
<color name="dark_status_bar">#000000</color>
|
||||
<color name="text_color_dark">#BBBBBB</color>
|
||||
|
||||
<!-- 暗黑模式下预警颜色 - 降低亮度 -->
|
||||
<color name="alert_red">#B82E2A</color>
|
||||
<color name="alert_orange">#B36800</color>
|
||||
<color name="alert_yellow">#AA9500</color>
|
||||
<color name="alert_blue">#1667A8</color>
|
||||
<color name="alert_default">#666666</color>
|
||||
</resources>
|
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 夜间模式主题 -->
|
||||
<style name="Theme.MyApplication" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="android:windowBackground">@color/dark_background</item>
|
||||
<item name="android:statusBarColor">@color/dark_status_bar</item>
|
||||
<item name="android:navigationBarColor">@color/dark_status_bar</item>
|
||||
</style>
|
||||
|
||||
<!-- Compose应用专用夜间主题 -->
|
||||
<style name="Theme.MyApplication.Compose" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- 添加必要的设置以支持Compose -->
|
||||
<item name="android:statusBarColor">@color/dark_status_bar</item>
|
||||
<item name="android:navigationBarColor">@color/dark_status_bar</item>
|
||||
<item name="android:windowBackground">@color/dark_background</item>
|
||||
</style>
|
||||
|
||||
<!-- 暗黑模式主题 - 降低整体亮度 -->
|
||||
<style name="Theme.MinimalistWeather" parent="Theme.AppCompat.NoActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:windowBackground">@color/dark_background</item>
|
||||
<item name="android:textColorPrimary">@color/dark_text_primary</item>
|
||||
<item name="android:textColorSecondary">@color/dark_text_secondary</item>
|
||||
<item name="android:statusBarColor">@color/dark_status_bar</item>
|
||||
<item name="android:navigationBarColor">@color/dark_status_bar</item>
|
||||
<item name="actionBarStyle">@style/DarkActionBar</item>
|
||||
<item name="toolbarStyle">@style/DarkToolbar</item>
|
||||
</style>
|
||||
|
||||
<!-- 暗黑模式下的ActionBar样式 -->
|
||||
<style name="DarkActionBar" parent="Widget.AppCompat.ActionBar">
|
||||
<item name="background">@color/colorPrimaryDark</item>
|
||||
<item name="titleTextStyle">@style/DarkTitleText</item>
|
||||
</style>
|
||||
|
||||
<!-- 暗黑模式下的Toolbar样式 -->
|
||||
<style name="DarkToolbar" parent="Widget.AppCompat.Toolbar">
|
||||
<item name="android:background">@color/colorPrimaryDark</item>
|
||||
<item name="titleTextColor">@color/dark_text_primary</item>
|
||||
<item name="subtitleTextColor">@color/dark_text_secondary</item>
|
||||
</style>
|
||||
|
||||
<!-- 暗黑模式下的标题文本样式 -->
|
||||
<style name="DarkTitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
|
||||
<item name="android:textColor">@color/dark_text_primary</item>
|
||||
</style>
|
||||
</resources>
|
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="colorPrimary">#3388AA</color>
|
||||
<color name="colorPrimaryDark">#1F6F91</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
<color name="light_background">#FFFFFF</color>
|
||||
<color name="light_text_primary">#333333</color>
|
||||
<color name="light_text_secondary">#757575</color>
|
||||
<color name="light_status_bar">#3388AA</color>
|
||||
<color name="dark_background">#121212</color>
|
||||
<color name="dark_text_primary">#E1E1E1</color>
|
||||
<color name="dark_text_secondary">#AAAAAA</color>
|
||||
<color name="dark_status_bar">#000000</color>
|
||||
<color name="text_color_dark">#E1E1E1</color>
|
||||
<color name="text_color_light">#333333</color>
|
||||
|
||||
<!-- 天气预警颜色 -->
|
||||
<color name="alert_red">#FFE53935</color>
|
||||
<color name="alert_orange">#FFFF9800</color>
|
||||
<color name="alert_yellow">#FFFFEB3B</color>
|
||||
<color name="alert_blue">#FF2196F3</color>
|
||||
<color name="alert_default">#FF9E9E9E</color>
|
||||
</resources>
|