1
0
This commit is contained in:
xuegao 2021-10-19 20:25:51 +08:00
commit 47e789d6da
421 changed files with 12005 additions and 0 deletions

16
MyApplication/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
*.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
/entry/.preview
.cxx
/node_modules

3
MyApplication/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
MyApplication/.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

23
MyApplication/.idea/gradle.xml generated Normal file
View File

@ -0,0 +1,23 @@
<?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="PLATFORM" />
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="C:\Program Files\Huawei\DevEco Studio 3.0.0.600\tools\gradle" />
<option name="gradleJvm" value="#JAVA_INTERNAL" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/entry" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

25
MyApplication/.idea/jarRepositories.xml generated Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://developer.huawei.com/repo/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://repo.huaweicloud.com/repository/maven/" />
</remote-repository>
</component>
</project>

4
MyApplication/.idea/misc.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

View File

@ -0,0 +1,33 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply plugin: 'com.huawei.ohos.app'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 6
}
buildscript {
repositories {
maven {
url 'https://repo.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
}
dependencies {
classpath 'com.huawei.ohos:hap:3.0.3.2'
classpath 'com.huawei.ohos:decctest:1.2.6.0'
}
}
allprojects {
repositories {
maven {
url 'https://repo.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
}
}

2
MyApplication/entry/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/build
/node_modules

View File

@ -0,0 +1,26 @@
apply plugin: 'com.huawei.ohos.hap'
apply plugin: 'com.huawei.ohos.decctest'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 6
defaultConfig {
compatibleSdkVersion 6
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
testImplementation 'junit:junit:4.13.1'
ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.200'
}
decc {
supportType = ['html','xml']
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
# config module specific ProGuard rules here.

View File

@ -0,0 +1,26 @@
package com.heweather.owp;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.heweather.hedemo", appContext.getPackageName());
}
}

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.heweather.owp">
<!-- 用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 用于获取运营商信息,用于支持提供运营商信息相关的接口 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 用于访问wifi网络信息wifi信息会用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 用于获取wifi的获取权限wifi信息会用来进行网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 用于访问网络,网络定位需要上网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 用于读取手机当前的状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 用于写入缓存数据到扩展存储卡 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 用于申请调用A-GPS模块 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!-- 用于申请获取蓝牙信息进行室内定位 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".view.activity.MainActivity"
android:exported="true"
android:launchMode="singleInstance" />
<activity android:name=".view.activity.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 高德 -->
<!-- 设置key -->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="9656fca1e4cef43a19082b4f37b600bb" />
<service android:name="com.amap.api.location.APSService" />
<service
android:name=".service.LocationService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.ACCESS_FINE_LOCATION" />
<activity android:name=".view.activity.SettingActivity" />
<activity android:name=".view.activity.ControlCityActivity" />
<activity android:name=".view.activity.AboutActivity" />
<activity android:name=".view.activity.BaseActivity" />
<activity android:name=".view.activity.SearchActivity" />
</application>
</manifest>

View File

@ -0,0 +1,51 @@
{
"app": {
"bundleName": "com.example.myapplication",
"vendor": "example",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.example.myapplication",
"name": ".MyApplication",
"mainAbility": "com.example.myapplication.MainAbility",
"deviceType": [
"phone",
"tablet",
"tv",
"wearable",
"car"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry",
"installationFree": false
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"visible": true,
"name": "com.example.myapplication.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard"
}
]
}
}

View File

@ -0,0 +1,75 @@
package com.heweather.owp;
import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import com.heweather.owp.crash.CrashHandler;
import com.heweather.owp.utils.ContentUtil;
import org.apache.log4j.Level;
import java.io.File;
import java.util.logging.Logger;
import de.mindpipe.android.logging.log4j.LogConfigurator;
import interfaces.heweather.com.interfacesmodule.view.HeConfig;
public class MyApplication extends Application {
//获取屏幕的高
private static MyApplication instance = null;
public Logger log;
@Override
public void onCreate() {
super.onCreate();
instance = this;
//在主线程中new的handler就是主线程的handler
//初始化Handler
HeConfig.init(ContentUtil.PUBLIC_ID, ContentUtil.APK_KEY);
HeConfig.switchToDevService();
configLog();
}
public void configLog() {
try {
final LogConfigurator logConfigurator = new LogConfigurator();
logConfigurator.setFileName(Environment.getExternalStorageDirectory() + File.separator + "crifanli_log4j.log");
// Set the root log level
logConfigurator.setRootLevel(Level.DEBUG);
// Set log level of a specific logger
logConfigurator.setLevel("org.apache", Level.ERROR);
logConfigurator.configure();
CrashHandler catchHandler = CrashHandler.getInstance();
catchHandler.init(getApplicationContext());
} catch (Exception e) {
String TAG = "sky";
Log.i(TAG, "configLog: " + e);
}
//gLogger = Logger.getLogger(this.getClass());
log = Logger.getLogger("CrifanLiLog4jTest");
}
/**
* 获得实例
*
* @return
*/
public static MyApplication getInstance() {
return instance;
}
/**
* 获取context对象
*/
public static Context getContext() {
return instance.getApplicationContext();
}
}

View File

@ -0,0 +1,96 @@
package com.heweather.owp.adapter;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.heweather.owp.R;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.bean.CityBeanList;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.SpUtils;
import com.heweather.owp.view.activity.ControlCityActivity;
import java.util.List;
public class ControlCityAdapter extends Adapter<ControlCityAdapter.MyViewHolder> {
private List<CityBean> datas;
private ControlCityActivity activity;
public ControlCityAdapter(ControlCityActivity controlCityActivity, List<CityBean> datas) {
activity = controlCityActivity;
this.datas = datas;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_follow_city, viewGroup, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, @SuppressLint("RecyclerView") final int i) {
myViewHolder.tvItemCity.setText(datas.get(i).getCityName());
myViewHolder.ivDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CityBeanList favorCity = SpUtils.getBean(activity, "cityBean", CityBeanList.class);
CityBeanList favorCityEn = SpUtils.getBean(activity, "cityBeanEn", CityBeanList.class);
List<CityBean> cityBeans = favorCity.getCityBeans();
List<CityBean> cityBeansEn = favorCityEn.getCityBeans();
for (int x = 0; x < cityBeans.size(); x++) {
if (cityBeans.get(x).getCityId().equals(datas.get(i).getCityId())) {
cityBeans.remove(x);
}
}
for (int x = 0; x < cityBeansEn.size(); x++) {
if (cityBeansEn.get(x).getCityId().equals(datas.get(i).getCityId())) {
cityBeansEn.remove(x);
}
}
datas.remove(i);
CityBeanList cityBeanList = new CityBeanList();
cityBeanList.setCityBeans(cityBeans);
CityBeanList cityBeanListEn = new CityBeanList();
cityBeanListEn.setCityBeans(cityBeansEn);
SpUtils.saveBean(activity, "cityBeanEn", cityBeanListEn);
SpUtils.saveBean(activity, "cityBean", cityBeanList);
//删除动画
notifyItemRemoved(i);
notifyDataSetChanged();
ContentUtil.CITY_CHANGE = true;
// DataUtil.deleteId(i);
}
});
}
@Override
public int getItemCount() {
return datas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final ImageView ivDelete;
private final TextView tvItemCity;
MyViewHolder(@NonNull View itemView) {
super(itemView);
ivDelete = itemView.findViewById(R.id.iv_item_delete);
tvItemCity = itemView.findViewById(R.id.tv_item_city);
}
}
}

View File

@ -0,0 +1,151 @@
package com.heweather.owp.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.heweather.owp.R;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.IconUtils;
import org.joda.time.DateTime;
import java.util.List;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherDailyBean;
public class ForecastAdapter extends Adapter<ForecastAdapter.MyViewHolder> {
private List<WeatherDailyBean.DailyBean> datas;
private Context context;
public ForecastAdapter(Context context, List<WeatherDailyBean.DailyBean> datas) {
this.datas = datas;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_forecast, viewGroup, false);
return new MyViewHolder(view);
}
public void refreshData(Context context, List<WeatherDailyBean.DailyBean> datas) {
this.datas = datas;
this.context = context;
notifyDataSetChanged();
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, @SuppressLint("RecyclerView") final int i) {
WeatherDailyBean.DailyBean forecastBase = datas.get(i);
String condCodeD = forecastBase.getIconDay();
String condCodeN = forecastBase.getIconNight();
String tmpMin = forecastBase.getTempMin();
String tmpMax = forecastBase.getTempMax();
myViewHolder.tvMax.setText(tmpMax + "°");
myViewHolder.tvMin.setText(tmpMin + "°");
myViewHolder.ivDay.setImageResource(IconUtils.getDayIconDark(condCodeD));
myViewHolder.ivNight.setImageResource(IconUtils.getDayIconDark(condCodeN));
DateTime now = DateTime.now();
myViewHolder.tvWeek.setText(getWeek(now.plusDays(i).getDayOfWeek()));
myViewHolder.tvWeek.setTextColor(context.getResources().getColor(R.color.edit_hint_color));
if (i == 0) {
myViewHolder.tvWeek.setText(context.getString(R.string.today));
}
}
/**
* 获取星期
*
* @param num 0-6
* @return 星期
*/
private String getWeek(int num) {
String week = " ";
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
switch (num) {
case 1:
week = "Mon";
break;
case 2:
week = "Tues";
break;
case 3:
week = "Wed";
break;
case 4:
week = "Thur";
break;
case 5:
week = "Fri";
break;
case 6:
week = "Sat";
break;
case 7:
week = "Sun";
break;
}
} else {
switch (num) {
case 1:
week = "周一";
break;
case 2:
week = "周二";
break;
case 3:
week = "周三";
break;
case 4:
week = "周四";
break;
case 5:
week = "周五";
break;
case 6:
week = "周六";
break;
case 7:
week = "周日";
break;
}
}
return week;
}
@Override
public int getItemCount() {
return datas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final ImageView ivDay;
private final ImageView ivNight;
private final TextView tvWeek;
private final TextView tvMin;
private final TextView tvMax;
MyViewHolder(@NonNull View itemView) {
super(itemView);
ivDay = itemView.findViewById(R.id.iv_day);
ivNight = itemView.findViewById(R.id.iv_night);
tvWeek = itemView.findViewById(R.id.tv_week);
tvMin = itemView.findViewById(R.id.tv_min);
tvMax = itemView.findViewById(R.id.tv_max);
}
}
}

View File

@ -0,0 +1,91 @@
package com.heweather.owp.adapter;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.heweather.owp.dataInterface.DataUtil;
import com.heweather.owp.R;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.bean.CityBeanList;
import com.heweather.owp.utils.SpUtils;
import com.heweather.owp.view.activity.MainActivity;
import com.heweather.owp.view.window.LocListWindow;
import java.util.ArrayList;
import java.util.List;
public class LocLIstAdapter extends Adapter<RecyclerView.ViewHolder> {
private List<CityBean> data;
private LocListWindow locListWindow;
private MainActivity activity;
public LocLIstAdapter(LocListWindow locListWindow, List<CityBean> data, MainActivity context) {
this.data = data;
this.locListWindow = locListWindow;
this.activity = context;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view;
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_favorite_light, viewGroup, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int i) {
MyViewHolder myViewHolder = (MyViewHolder) viewHolder;
myViewHolder.tvCity.setText(data.get(i).getCityName());
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String city = data.get(i).getCityId();
String cityName = data.get(i).getCityName();
CityBean cityBean = new CityBean();
cityBean.setCityName(cityName);
cityBean.setCityId(city);
CityBeanList cityBeans;
List<CityBean> citys = new ArrayList<>();
cityBeans = SpUtils.getBean(activity, "cityBean", CityBeanList.class);
if (cityBeans != null && cityBeans.getCityBeans() != null) {
citys = cityBeans.getCityBeans();
}else {
cityBeans = new CityBeanList();
}
citys.add(0, cityBean);
cityBeans.setCityBeans(citys);
SpUtils.saveBean(activity, "cityBean", cityBeans);
SpUtils.saveBean(activity, "cityBeanEn", cityBeans);
SpUtils.putString(activity, "lastLocation", city);
DataUtil.setCid(city);
locListWindow.dismiss();
}
});
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView tvCity;
MyViewHolder(@NonNull View itemView) {
super(itemView);
tvCity = itemView.findViewById(R.id.tv_item_favorite_city);
}
}
}

View File

@ -0,0 +1,201 @@
package com.heweather.owp.adapter;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.heweather.owp.R;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.bean.CityBeanList;
import com.heweather.owp.dataInterface.DataUtil;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.SpUtils;
import com.heweather.owp.view.activity.SearchActivity;
import java.util.ArrayList;
import java.util.List;
import interfaces.heweather.com.interfacesmodule.bean.base.Code;
import interfaces.heweather.com.interfacesmodule.bean.base.Lang;
import interfaces.heweather.com.interfacesmodule.bean.base.Mode;
import interfaces.heweather.com.interfacesmodule.bean.base.Range;
import interfaces.heweather.com.interfacesmodule.bean.geo.GeoBean;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
/**
* 最近搜索
*/
public class SearchAdapter extends Adapter<RecyclerView.ViewHolder> {
private List<CityBean> data;
private SearchActivity activity;
private String searchText;
private Lang lang;
private CityBeanList cityBeanList = new CityBeanList();
private boolean isSearching;
public SearchAdapter(SearchActivity activity, List<CityBean> data, String searchText, boolean isSearching) {
this.activity = activity;
this.data = data;
this.searchText = searchText;
this.isSearching = isSearching;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
lang = Lang.EN;
} else {
lang = Lang.ZH_HANS;
}
View view;
if (isSearching) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_searching, viewGroup, false);
} else {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_history, viewGroup, false);
}
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder myViewHolder, @SuppressLint("RecyclerView") final int i) {
MyViewHolder viewHolder = (MyViewHolder) myViewHolder;
View itemView = viewHolder.itemView;
String name = data.get(i).getCityName();
int x = name.indexOf("-");
String parentCity = name.substring(0, x);
String location = name.substring(x + 1);
String cityName = location + "" + parentCity + "" + data.get(i).getAdminArea() + "" + data.get(i).getCnty();
if (TextUtils.isEmpty(data.get(i).getAdminArea())) {
cityName = location + "" + parentCity + "" + data.get(i).getCnty();
}
if (!TextUtils.isEmpty(cityName)) {
viewHolder.tvCity.setText(cityName);
if (cityName.contains(searchText)) {
int index = cityName.indexOf(searchText);
//创建一个 SpannableString对象
SpannableString sp = new SpannableString(cityName);
//设置高亮样式一
sp.setSpan(new ForegroundColorSpan(activity.getResources().getColor(R.color.light_text_color)), index, index + searchText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
viewHolder.tvCity.setText(sp);
}
}
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String cid = data.get(i).getCityId();
if (lang.equals(Lang.ZH_HANS)) {
saveData(Lang.EN, "cityBeanEn", cid);
saveBean("cityBean", cid, i);
} else {
saveData(Lang.ZH_HANS, "cityBean", cid);
saveBean("cityBeanEn", cid, i);
}
activity.onBackPressed();
}
});
}
private void saveBean(final String key, String cid, int x) {
List<CityBean> citys = new ArrayList<>();
cityBeanList = SpUtils.getBean(activity, key, CityBeanList.class);
if (cityBeanList != null && cityBeanList.getCityBeans() != null) {
citys = cityBeanList.getCityBeans();
}
for (int i = 0; i < citys.size(); i++) {
if (citys.get(i).getCityId().equals(cid)) {
citys.remove(i);
}
}
if (citys.size() == 10) {
citys.remove(9);
}
citys.add(0, data.get(x));
CityBeanList cityBeans = new CityBeanList();
cityBeans.setCityBeans(citys);
SpUtils.saveBean(activity, key, cityBeans);
}
private void saveData(Lang lang, final String key, final String cid) {
HeWeather.getGeoCityLookup(activity, cid, Mode.FUZZY, Range.WORLD, 1, lang, new HeWeather.OnResultGeoListener() {
@Override
public void onError(Throwable throwable) {
Log.i("sky", "onError: ");
activity.onBackPressed();
}
@Override
public void onSuccess(GeoBean search) {
List<CityBean> citys = new ArrayList<>();
if (search.getStatus().equals(Code.OK.getCode())) {
List<GeoBean.LocationBean> basic = search.getLocationBean();
GeoBean.LocationBean basicData = basic.get(0);
String parentCity = basicData.getAdm2();
String adminArea = basicData.getAdm1();
String cnty = basicData.getCountry();
if (TextUtils.isEmpty(parentCity)) {
parentCity = adminArea;
}
if (TextUtils.isEmpty(adminArea)) {
parentCity = cnty;
}
CityBean cityBean = new CityBean();
cityBean.setCityName(parentCity + " - " + basicData.getName());
cityBean.setCityId(basicData.getId());
cityBean.setCnty(cnty);
cityBean.setAdminArea(adminArea);
cityBeanList = SpUtils.getBean(activity, key, CityBeanList.class);
if (cityBeanList != null && cityBeanList.getCityBeans() != null) {
citys = cityBeanList.getCityBeans();
}
for (int i = 0; i < citys.size(); i++) {
if (citys.get(i).getCityId().equals(cid)) {
citys.remove(i);
}
}
if (citys.size() == 10) {
citys.remove(9);
}
citys.add(0, cityBean);
CityBeanList cityBeans = new CityBeanList();
cityBeans.setCityBeans(citys);
SpUtils.saveBean(activity, key, cityBeans);
DataUtil.setCid(cid);
}
}
});
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView tvCity;
MyViewHolder(@NonNull View itemView) {
super(itemView);
tvCity = itemView.findViewById(R.id.tv_item_history_city);
}
}
}

View File

@ -0,0 +1,46 @@
package com.heweather.owp.adapter;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.view.ViewGroup;
import java.util.List;
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mList;
public ViewPagerAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.mList = list;
}
@Override
public Fragment getItem(int position) {
return mList.get(position);
}
@Override
public int getCount() {
return mList != null ? mList.size() : 0;
}
@Override
public int getItemPosition(@NonNull Object object) {
return PagerAdapter.POSITION_NONE;
}
@Override
public CharSequence getPageTitle(int position) {
return "";
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
// super.destroyItem(container, position, object);
}
}

View File

@ -0,0 +1,37 @@
package com.heweather.owp.bean;
public class AddAttentionBean {
/**
* title : 3282
* msg : 信息新增成功
* status : success
*/
private String title;
private String msg;
private String status;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View File

@ -0,0 +1,15 @@
package com.heweather.owp.bean;
import java.util.List;
public class AttentionBean {
private List<AttentionBeanBase> datas;
public List<AttentionBeanBase> getDatas() {
return datas;
}
public void setDatas(List<AttentionBeanBase> datas) {
this.datas = datas;
}
}

View File

@ -0,0 +1,121 @@
package com.heweather.owp.bean;
public class AttentionBeanBase {
private String title;
private String time;
private String minTmp;
private String maxTmp;
private String aql;
private String wind;
private String type;
private String cid;
private String place;
private String attentionType;
private String deleteId;
private boolean dataIsTrue;
private boolean isNowCity;
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String getDeleteId() {
return deleteId;
}
public void setDeleteId(String deleteId) {
this.deleteId = deleteId;
}
public boolean isNowCity() {
return isNowCity;
}
public void setNowCity(boolean nowCity) {
isNowCity = nowCity;
}
public String getAttentionType() {
return attentionType;
}
public void setAttentionType(String attentionType) {
this.attentionType = attentionType;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public boolean getDataIsTrue() {
return dataIsTrue;
}
public void setDataIsTrue(boolean dataIsTrue) {
this.dataIsTrue = dataIsTrue;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getMinTmp() {
return minTmp;
}
public void setMinTmp(String minTmp) {
this.minTmp = minTmp;
}
public String getMaxTmp() {
return maxTmp;
}
public void setMaxTmp(String maxTmp) {
this.maxTmp = maxTmp;
}
public String getAql() {
return aql;
}
public void setAql(String aql) {
this.aql = aql;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
}

View File

@ -0,0 +1,33 @@
package com.heweather.owp.bean;
import java.util.List;
public class BarBean {
String title;
int totalLevel;
List<Integer> levels;
public List<Integer> getLevels() {
return levels;
}
public void setLevels(List<Integer> levels) {
this.levels = levels;
}
public int getTotalLevel() {
return totalLevel;
}
public void setTotalLevel(int totalLevel) {
this.totalLevel = totalLevel;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@ -0,0 +1,220 @@
package com.heweather.owp.bean;
import java.util.List;
public class City {
/**
* cityList : [{"appUserId":4,"authorId":0,"authorName":" 系统 ","authorTime":"2018-12-25 15:55:51","basic":{"cid":"CN101010300","location":"朝阳","parent_city":"北京","admin_area":"北京","cnty":"中国","lat":"39.92148972","lon":"116.48641205"},"cityId":"CN101010300","display":1,"id":74,"recordStatus":0}]
* msg : 获取成功
* status : success
*/
private String msg;
private String status;
private List<CityListBean> cityList;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<CityListBean> getCityList() {
return cityList;
}
public void setCityList(List<CityListBean> cityList) {
this.cityList = cityList;
}
public static class CityListBean {
/**
* appUserId : 4
* authorId : 0
* authorName : 系统
* authorTime : 2018-12-25 15:55:51
* basic : {"cid":"CN101010300","location":"朝阳","parent_city":"北京","admin_area":"北京","cnty":"中国","lat":"39.92148972","lon":"116.48641205"}
* cityId : CN101010300
* display : 1
* id : 74
* recordStatus : 0
*/
private int appUserId;
private int authorId;
private String authorName;
private String authorTime;
private BasicBean basic;
private String cityId;
private int display;
private int id;
private int recordStatus;
private int orderby;
public int getOrderby() {
return orderby;
}
public void setOrderby(int orderby) {
this.orderby = orderby;
}
public int getAppUserId() {
return appUserId;
}
public void setAppUserId(int appUserId) {
this.appUserId = appUserId;
}
public int getAuthorId() {
return authorId;
}
public void setAuthorId(int authorId) {
this.authorId = authorId;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getAuthorTime() {
return authorTime;
}
public void setAuthorTime(String authorTime) {
this.authorTime = authorTime;
}
public BasicBean getBasic() {
return basic;
}
public void setBasic(BasicBean basic) {
this.basic = basic;
}
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public int getDisplay() {
return display;
}
public void setDisplay(int display) {
this.display = display;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getRecordStatus() {
return recordStatus;
}
public void setRecordStatus(int recordStatus) {
this.recordStatus = recordStatus;
}
public static class BasicBean {
/**
* cid : CN101010300
* location : 朝阳
* parent_city : 北京
* admin_area : 北京
* cnty : 中国
* lat : 39.92148972
* lon : 116.48641205
*/
private String cid;
private String location;
private String parent_city;
private String admin_area;
private String cnty;
private String lat;
private String lon;
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getParent_city() {
return parent_city;
}
public void setParent_city(String parent_city) {
this.parent_city = parent_city;
}
public String getAdmin_area() {
return admin_area;
}
public void setAdmin_area(String admin_area) {
this.admin_area = admin_area;
}
public String getCnty() {
return cnty;
}
public void setCnty(String cnty) {
this.cnty = cnty;
}
public String getLat() {
return lat;
}
public void setLat(String lat) {
this.lat = lat;
}
public String getLon() {
return lon;
}
public void setLon(String lon) {
this.lon = lon;
}
}
}
}

View File

@ -0,0 +1,67 @@
package com.heweather.owp.bean;
public class CityBean {
private String cityName;
private String cityId;
private String cnty;
private String location;
private String parentCity;
private String adminArea;
private boolean isFavor;
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public boolean isFavor() {
return isFavor;
}
public void setFavor(boolean favor) {
isFavor = favor;
}
public String getCnty() {
return cnty;
}
public void setCnty(String cnty) {
this.cnty = cnty;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getAdminArea() {
return adminArea;
}
public void setAdminArea(String adminArea) {
this.adminArea = adminArea;
}
public String getParentCity() {
return parentCity;
}
public void setParentCity(String parentCity) {
this.parentCity = parentCity;
}
}

View File

@ -0,0 +1,67 @@
package com.heweather.owp.bean;
public class CityBeanEn {
private String cityName;
private String cityId;
private String cnty;
private String location;
private String parentCity;
private String adminArea;
private boolean isFavor;
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public boolean isFavor() {
return isFavor;
}
public void setFavor(boolean favor) {
isFavor = favor;
}
public String getCnty() {
return cnty;
}
public void setCnty(String cnty) {
this.cnty = cnty;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getAdminArea() {
return adminArea;
}
public void setAdminArea(String adminArea) {
this.adminArea = adminArea;
}
public String getParentCity() {
return parentCity;
}
public void setParentCity(String parentCity) {
this.parentCity = parentCity;
}
}

View File

@ -0,0 +1,15 @@
package com.heweather.owp.bean;
import java.util.List;
public class CityBeanList {
private List<CityBean> cityBeans;
public List<CityBean> getCityBeans() {
return cityBeans;
}
public void setCityBeans(List<CityBean> cityBeans) {
this.cityBeans = cityBeans;
}
}

View File

@ -0,0 +1,82 @@
package com.heweather.owp.bean;
/**
* Created by niuchong on 2018/6/3.
*/
public class CityNow {
/**
* lat : 39.90498734
* lon : 116.4052887
* city : 北京
* location : 北京
* province : 北京
* tmp : 29
* code : 104
*/
private String lat;
private String lon;
private String city;
private String location;
private String province;
private String tmp;
private String code;
public String getLat() {
return lat;
}
public void setLat(String lat) {
this.lat = lat;
}
public String getLon() {
return lon;
}
public void setLon(String lon) {
this.lon = lon;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getTmp() {
return tmp;
}
public void setTmp(String tmp) {
this.tmp = tmp;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}

View File

@ -0,0 +1,15 @@
package com.heweather.owp.bean;
import java.util.List;
public class ForecastBean {
private List<SmartForecastBean> beans;
public List<SmartForecastBean> getBeans() {
return beans;
}
public void setBeans(List<SmartForecastBean> beans) {
this.beans = beans;
}
}

View File

@ -0,0 +1,33 @@
package com.heweather.owp.bean;
import java.util.List;
public class PushBean {
private String msg;
private String status;
private List<PushList> pushList;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<PushList> getPushList() {
return pushList;
}
public void setPushList(List<PushList> pushList) {
this.pushList = pushList;
}
}

View File

@ -0,0 +1,82 @@
package com.heweather.owp.bean;
public class PushList {
/**
* id : 1
* triggerTime 发生时间
* 1,明天2后天
* cityId : CN101010100
* event : 事件类型
* 0 雨雪天气
* 1 温度骤变
* 2 天气预警
* 3 空气质量中度污染及以上
* remindTime 提醒时间
* 1上午
* 2下午
*/
private String id;
private String triggerTime;
private String cityId;
private String event;
private String remindTime;
private String positionStatus;
private String orderby;
public String getOrderby() {
return orderby;
}
public void setOrderby(String orderby) {
this.orderby = orderby;
}
public String getPositionStatus() {
return positionStatus;
}
public void setPositionStatus(String positionStatus) {
this.positionStatus = positionStatus;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTriggerTime() {
return triggerTime;
}
public void setTriggerTime(String triggerTime) {
this.triggerTime = triggerTime;
}
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public String getRemindTime() {
return remindTime;
}
public void setRemindTime(String remindTime) {
this.remindTime = remindTime;
}
}

View File

@ -0,0 +1,52 @@
package com.heweather.owp.bean;
public class ReminderCache {
/**
* cityId, true, triggerTime, event, nowCity, deleteId
*/
String cityId;
String triggerTime;
String event;
boolean nowCity;
String deleteId;
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getTriggerTime() {
return triggerTime;
}
public void setTriggerTime(String triggerTime) {
this.triggerTime = triggerTime;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public boolean isNowCity() {
return nowCity;
}
public void setNowCity(boolean nowCity) {
this.nowCity = nowCity;
}
public String getDeleteId() {
return deleteId;
}
public void setDeleteId(String deleteId) {
this.deleteId = deleteId;
}
}

View File

@ -0,0 +1,129 @@
package com.heweather.owp.bean;
import java.util.List;
public class SettingBean {
private String msg;
private String status;
private List<ExtendListBean> extendList;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<ExtendListBean> getExtendList() {
return extendList;
}
public void setExtendList(List<ExtendListBean> extendList) {
this.extendList = extendList;
}
public static class ExtendListBean {
/**
* authorId : 0
* authorName : 系统
* authorTime : 2019-02-22 18:00:15
* display : 1
* id : 1
* k : 1
* recordStatus : 0
* token : AkqUTcgsck8qjWJaJgUnBqeBRcIF0ApS1bBvkyn6PP32
* v : 2
*/
private int authorId;
private String authorName;
private String authorTime;
private int display;
private int id;
private String k;
private int recordStatus;
private String token;
private String v;
public int getAuthorId() {
return authorId;
}
public void setAuthorId(int authorId) {
this.authorId = authorId;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getAuthorTime() {
return authorTime;
}
public void setAuthorTime(String authorTime) {
this.authorTime = authorTime;
}
public int getDisplay() {
return display;
}
public void setDisplay(int display) {
this.display = display;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getK() {
return k;
}
public void setK(String k) {
this.k = k;
}
public int getRecordStatus() {
return recordStatus;
}
public void setRecordStatus(int recordStatus) {
this.recordStatus = recordStatus;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getV() {
return v;
}
public void setV(String v) {
this.v = v;
}
}
}

View File

@ -0,0 +1,22 @@
package com.heweather.owp.bean;
public class SmartForecastBean {
String forecastTitle;
boolean hasAdded;
public String getForecastTitle() {
return forecastTitle;
}
public void setForecastTitle(String forecastTitle) {
this.forecastTitle = forecastTitle;
}
public boolean isHasAdded() {
return hasAdded;
}
public void setHasAdded(boolean hasAdded) {
this.hasAdded = hasAdded;
}
}

View File

@ -0,0 +1,41 @@
package com.heweather.owp.bean;
public class UpdateResponse {
private int update;
private String releaseNote;
private String url;
private String version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public int getUpdate() {
return update;
}
public void setUpdate(int update) {
this.update = update;
}
public String getReleaseNote() {
return releaseNote;
}
public void setReleaseNote(String releaseNote) {
this.releaseNote = releaseNote;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@ -0,0 +1,209 @@
package com.heweather.owp.crash;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private Logger logger;
private static final String TAG = "CrashHandler";
// CrashHandler 实例
@SuppressLint("StaticFieldLeak")
private static CrashHandler INSTANCE = new CrashHandler();
// 程序的 Context 对象
private Context mContext;
// 系统默认的 UncaughtException 处理类
private Thread.UncaughtExceptionHandler mDefaultHandler;
// 用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<>();
// 用于格式化日期,作为日志文件名的一部分
@SuppressLint("SimpleDateFormat")
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
/**
* 保证只有一个 CrashHandler 实例
*/
private CrashHandler() {
}
/**
* 获取 CrashHandler 实例 ,单例模式
*/
public static CrashHandler getInstance() {
return INSTANCE;
}
/**
* 始化
*/
public void init( Context context) {
logger = Logger.getLogger(CrashHandler.class);
mContext = context;
// 获取系统默认的 UncaughtException 处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该 CrashHandler 为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* UncaughtException 发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e(TAG, "error : ", e);
}
// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
/**
* 自定义错误处理收集错误信息发送错误报告等操作均在此完成
*
* @return true如果处理了该异常信息否则返回 false
*/
private boolean handleException(final Throwable ex) {
if (ex == null) {
return false;
}
// 使用 Toast 来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
logger.error("系统异常退出", ex);
// Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出。!!!!"+path, Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
// 收集设备参数信息
collectDeviceInfo(mContext);
// 保存日志文件
String path = saveCrashInfo2File(ex);
Log.d(TAG, "handleException: " + path);
return true;
}
/**
* 收集设备参数信息
*
*/
private void collectDeviceInfo(Context ctx) {
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
} catch (NameNotFoundException e) {
Log.e(TAG, "an error occured when collect package info", e);
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
Log.d(TAG, field.getName() + " : " + field.get(null));
} catch (Exception e) {
Log.e(TAG, "an error occured when collect crash info", e);
}
}
}
/**
* 保存错误信息到文件中
* @return 返回文件名称, 便于将文件传送到服务器
*/
private String saveCrashInfo2File(Throwable ex) {
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : infos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + "\n");
}
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
try {
String time = formatter.format(new Date());
String fileName = time + ".log";
if ( Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = Environment.getExternalStorageDirectory().getPath() + "/Heweather/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
fos.close();
}
Log.d(TAG, "saveCrashInfo2File: " + fileName);
return fileName;
} catch (Exception e) {
Log.e(TAG, "an error occured while writing file...", e);
}
return null;
}
}

View File

@ -0,0 +1,7 @@
package com.heweather.owp.dataInterface;
public interface DataInterface {
void setCid(String cid);
void deleteID(int index);
void changeBack(String condCode);
}

View File

@ -0,0 +1,26 @@
package com.heweather.owp.dataInterface;
public class DataUtil {
private static DataInterface dataInterface;
public static void setDataInterface(DataInterface inter) {
dataInterface = inter;
}
public static void setCid(String cid) {
if (dataInterface != null) {
dataInterface.setCid(cid);
}
}
public static void deleteId(int index){
if (dataInterface != null) {
dataInterface.deleteID(index);
}
}
public static void changeBack(String condCode){
if (dataInterface!=null){
dataInterface.changeBack(condCode);
}
}
}

View File

@ -0,0 +1,46 @@
package com.heweather.owp.presenters;
import interfaces.heweather.com.interfacesmodule.bean.WarningBean;
import interfaces.heweather.com.interfacesmodule.bean.air.AirNowBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherDailyBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherHourlyBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherNowBean;
/**
* Created by niuchong on 2018/5/17.
*/
public interface WeatherInterface {
/**
* 实况天气
*/
void getWeatherNow(WeatherNowBean bean);
/**
* 3-7天天气预报
*/
void getWeatherForecast(WeatherDailyBean bean);
/**
* 灾害天气预警
*/
void getWarning(WarningBean.WarningBeanBase bean);
/**
* 空气实况
*/
void getAirNow(AirNowBean bean);
/**
* 空气预报
*/
// void getAirForecast(AirForecast bean);
/**
* 逐小时预报
*/
void getWeatherHourly(WeatherHourlyBean bean);
}

View File

@ -0,0 +1,39 @@
package com.heweather.owp.presenters;
/**
* Created by niuchong on 2018/5/17.
*/
public interface WeatherPresenters {
/**
* 实况天气
*/
void getWeatherNow(String location);
/**
* 3-7天天气预报
*/
void getWeatherForecast(String location);
/**
* 灾害天气预警
*/
void getWarning(String location);
/**
* 空气实况
*/
void getAirNow(String location);
/**
* 空气预报
*/
void getAirForecast(String location);
/**
* 逐小时预报
*/
void getWeatherHourly(String location);
}

View File

@ -0,0 +1,204 @@
package com.heweather.owp.presenters.impl;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.heweather.owp.presenters.WeatherInterface;
import com.heweather.owp.presenters.WeatherPresenters;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.SpUtils;
import interfaces.heweather.com.interfacesmodule.bean.WarningBean;
import interfaces.heweather.com.interfacesmodule.bean.air.AirNowBean;
import interfaces.heweather.com.interfacesmodule.bean.base.Code;
import interfaces.heweather.com.interfacesmodule.bean.base.Lang;
import interfaces.heweather.com.interfacesmodule.bean.base.Mode;
import interfaces.heweather.com.interfacesmodule.bean.base.Range;
import interfaces.heweather.com.interfacesmodule.bean.base.Unit;
import interfaces.heweather.com.interfacesmodule.bean.geo.GeoBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherDailyBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherHourlyBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherNowBean;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
/**
* Created by niuchong on 2018/5/17.
*/
public class WeatherImpl implements WeatherPresenters {
private Context context;
private WeatherInterface weatherInterface;
private String TAG = "sky";
private Lang lang;
private Unit unit;
public WeatherImpl(Context context, WeatherInterface weatherInterface) {
this.context = context;
this.weatherInterface = weatherInterface;
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
lang = Lang.EN;
} else {
lang = Lang.ZH_HANS;
}
unit = Unit.METRIC;
}
@Override
public void getWeatherNow(String location) {
HeWeather.getWeatherNow(context, location, lang, unit, new HeWeather.OnResultWeatherNowListener() {
@Override
public void onError(Throwable throwable) {
WeatherNowBean weatherNow = SpUtils.getBean(context, "weatherNow", WeatherNowBean.class);
weatherInterface.getWeatherNow(weatherNow);
}
@Override
public void onSuccess(WeatherNowBean weatherNowBean) {
if (Code.OK.getCode().equalsIgnoreCase(weatherNowBean.getCode())) {
weatherInterface.getWeatherNow(weatherNowBean);
SpUtils.saveBean(context, "weatherNow", weatherNowBean);
}
}
});
}
@Override
public void getWeatherForecast(final String location) {
HeWeather.getWeather3D(context, location, lang, unit, new HeWeather.OnResultWeatherDailyListener() {
@Override
public void onError(Throwable throwable) {
Log.i("sky", "getWeatherForecast onError: ");
WeatherDailyBean weatherForecast = SpUtils.getBean(context, "weatherForecast", WeatherDailyBean.class);
weatherInterface.getWeatherForecast(weatherForecast);
getAirForecast(location);
}
@Override
public void onSuccess(WeatherDailyBean weatherDailyBean) {
if (Code.OK.getCode().equalsIgnoreCase(weatherDailyBean.getCode())) {
weatherInterface.getWeatherForecast(weatherDailyBean);
getAirForecast(location);
SpUtils.saveBean(context, "weatherForecast", weatherDailyBean);
}
}
});
}
@Override
public void getWarning(String location) {
HeWeather.getWarning(context, location, lang, new HeWeather.OnResultWarningListener() {
@Override
public void onError(Throwable throwable) {
weatherInterface.getWarning(null);
Log.i("sky", "getWarning onError: " + throwable);
}
@Override
public void onSuccess(WarningBean warningBean) {
if (Code.OK.getCode().equalsIgnoreCase(warningBean.getCode())) {
if (warningBean.getBeanBaseList() != null && warningBean.getBeanBaseList().size() > 0) {
weatherInterface.getWarning(warningBean.getBeanBaseList().get(0));
SpUtils.saveBean(context, "alarm", warningBean);
}
}
}
});
}
@Override
public void getAirNow(final String location) {
HeWeather.getAirNow(context, location, lang, new HeWeather.OnResultAirNowListener() {
@Override
public void onError(Throwable throwable) {
Log.i("sky", "getAirNow onError: ");
getParentAir(location);
}
@Override
public void onSuccess(AirNowBean airNowBean) {
if (Code.OK.getCode().equalsIgnoreCase(airNowBean.getCode())) {
weatherInterface.getAirNow(airNowBean);
SpUtils.saveBean(context, "airNow", airNowBean);
}
}
});
}
private void getParentAir(String location) {
HeWeather.getGeoCityLookup(context, location, Mode.FUZZY, Range.WORLD, 3, lang, new HeWeather.OnResultGeoListener() {
@Override
public void onError(Throwable throwable) {
}
@Override
public void onSuccess(GeoBean geoBean) {
String parentCity = geoBean.getLocationBean().get(0).getAdm2();
if (TextUtils.isEmpty(parentCity)) {
parentCity = geoBean.getLocationBean().get(0).getAdm1();
}
HeWeather.getAirNow(context, parentCity, lang, new HeWeather.OnResultAirNowListener() {
@Override
public void onError(Throwable throwable) {
weatherInterface.getAirNow(null);
}
@Override
public void onSuccess(AirNowBean airNow) {
if (Code.OK.getCode().equalsIgnoreCase(airNow.getCode())) {
weatherInterface.getAirNow(airNow);
}
}
});
}
});
}
@Override
public void getAirForecast(String location) {
// HeWeather.getAirForecast(context, location, lang, unit, new HeWeather.OnResultAirForecastBeansListener() {
// @Override
// public void onError(Throwable throwable) {
// Log.i(TAG, "getAirForecast onError: ");
// AirForecast airForecast = SpUtils.getBean(context, "airForecast", AirForecast.class);
// weatherInterface.getAirForecast(airForecast);
// }
//
// @Override
// public void onSuccess(List<AirForecast> list) {
// weatherInterface.getAirForecast(list.get(0));
// SpUtils.saveBean(context, "airForecast", list.get(0));
//
// }
// });
}
@Override
public void getWeatherHourly(String location) {
HeWeather.getWeather24Hourly(context, location, lang, unit, new HeWeather.OnResultWeatherHourlyListener() {
@Override
public void onError(Throwable throwable) {
Log.i("sky", "getWeatherHourly onError: getWeatherHourly");
}
@Override
public void onSuccess(WeatherHourlyBean weatherHourlyBean) {
if (Code.OK.getCode().equalsIgnoreCase(weatherHourlyBean.getCode())) {
weatherInterface.getWeatherHourly(weatherHourlyBean);
SpUtils.saveBean(context, "weatherHourly", weatherHourlyBean);
}
}
});
}
}

View File

@ -0,0 +1,68 @@
package com.heweather.owp.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.heweather.owp.MyApplication;
import com.heweather.owp.utils.ContentUtil;
public class LocationService extends Service {
private final String TAG = "sky";
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation.getErrorCode() == 0) {
ContentUtil.NOW_LON = aMapLocation.getLongitude();
ContentUtil.NOW_LAT = aMapLocation.getLatitude();
Log.i(TAG, "now location: " + ContentUtil.NOW_LON + "," + ContentUtil.NOW_LAT);
}else {
String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
Log.e(TAG, errText);
}
}
};
public LocationService() {
}
@Override
public void onCreate() {
super.onCreate();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//声明AMapLocationClientOption对象
AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
//设置定位模式为AMapLocationMode.Hight_Accuracy高精度模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置定位间隔,单位毫秒,默认为2000ms最低1000ms
mLocationOption.setInterval(10000);
//单位是毫秒默认30000毫秒建议超时时间不要低于8000毫秒
mLocationOption.setHttpTimeOut(20000);
mLocationClient.setLocationListener(mLocationListener);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View File

@ -0,0 +1,59 @@
package com.heweather.owp.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
public class APKVersionCodeUtils {
/**
* 获取当前本地apk的versionCode
*
* @param mContext
* @return
*/
public static int getVersionCode(Context mContext) {
int versionCode = 0;
try {
//获取软件版本号对应AndroidManifest.xml下android:versionCode
versionCode = mContext.getPackageManager().
getPackageInfo(mContext.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionCode;
}
/**
* 获取versionName
*
* @param context 上下文
* @return
*/
public static String getVersionName(Context context) {
String versionName = "";
try {
versionName = context.getPackageManager().
getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionName;
}
/**
* 获取应用程序名称
*/
public static synchronized String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,104 @@
package com.heweather.owp.utils;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;
import com.zhy.http.okhttp.callback.StringCallback;
import java.io.File;
import java.util.HashMap;
/**
* 作者niu on 2018/6/03
*/
public class AppNetConfig {
/**
* post请求
*
* @param url
* @param params
* @param headers 请求头是非必传字段如果没有设置null即可
* @param callback
*/
public static final void RequestPost(final String url, final HashMap<String, String> params,
final HashMap<String, String> headers, final StringCallback callback) {
if ( headers == null ) {
OkHttpUtils.post().url(url).params(params).build().execute(callback);
} else {
OkHttpUtils.post().url(url).headers(headers).params(params).build().execute(callback);
}
}
/**
* post请求
*
* @param url
* @param params
* @param headers 请求头是非必传字段如果没有设置null即可
* @param callback
*/
public static final void RequestPost(final String url, final int writeTimeOut, final HashMap<String, String> params,
final HashMap<String, String> headers, final StringCallback callback) {
if ( headers == null ) {
OkHttpUtils.post().url(url).params(params).build().readTimeOut(writeTimeOut).execute(callback);
} else {
OkHttpUtils.post().url(url).headers(headers).params(params).build().readTimeOut(writeTimeOut).execute(callback);
}
}
/**
* get请求
*
* @param url
* @param callback
*/
public static final void RequestGet(final String url, final StringCallback callback) {
OkHttpUtils.get().url(url).build().execute(callback);
}
public static final void GetFile(final String url , final FileCallBack callBack){
OkHttpUtils.get().url(url).build().execute(callBack);
}
/**
* 上传单个文件
*
* @param name 文件标识
* @param fileName 文件名 lyh.png
* @param file 上传的文件
* @param params 需要携带的参数
* @param url 上传的目标地址
* @param headers 需要携带的请求头
* @param callback 请求结果的回调
*/
public static final void RequestUpFile(final String name, final int writeTimeOut, final String fileName,
final File file, final HashMap<String, String> params, final String url,
final HashMap<String, String> headers, final StringCallback callback) {
if ( headers == null ) {
OkHttpUtils.post().addFile(name, fileName, file).params(params).url(url).build().writeTimeOut(writeTimeOut).execute(callback);
} else {
OkHttpUtils.post().addFile(name, fileName, file).params(params).headers(headers).url(url).build().writeTimeOut(writeTimeOut).execute(callback);
}
}
/**
* 上传多个文件
*
* @param key 本次上传的唯一标识
* @param files 上传的文件String类型的key为文件名 :lyh.png , File类型的value是上传的文件
* @param params 需要携带的参数
* @param url 上传的目标地址
* @param headers 需要携带的请求头信息
* @param callback 服务器响应结果的回调
*/
public static final void RequestUpFiles(final String key, final HashMap<String, File> files,
final HashMap<String, String> params, final String url,
final HashMap<String, String> headers, final StringCallback callback) {
if ( headers == null ) {
OkHttpUtils.post().files(key, files).params(params).url(url).build().execute(callback);
} else {
OkHttpUtils.post().files(key, files).params(params).headers(headers).url(url).build().execute(callback);
}
}
}

View File

@ -0,0 +1,18 @@
package com.heweather.owp.utils;
/**
* Created by niuchong on 2018/5/29.
*/
public final class BuildConfig {
public static final boolean DEBUG = false;
public static final String APPLICATION_ID = "ch.ielse.view";
public static final String BUILD_TYPE = "release";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
public BuildConfig() {
}
}

View File

@ -0,0 +1,39 @@
package com.heweather.owp.utils;
import com.heweather.owp.MyApplication;
/**
* Created by niuchong on 2019/4/7.
*/
public class ContentUtil {
//用户id
public static final String PUBLIC_ID = "public_id";
//用户key
public static final String APK_KEY = "key";
//当前所在位置
public static Double NOW_LON = 116.40;
public static Double NOW_LAT = 39.9;
//当前城市
public static String NOW_CITY_ID = SpUtils.getString(MyApplication.getContext(), "lastLocation", "CN101010100");
public static String NOW_CITY_NAME = SpUtils.getString(MyApplication.getContext(), "nowCityName", "北京");
public static boolean FIRST_OPEN = SpUtils.getBoolean(MyApplication.getContext(), "first_open", true);
//应用设置里的文字
public static String SYS_LANG = "zh";
public static String APP_SETTING_LANG = SpUtils.getString(MyApplication.getContext(), "language", "sys");
public static String APP_SETTING_UNIT = SpUtils.getString(MyApplication.getContext(), "unit", "she");
public static String APP_SETTING_TESI = SpUtils.getString(MyApplication.getContext(), "size", "mid");
public static String APP_PRI_TESI = SpUtils.getString(MyApplication.getContext(), "size", "mid");
public static String APP_SETTING_THEME = SpUtils.getString(MyApplication.getContext(), "theme", "浅色");
public static boolean UNIT_CHANGE = false;
public static boolean CHANGE_LANG = false;
public static boolean CITY_CHANGE = false;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,363 @@
package com.heweather.owp.utils;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
public class DeviceUtil {
private static final boolean imeiFirst = true;
/**
* 1.优先CPU序列号
* 2.检验版本<=6.0 请求IMEI 为null->获取DevID
* 3.>=6.0 有权限请求IMEI 为null -> 获取DevId
* 4.>=6.0 无权限->DevId
*/
public static String getCPUSerial(Context context) {
String defaultCPUSerial = "0000000000000000";
String str, strCPU, cpuAddress = defaultCPUSerial;
try {
if (imeiFirst) {
cpuAddress = getDeviceId(context);
}
if (!imeiFirst || Build.UNKNOWN.equals(cpuAddress)) {
//读取CPU信息
Process pp = Runtime.getRuntime().exec("cat /proc/cpuinfo | grep Serial");
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
//查找CPU序列号
for (int i = 1; i < 100; i++) {
str = input.readLine();
if (str != null) {
//查找到序列号所在行
if (str.contains("Serial")) {
//提取序列号
strCPU = str.substring(str.indexOf(":") + 1, str.length());
//去空格
cpuAddress = strCPU.trim();
break;
}
}
}
}
if (defaultCPUSerial.equals(cpuAddress) || TextUtils.isEmpty(cpuAddress) || Build.UNKNOWN.equals(cpuAddress)) {
if (imeiFirst) {
cpuAddress = getDevIDShort();
} else {
cpuAddress = getDeviceId(context);
if (Build.UNKNOWN.equals(cpuAddress)) {
//没有IMEI
cpuAddress = getDevIDShort();
}
}
} else if (!imeiFirst) {
cpuAddress = "A" + cpuAddress;
}
} catch (Exception ignored) {
}
return cpuAddress;
}
/**
* 获取MAC wifi
*/
@SuppressLint("HardwareIds")
public static String getWiFiMAC(Context context) {
String wifiMAC = null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
try {
// 获得IpD地址
InetAddress ip = getLocalInetAddress();
byte[] b = NetworkInterface.getByInetAddress(ip).getHardwareAddress();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < b.length; i++) {
if (i != 0) {
sb.append(':');
}
String str = Integer.toHexString(b[i] & 0xFF);
sb.append(str.length() == 1 ? 0 + str : str);
}
wifiMAC = sb.toString().toUpperCase();
} catch (Exception ignored) {
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) {
continue;
}
byte[] macBytes = nif.getHardwareAddress();
if (macBytes != null) {
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:", b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
wifiMAC = res1.toString();
}
}
} else {
WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wm != null) {
if (wm.getConnectionInfo() != null) {
wifiMAC = wm.getConnectionInfo().getMacAddress();
}
}
}
} catch (Exception ignored) {
}
return object2String(wifiMAC, Build.UNKNOWN).replace(":", "");
}
/**
* 获取Android_ID
*/
public static String getAndroid_Id(Context context) {
try {
String androidId = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
return object2String(androidId, Build.UNKNOWN);
} catch (Exception e) {
return Build.UNKNOWN;
}
}
/**
* 获取Serial Number
*/
public static String getSerialNumber() {
String serial;
try {
serial = Build.class.getField("SERIAL").get(null).toString();
} catch (Exception exception) {
//serial需要一个初始化
serial = "serial"; // 随便一个初始化
}
return object2String(serial, Build.UNKNOWN);
}
/**
* 获取IMEI
*/
@SuppressLint("HardwareIds")
private static String getDeviceId(Context context) {
try {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return Build.UNKNOWN;
} else if (telephonyManager != null) {
String imei = telephonyManager.getDeviceId();
if (TextUtils.isEmpty(imei)) {
return Build.UNKNOWN;
}
return "B" + imei;
} else {
return Build.UNKNOWN;
}
} catch (Exception e) {
return Build.UNKNOWN;
}
}
/**
* 根据设备硬件信息生成15位串号
* <p>
* Build.BRAND --设备品牌
* Build.CPU_ABI --CPU指令集
* Build.DEVICE --设备参数
* Build.DISPLAY --显示屏参数
* Build.HOST --HOST
* Build.ID --修订版本列表
* Build.MANUFACTURER --硬件制造商
* Build.MODEL --版本
* Build.PRODUCT --手机制造商
* Build.TAGS --描述build的标签
* Build.TYPE --builder类型
* Build.USER
*/
private static String getDevIDShort() {
return "C" + Build.BOARD.length() % 10 + Build.BRAND.length() % 10 + Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 + Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 + Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 + Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 + Build.TAGS.length() % 10 + Build.TYPE.length() % 10 + Build.USER.length() % 10;
}
/**
* 获取系统的其他信息组成json
*/
public static String getOther(Context context) {
StringBuilder sb = new StringBuilder();
sb.append("{");
try {
sb.append("\"kvn\":\"").append(BuildConfig.VERSION_NAME).append("\"").append(",");
sb.append("\"kvc\":\"").append(BuildConfig.VERSION_CODE).append("\"").append(",");
sb.append("\"sid\":\"").append(object2String(Build.ID)).append("\"").append(",");
sb.append("\"sdv\":\"").append(object2String(Build.DEVICE)).append("\"").append(",");
sb.append("\"sbr\":\"").append(object2String(Build.BRAND)).append("\"").append(",");
sb.append("\"smo\":\"").append(object2String(Build.MODEL)).append("\"").append(",");
sb.append("\"spd\":\"").append(object2String(Build.PRODUCT)).append("\"").append(",");
sb.append("\"smf\":\"").append(object2String(Build.MANUFACTURER)).append("\"").append(",");
sb.append("\"shw\":\"").append(object2String(Build.HARDWARE)).append("\"").append(",");
sb.append("\"sfp\":\"").append(object2String(Build.FINGERPRINT)).append("\"").append(",");
sb.append("\"stp\":\"").append(object2String(Build.TYPE)).append("\"").append(",");
sb.append("\"shs\":\"").append(object2String(Build.HOST)).append("\"").append(",");
sb.append("\"sbd\":\"").append(object2String(Build.BOARD)).append("\"").append(",");
sb.append("\"stm\":\"").append(object2String(Build.TIME)).append("\"").append(",");
sb.append("\"sca\":\"").append(object2String(Build.CPU_ABI)).append("\"").append(",");
sb.append("\"sbl\":\"").append(object2String(Build.BOOTLOADER)).append("\"").append(",");
sb.append("\"sdp\":\"").append(object2String(Build.DISPLAY)).append("\"").append(",");
sb.append("\"stg\":\"").append(object2String(Build.TAGS)).append("\"").append(",");
sb.append("\"svr\":\"").append(object2String(Build.VERSION.RELEASE)).append("\"").append(",");
sb.append("\"svs\":\"").append(object2String(Build.VERSION.SDK_INT)).append("\"").append(",");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
sb.append("\"svb\":\"").append(object2String(Build.VERSION.BASE_OS)).append("\"").append(",");
}
sb.append("\"svc\":\"").append(object2String(Build.VERSION.CODENAME)).append("\"").append(",");
sb.append("\"svi\":\"").append(object2String(Build.VERSION.INCREMENTAL)).append("\"").append(",");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
sb.append("\"svs\":\"").append(object2String(Build.VERSION.SECURITY_PATCH)).append("\"").append(",");
}
if (context != null) {
TelephonyManager phone = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
sb.append("\"avc\":\"").append(context.getPackageName()).append("\"").append(",");
sb.append("\"avn\":\"").append(getVersionName(context)).append("\"").append(",");
sb.append("\"aan\":\"").append(getAppName(context)).append("\"").append(",");
if (phone != null) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
@SuppressLint("HardwareIds") String telephone = phone.getSimSerialNumber();
if (!TextUtils.isEmpty(telephone)) {
sb.append("\"psn\":\"").append(object2String(telephone)).append("\"").append(",");
}
@SuppressLint("HardwareIds") String subscriberId = phone.getSubscriberId();
if (!TextUtils.isEmpty(subscriberId)) {
sb.append("\"psi\":\"").append(object2String(subscriberId)).append("\"").append(",");
}
}
int phoneType = phone.getPhoneType();
sb.append("\"ppt\":\"").append(object2String(phoneType)).append("\"").append(",");
String simCountryIso = phone.getSimCountryIso();
if (!TextUtils.isEmpty(simCountryIso)) {
sb.append("\"psc\":\"").append(object2String(simCountryIso)).append("\"").append(",");
}
String simOperator = phone.getSimOperator();
if (!TextUtils.isEmpty(simOperator)) {
sb.append("\"pso\":\"").append(object2String(simOperator)).append("\"").append(",");
}
String simOperatorName = phone.getSimOperatorName();
if (!TextUtils.isEmpty(simOperatorName)) {
sb.append("\"psn\":\"").append(object2String(simOperatorName)).append("\"").append(",");
}
}
if (context.getResources() != null) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
if (metrics != null) {
sb.append("\"dmd\":\"").append(object2String(metrics.density)).append("\"").append(",");
sb.append("\"ddp\":\"").append(object2String(metrics.densityDpi)).append("\"").append(",");
sb.append("\"dmx\":\"").append(object2String(metrics.xdpi)).append("\"").append(",");
sb.append("\"dmy\":\"").append(object2String(metrics.ydpi)).append("\"").append(",");
sb.append("\"dsd\":\"").append(object2String(metrics.scaledDensity)).append("\"").append(",");
}
}
}
sb = sb.deleteCharAt(sb.length() - 1);
} catch (Exception ignored) {
}
sb.append("}");
return sb.toString();
}
private static String object2String(Object object) {
return object2String(object, "");
}
private static String object2String(Object object, String defaultString) {
if (object instanceof String) {
return TextUtils.isEmpty((String) object) ? defaultString : ((String) object).trim();
} else {
return object == null ? defaultString : object.toString();
}
}
/**
* 获取移动设备本地IP
*/
private static InetAddress getLocalInetAddress() {
InetAddress ip = null;
try {
// 列举
Enumeration<NetworkInterface> en_netInterface = NetworkInterface.getNetworkInterfaces();
while (en_netInterface.hasMoreElements()) {
NetworkInterface ni = en_netInterface.nextElement();
Enumeration<InetAddress> en_ip = ni.getInetAddresses();
while (en_ip.hasMoreElements()) {
ip = en_ip.nextElement();
if (!ip.isLoopbackAddress() && !ip.getHostAddress().contains(":")) {
break;
} else {
ip = null;
}
}
if (ip != null) {
break;
}
}
} catch (SocketException ignored) {
}
return ip;
}
/**
* 获取versionName
*
* @param context 上下文
* @return
*/
private static String getVersionName(Context context) {
String versionName = "";
try {
versionName = context.getPackageManager().
getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException ignored) {
}
return versionName;
}
private static synchronized String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (Exception ignored) {
}
return null;
}
}

View File

@ -0,0 +1,67 @@
package com.heweather.owp.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.DisplayMetrics;
import android.util.TypedValue;
public class DisplayUtil {
public static int dip2px(Context context, int dp){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,context.getResources().getDisplayMetrics());
}
protected static int sp2px(Context context, int sp){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,context.getResources().getDisplayMetrics());
}
public static int px2dp(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
public static Bitmap bitmapResize(Bitmap src, float pxX, float pxY){
//压缩图片
Matrix matrix = new Matrix();
matrix.postScale(pxX / src.getWidth(), pxY / src.getHeight());
Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
return ret;
}
public static int getScreenWidth(Context context){
DisplayMetrics dm = context.getResources().getDisplayMetrics();
return dm.widthPixels;
}
public static int getScreenHeight(Context context){
DisplayMetrics dm = context.getResources().getDisplayMetrics();
return dm.heightPixels;
}
}

View File

@ -0,0 +1,881 @@
package com.heweather.owp.utils;
import com.heweather.owp.R;
public class IconUtils {
/**
* 获取白天深色天气图标
*/
public static int getDayIconDark(String weather) {
int imageId;
switch (weather) {
case "100":
imageId = R.mipmap.icon_100d;
break;
case "101":
imageId = R.mipmap.icon_101d;
break;
case "102":
imageId = R.mipmap.icon_102d;
break;
case "103":
imageId = R.mipmap.icon_103d;
break;
case "104":
imageId = R.mipmap.icon_104d;
break;
case "200":
imageId = R.mipmap.icon_200d;
break;
case "201":
imageId = R.mipmap.icon_210d;
break;
case "202":
imageId = R.mipmap.icon_202d;
break;
case "203":
imageId = R.mipmap.icon_203d;
break;
case "204":
imageId = R.mipmap.icon_204d;
break;
case "205":
imageId = R.mipmap.icon_205d;
break;
case "206":
imageId = R.mipmap.icon_206d;
break;
case "207":
imageId = R.mipmap.icon_207d;
break;
case "208":
imageId = R.mipmap.icon_208d;
break;
case "209":
imageId = R.mipmap.icon_209d;
break;
case "210":
imageId = R.mipmap.icon_210d;
break;
case "211":
imageId = R.mipmap.icon_211d;
break;
case "212":
imageId = R.mipmap.icon_212d;
break;
case "213":
imageId = R.mipmap.icon_213d;
break;
case "300":
imageId = R.mipmap.icon_300d;
break;
case "301":
imageId = R.mipmap.icon_301d;
break;
case "302":
imageId = R.mipmap.icon_302d;
break;
case "303":
imageId = R.mipmap.icon_303d;
break;
case "304":
imageId = R.mipmap.icon_304d;
break;
case "305":
imageId = R.mipmap.icon_305d;
break;
case "306":
imageId = R.mipmap.icon_306d;
break;
case "307":
imageId = R.mipmap.icon_307d;
break;
case "308":
imageId = R.mipmap.icon_308d;
break;
case "309":
imageId = R.mipmap.icon_309d;
break;
case "310":
imageId = R.mipmap.icon_310d;
break;
case "311":
imageId = R.mipmap.icon_311d;
break;
case "312":
imageId = R.mipmap.icon_312d;
break;
case "313":
imageId = R.mipmap.icon_313d;
break;
case "314":
imageId = R.mipmap.icon_314d;
break;
case "315":
imageId = R.mipmap.icon_315d;
break;
case "316":
imageId = R.mipmap.icon_316d;
break;
case "317":
imageId = R.mipmap.icon_317d;
break;
case "318":
imageId = R.mipmap.icon_318d;
break;
case "399":
imageId = R.mipmap.icon_399d;
break;
case "400":
imageId = R.mipmap.icon_400d;
break;
case "401":
imageId = R.mipmap.icon_401d;
break;
case "402":
imageId = R.mipmap.icon_402d;
break;
case "403":
imageId = R.mipmap.icon_403d;
break;
case "404":
imageId = R.mipmap.icon_404d;
break;
case "405":
imageId = R.mipmap.icon_405d;
break;
case "406":
imageId = R.mipmap.icon_406d;
break;
case "407":
imageId = R.mipmap.icon_407d;
break;
case "408":
imageId = R.mipmap.icon_408d;
break;
case "409":
imageId = R.mipmap.icon_409d;
break;
case "410":
imageId = R.mipmap.icon_410d;
break;
case "499":
imageId = R.mipmap.icon_499d;
break;
case "500":
imageId = R.mipmap.icon_500d;
break;
case "501":
imageId = R.mipmap.icon_501d;
break;
case "502":
imageId = R.mipmap.icon_502d;
break;
case "503":
imageId = R.mipmap.icon_503d;
break;
case "504":
imageId = R.mipmap.icon_504d;
break;
case "507":
imageId = R.mipmap.icon_507d;
break;
case "508":
imageId = R.mipmap.icon_508d;
break;
case "509":
imageId = R.mipmap.icon_509d;
break;
case "510":
imageId = R.mipmap.icon_510d;
break;
case "511":
imageId = R.mipmap.icon_511d;
break;
case "512":
imageId = R.mipmap.icon_512d;
break;
case "513":
imageId = R.mipmap.icon_513d;
break;
case "514":
imageId = R.mipmap.icon_514d;
break;
case "515":
imageId = R.mipmap.icon_515d;
break;
case "900":
imageId = R.mipmap.icon_900d;
break;
case "901":
imageId = R.mipmap.icon_901d;
break;
case "999":
imageId = R.mipmap.icon_999d;
break;
default:
imageId = R.mipmap.icon_100d;
break;
}
return imageId;
}
/**
* 获取白天深色天气图标
*/
public static int getNightIconDark(String weather) {
int imageId;
switch (weather) {
case "100":
imageId = R.mipmap.icon_100n;
break;
case "101":
imageId = R.mipmap.icon_101n;
break;
case "102":
imageId = R.mipmap.icon_102n;
break;
case "103":
imageId = R.mipmap.icon_103n;
break;
case "104":
imageId = R.mipmap.icon_104n;
break;
case "200":
imageId = R.mipmap.icon_200n;
break;
case "201":
imageId = R.mipmap.icon_210n;
break;
case "202":
imageId = R.mipmap.icon_202n;
break;
case "203":
imageId = R.mipmap.icon_203n;
break;
case "204":
imageId = R.mipmap.icon_204n;
break;
case "205":
imageId = R.mipmap.icon_205n;
break;
case "206":
imageId = R.mipmap.icon_206n;
break;
case "207":
imageId = R.mipmap.icon_207n;
break;
case "208":
imageId = R.mipmap.icon_208n;
break;
case "209":
imageId = R.mipmap.icon_209n;
break;
case "210":
imageId = R.mipmap.icon_210n;
break;
case "211":
imageId = R.mipmap.icon_211n;
break;
case "212":
imageId = R.mipmap.icon_212n;
break;
case "213":
imageId = R.mipmap.icon_213n;
break;
case "300":
imageId = R.mipmap.icon_300n;
break;
case "301":
imageId = R.mipmap.icon_301n;
break;
case "302":
imageId = R.mipmap.icon_302n;
break;
case "303":
imageId = R.mipmap.icon_303n;
break;
case "304":
imageId = R.mipmap.icon_304n;
break;
case "305":
imageId = R.mipmap.icon_305n;
break;
case "306":
imageId = R.mipmap.icon_306n;
break;
case "307":
imageId = R.mipmap.icon_307n;
break;
case "308":
imageId = R.mipmap.icon_308n;
break;
case "309":
imageId = R.mipmap.icon_309n;
break;
case "310":
imageId = R.mipmap.icon_310n;
break;
case "311":
imageId = R.mipmap.icon_311n;
break;
case "312":
imageId = R.mipmap.icon_312n;
break;
case "313":
imageId = R.mipmap.icon_313n;
break;
case "314":
imageId = R.mipmap.icon_314n;
break;
case "315":
imageId = R.mipmap.icon_315n;
break;
case "316":
imageId = R.mipmap.icon_316n;
break;
case "317":
imageId = R.mipmap.icon_317n;
break;
case "318":
imageId = R.mipmap.icon_318n;
break;
case "399":
imageId = R.mipmap.icon_399n;
break;
case "400":
imageId = R.mipmap.icon_400n;
break;
case "401":
imageId = R.mipmap.icon_401n;
break;
case "402":
imageId = R.mipmap.icon_402n;
break;
case "403":
imageId = R.mipmap.icon_403n;
break;
case "404":
imageId = R.mipmap.icon_404n;
break;
case "405":
imageId = R.mipmap.icon_405n;
break;
case "406":
imageId = R.mipmap.icon_406n;
break;
case "407":
imageId = R.mipmap.icon_407n;
break;
case "408":
imageId = R.mipmap.icon_408n;
break;
case "409":
imageId = R.mipmap.icon_409n;
break;
case "410":
imageId = R.mipmap.icon_410n;
break;
case "499":
imageId = R.mipmap.icon_499n;
break;
case "500":
imageId = R.mipmap.icon_500n;
break;
case "501":
imageId = R.mipmap.icon_501n;
break;
case "502":
imageId = R.mipmap.icon_502n;
break;
case "503":
imageId = R.mipmap.icon_503n;
break;
case "504":
imageId = R.mipmap.icon_504n;
break;
case "507":
imageId = R.mipmap.icon_507n;
break;
case "508":
imageId = R.mipmap.icon_508n;
break;
case "509":
imageId = R.mipmap.icon_509n;
break;
case "510":
imageId = R.mipmap.icon_510n;
break;
case "511":
imageId = R.mipmap.icon_511n;
break;
case "512":
imageId = R.mipmap.icon_512n;
break;
case "513":
imageId = R.mipmap.icon_513n;
break;
case "514":
imageId = R.mipmap.icon_514n;
break;
case "515":
imageId = R.mipmap.icon_515n;
break;
case "900":
imageId = R.mipmap.icon_900n;
break;
case "901":
imageId = R.mipmap.icon_901n;
break;
case "999":
imageId = R.mipmap.icon_999n;
break;
default:
imageId = R.mipmap.icon_100n;
break;
}
return imageId;
}
/**
* 获取白天背景
*/
public static int getDayBack(String weather) {
int imageId;
switch (weather) {
case "100":
imageId = R.mipmap.back_100d;
break;
case "101":
imageId = R.mipmap.back_101d;
break;
case "102":
imageId = R.mipmap.back_102d;
break;
case "103":
imageId = R.mipmap.back_103d;
break;
case "104":
imageId = R.mipmap.back_104d;
break;
case "200":
imageId = R.mipmap.back_200d;
break;
case "201":
imageId = R.mipmap.back_210d;
break;
case "202":
imageId = R.mipmap.back_202d;
break;
case "203":
imageId = R.mipmap.back_203d;
break;
case "204":
imageId = R.mipmap.back_204d;
break;
case "205":
imageId = R.mipmap.back_205d;
break;
case "206":
imageId = R.mipmap.back_206d;
break;
case "207":
imageId = R.mipmap.back_207d;
break;
case "208":
imageId = R.mipmap.back_208d;
break;
case "209":
imageId = R.mipmap.back_209d;
break;
case "210":
imageId = R.mipmap.back_210d;
break;
case "211":
imageId = R.mipmap.back_211d;
break;
case "212":
imageId = R.mipmap.back_212d;
break;
case "213":
imageId = R.mipmap.back_213d;
break;
case "300":
imageId = R.mipmap.back_300d;
break;
case "301":
imageId = R.mipmap.back_301d;
break;
case "302":
imageId = R.mipmap.back_302d;
break;
case "303":
imageId = R.mipmap.back_303d;
break;
case "304":
imageId = R.mipmap.back_304d;
break;
case "305":
imageId = R.mipmap.back_305d;
break;
case "306":
imageId = R.mipmap.back_306d;
break;
case "307":
imageId = R.mipmap.back_307d;
break;
case "308":
imageId = R.mipmap.back_308d;
break;
case "309":
imageId = R.mipmap.back_309d;
break;
case "310":
imageId = R.mipmap.back_310d;
break;
case "311":
imageId = R.mipmap.back_311d;
break;
case "312":
imageId = R.mipmap.back_312d;
break;
case "313":
imageId = R.mipmap.back_313d;
break;
case "314":
imageId = R.mipmap.back_314d;
break;
case "315":
imageId = R.mipmap.back_315d;
break;
case "316":
imageId = R.mipmap.back_316d;
break;
case "317":
imageId = R.mipmap.back_317d;
break;
case "318":
imageId = R.mipmap.back_318d;
break;
case "399":
imageId = R.mipmap.back_399d;
break;
case "400":
imageId = R.mipmap.back_400d;
break;
case "401":
imageId = R.mipmap.back_401d;
break;
case "402":
imageId = R.mipmap.back_402d;
break;
case "403":
imageId = R.mipmap.back_403d;
break;
case "404":
imageId = R.mipmap.back_404d;
break;
case "405":
imageId = R.mipmap.back_405d;
break;
case "406":
imageId = R.mipmap.back_406d;
break;
case "407":
imageId = R.mipmap.back_407d;
break;
case "408":
imageId = R.mipmap.back_408d;
break;
case "409":
imageId = R.mipmap.back_409d;
break;
case "410":
imageId = R.mipmap.back_410d;
break;
case "499":
imageId = R.mipmap.back_499d;
break;
case "500":
imageId = R.mipmap.back_500d;
break;
case "501":
imageId = R.mipmap.back_501d;
break;
case "502":
imageId = R.mipmap.back_502d;
break;
case "503":
imageId = R.mipmap.back_503d;
break;
case "504":
imageId = R.mipmap.back_504d;
break;
case "507":
imageId = R.mipmap.back_507d;
break;
case "508":
imageId = R.mipmap.back_508d;
break;
case "509":
imageId = R.mipmap.back_509d;
break;
case "510":
imageId = R.mipmap.back_510d;
break;
case "511":
imageId = R.mipmap.back_511d;
break;
case "512":
imageId = R.mipmap.back_512d;
break;
case "513":
imageId = R.mipmap.back_513d;
break;
case "514":
imageId = R.mipmap.back_514d;
break;
case "515":
imageId = R.mipmap.back_515d;
break;
case "900":
imageId = R.mipmap.back_900d;
break;
case "901":
imageId = R.mipmap.back_901d;
break;
case "999":
imageId = R.mipmap.back_999d;
break;
default:
imageId = R.mipmap.back_100d;
break;
}
return imageId;
}
/**
* 获取晚上背景
*/
public static int getNightBack(String weather) {
int imageId;
switch (weather) {
case "100":
imageId = R.mipmap.back_100n;
break;
case "101":
imageId = R.mipmap.back_101n;
break;
case "102":
imageId = R.mipmap.back_102n;
break;
case "103":
imageId = R.mipmap.back_103n;
break;
case "104":
imageId = R.mipmap.back_104n;
break;
case "200":
imageId = R.mipmap.back_200n;
break;
case "201":
imageId = R.mipmap.back_210n;
break;
case "202":
imageId = R.mipmap.back_202n;
break;
case "203":
imageId = R.mipmap.back_203n;
break;
case "204":
imageId = R.mipmap.back_204n;
break;
case "205":
imageId = R.mipmap.back_205n;
break;
case "206":
imageId = R.mipmap.back_206n;
break;
case "207":
imageId = R.mipmap.back_207n;
break;
case "208":
imageId = R.mipmap.back_208n;
break;
case "209":
imageId = R.mipmap.back_209n;
break;
case "210":
imageId = R.mipmap.back_210n;
break;
case "211":
imageId = R.mipmap.back_211n;
break;
case "212":
imageId = R.mipmap.back_212n;
break;
case "213":
imageId = R.mipmap.back_213n;
break;
case "300":
imageId = R.mipmap.back_300n;
break;
case "301":
imageId = R.mipmap.back_301n;
break;
case "302":
imageId = R.mipmap.back_302n;
break;
case "303":
imageId = R.mipmap.back_303n;
break;
case "304":
imageId = R.mipmap.back_304n;
break;
case "305":
imageId = R.mipmap.back_305n;
break;
case "306":
imageId = R.mipmap.back_306n;
break;
case "307":
imageId = R.mipmap.back_307n;
break;
case "308":
imageId = R.mipmap.back_308n;
break;
case "309":
imageId = R.mipmap.back_309n;
break;
case "310":
imageId = R.mipmap.back_310n;
break;
case "311":
imageId = R.mipmap.back_311n;
break;
case "312":
imageId = R.mipmap.back_312n;
break;
case "313":
imageId = R.mipmap.back_313n;
break;
case "314":
imageId = R.mipmap.back_314n;
break;
case "315":
imageId = R.mipmap.back_315n;
break;
case "316":
imageId = R.mipmap.back_316n;
break;
case "317":
imageId = R.mipmap.back_317n;
break;
case "318":
imageId = R.mipmap.back_318n;
break;
case "399":
imageId = R.mipmap.back_399n;
break;
case "400":
imageId = R.mipmap.back_400n;
break;
case "401":
imageId = R.mipmap.back_401n;
break;
case "402":
imageId = R.mipmap.back_402n;
break;
case "403":
imageId = R.mipmap.back_403n;
break;
case "404":
imageId = R.mipmap.back_404n;
break;
case "405":
imageId = R.mipmap.back_405n;
break;
case "406":
imageId = R.mipmap.back_406n;
break;
case "407":
imageId = R.mipmap.back_407n;
break;
case "408":
imageId = R.mipmap.back_408n;
break;
case "409":
imageId = R.mipmap.back_409n;
break;
case "410":
imageId = R.mipmap.back_410n;
break;
case "499":
imageId = R.mipmap.back_499n;
break;
case "500":
imageId = R.mipmap.back_500n;
break;
case "501":
imageId = R.mipmap.back_501n;
break;
case "502":
imageId = R.mipmap.back_502n;
break;
case "503":
imageId = R.mipmap.back_503n;
break;
case "504":
imageId = R.mipmap.back_504n;
break;
case "507":
imageId = R.mipmap.back_507n;
break;
case "508":
imageId = R.mipmap.back_508n;
break;
case "509":
imageId = R.mipmap.back_509n;
break;
case "510":
imageId = R.mipmap.back_510n;
break;
case "511":
imageId = R.mipmap.back_511n;
break;
case "512":
imageId = R.mipmap.back_512n;
break;
case "513":
imageId = R.mipmap.back_513n;
break;
case "514":
imageId = R.mipmap.back_514n;
break;
case "515":
imageId = R.mipmap.back_515n;
break;
case "900":
imageId = R.mipmap.back_900n;
break;
case "901":
imageId = R.mipmap.back_901n;
break;
case "999":
imageId = R.mipmap.back_999n;
break;
default:
imageId = R.mipmap.back_100n;
break;
}
return imageId;
}
}

View File

@ -0,0 +1,65 @@
package com.heweather.owp.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
/**
* Created by lianchong on 2018/1/23.
*/
public class NetStateUtils {
/**
* 获取当前的网络状态 没有网络-0WIFI网络14G网络-43G网络-32G网络-2
* 自定义
*/
public static boolean getAPNType(Context context) {
boolean netType;
//获取手机所有连接管理对象
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//获取NetworkInfo对象
NetworkInfo networkInfo = null;
if (manager != null) {
networkInfo = manager.getActiveNetworkInfo();
}
//NetworkInfo对象为空 则代表没有网络
if (networkInfo == null) {
//无网络
netType = false;
} else {
//有网
netType = true;
}
return netType;
}
public static boolean isWifiConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWiFiNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWiFiNetworkInfo != null) {
return mWiFiNetworkInfo.isAvailable();
}
}
return false;
}
/**
* 判断MOBILE网络是否可用
*
* @param context
* @return
*/
public static boolean isMobileConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mMobileNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mMobileNetworkInfo != null) {
return mMobileNetworkInfo.isAvailable();
}
}
return false;
}
}

View File

@ -0,0 +1,318 @@
package com.heweather.owp.utils;
import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.widget.Toast;
import com.heweather.owp.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by niuchong on 2018/5/16.
*/
public class PermissionUtils {
private static final String TAG = PermissionUtils.class.getSimpleName();
public static final int CODE_READ_PHONE_STATE = 1;
public static final int CODE_ACCESS_FINE_LOCATION = 2;
public static final int CODE_ACCESS_COARSE_LOCATION = 3;
public static final int CODE_ACCESS_LOCATION_EXTRA_COMMANDS = 4;
public static final int CODE_READ_EXTERNAL_STORAGE = 5;
public static final int CODE_WRITE_EXTERNAL_STORAGE = 6;
public static final int CODE_MULTI_PERMISSION = 100;
public static final String PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE;
public static final String PERMISSION_ACCESS_FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
public static final String PERMISSION_ACCESS_COARSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
public static final String PERMISSION_ACCESS_LOCATION_EXTRA_COMMANDS = Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS;
public static final String PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;
public static final String PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;
private static final String[] requestPermissions = {
PERMISSION_READ_PHONE_STATE,
PERMISSION_ACCESS_FINE_LOCATION,
PERMISSION_ACCESS_COARSE_LOCATION,
PERMISSION_ACCESS_LOCATION_EXTRA_COMMANDS,
PERMISSION_READ_EXTERNAL_STORAGE,
PERMISSION_WRITE_EXTERNAL_STORAGE
};
public interface PermissionGrant {
void onPermissionGranted(int requestCode);
}
/**
* Requests permission.
*
* @param activity
* @param requestCode request code, e.g. if you need request CAMERA permission,parameters is PermissionUtils.CODE_CAMERA
*/
public static void requestPermission(final Activity activity, final int requestCode, PermissionGrant permissionGrant) {
if (activity == null) {
return;
}
if (requestCode < 0 || requestCode >= requestPermissions.length) {
Log.w(TAG, "requestPermission illegal requestCode:" + requestCode);
return;
}
final String requestPermission = requestPermissions[requestCode];
//如果是6.0以下的手机ActivityCompat.checkSelfPermission()会始终等于PERMISSION_GRANTED
// 但是如果用户关闭了你申请的权限ActivityCompat.checkSelfPermission(),会导致程序崩溃(java.lang.RuntimeException: Unknown exception code: 1 msg null)
// 你可以使用try{}catch(){},处理异常也可以在这个地方低于23就什么都不做
// 个人建议try{}catch(){}单独处理提示用户开启权限
// if (Build.VERSION.SDK_INT < 23) {
// return;
// }
int checkSelfPermission;
try {
checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission);
} catch (RuntimeException e) {
Toast.makeText(activity, "please open this permission", Toast.LENGTH_SHORT)
.show();
return;
}
if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
// Log.i(TAG, "ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED");
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) {
// Log.i(TAG, "requestPermission shouldShowRequestPermissionRationale");
shouldShowRationale(activity, requestCode, requestPermission);
} else {
ActivityCompat.requestPermissions(activity, new String[]{requestPermission}, requestCode);
}
} else {
// Toast.makeText(activity, "opened:" + requestPermissions[requestCode], Toast.LENGTH_SHORT).show();
permissionGrant.onPermissionGranted(requestCode);
}
}
private static void requestMultiResult(Activity activity, String[] permissions, int[] grantResults, PermissionGrant permissionGrant) {
if (activity == null) {
return;
}
Log.d(TAG, "onRequestPermissionsResult permissions length:" + permissions.length);
Map<String, Integer> perms = new HashMap<>();
ArrayList<String> notGranted = new ArrayList<>();
for (int i = 0; i < permissions.length; i++) {
Log.d(TAG, "permissions: [i]:" + i + ", permissions[i]" + permissions[i] + ",grantResults[i]:" + grantResults[i]);
perms.put(permissions[i], grantResults[i]);
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
notGranted.add(permissions[i]);
}
}
if (notGranted.size() == 0) {
// Toast.makeText(activity, "all permission success" + notGranted, Toast.LENGTH_SHORT)
// .show();
permissionGrant.onPermissionGranted(CODE_MULTI_PERMISSION);
} else {
openSettingActivity(activity, "those permission need granted!");
}
}
/**
* 一次申请多个权限
*/
public static void requestMultiPermissions(final Activity activity, PermissionGrant grant) {
final List<String> permissionsList = getNoGrantedPermission(activity, false);
final List<String> shouldRationalePermissionsList = getNoGrantedPermission(activity, true);
// checkSelfPermission
if (permissionsList == null || shouldRationalePermissionsList == null) {
return;
}
Log.d(TAG, "requestMultiPermissions permissionsList:" + permissionsList.size() + ",shouldRationalePermissionsList:" + shouldRationalePermissionsList.size());
if (permissionsList.size() > 0) {
ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String[permissionsList.size()]),
CODE_MULTI_PERMISSION);
Log.d(TAG, "showMessageOKCancel requestPermissions");
} else if (shouldRationalePermissionsList.size() > 0) {
ActivityCompat.requestPermissions(activity, shouldRationalePermissionsList.toArray(new String[shouldRationalePermissionsList.size()]),
CODE_MULTI_PERMISSION);
// showMessageOKCancel(activity, "should open those permission",
// new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// ActivityCompat.requestPermissions(activity, shouldRationalePermissionsList.toArray(new String[shouldRationalePermissionsList.size()]),
// CODE_MULTI_PERMISSION);
// Log.d(TAG, "showMessageOKCancel requestPermissions");
// }
// });
} else {
grant.onPermissionGranted(CODE_MULTI_PERMISSION);
}
}
private static void shouldShowRationale(final Activity activity, final int requestCode, final String requestPermission) {
String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions);
ActivityCompat.requestPermissions(activity,
new String[]{
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
},
requestCode);
// showMessageOKCancel(activity, "Rationale: " + permissionsHint[requestCode], new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// ActivityCompat.requestPermissions(activity,
// new String[]{requestPermission},
// requestCode);
// Log.d(TAG, "showMessageOKCancel requestPermissions:" + requestPermission);
// }
// });
}
private static void showMessageOKCancel(final Activity context, String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(context)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
/**
* @param activity
* @param requestCode Need consistent with requestPermission
* @param permissions
* @param grantResults
*/
public static void requestPermissionsResult(final Activity activity, final int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults, PermissionGrant permissionGrant) {
if (activity == null) {
return;
}
Log.d(TAG, "requestPermissionsResult requestCode:" + requestCode);
if (requestCode == CODE_MULTI_PERMISSION) {
requestMultiResult(activity, permissions, grantResults, permissionGrant);
return;
}
if (requestCode < 0 || requestCode >= requestPermissions.length) {
Log.w(TAG, "requestPermissionsResult illegal requestCode:" + requestCode);
// Toast.makeText(activity, "illegal requestCode:" + requestCode, Toast.LENGTH_SHORT).show();
return;
}
Log.i(TAG, "onRequestPermissionsResult requestCode:" + requestCode + ",permissions:" + permissions.toString()
+ ",grantResults:" + grantResults.toString() + ",length:" + grantResults.length);
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult PERMISSION_GRANTED");
// success, do something, can use callback
permissionGrant.onPermissionGranted(requestCode);
} else {
// hint user this permission function
Log.i(TAG, "onRequestPermissionsResult PERMISSION NOT GRANTED");
String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions);
openSettingActivity(activity, "Result" + permissionsHint[requestCode]);
}
}
private static void openSettingActivity(final Activity activity, String message) {
// Intent intent = new Intent();
// intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
// Log.d(TAG, "getPackageName(): " + activity.getPackageName());
// Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
// intent.setData(uri);
// activity.startActivity(intent);
// showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// Intent intent = new Intent();
// intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
// Log.d(TAG, "getPackageName(): " + activity.getPackageName());
// Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
// intent.setData(uri);
// activity.startActivity(intent);
// }
// });
}
/**
* @param activity
* @param isShouldRationale true: return no granted and shouldShowRequestPermissionRationale permissions, false:return no granted and !shouldShowRequestPermissionRationale
* @return
*/
public static ArrayList<String> getNoGrantedPermission(Activity activity, boolean isShouldRationale) {
ArrayList<String> permissions = new ArrayList<>();
for (int i = 0; i < requestPermissions.length; i++) {
String requestPermission = requestPermissions[i];
// checkSelfPermission
int checkSelfPermission = -1;
try {
checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission);
} catch (RuntimeException e) {
// Toast.makeText(activity, "please open those permission", Toast.LENGTH_SHORT)
// .show();
Log.e(TAG, "RuntimeException:" + e.getMessage());
return null;
}
if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "getNoGrantedPermission ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED:" + requestPermission);
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) {
Log.d(TAG, "shouldShowRequestPermissionRationale if");
if (isShouldRationale) {
permissions.add(requestPermission);
}
} else {
if (!isShouldRationale) {
permissions.add(requestPermission);
}
Log.d(TAG, "shouldShowRequestPermissionRationale else");
}
}
}
return permissions;
}
}

View File

@ -0,0 +1,477 @@
package com.heweather.owp.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by niuchong on 2018/5/29.
*/
public class SpUtils {
public static String PREFERENCE_NAME = "HeOpenApp";
/**
* 清空统计数据
*
* @param context
*/
public static void clearSp(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.clear().commit();
}
/**
* put string preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putString(Context context, String key, String value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(key, value);
return editor.commit();
}
/**
* get string preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or null. Throws ClassCastException if there is a preference with this
* name that is not a string
* @see #getString(Context, String, String)
*/
public static String getString(Context context, String key) {
return getString(context, key, null);
}
/**
* get string preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a string
*/
public static String getString(Context context, String key, String defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getString(key, defaultValue);
}
/**
* put int preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putInt(Context context, String key, int value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(key, value);
return editor.commit();
}
/**
* get int preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a int
* @see #getInt(Context, String, int)
*/
public static int getInt(Context context, String key) {
return getInt(context, key, -1);
}
/**
* get int preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a int
*/
public static int getInt(Context context, String key, int defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getInt(key, defaultValue);
}
/**
* put long preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putLong(Context context, String key, long value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putLong(key, value);
return editor.commit();
}
/**
* get long preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a long
* @see #getLong(Context, String, long)
*/
public static long getLong(Context context, String key) {
return getLong(context, key, -1);
}
/**
* get long preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a long
*/
public static long getLong(Context context, String key, long defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getLong(key, defaultValue);
}
/**
* put float preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putFloat(Context context, String key, float value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putFloat(key, value);
return editor.commit();
}
/**
* get float preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a float
* @see #getFloat(Context, String, float)
*/
public static float getFloat(Context context, String key) {
return getFloat(context, key, -1);
}
/**
* get float preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a float
*/
public static float getFloat(Context context, String key, float defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getFloat(key, defaultValue);
}
/**
* put boolean preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putBoolean(Context context, String key, boolean value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(key, value);
return editor.commit();
}
/**
* get boolean preferences, default is false
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or false. Throws ClassCastException if there is a preference with this
* name that is not a boolean
* @see #getBoolean(Context, String, boolean)
*/
public static boolean getBoolean(Context context, String key) {
return getBoolean(context, key, false);
}
/**
* get boolean preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a boolean
*/
public static boolean getBoolean(Context context, String key, boolean defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getBoolean(key, defaultValue);
}
public static String SceneList2String(HashMap<String, Integer> hashmap)
throws IOException {
// 实例化一个ByteArrayOutputStream对象用来装载压缩后的字节文件
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 然后将得到的字符数据装载到ObjectOutputStream
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
byteArrayOutputStream);
// writeObject 方法负责写入特定类的对象的状态以便相应的 readObject 方法可以还原它
objectOutputStream.writeObject(hashmap);
// 最后用Base64.encode将字节文件转换成Base64编码保存在String中
String SceneListString = new String(Base64.encode(
byteArrayOutputStream.toByteArray(), Base64.DEFAULT));
// 关闭objectOutputStream
objectOutputStream.close();
return SceneListString;
}
@SuppressWarnings("unchecked")
public static HashMap<String, Integer> String2SceneList(
String SceneListString) throws StreamCorruptedException,
IOException, ClassNotFoundException {
byte[] mobileBytes = Base64.decode(SceneListString.getBytes(),
Base64.DEFAULT);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
mobileBytes);
ObjectInputStream objectInputStream = new ObjectInputStream(
byteArrayInputStream);
HashMap<String, Integer> SceneList = (HashMap<String, Integer>) objectInputStream
.readObject();
objectInputStream.close();
return SceneList;
}
public static boolean putHashMap(Context context, String key,
HashMap<String, Integer> hashmap) {
SharedPreferences settings = context.getSharedPreferences(
PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
try {
String listStr = SceneList2String(hashmap);
editor.putString(key, listStr);
} catch (IOException e) {
e.printStackTrace();
}
return editor.commit();
}
public static HashMap<String, Integer> getHashMap(Context context,
String key) {
SharedPreferences settings = context.getSharedPreferences(
PREFERENCE_NAME, Context.MODE_PRIVATE);
String listStr = settings.getString(key, "");
try {
return String2SceneList(listStr);
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 保存List<String>
*
* @param key
* @param values
*/
public static boolean putStringList(Context context, String key, List<String> values) {
SharedPreferences.Editor edit = context.getSharedPreferences(
PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
edit.putInt(key, values.size());
for (int i = 0; i < values.size(); i++) {
edit.putString(key + i, values.get(i));
}
return edit.commit();
}
/**
* 获取List<String>
*
* @param key
* @return
*/
public static List<String> getStringList(Context context, String key) {
List<String> values = new ArrayList<>();
SharedPreferences sp = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
int listSize = sp.getInt(key, 0);
for (int i = 0; i < listSize; i++) {
values.add(sp.getString(key + i, null));
}
return values;
}
/**
* 保存List<Integer>
*
* @param key
* @param values
*/
public static boolean putIntList(Context context, String key, List<Integer> values) {
SharedPreferences.Editor edit = context.getSharedPreferences(
PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
edit.putInt(key, values.size());
for (int i = 0; i < values.size(); i++) {
edit.putInt(key + i, values.get(i));
}
return edit.commit();
}
/**
* 获取List<Integer>
*
* @param key
* @return
*/
public static List<Integer> getIntList(Context context, String key) {
List<Integer> values = new ArrayList<>();
SharedPreferences sp = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
int listSize = sp.getInt(key, 0);
for (int i = 0; i < listSize; i++) {
values.add(sp.getInt(key + i, 0));
}
return values;
}
/**
* 保存List<Long>
*
* @param key
* @param values
*/
public static boolean putLongList(Context context, String key, List<Long> values) {
SharedPreferences.Editor edit = context.getSharedPreferences(
PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
edit.putInt(key, values.size());
for (int i = 0; i < values.size(); i++) {
edit.putLong(key + i, values.get(i));
}
return edit.commit();
}
/**
* 获取List<Long>
*
* @param key
* @return
*/
public static List<Long> getLongList(Context context, String key) {
List<Long> values = new ArrayList<>();
SharedPreferences sp = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
int listSize = sp.getInt(key, 0);
for (int i = 0; i < listSize; i++) {
values.add(sp.getLong(key + i, 0));
}
return values;
}
/**
* 保存List<Object>
*
* @param context
* @param key
* @param datalist
*/
public <T> void putListBean(Context context, String key, List<T> datalist) {
SharedPreferences.Editor edit = context.getSharedPreferences(
PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
if (null == datalist || datalist.size() <= 0) {
return;
}
Gson gson = new Gson();
//转换成json数据再保存
String strJson = gson.toJson(datalist);
edit.putString(key, strJson);
edit.commit();
}
/**
* 获取List<Object>
*
* @param context
* @param key
* @return listBean
*/
public <T> List<T> getListBean(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
List<T> dataList = new ArrayList<T>();
String strJson = sp.getString(key, null);
if (null == strJson) {
return dataList;
}
Gson gson = new Gson();
dataList = gson.fromJson(strJson, new TypeToken<List<T>>() {
}.getType());
return dataList;
}
/**
* 存放实体类以及任意类型
*
* @param context 上下文对象
* @param key
* @param obj
*/
public static void saveBean(Context context, String key,
Object obj) {
SharedPreferences.Editor editor = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
Gson gson = new Gson();
String objString = gson.toJson(obj);
editor.putString(key, objString).commit();
}
/**
* @param context
* @param key
* @param clazz 这里传入一个类就是我们所需要的实体类(obj)
* @return 返回我们封装好的该实体类(obj)
*/
public static <T> T getBean(Context context, String key,
Class<T> clazz) {
String objString = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE).getString(key, "");
Gson gson = new Gson();
return gson.fromJson(objString, clazz);
}
}

View File

@ -0,0 +1,276 @@
package com.heweather.owp.utils;
public class TransUnitUtil {
public static int getInt(String value) {
try {
int i = Integer.parseInt(value);
return i;
} catch (Exception e) {
return 0;
}
}
public static long getF(String value) {
try {
long i = Integer.parseInt(value);
i = Math.round((i * 1.8 + 32));
return i;
} catch (Exception e) {
return 0;
}
}
public static double getDouble(String value) {
try {
double i = Double.parseDouble(value);
return i;
} catch (Exception e) {
return 0.00;
}
}
public static int getCNIAQI(double score, String aqiItem) {
if (score <= 0) {
return 0;
}
double iaqihi, iaqilo, bphi, bplo;
switch (aqiItem) {
case "so2":
if (score <= 150) {
bphi = 150;
bplo = 0;
iaqihi = 50;
iaqilo = 0;
} else if (score <= 500) {
bphi = 500;
bplo = 150;
iaqihi = 100;
iaqilo = 50;
} else if (score <= 650) {
bphi = 650;
bplo = 500;
iaqihi = 150;
iaqilo = 100;
} else if (score <= 800) {
bphi = 800;
bplo = 650;
iaqihi = 200;
iaqilo = 150;
} else if (score <= 1600) {
bphi = 1600;
bplo = 800;
iaqihi = 300;
iaqilo = 200;
} else if (score <= 2100) {
bphi = 2100;
bplo = 1600;
iaqihi = 400;
iaqilo = 300;
} else {
bphi = 2620;
bplo = 2100;
iaqihi = 500;
iaqilo = 400;
}
break;
case "no2":
if (score <= 100) {
bphi = 100;
bplo = 0;
iaqihi = 50;
iaqilo = 0;
} else if (score <= 200) {
bphi = 200;
bplo = 100;
iaqihi = 100;
iaqilo = 50;
} else if (score <= 700) {
bphi = 700;
bplo = 200;
iaqihi = 150;
iaqilo = 100;
} else if (score <= 1200) {
bphi = 1200;
bplo = 700;
iaqihi = 200;
iaqilo = 150;
} else if (score <= 2340) {
bphi = 2340;
bplo = 1200;
iaqihi = 300;
iaqilo = 200;
} else if (score <= 3090) {
bphi = 3090;
bplo = 2340;
iaqihi = 400;
iaqilo = 300;
} else {
bphi = 3840;
bplo = 3090;
iaqihi = 500;
iaqilo = 400;
}
break;
case "pm10":
if (score <= 50) {
bphi = 50;
bplo = 0;
iaqihi = 50;
iaqilo = 0;
} else if (score <= 150) {
bphi = 150;
bplo = 50;
iaqihi = 100;
iaqilo = 50;
} else if (score <= 250) {
bphi = 250;
bplo = 150;
iaqihi = 150;
iaqilo = 100;
} else if (score <= 350) {
bphi = 350;
bplo = 250;
iaqihi = 200;
iaqilo = 150;
} else if (score <= 420) {
bphi = 420;
bplo = 350;
iaqihi = 300;
iaqilo = 200;
} else if (score <= 500) {
bphi = 500;
bplo = 420;
iaqihi = 400;
iaqilo = 300;
} else {
bphi = 600;
bplo = 500;
iaqihi = 500;
iaqilo = 400;
}
break;
case "co":
if (score <= 5) {
bphi = 5;
bplo = 0;
iaqihi = 50;
iaqilo = 0;
} else if (score <= 10) {
bphi = 10;
bplo = 5;
iaqihi = 100;
iaqilo = 50;
} else if (score <= 35) {
bphi = 35;
bplo = 10;
iaqihi = 150;
iaqilo = 100;
} else if (score <= 60) {
bphi = 60;
bplo = 35;
iaqihi = 200;
iaqilo = 150;
} else if (score <= 90) {
bphi = 90;
bplo = 60;
iaqihi = 300;
iaqilo = 200;
} else if (score <= 120) {
bphi = 120;
bplo = 90;
iaqihi = 400;
iaqilo = 300;
} else {
bphi = 150;
bplo = 120;
iaqihi = 500;
iaqilo = 400;
}
break;
case "o3":
if (score <= 160) {
bphi = 160;
bplo = 0;
iaqihi = 50;
iaqilo = 0;
} else if (score <= 200) {
bphi = 200;
bplo = 160;
iaqihi = 100;
iaqilo = 50;
} else if (score <= 300) {
bphi = 300;
bplo = 200;
iaqihi = 150;
iaqilo = 100;
} else if (score <= 400) {
bphi = 400;
bplo = 300;
iaqihi = 200;
iaqilo = 150;
} else if (score <= 800) {
bphi = 800;
bplo = 400;
iaqihi = 300;
iaqilo = 200;
} else if (score <= 1000) {
bphi = 1000;
bplo = 800;
iaqihi = 400;
iaqilo = 300;
} else {
bphi = 1200;
bplo = 1000;
iaqihi = 500;
iaqilo = 400;
}
break;
case "pm25":
if (score <= 35) {
bphi = 35;
bplo = 0;
iaqihi = 50;
iaqilo = 0;
} else if (score <= 75) {
bphi = 75;
bplo = 35;
iaqihi = 100;
iaqilo = 50;
} else if (score <= 115) {
bphi = 115;
bplo = 75;
iaqihi = 150;
iaqilo = 100;
} else if (score <= 150) {
bphi = 150;
bplo = 115;
iaqihi = 200;
iaqilo = 150;
} else if (score <= 250) {
bphi = 250;
bplo = 150;
iaqihi = 300;
iaqilo = 200;
} else if (score <= 350) {
bphi = 350;
bplo = 250;
iaqihi = 400;
iaqilo = 300;
} else {
bphi = 500;
bplo = 350;
iaqihi = 500;
iaqilo = 400;
}
break;
default:
return 0;
}
return Math.min((int) Math.ceil((iaqihi - iaqilo) * (score - bplo) / (bphi - bplo) + iaqilo), 500);
}
}

View File

@ -0,0 +1,767 @@
package com.heweather.owp.view;//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build.VERSION;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.annotation.RestrictTo.Scope;
import android.support.annotation.VisibleForTesting;
import android.support.design.R.dimen;
import android.support.design.R.styleable;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.CoordinatorLayout.Behavior;
import android.support.v4.math.MathUtils;
import android.support.v4.view.AbsSavedState;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.support.v4.widget.ViewDragHelper.Callback;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import com.heweather.owp.MyApplication;
import com.heweather.owp.utils.DisplayUtil;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class MyBottomBehavior<V extends View> extends Behavior<V> {
public static final int STATE_DRAGGING = 1;
public static final int STATE_SETTLING = 2;
public static final int STATE_EXPANDED = 3;
public static final int STATE_COLLAPSED = 4;
public static final int STATE_HIDDEN = 5;
public static final int STATE_HALF_EXPANDED = 6;
public static final int PEEK_HEIGHT_AUTO = -1;
private static final float HIDE_THRESHOLD = 0.5F;
private static final float HIDE_FRICTION = 0.1F;
private boolean fitToContents = true;
private float maximumVelocity;
private int peekHeight;
private boolean peekHeightAuto;
private int peekHeightMin;
private int lastPeekHeight;
int fitToContentsOffset;
int halfExpandedOffset;
int collapsedOffset;
boolean hideable;
private boolean skipCollapsed;
int state = 4;
ViewDragHelper viewDragHelper;
private boolean ignoreEvents;
private int lastNestedScrollDy;
private boolean nestedScrolled;
int parentHeight;
WeakReference<V> viewRef;
WeakReference<View> nestedScrollingChildRef;
private MyBottomBehavior.BottomSheetCallback callback;
private VelocityTracker velocityTracker;
int activePointerId;
private int initialY;
boolean touchingScrollingChild;
private Map<View, Integer> importantForAccessibilityMap;
private final Callback dragCallback = new Callback() {
public boolean tryCaptureView(@NonNull View child, int pointerId) {
if (MyBottomBehavior.this.state == 1) {
return false;
} else if (MyBottomBehavior.this.touchingScrollingChild) {
return false;
} else {
if (MyBottomBehavior.this.state == 3 && MyBottomBehavior.this.activePointerId == pointerId) {
View scroll = (View) MyBottomBehavior.this.nestedScrollingChildRef.get();
if (scroll != null && scroll.canScrollVertically(-1)) {
return false;
}
}
return MyBottomBehavior.this.viewRef != null && MyBottomBehavior.this.viewRef.get() == child;
}
}
public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
MyBottomBehavior.this.dispatchOnSlide(top);
}
public void onViewDragStateChanged(int state) {
if (state == 1) {
MyBottomBehavior.this.setStateInternal(1);
}
}
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
int top;
byte targetState;
int currentTop;
if (yvel < 0.0F) {//上滑
currentTop = releasedChild.getTop();
if (currentTop >= MyBottomBehavior.this.halfExpandedOffset) {
top = MyBottomBehavior.this.halfExpandedOffset;
targetState = 6;
} else {
top = 0;
targetState = 3;
}
} else if (!MyBottomBehavior.this.hideable || !MyBottomBehavior.this.shouldHide(releasedChild, yvel) || releasedChild.getTop() <= MyBottomBehavior.this.collapsedOffset && Math.abs(xvel) >= Math.abs(yvel)) {
currentTop = releasedChild.getTop();
if (currentTop == 0){
top = 0;
targetState = 3;
}else if (currentTop <= MyBottomBehavior.this.halfExpandedOffset) {
top = MyBottomBehavior.this.halfExpandedOffset;
targetState = 6;
} else {
top = MyBottomBehavior.this.collapsedOffset;
targetState = 4;
}
} else {
top = MyBottomBehavior.this.parentHeight;
targetState = 5;
}
if (MyBottomBehavior.this.viewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top)) {
MyBottomBehavior.this.setStateInternal(2);
ViewCompat.postOnAnimation(releasedChild, MyBottomBehavior.this.new SettleRunnable(releasedChild, targetState));
} else {
MyBottomBehavior.this.setStateInternal(targetState);
}
}
public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
return MathUtils.clamp(top, MyBottomBehavior.this.getExpandedOffset(), MyBottomBehavior.this.hideable ? MyBottomBehavior.this.parentHeight : MyBottomBehavior.this.collapsedOffset);
}
public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
return child.getLeft();
}
public int getViewVerticalDragRange(@NonNull View child) {
return MyBottomBehavior.this.hideable ? MyBottomBehavior.this.parentHeight : MyBottomBehavior.this.collapsedOffset;
}
};
public MyBottomBehavior() {
}
public MyBottomBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, styleable.BottomSheetBehavior_Layout);
TypedValue value = a.peekValue(styleable.BottomSheetBehavior_Layout_behavior_peekHeight);
if (value != null && value.data == -1) {
this.setPeekHeight(value.data);
} else {
this.setPeekHeight(a.getDimensionPixelSize(styleable.BottomSheetBehavior_Layout_behavior_peekHeight, -1));
}
this.setHideable(a.getBoolean(styleable.BottomSheetBehavior_Layout_behavior_hideable, false));
this.setFitToContents(a.getBoolean(styleable.BottomSheetBehavior_Layout_behavior_fitToContents, true));
this.setSkipCollapsed(a.getBoolean(styleable.BottomSheetBehavior_Layout_behavior_skipCollapsed, false));
a.recycle();
ViewConfiguration configuration = ViewConfiguration.get(context);
this.maximumVelocity = (float) configuration.getScaledMaximumFlingVelocity();
}
public Parcelable onSaveInstanceState(CoordinatorLayout parent, V child) {
return new MyBottomBehavior.SavedState(super.onSaveInstanceState(parent, child), this.state);
}
public void onRestoreInstanceState(CoordinatorLayout parent, V child, Parcelable state) {
MyBottomBehavior.SavedState ss = (MyBottomBehavior.SavedState) state;
super.onRestoreInstanceState(parent, child, ss.getSuperState());
if (ss.state != 1 && ss.state != 2) {
this.state = ss.state;
} else {
this.state = 4;
}
}
public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
if (ViewCompat.getFitsSystemWindows(parent) && !ViewCompat.getFitsSystemWindows(child)) {
child.setFitsSystemWindows(true);
}
int savedTop = child.getTop();
parent.onLayoutChild(child, layoutDirection);
this.parentHeight = parent.getHeight();
if (this.peekHeightAuto) {
if (this.peekHeightMin == 0) {
this.peekHeightMin = parent.getResources().getDimensionPixelSize(dimen.design_bottom_sheet_peek_height_min);
}
this.lastPeekHeight = Math.max(this.peekHeightMin, this.parentHeight - parent.getWidth() * 9 / 16);
} else {
this.lastPeekHeight = this.peekHeight;
}
this.fitToContentsOffset = Math.max(0, this.parentHeight - child.getHeight());
this.halfExpandedOffset = parent.getHeight() - DisplayUtil.dip2px(MyApplication.getInstance(), 470);
this.calculateCollapsedOffset();
if (this.state == 3) {
ViewCompat.offsetTopAndBottom(child, this.getExpandedOffset());
} else if (this.state == 6) {
ViewCompat.offsetTopAndBottom(child, this.halfExpandedOffset);
} else if (this.hideable && this.state == 5) {
ViewCompat.offsetTopAndBottom(child, this.parentHeight);
} else if (this.state == 4) {
ViewCompat.offsetTopAndBottom(child, this.collapsedOffset);
} else if (this.state == 1 || this.state == 2) {
ViewCompat.offsetTopAndBottom(child, savedTop - child.getTop());
}
if (this.viewDragHelper == null) {
this.viewDragHelper = ViewDragHelper.create(parent, this.dragCallback);
}
this.viewRef = new WeakReference(child);
this.nestedScrollingChildRef = new WeakReference(this.findScrollingChild(child));
return true;
}
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (!child.isShown()) {
this.ignoreEvents = true;
return false;
} else {
int action = event.getActionMasked();
if (action == 0) {
this.reset();
}
if (this.velocityTracker == null) {
this.velocityTracker = VelocityTracker.obtain();
}
this.velocityTracker.addMovement(event);
switch (action) {
case 0:
int initialX = (int) event.getX();
this.initialY = (int) event.getY();
View scroll = this.nestedScrollingChildRef != null ? (View) this.nestedScrollingChildRef.get() : null;
if (scroll != null && parent.isPointInChildBounds(scroll, initialX, this.initialY)) {
this.activePointerId = event.getPointerId(event.getActionIndex());
this.touchingScrollingChild = true;
}
this.ignoreEvents = this.activePointerId == -1 && !parent.isPointInChildBounds(child, initialX, this.initialY);
break;
case 1:
case 3:
this.touchingScrollingChild = false;
this.activePointerId = -1;
if (this.ignoreEvents) {
this.ignoreEvents = false;
return false;
}
case 2:
}
if (!this.ignoreEvents && this.viewDragHelper != null && this.viewDragHelper.shouldInterceptTouchEvent(event)) {
return true;
} else {
View scroll = this.nestedScrollingChildRef != null ? (View) this.nestedScrollingChildRef.get() : null;
return action == 2 && scroll != null && !this.ignoreEvents && this.state != 1 && !parent.isPointInChildBounds(scroll, (int) event.getX(), (int) event.getY()) && this.viewDragHelper != null && Math.abs((float) this.initialY - event.getY()) > (float) this.viewDragHelper.getTouchSlop();
}
}
}
public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (!child.isShown()) {
return false;
} else {
int action = event.getActionMasked();
if (this.state == 1 && action == 0) {
return true;
} else {
if (this.viewDragHelper != null) {
this.viewDragHelper.processTouchEvent(event);
}
if (action == 0) {
this.reset();
}
if (this.velocityTracker == null) {
this.velocityTracker = VelocityTracker.obtain();
}
this.velocityTracker.addMovement(event);
if (action == 2 && !this.ignoreEvents && Math.abs((float) this.initialY - event.getY()) > (float) this.viewDragHelper.getTouchSlop()) {
this.viewDragHelper.captureChildView(child, event.getPointerId(event.getActionIndex()));
}
return !this.ignoreEvents;
}
}
}
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
this.lastNestedScrollDy = 0;
this.nestedScrolled = false;
return (axes & 2) != 0;
}
public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
if (type != 1) {
View scrollingChild = (View) this.nestedScrollingChildRef.get();
if (target == scrollingChild) {
int currentTop = child.getTop();
int newTop = currentTop - dy;
if (dy > 0) {
if (newTop < this.getExpandedOffset()) {
consumed[1] = currentTop - this.getExpandedOffset();
ViewCompat.offsetTopAndBottom(child, -consumed[1]);
this.setStateInternal(3);
} else {
consumed[1] = dy;
ViewCompat.offsetTopAndBottom(child, -dy);
this.setStateInternal(1);
}
} else if (dy < 0 && !target.canScrollVertically(-1)) {
if (newTop > this.collapsedOffset && !this.hideable) {
consumed[1] = currentTop - this.collapsedOffset;
ViewCompat.offsetTopAndBottom(child, -consumed[1]);
this.setStateInternal(4);
} else {
consumed[1] = dy;
ViewCompat.offsetTopAndBottom(child, -dy);
this.setStateInternal(1);
}
}
this.dispatchOnSlide(child.getTop());
this.lastNestedScrollDy = dy;
this.nestedScrolled = true;
}
}
}
public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int type) {
if (child.getTop() == this.getExpandedOffset()) {
this.setStateInternal(3);
} else if (target == this.nestedScrollingChildRef.get() && this.nestedScrolled) {
int top;
byte targetState;
if (this.lastNestedScrollDy > 0) {//上滑
int currentTop = child.getTop();
if (currentTop < this.halfExpandedOffset) {
top = 0;
targetState = 3;
} else {
top = this.halfExpandedOffset;
targetState = 6;
}
} else if (this.hideable && this.shouldHide(child, this.getYVelocity())) {//可隐藏
top = this.parentHeight;
targetState = 5;
} else if (this.lastNestedScrollDy == 0) {
int currentTop = child.getTop();
if (this.fitToContents) {
if (Math.abs(currentTop - this.fitToContentsOffset) < Math.abs(currentTop - this.collapsedOffset)) {
top = this.fitToContentsOffset;
targetState = 3;
} else {
top = this.collapsedOffset;
targetState = 4;
}
} else if (currentTop < this.halfExpandedOffset) {
if (currentTop < Math.abs(currentTop - this.collapsedOffset)) {
top = 0;
targetState = 3;
} else {
top = this.halfExpandedOffset;
targetState = 6;
}
} else if (Math.abs(currentTop - this.halfExpandedOffset) < Math.abs(currentTop - this.collapsedOffset)) {
top = this.halfExpandedOffset;
targetState = 6;
} else {
top = this.collapsedOffset;
targetState = 4;
}
} else {
int currentTop = child.getTop();
if (currentTop < this.halfExpandedOffset) {
top = this.halfExpandedOffset;
targetState = 6;
} else {
top = this.collapsedOffset;
targetState = 4;
}
}
if (this.viewDragHelper.smoothSlideViewTo(child, child.getLeft(), top)) {
this.setStateInternal(2);
ViewCompat.postOnAnimation(child, new MyBottomBehavior.SettleRunnable(child, targetState));
} else {
this.setStateInternal(targetState);
}
this.nestedScrolled = false;
}
}
public boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, float velocityX, float velocityY) {
return target == this.nestedScrollingChildRef.get() && (this.state != 3 || super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY));
}
public boolean isFitToContents() {
return this.fitToContents;
}
public void setFitToContents(boolean fitToContents) {
if (this.fitToContents != fitToContents) {
this.fitToContents = fitToContents;
if (this.viewRef != null) {
this.calculateCollapsedOffset();
}
this.setStateInternal(this.fitToContents && this.state == 6 ? 3 : this.state);
}
}
public final void setPeekHeight(int peekHeight) {
boolean layout = false;
if (peekHeight == -1) {
if (!this.peekHeightAuto) {
this.peekHeightAuto = true;
layout = true;
}
} else if (this.peekHeightAuto || this.peekHeight != peekHeight) {
this.peekHeightAuto = false;
this.peekHeight = Math.max(0, peekHeight);
this.collapsedOffset = this.parentHeight - peekHeight;
layout = true;
}
if (layout && this.state == 4 && this.viewRef != null) {
View view = (View) this.viewRef.get();
if (view != null) {
view.requestLayout();
}
}
}
public final int getPeekHeight() {
return this.peekHeightAuto ? -1 : this.peekHeight;
}
public void setHideable(boolean hideable) {
this.hideable = hideable;
}
public boolean isHideable() {
return this.hideable;
}
public void setSkipCollapsed(boolean skipCollapsed) {
this.skipCollapsed = skipCollapsed;
}
public boolean getSkipCollapsed() {
return this.skipCollapsed;
}
public void setBottomSheetCallback(MyBottomBehavior.BottomSheetCallback callback) {
this.callback = callback;
}
public final void setState(final int state) {
if (state != this.state) {
if (this.viewRef == null) {
if (state == 4 || state == 3 || state == 6 || this.hideable && state == 5) {
this.state = state;
}
} else {
final View child = (View) this.viewRef.get();
if (child != null) {
ViewParent parent = child.getParent();
if (parent != null && parent.isLayoutRequested() && ViewCompat.isAttachedToWindow(child)) {
child.post(new Runnable() {
public void run() {
MyBottomBehavior.this.startSettlingAnimation(child, state);
}
});
} else {
this.startSettlingAnimation(child, state);
}
}
}
}
}
public final int getState() {
return this.state;
}
void setStateInternal(int state) {
if (this.state != state) {
this.state = state;
if (state != 6 && state != 3) {
if (state == 5 || state == 4) {
this.updateImportantForAccessibility(false);
}
} else {
this.updateImportantForAccessibility(true);
}
View bottomSheet = (View) this.viewRef.get();
if (bottomSheet != null && this.callback != null) {
this.callback.onStateChanged(bottomSheet, state);
}
}
}
private void calculateCollapsedOffset() {
if (this.fitToContents) {
this.collapsedOffset = Math.max(this.parentHeight - this.lastPeekHeight, this.fitToContentsOffset);
} else {
this.collapsedOffset = this.parentHeight - this.lastPeekHeight;
}
}
private void reset() {
this.activePointerId = -1;
if (this.velocityTracker != null) {
this.velocityTracker.recycle();
this.velocityTracker = null;
}
}
boolean shouldHide(View child, float yvel) {
if (this.skipCollapsed) {
return true;
} else if (child.getTop() < this.collapsedOffset) {
return false;
} else {
float newTop = (float) child.getTop() + yvel * 0.1F;
return Math.abs(newTop - (float) this.collapsedOffset) / (float) this.peekHeight > 0.5F;
}
}
@VisibleForTesting
View findScrollingChild(View view) {
if (ViewCompat.isNestedScrollingEnabled(view)) {
return view;
} else {
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
int i = 0;
for (int count = group.getChildCount(); i < count; ++i) {
View scrollingChild = this.findScrollingChild(group.getChildAt(i));
if (scrollingChild != null) {
return scrollingChild;
}
}
}
return null;
}
}
private float getYVelocity() {
if (this.velocityTracker == null) {
return 0.0F;
} else {
this.velocityTracker.computeCurrentVelocity(1000, this.maximumVelocity);
return this.velocityTracker.getYVelocity(this.activePointerId);
}
}
private int getExpandedOffset() {
return this.fitToContents ? this.fitToContentsOffset : 0;
}
void startSettlingAnimation(View child, int state) {
int top;
if (state == 4) {
top = this.collapsedOffset;
} else if (state == 6) {
top = this.halfExpandedOffset;
if (this.fitToContents && top <= this.fitToContentsOffset) {
state = 3;
top = this.fitToContentsOffset;
}
} else if (state == 3) {
top = this.getExpandedOffset();
} else {
if (!this.hideable || state != 5) {
throw new IllegalArgumentException("Illegal state argument: " + state);
}
top = this.parentHeight;
}
if (this.viewDragHelper.smoothSlideViewTo(child, child.getLeft(), top)) {
this.setStateInternal(2);
ViewCompat.postOnAnimation(child, new MyBottomBehavior.SettleRunnable(child, state));
} else {
this.setStateInternal(state);
}
}
void dispatchOnSlide(int top) {
View bottomSheet = (View) this.viewRef.get();
if (bottomSheet != null && this.callback != null) {
if (top > this.collapsedOffset) {
this.callback.onSlide(bottomSheet, (float) (this.collapsedOffset - top) / (float) (this.parentHeight - this.collapsedOffset));
} else {
this.callback.onSlide(bottomSheet, (float) (this.collapsedOffset - top) / (float) (this.collapsedOffset - this.getExpandedOffset()));
}
}
}
@VisibleForTesting
int getPeekHeightMin() {
return this.peekHeightMin;
}
public static <V extends View> MyBottomBehavior<V> from(V view) {
LayoutParams params = view.getLayoutParams();
if (!(params instanceof CoordinatorLayout.LayoutParams)) {
throw new IllegalArgumentException("The view is not a child of CoordinatorLayout");
} else {
Behavior behavior = ((CoordinatorLayout.LayoutParams) params).getBehavior();
if (!(behavior instanceof MyBottomBehavior)) {
throw new IllegalArgumentException("The view is not associated with MyBottomBehavior");
} else {
return (MyBottomBehavior) behavior;
}
}
}
private void updateImportantForAccessibility(boolean expanded) {
if (this.viewRef != null) {
ViewParent viewParent = ((View) this.viewRef.get()).getParent();
if (viewParent instanceof CoordinatorLayout) {
CoordinatorLayout parent = (CoordinatorLayout) viewParent;
int childCount = parent.getChildCount();
if (VERSION.SDK_INT >= 16 && expanded) {
if (this.importantForAccessibilityMap != null) {
return;
}
this.importantForAccessibilityMap = new HashMap(childCount);
}
for (int i = 0; i < childCount; ++i) {
View child = parent.getChildAt(i);
if (child != this.viewRef.get()) {
if (!expanded) {
if (this.importantForAccessibilityMap != null && this.importantForAccessibilityMap.containsKey(child)) {
ViewCompat.setImportantForAccessibility(child, (Integer) this.importantForAccessibilityMap.get(child));
}
} else {
if (VERSION.SDK_INT >= 16) {
this.importantForAccessibilityMap.put(child, child.getImportantForAccessibility());
}
ViewCompat.setImportantForAccessibility(child, 4);
}
}
}
if (!expanded) {
this.importantForAccessibilityMap = null;
}
}
}
}
protected static class SavedState extends AbsSavedState {
final int state;
public static final Creator<SavedState> CREATOR = new ClassLoaderCreator<SavedState>() {
public MyBottomBehavior.SavedState createFromParcel(Parcel in, ClassLoader loader) {
return new MyBottomBehavior.SavedState(in, loader);
}
public MyBottomBehavior.SavedState createFromParcel(Parcel in) {
return new MyBottomBehavior.SavedState(in, (ClassLoader) null);
}
public MyBottomBehavior.SavedState[] newArray(int size) {
return new MyBottomBehavior.SavedState[size];
}
};
public SavedState(Parcel source) {
this(source, (ClassLoader) null);
}
public SavedState(Parcel source, ClassLoader loader) {
super(source, loader);
this.state = source.readInt();
}
public SavedState(Parcelable superState, int state) {
super(superState);
this.state = state;
}
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(this.state);
}
}
private class SettleRunnable implements Runnable {
private final View view;
private final int targetState;
SettleRunnable(View view, int targetState) {
this.view = view;
this.targetState = targetState;
}
public void run() {
if (MyBottomBehavior.this.viewDragHelper != null && MyBottomBehavior.this.viewDragHelper.continueSettling(true)) {
ViewCompat.postOnAnimation(this.view, this);
} else {
MyBottomBehavior.this.setStateInternal(this.targetState);
}
}
}
@Retention(RetentionPolicy.SOURCE)
@RestrictTo({Scope.LIBRARY_GROUP})
public @interface State {
}
public abstract static class BottomSheetCallback {
public BottomSheetCallback() {
}
public abstract void onStateChanged(@NonNull View var1, int var2);
public abstract void onSlide(@NonNull View var1, float var2);
}
}

View File

@ -0,0 +1,45 @@
package com.heweather.owp.view.activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.heweather.owp.R;
public class AboutActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
findViewById(R.id.iv_about_back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBackPressed();
}
});
TextView tvVersion = findViewById(R.id.tv_version_num);
tvVersion.setText(getVersionName(this));
}
/**
* 获取versionName
*
* @param context 上下文
* @return 版本号
*/
private static String getVersionName(Context context) {
String versionName = "";
try {
versionName = context.getPackageManager().
getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return "v" + versionName;
}
}

View File

@ -0,0 +1,109 @@
package com.heweather.owp.view.activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.TypedValue;
import android.widget.TextView;
import com.heweather.owp.utils.ContentUtil;
import java.util.List;
import java.util.Locale;
public class BaseActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
@Override
public Resources getResources() {
// 本地语言设置
String language = Locale.getDefault().getLanguage();
Resources resources = super.getResources();
Configuration configuration = resources.getConfiguration();
if (ContentUtil.APP_SETTING_LANG.equals("en")) {
configuration.locale = Locale.ENGLISH;// 英语
ContentUtil.SYS_LANG = "en";
} else {
if (ContentUtil.APP_SETTING_LANG.equals("sys") && !"zh".equals(language)) {
configuration.locale = Locale.ENGLISH;// 英语
ContentUtil.SYS_LANG = "en";
} else {
configuration.locale = Locale.SIMPLIFIED_CHINESE;// 简体中文
ContentUtil.SYS_LANG = "zh";
}
}
switch (ContentUtil.APP_SETTING_TESI) {
case "small":
configuration.fontScale = 0.8f;
break;
case "mid":
configuration.fontScale = 1f;
break;
case "large":
configuration.fontScale = 1.1f;
break;
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return resources;
}
@Override
protected void onResume() {
super.onResume();
}
public void smallLarge(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 11 / 8);
}
}
public void smallMid(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 5 / 4);
}
}
public void midSmall(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 4 / 5);
}
}
public void midLarge(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 11 / 10);
}
}
public void largeSmall(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 8 / 11);
}
}
public void largeMid(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 10 / 11);
}
}
}

View File

@ -0,0 +1,51 @@
package com.heweather.owp.view.activity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import com.heweather.owp.R;
import com.heweather.owp.adapter.ControlCityAdapter;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.bean.CityBeanList;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.SpUtils;
import java.util.ArrayList;
import java.util.List;
public class ControlCityActivity extends BaseActivity {
private List<CityBean> datas = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_city);
ImageView ivBack = findViewById(R.id.iv_control_back);
ivBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBackPressed();
}
});
RecyclerView rcControl = findViewById(R.id.recycle_control);
CityBeanList cityBeanList = SpUtils.getBean(this, "cityBean", CityBeanList.class);
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
cityBeanList = SpUtils.getBean(this, "cityBeanEn", CityBeanList.class);
}
if (cityBeanList != null) {
datas = cityBeanList.getCityBeans();
}
LinearLayoutManager forecastManager = new LinearLayoutManager(this);
forecastManager.setOrientation(LinearLayoutManager.VERTICAL);
ControlCityAdapter followCityAdapter = new ControlCityAdapter(this, datas);
rcControl.setAdapter(followCityAdapter);
rcControl.setLayoutManager(forecastManager);
rcControl.setItemAnimator(new DefaultItemAnimator());
}
}

View File

@ -0,0 +1,457 @@
package com.heweather.owp.view.activity;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.heweather.owp.R;
import com.heweather.owp.adapter.ViewPagerAdapter;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.bean.CityBeanList;
import com.heweather.owp.dataInterface.DataInterface;
import com.heweather.owp.dataInterface.DataUtil;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.DisplayUtil;
import com.heweather.owp.utils.IconUtils;
import com.heweather.owp.utils.SpUtils;
import com.heweather.owp.view.fragment.WeatherFragment;
import com.heweather.owp.view.window.LocListWindow;
import org.joda.time.DateTime;
import java.util.ArrayList;
import java.util.List;
import interfaces.heweather.com.interfacesmodule.bean.base.Code;
import interfaces.heweather.com.interfacesmodule.bean.base.Lang;
import interfaces.heweather.com.interfacesmodule.bean.base.Mode;
import interfaces.heweather.com.interfacesmodule.bean.base.Range;
import interfaces.heweather.com.interfacesmodule.bean.geo.GeoBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherNowBean;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
public class MainActivity extends BaseActivity implements View.OnClickListener, DataInterface {
private List<Fragment> fragments;
private List<String> locaitons;
private List<String> locaitonsEn;
private List<String> cityIds;
private ViewPager viewPager;
private LinearLayout llRound;
private int mNum = 0;
private TextView tvLocation;
private ImageView ivLoc;
CityBeanList cityBeanList = new CityBeanList();
private ImageView ivBack;
private String condCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Window window = getWindow();
//透明状态栏
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
viewPager = findViewById(R.id.view_pager);
llRound = findViewById(R.id.ll_round);
tvLocation = findViewById(R.id.tv_location);
ivLoc = findViewById(R.id.iv_loc);
ivBack = findViewById(R.id.iv_main_back);
RelativeLayout rvTitle = findViewById(R.id.rv_title);
initFragments(true);
ImageView ivSet = findViewById(R.id.iv_set);
ImageView ivAdd = findViewById(R.id.iv_add_city);
ivSet.setOnClickListener(this);
ivAdd.setOnClickListener(this);
setMargins(viewPager, 0, getStatusBarHeight(this) + DisplayUtil.dip2px(this, 52), 0, 0);
setMargins(rvTitle, 0, getStatusBarHeight(this), 0, 0);
}
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation.getErrorCode() == 0) {
ContentUtil.NOW_LON = aMapLocation.getLongitude();
ContentUtil.NOW_LAT = aMapLocation.getLatitude();
getNowCity(true);
mLocationClient.onDestroy();
} else {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// 没有权限
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.pop_loc_list, null);
LocListWindow locListWindow = new LocListWindow(view, MATCH_PARENT, MATCH_PARENT, MainActivity.this);
locListWindow.show();
locListWindow.showAtLocation(tvLocation, Gravity.CENTER, 0, 0);
if (ContentUtil.FIRST_OPEN) {
ContentUtil.FIRST_OPEN = false;
SpUtils.putBoolean(MainActivity.this, "first_open", false);
}
}
getNowCity(true);
mLocationClient.onDestroy();
}
}
};
/**
* 兼容全面屏的状态栏高度
*/
public void setMargins(View view, int l, int t, int r, int b) {
if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
p.setMargins(l, t, r, b);
view.requestLayout();
}
}
/**
* 获取状态栏高度
*/
private static int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
}
private void initFragments(boolean first) {
cityBeanList = SpUtils.getBean(MainActivity.this, "cityBean", CityBeanList.class);
CityBeanList cityBeanEn = SpUtils.getBean(MainActivity.this, "cityBeanEn", CityBeanList.class);
CityBeanList cityBean = SpUtils.getBean(MainActivity.this, "cityBean", CityBeanList.class);
locaitonsEn = new ArrayList<>();
locaitons = new ArrayList<>();
if (cityBeanEn != null) {
for (CityBean city : cityBeanEn.getCityBeans()) {
String cityName = city.getCityName();
locaitonsEn.add(cityName);
}
}
if (cityBean != null) {
for (CityBean city : cityBean.getCityBeans()) {
String cityName = city.getCityName();
locaitons.add(cityName);
}
}
cityIds = new ArrayList<>();
fragments = new ArrayList<>();
if (first) {
initLocation();
} else {
getNowCity(false);
}
}
private void initLocation() {
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
//声明AMapLocationClientOption对象
AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
//设置定位模式为AMapLocationMode.Hight_Accuracy高精度模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置定位间隔,单位毫秒,默认为2000ms最低1000ms
mLocationOption.setInterval(10000);
//单位是毫秒默认30000毫秒建议超时时间不要低于8000毫秒
mLocationOption.setHttpTimeOut(20000);
mLocationClient.setLocationListener(mLocationListener);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
}
private void getNowCity(final boolean first) {
Lang lang;
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
lang = Lang.EN;
} else {
lang = Lang.ZH_HANS;
}
HeWeather.getGeoCityLookup(this, ContentUtil.NOW_LON + "," + ContentUtil.NOW_LAT, Mode.FUZZY, Range.WORLD, 3, lang, new HeWeather.OnResultGeoListener() {
@Override
public void onError(Throwable throwable) {
List<CityBean> cityBeans = new ArrayList<>();
CityBean cityBean = new CityBean();
cityBean.setCityName("北京");
cityBean.setCityId("CN101010100");
cityBeans.add(cityBean);
getData(cityBeans, first);
}
@Override
public void onSuccess(GeoBean search) {
GeoBean.LocationBean basic = search.getLocationBean().get(0);
String cid = basic.getId();
String location = basic.getName();
if (first) {
ContentUtil.NOW_CITY_ID = cid;
ContentUtil.NOW_CITY_NAME = location;
}
List<CityBean> cityBeans = new ArrayList<>();
CityBean cityBean = new CityBean();
cityBean.setCityName(location);
cityBean.setCityId(cid);
locaitons.add(0, location);
locaitonsEn.add(0, location);
if (cityBeanList != null && cityBeanList.getCityBeans() != null && cityBeanList.getCityBeans().size() > 0) {
cityBeans = cityBeanList.getCityBeans();
cityBeans.add(0, cityBean);
} else {
cityBeans.add(cityBean);
}
tvLocation.setText(location);
getData(cityBeans, first);
}
});
}
private void getNow(String location, final boolean nowCity) {
HeWeather.getGeoCityLookup(this, location, Mode.FUZZY, Range.WORLD, 3, Lang.ZH_HANS, new HeWeather.OnResultGeoListener() {
@Override
public void onError(Throwable throwable) {
}
@Override
public void onSuccess(GeoBean search) {
GeoBean.LocationBean basic = search.getLocationBean().get(0);
String cid = basic.getId();
String location = basic.getName();
if (nowCity) {
ContentUtil.NOW_CITY_ID = cid;
ContentUtil.NOW_CITY_NAME = location;
if (cityIds != null && cityIds.size() > 0) {
cityIds.add(0, cid);
cityIds.remove(1);
}
}
HeWeather.getWeatherNow(MainActivity.this, cid, new HeWeather.OnResultWeatherNowListener() {
@Override
public void onError(Throwable throwable) {
}
@Override
public void onSuccess(WeatherNowBean weatherNowBean) {
if (Code.OK.getCode().equalsIgnoreCase(weatherNowBean.getCode())) {
WeatherNowBean.NowBaseBean now = weatherNowBean.getNow();
condCode = now.getIcon();
DateTime nowTime = DateTime.now();
int hourOfDay = nowTime.getHourOfDay();
if (hourOfDay > 6 && hourOfDay < 19) {
ivBack.setImageResource(IconUtils.getDayBack(condCode));
} else {
ivBack.setImageResource(IconUtils.getNightBack(condCode));
}
}
}
});
}
});
}
/**
* 获取数据
*/
private void getData(List<CityBean> cityBeans, boolean first) {
fragments = new ArrayList<>();
llRound.removeAllViews();
for (CityBean city : cityBeans) {
String cityId = city.getCityId();
cityIds.add(cityId);
WeatherFragment weatherFragment = WeatherFragment.newInstance(cityId);
fragments.add(weatherFragment);
}
if (cityIds.get(0).equalsIgnoreCase(ContentUtil.NOW_CITY_ID)) {
ivLoc.setVisibility(View.VISIBLE);
} else {
ivLoc.setVisibility(View.INVISIBLE);
}
View view;
for (int i = 0; i < fragments.size(); i++) {
//创建底部指示器(小圆点)
view = new View(MainActivity.this);
view.setBackgroundResource(R.drawable.background);
view.setEnabled(false);
//设置宽高
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(DisplayUtil.dip2px(this, 4), DisplayUtil.dip2px(this, 4));
//设置间隔
if (fragments.get(i) != fragments.get(0)) {
layoutParams.leftMargin = 10;
}
//添加到LinearLayout
llRound.addView(view, layoutParams);
}
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(), fragments));
//第一次显示小白点
llRound.getChildAt(0).setEnabled(true);
mNum = 0;
if (fragments.size() == 1) {
llRound.setVisibility(View.GONE);
} else {
llRound.setVisibility(View.VISIBLE);
}
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
if (cityIds.get(i).equalsIgnoreCase(ContentUtil.NOW_CITY_ID)) {
ivLoc.setVisibility(View.VISIBLE);
} else {
ivLoc.setVisibility(View.INVISIBLE);
}
llRound.getChildAt(mNum).setEnabled(false);
llRound.getChildAt(i).setEnabled(true);
mNum = i;
tvLocation.setText(locaitons.get(i));
if (ContentUtil.SYS_LANG.equalsIgnoreCase("en")) {
tvLocation.setText(locaitonsEn.get(i));
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
if (!first && fragments.size() > 1) {
viewPager.setCurrentItem(1);
getNow(cityIds.get(1), false);
} else {
viewPager.setCurrentItem(0);
getNow(ContentUtil.NOW_LON + "," + ContentUtil.NOW_LAT, true);
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_set:
startActivity(new Intent(this, SettingActivity.class));
break;
case R.id.iv_add_city:
startActivity(new Intent(this, SearchActivity.class));
break;
}
}
@Override
protected void onResume() {
super.onResume();
DataUtil.setDataInterface(this);
if (!ContentUtil.APP_PRI_TESI.equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
if (fragments != null && fragments.size() > 0) {
for (Fragment fragment : fragments) {
WeatherFragment weatherFragment = (WeatherFragment) fragment;
weatherFragment.changeTextSize();
}
}
if ("small".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
tvLocation.setTextSize(15);
} else if ("large".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
tvLocation.setTextSize(17);
} else {
tvLocation.setTextSize(16);
}
ContentUtil.APP_PRI_TESI = ContentUtil.APP_SETTING_TESI;
}
if (ContentUtil.CHANGE_LANG) {
if (ContentUtil.SYS_LANG.equalsIgnoreCase("en")) {
changeLang(Lang.EN);
} else {
changeLang(Lang.ZH_HANS);
}
ContentUtil.CHANGE_LANG = false;
}
if (ContentUtil.CITY_CHANGE) {
initFragments(true);
ContentUtil.CITY_CHANGE = false;
}
if (ContentUtil.UNIT_CHANGE) {
for (Fragment fragment : fragments) {
WeatherFragment weatherFragment = (WeatherFragment) fragment;
weatherFragment.changeUnit();
}
ContentUtil.UNIT_CHANGE = false;
}
}
@Override
public void setCid(String cid) {
initFragments(false);
}
@Override
public void deleteID(int index) {
initFragments(true);
}
@Override
public void changeBack(String condCode) {
DateTime nowTime = DateTime.now();
int hourOfDay = nowTime.getHourOfDay();
if (hourOfDay > 6 && hourOfDay < 19) {
ivBack.setImageResource(IconUtils.getDayBack(condCode));
} else {
ivBack.setImageResource(IconUtils.getNightBack(condCode));
}
}
private void changeLang(final Lang lang) {
HeWeather.getGeoCityLookup(this, ContentUtil.NOW_LON + "," + ContentUtil.NOW_LAT, Mode.FUZZY, Range.WORLD, 3, lang, new HeWeather.OnResultGeoListener() {
@Override
public void onError(Throwable throwable) {
}
@Override
public void onSuccess(GeoBean search) {
GeoBean.LocationBean basic = search.getLocationBean().get(0);
String location = basic.getName();
if (lang == Lang.EN) {
locaitonsEn.remove(0);
locaitonsEn.add(0, location);
tvLocation.setText(locaitonsEn.get(mNum));
} else if (lang == Lang.ZH_HANS) {
locaitons.remove(0);
locaitons.add(0, location);
tvLocation.setText(locaitons.get(mNum));
}
}
});
}
}

View File

@ -0,0 +1,141 @@
package com.heweather.owp.view.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.heweather.owp.R;
import com.heweather.owp.adapter.SearchAdapter;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.utils.ContentUtil;
import java.util.ArrayList;
import java.util.List;
import interfaces.heweather.com.interfacesmodule.bean.base.Code;
import interfaces.heweather.com.interfacesmodule.bean.base.Lang;
import interfaces.heweather.com.interfacesmodule.bean.base.Mode;
import interfaces.heweather.com.interfacesmodule.bean.base.Range;
import interfaces.heweather.com.interfacesmodule.bean.geo.GeoBean;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
public class SearchActivity extends AppCompatActivity implements View.OnClickListener {
private AutoCompleteTextView etSearch;
private LinearLayout llHistory;
private RecyclerView rvSearch;
private Lang lang;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
lang = Lang.EN;
} else {
lang = Lang.ZH_HANS;
}
initView();
initSearch();
}
private void initView() {
ImageView ivBack = findViewById(R.id.iv_search_back);
etSearch = findViewById(R.id.et_search);
llHistory = findViewById(R.id.ll_history);
rvSearch = findViewById(R.id.recycle_search);
LinearLayoutManager sevenManager = new LinearLayoutManager(this);
sevenManager.setOrientation(LinearLayoutManager.VERTICAL);
rvSearch.setLayoutManager(sevenManager);
ivBack.setOnClickListener(this);
}
private void initSearch() {
etSearch.setThreshold(1);
//编辑框输入监听
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String searchResult = etSearch.getText().toString();
if (!TextUtils.isEmpty(searchResult)) {
llHistory.setVisibility(View.GONE);
rvSearch.setVisibility(View.VISIBLE);
getSearchResult(searchResult);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_search_back:
onBackPressed();
break;
}
}
private void getSearchResult(String location) {
HeWeather.getGeoCityLookup(this, location, Mode.FUZZY, Range.WORLD, 10, lang, new HeWeather.OnResultGeoListener() {
@Override
public void onError(Throwable throwable) {
GeoBean search = new GeoBean();
search.setStatus("noData");
}
@Override
public void onSuccess(GeoBean search) {
if (search.getStatus().equals(Code.OK.getCode())) {
final List<GeoBean.LocationBean> basic = search.getLocationBean();
List<CityBean> data = new ArrayList<>();
if (basic != null && basic.size() > 0) {
if (data.size() > 0) {
data.clear();
}
for (int i = 0; i < basic.size(); i++) {
GeoBean.LocationBean basicData = basic.get(i);
String parentCity = basicData.getAdm2();
String adminArea = basicData.getAdm1();
String cnty = basicData.getCountry();
if (TextUtils.isEmpty(parentCity)) {
parentCity = adminArea;
}
if (TextUtils.isEmpty(adminArea)) {
parentCity = cnty;
}
CityBean cityBean = new CityBean();
cityBean.setCityName(parentCity + " - " + basicData.getName());
cityBean.setCityId(basicData.getId());
cityBean.setCnty(cnty);
cityBean.setAdminArea(adminArea);
data.add(cityBean);
}
SearchAdapter searchAdapter = new SearchAdapter(SearchActivity.this, data, etSearch.getText().toString(), true);
rvSearch.setAdapter(searchAdapter);
searchAdapter.notifyDataSetChanged();
}
}
}
});
}
}

View File

@ -0,0 +1,288 @@
package com.heweather.owp.view.activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.heweather.owp.R;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.SpUtils;
import java.util.ArrayList;
import java.util.List;
public class SettingActivity extends BaseActivity implements View.OnClickListener {
private TextView tvSys;
private TextView tvChinese;
private TextView tvEnglish;
private TextView tvHua;
private TextView tvShe;
private TextView tvSmall;
private TextView tvMid;
private TextView tvLarge;
private ImageView ivSys;
private ImageView ivChinese;
private ImageView ivEnglish;
private ImageView ivHua;
private ImageView ivShe;
private ImageView ivSmall;
private ImageView ivMid;
private ImageView ivLarge;
private TextView tvControl;
private TextView tvAbout;
private TextView tvLangTitle;
private TextView tvUnitTitle;
private TextView tvSizeTitle;
private List<TextView> tvList = new ArrayList<>();
private String preSize = "mid";
private TextView tvSetTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
initView();
}
private void initView() {
tvList = new ArrayList<>();
String language = SpUtils.getString(this, "language", "sys");
String unit = SpUtils.getString(this, "unit", "she");
String size = SpUtils.getString(this, "size", "mid");
ImageView ivBack = findViewById(R.id.iv_setting_back);
RelativeLayout rvControl = findViewById(R.id.rv_control);
RelativeLayout rvSys = findViewById(R.id.rv_system_language);
RelativeLayout rvChinese = findViewById(R.id.rv_chinese_language);
RelativeLayout rvEnglish = findViewById(R.id.rv_english_language);
RelativeLayout rvShe = findViewById(R.id.rv_she);
RelativeLayout rvHua = findViewById(R.id.rv_hua);
RelativeLayout rvSmall = findViewById(R.id.rv_small);
RelativeLayout rvMid = findViewById(R.id.rv_mid);
RelativeLayout rvLarge = findViewById(R.id.rv_large);
RelativeLayout rvAbout = findViewById(R.id.rv_about);
tvSetTitle = findViewById(R.id.tv_setting_title);
tvControl = findViewById(R.id.tv_control);
tvAbout = findViewById(R.id.tv_about);
tvLangTitle = findViewById(R.id.tv_choose_lang);
tvUnitTitle = findViewById(R.id.tv_choose_unit);
tvSizeTitle = findViewById(R.id.tv_choose_size);
tvSys = findViewById(R.id.tv_sys_right);
tvChinese = findViewById(R.id.tv_ch_right);
tvEnglish = findViewById(R.id.tv_en_right);
tvHua = findViewById(R.id.tv_hua_right);
tvShe = findViewById(R.id.tv_she_right);
tvSmall = findViewById(R.id.tv_small_right);
tvMid = findViewById(R.id.tv_mid_right);
tvLarge = findViewById(R.id.tv_large_right);
ivSys = findViewById(R.id.iv_sys_right);
ivChinese = findViewById(R.id.iv_ch_right);
ivEnglish = findViewById(R.id.iv_en_right);
ivHua = findViewById(R.id.iv_hua_right);
ivShe = findViewById(R.id.iv_she_right);
ivSmall = findViewById(R.id.iv_small_right);
ivMid = findViewById(R.id.iv_mid_right);
ivLarge = findViewById(R.id.iv_large_right);
tvList.add(tvControl);
tvList.add(tvAbout);
tvList.add(tvLangTitle);
tvList.add(tvUnitTitle);
tvList.add(tvSizeTitle);
tvList.add(tvSys);
tvList.add(tvChinese);
tvList.add(tvEnglish);
tvList.add(tvHua);
tvList.add(tvShe);
tvList.add(tvSmall);
tvList.add(tvMid);
tvList.add(tvLarge);
rvControl.setOnClickListener(this);
rvChinese.setOnClickListener(this);
rvSys.setOnClickListener(this);
rvEnglish.setOnClickListener(this);
rvShe.setOnClickListener(this);
rvHua.setOnClickListener(this);
rvSmall.setOnClickListener(this);
rvMid.setOnClickListener(this);
rvLarge.setOnClickListener(this);
rvAbout.setOnClickListener(this);
ivBack.setOnClickListener(this);
switch (language) {
case "sys":
chooseView(tvSys, ivSys);
unChooseView(tvChinese, ivChinese);
unChooseView(tvEnglish, ivEnglish);
break;
case "zh":
chooseView(tvChinese, ivChinese);
unChooseView(tvSys, ivSys);
unChooseView(tvEnglish, ivEnglish);
break;
case "en":
chooseView(tvEnglish, ivEnglish);
unChooseView(tvSys, ivSys);
unChooseView(tvChinese, ivChinese);
break;
}
switch (unit) {
case "she":
chooseView(tvShe, ivShe);
unChooseView(tvHua, ivHua);
break;
case "hua":
chooseView(tvHua, ivHua);
unChooseView(tvShe, ivShe);
break;
}
switch (size) {
case "small":
preSize = "small";
chooseView(tvSmall, ivSmall);
unChooseView(tvMid, ivMid);
unChooseView(tvLarge, ivLarge);
break;
case "mid":
preSize = "mid";
chooseView(tvMid, ivMid);
unChooseView(tvSmall, ivSmall);
unChooseView(tvLarge, ivLarge);
break;
case "large":
preSize = "large";
chooseView(tvLarge, ivLarge);
unChooseView(tvSmall, ivSmall);
unChooseView(tvMid, ivMid);
break;
}
ContentUtil.APP_PRI_TESI = preSize;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_setting_back:
onBackPressed();
break;
case R.id.rv_control:
startActivity(new Intent(this, ControlCityActivity.class));
break;
case R.id.rv_system_language:
SpUtils.putString(this, "language", "sys");
ContentUtil.APP_SETTING_LANG = "sys";
chooseView(tvSys, ivSys);
unChooseView(tvChinese, ivChinese);
unChooseView(tvEnglish, ivEnglish);
changeLang();
break;
case R.id.rv_chinese_language:
SpUtils.putString(this, "language", "zh");
ContentUtil.APP_SETTING_LANG = "zh";
chooseView(tvChinese, ivChinese);
unChooseView(tvSys, ivSys);
unChooseView(tvEnglish, ivEnglish);
changeLang();
break;
case R.id.rv_english_language:
SpUtils.putString(this, "language", "en");
ContentUtil.APP_SETTING_LANG = "en";
chooseView(tvEnglish, ivEnglish);
unChooseView(tvSys, ivSys);
unChooseView(tvChinese, ivChinese);
changeLang();
break;
case R.id.rv_she:
ContentUtil.UNIT_CHANGE = true;
SpUtils.putString(this, "unit", "she");
ContentUtil.APP_SETTING_UNIT = "she";
chooseView(tvShe, ivShe);
unChooseView(tvHua, ivHua);
break;
case R.id.rv_hua:
ContentUtil.UNIT_CHANGE = true;
ContentUtil.APP_SETTING_UNIT = "hua";
SpUtils.putString(this, "unit", "hua");
chooseView(tvHua, ivHua);
unChooseView(tvShe, ivShe);
break;
case R.id.rv_small:
SpUtils.putString(this, "size", "small");
chooseView(tvSmall, ivSmall);
unChooseView(tvMid, ivMid);
unChooseView(tvLarge, ivLarge);
if (preSize.equalsIgnoreCase("mid")) {
midSmall(tvList);
} else if (preSize.equalsIgnoreCase("large")) {
largeSmall(tvList);
}
ContentUtil.APP_PRI_TESI = preSize;
preSize = "small";
ContentUtil.APP_SETTING_TESI = "small";
break;
case R.id.rv_mid:
SpUtils.putString(this, "size", "mid");
chooseView(tvMid, ivMid);
unChooseView(tvSmall, ivSmall);
unChooseView(tvLarge, ivLarge);
if (preSize.equalsIgnoreCase("small")) {
smallMid(tvList);
} else if (preSize.equalsIgnoreCase("large")) {
largeMid(tvList);
}
ContentUtil.APP_PRI_TESI = preSize;
preSize = "mid";
ContentUtil.APP_SETTING_TESI = "mid";
break;
case R.id.rv_large:
SpUtils.putString(this, "size", "large");
chooseView(tvLarge, ivLarge);
unChooseView(tvSmall, ivSmall);
unChooseView(tvMid, ivMid);
if (preSize.equalsIgnoreCase("small")) {
smallLarge(tvList);
} else if (preSize.equalsIgnoreCase("mid")) {
midLarge(tvList);
}
ContentUtil.APP_PRI_TESI = preSize;
preSize = "large";
ContentUtil.APP_SETTING_TESI = "large";
break;
case R.id.rv_about:
startActivity(new Intent(this, AboutActivity.class));
break;
}
}
private void chooseView(TextView textView, ImageView imageView) {
textView.setTextColor(getResources().getColor(R.color.color_4a4a4a));
imageView.setVisibility(View.VISIBLE);
}
private void unChooseView(TextView textView, ImageView imageView) {
textView.setTextColor(getResources().getColor(R.color.color_a4a4a4));
imageView.setVisibility(View.GONE);
}
private void changeLang() {
ContentUtil.CHANGE_LANG = true;
tvControl.setText(R.string.control_city);
tvLangTitle.setText(R.string.choose_lang);
tvUnitTitle.setText(R.string.choose_unit);
tvSizeTitle.setText(R.string.choose_text_size);
tvSys.setText(R.string.system_lang);
tvChinese.setText(R.string.chinese);
tvEnglish.setText(R.string.english);
tvShe.setText(R.string.she);
tvHua.setText(R.string.hua);
tvSmall.setText(R.string.small);
tvMid.setText(R.string.mid);
tvLarge.setText(R.string.large);
tvAbout.setText(R.string.about);
tvSetTitle.setText(R.string.setting);
}
}

View File

@ -0,0 +1,62 @@
package com.heweather.owp.view.activity;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import com.heweather.owp.R;
import com.heweather.owp.service.LocationService;
public class SplashActivity extends AppCompatActivity {
final int REQUEST_PERMISSION_LOCATION = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
initPermission();
}
private void initPermission() {
if (ContextCompat.checkSelfPermission(SplashActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(SplashActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(SplashActivity.this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// 没有权限
ActivityCompat.requestPermissions(SplashActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE},
REQUEST_PERMISSION_LOCATION);
} else {
startService(new Intent(this, LocationService.class));
startIntent();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISSION_LOCATION:
startService(new Intent(this, LocationService.class));
startIntent();
break;
default:
startIntent();
break;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void startIntent() {
startActivity(new Intent(this, MainActivity.class));
finish();
}
}

View File

@ -0,0 +1,813 @@
package com.heweather.owp.view.fragment;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.heweather.owp.MyApplication;
import com.heweather.owp.R;
import com.heweather.owp.adapter.ForecastAdapter;
import com.heweather.owp.dataInterface.DataUtil;
import com.heweather.owp.presenters.WeatherInterface;
import com.heweather.owp.presenters.impl.WeatherImpl;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.IconUtils;
import com.heweather.owp.utils.TransUnitUtil;
import com.heweather.owp.view.horizonview.HourlyForecastView;
import com.heweather.owp.view.horizonview.IndexHorizontalScrollView;
import com.heweather.owp.view.horizonview.ScrollWatched;
import com.heweather.owp.view.horizonview.ScrollWatcher;
import com.heweather.owp.view.skyview.SunView;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.util.ArrayList;
import java.util.List;
import interfaces.heweather.com.interfacesmodule.bean.WarningBean;
import interfaces.heweather.com.interfacesmodule.bean.air.AirNowBean;
import interfaces.heweather.com.interfacesmodule.bean.base.Lang;
import interfaces.heweather.com.interfacesmodule.bean.base.Mode;
import interfaces.heweather.com.interfacesmodule.bean.base.Range;
import interfaces.heweather.com.interfacesmodule.bean.geo.GeoBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherDailyBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherHourlyBean;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherNowBean;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
public class WeatherFragment extends Fragment implements WeatherInterface {
private static final String PARAM = "LOCATION";
List<ScrollWatcher> watcherList;
private List<TextView> textViewList = new ArrayList<>();
private ImageView ivTodayDay;
private ImageView ivTodayNight;
private TextView tvTodayTitle;
private TextView tvForecastTitle;
private TextView tvTodayMin;
private TextView tvTodayMax;
private TextView tvTodayHum;
private TextView tvTodayRain;
private TextView tvTodayPressure;
private TextView tvTodayVisible;
private TextView tvWindDir;
private TextView tvWindSc;
private TextView tvMin;
private TextView tvMax;
private TextView tvRain;
private TextView tvHum;
private TextView tvPressure;
private TextView tvVisible;
private TextView tvAirTitle;
private TextView tvAir;
private TextView tvAirNum;
private TextView tvTodayPm25;
private TextView tvTodayPm10;
private TextView tvTodaySo2;
private TextView tvTodayNo2;
private TextView tvTodayCo;
private TextView tvTodayO3;
private TextView tvSunTitle;
private RelativeLayout rvAir;
private HourlyForecastView hourlyForecastView;
private ScrollWatched watched;
private TextView tvLineMin;
private TextView tvLineMax;
private boolean isEn = false;
private SunView sunView;
private SunView moonView;
private String tz = "+8.0";
private String currentTime;
private String sunrise;
private String sunset;
private String moonRise;
private String moonSet;
private boolean hasAni = false;
private TextView tvCond;
private TextView tvTmp;
private View rootView;
private String todayMaxTmp;
private String todayMinTmp;
private WeatherDailyBean weatherForecastBean;
private WeatherHourlyBean weatherHourlyBean;
private String nowTmp;
private String location;
private String language;
private ImageView ivBack;
private String condCode;
private ImageView ivLine;
private GridLayout gridAir;
private SwipeRefreshLayout swipeRefreshLayout;
private TextView tvAlarm;
private RecyclerView rvForecast;
private ForecastAdapter forecastAdapter;
public static WeatherFragment newInstance(String cityId) {
WeatherFragment fragment = new WeatherFragment();
Bundle args = new Bundle();
args.putString(PARAM, cityId);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_weather, container, false);
}
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
isEn = ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en");
location = getArguments().getString(PARAM);
initObserver();
initView(view);
Lang lang = Lang.ZH_HANS;
if (isEn) {
lang = Lang.EN;
}
initData(location);
}
}
private void initView(View view) {
language = ContentUtil.SYS_LANG;
DateTime now = DateTime.now(DateTimeZone.UTC);
float a = Float.valueOf(tz);
float minute = a * 60;
now = now.plusMinutes(((int) minute));
currentTime = now.toString("HH:mm");
tvCond = view.findViewById(R.id.tv_today_cond);
tvTmp = view.findViewById(R.id.tv_today_tmp);
textViewList.add(tvTmp);
ivBack = view.findViewById(R.id.iv_back);
ivLine = view.findViewById(R.id.iv_line2);
gridAir = view.findViewById(R.id.grid_air);
rvForecast = view.findViewById(R.id.rv_forecast);
tvTodayTitle = view.findViewById(R.id.tv_today_title);
tvForecastTitle = view.findViewById(R.id.tv_forecast_title);
textViewList.add(tvTodayTitle);
textViewList.add(tvForecastTitle);
ivTodayDay = view.findViewById(R.id.iv_today_day);
ivTodayNight = view.findViewById(R.id.iv_today_night);
tvTodayMin = view.findViewById(R.id.tv_min_tmp);
textViewList.add(tvTodayMin);
tvTodayMax = view.findViewById(R.id.tv_max_tmp);
textViewList.add(tvTodayMax);
tvTodayHum = view.findViewById(R.id.tv_today_hum);
textViewList.add(tvTodayHum);
tvTodayRain = view.findViewById(R.id.tv_today_rain);
textViewList.add(tvTodayRain);
tvTodayPressure = view.findViewById(R.id.tv_today_pressure);
textViewList.add(tvTodayPressure);
tvTodayVisible = view.findViewById(R.id.tv_today_visible);
textViewList.add(tvTodayVisible);
tvWindDir = view.findViewById(R.id.tv_wind_dir);
textViewList.add(tvWindDir);
tvWindSc = view.findViewById(R.id.tv_wind_sc);
textViewList.add(tvWindSc);
tvMin = view.findViewById(R.id.tv_min);
textViewList.add(tvMin);
tvMax = view.findViewById(R.id.tv_max);
textViewList.add(tvMax);
tvRain = view.findViewById(R.id.tv_rain);
textViewList.add(tvRain);
tvHum = view.findViewById(R.id.tv_hum);
textViewList.add(tvHum);
tvPressure = view.findViewById(R.id.tv_pressure);
textViewList.add(tvPressure);
tvVisible = view.findViewById(R.id.tv_visible);
textViewList.add(tvVisible);
tvAirTitle = view.findViewById(R.id.air_title);
textViewList.add(tvAirTitle);
rvAir = view.findViewById(R.id.rv_air);
tvAir = view.findViewById(R.id.tv_air);
textViewList.add(tvAir);
tvAirNum = view.findViewById(R.id.tv_air_num);
textViewList.add(tvAirNum);
TextView tvPm25 = view.findViewById(R.id.tv_pm25);
textViewList.add(tvPm25);
tvTodayPm25 = view.findViewById(R.id.tv_today_pm25);
textViewList.add(tvTodayPm25);
TextView tvPm10 = view.findViewById(R.id.tv_pm10);
textViewList.add(tvPm10);
tvTodayPm10 = view.findViewById(R.id.tv_today_pm10);
textViewList.add(tvTodayPm10);
TextView tvSo2 = view.findViewById(R.id.tv_so2);
textViewList.add(tvSo2);
tvTodaySo2 = view.findViewById(R.id.tv_today_so2);
textViewList.add(tvTodaySo2);
TextView tvNo2 = view.findViewById(R.id.tv_no2);
textViewList.add(tvNo2);
tvTodayNo2 = view.findViewById(R.id.tv_today_no2);
textViewList.add(tvTodayNo2);
TextView tvCo = view.findViewById(R.id.tv_co);
textViewList.add(tvCo);
tvTodayCo = view.findViewById(R.id.tv_today_co);
textViewList.add(tvTodayCo);
TextView tvO3 = view.findViewById(R.id.tv_o3);
textViewList.add(tvO3);
tvTodayO3 = view.findViewById(R.id.tv_today_o3);
textViewList.add(tvTodayO3);
tvLineMin = view.findViewById(R.id.tv_line_min_tmp);
textViewList.add(tvLineMin);
tvLineMax = view.findViewById(R.id.tv_line_max_tmp);
textViewList.add(tvLineMax);
tvAlarm = view.findViewById(R.id.tv_today_alarm);
textViewList.add(tvAlarm);
TextView tvFrom = view.findViewById(R.id.tv_from);
tvFrom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startUri();
}
});
tvSunTitle = view.findViewById(R.id.tv_sun_title);
textViewList.add(tvSunTitle);
sunView = view.findViewById(R.id.sun_view);
moonView = view.findViewById(R.id.moon_view);
IndexHorizontalScrollView horizontalScrollView = view.findViewById(R.id.hsv);
hourlyForecastView = view.findViewById(R.id.hourly);
horizontalScrollView.setToday24HourView(hourlyForecastView);
watched.addWatcher(hourlyForecastView);
//横向滚动监听
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
horizontalScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
watched.notifyWatcher(scrollX);
}
});
}
swipeRefreshLayout = view.findViewById(R.id.swipe_layout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
initData(location);
}
});
}
/**
* 初始化横向滚动条的监听
*/
private void initObserver() {
watcherList = new ArrayList<>();
watched = new ScrollWatched() {
@Override
public void addWatcher(ScrollWatcher watcher) {
watcherList.add(watcher);
}
@Override
public void removeWatcher(ScrollWatcher watcher) {
watcherList.remove(watcher);
}
@Override
public void notifyWatcher(int x) {
for (ScrollWatcher watcher : watcherList) {
watcher.update(x);
}
}
};
}
private void initData(String location) {
WeatherImpl weatherImpl = new WeatherImpl(this.getActivity(), this);
weatherImpl.getWeatherHourly(location);
weatherImpl.getAirForecast(location);
weatherImpl.getAirNow(location);
weatherImpl.getWarning(location);
weatherImpl.getWeatherForecast(location);
weatherImpl.getWeatherNow(location);
}
@SuppressLint("SetTextI18n")
@Override
public void onResume() {
super.onResume();
isEn = ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en");
if (!language.equalsIgnoreCase(ContentUtil.SYS_LANG)) {
changeLang();
language = ContentUtil.SYS_LANG;
}
if (!hasAni && !TextUtils.isEmpty(sunrise) && !TextUtils.isEmpty(sunset) && !TextUtils.isEmpty(moonRise) && !TextUtils.isEmpty(moonSet)) {
DateTime now = DateTime.now(DateTimeZone.UTC);
float a = Float.valueOf(tz);
float minute = a * 60;
now = now.plusMinutes(((int) minute));
currentTime = now.toString("HH:mm");
sunView.setTimes(sunrise, sunset, currentTime);
moonView.setTimes(moonRise, moonSet, currentTime);
hasAni = true;
}
}
@SuppressLint("SetTextI18n")
public void changeUnit() {
if (ContentUtil.APP_SETTING_UNIT.equals("hua")) {
tvTodayMax.setText(TransUnitUtil.getF(todayMaxTmp) + "°");
tvTodayMin.setText(TransUnitUtil.getF(todayMinTmp) + "°");
tvTmp.setText(TransUnitUtil.getF(nowTmp) + "°");
} else {
tvTodayMax.setText(todayMaxTmp + "°");
tvTodayMin.setText(todayMinTmp + "°");
tvTmp.setText(nowTmp + "°");
}
getWeatherHourly(weatherHourlyBean);
getWeatherForecast(weatherForecastBean);
}
public void changeTextSize() {
if (!TextUtils.isEmpty(sunrise) && !TextUtils.isEmpty(sunset) && !TextUtils.isEmpty(moonRise) && !TextUtils.isEmpty(moonSet)) {
DateTime now = DateTime.now(DateTimeZone.UTC);
float a = Float.valueOf(tz);
float minute = a * 60;
now = now.plusMinutes(((int) minute));
currentTime = now.toString("HH:mm");
sunView.setTimes(sunrise, sunset, currentTime);
moonView.setTimes(moonRise, moonSet, currentTime);
hasAni = true;
}
getWeatherForecast(weatherForecastBean);
if (!ContentUtil.APP_PRI_TESI.equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
switch (ContentUtil.APP_PRI_TESI) {
case "small":
if ("mid".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
smallMid(textViewList);
} else if ("large".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
smallLarge(textViewList);
}
break;
case "mid":
if ("small".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
midSmall(textViewList);
} else if ("large".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
midLarge(textViewList);
}
break;
case "large":
if ("small".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
largeSmall(textViewList);
} else if ("mid".equalsIgnoreCase(ContentUtil.APP_SETTING_TESI)) {
largeMid(textViewList);
}
break;
}
}
}
@SuppressLint("SetTextI18n")
@Override
public void getWeatherNow(WeatherNowBean bean) {
if (bean != null && bean.getNow() != null) {
WeatherNowBean.NowBaseBean now = bean.getNow();
String rain = now.getPrecip();
String hum = now.getHumidity();
String pres = now.getPressure();
String vis = now.getVis();
String windDir = now.getWindDir();
String windSc = now.getWindScale();
String condTxt = now.getText();
condCode = now.getIcon();
nowTmp = now.getTemp();
tvCond.setText(condTxt);
tvTmp.setText(nowTmp + "°");
if (ContentUtil.APP_SETTING_UNIT.equals("hua")) {
tvTmp.setText(TransUnitUtil.getF(nowTmp) + "°");
}
tvTodayRain.setText(rain + "mm");
tvTodayPressure.setText(pres + "HPA");
tvTodayHum.setText(hum + "%");
tvTodayVisible.setText(vis + "KM");
tvWindDir.setText(windDir);
tvWindSc.setText(windSc + "");
DateTime nowTime = DateTime.now();
int hourOfDay = nowTime.getHourOfDay();
if (hourOfDay > 6 && hourOfDay < 19) {
ivBack.setImageResource(IconUtils.getDayBack(condCode));
} else {
ivBack.setImageResource(IconUtils.getNightBack(condCode));
}
if (isEn) {
tvWindSc.setText("Level" + windSc);
}
swipeRefreshLayout.setRefreshing(false);
}
}
@SuppressLint("SetTextI18n")
@Override
public void getWeatherForecast(WeatherDailyBean bean) {
if (bean != null && bean.getDaily() != null) {
weatherForecastBean = bean;
DateTime now = DateTime.now(DateTimeZone.UTC);
// tz = bean.getBasic().getTz();
float a = Float.valueOf(tz);
float minute = a * 60;
now = now.plusMinutes(((int) minute));
currentTime = now.toString("HH:mm");
List<WeatherDailyBean.DailyBean> daily_forecast = bean.getDaily();
WeatherDailyBean.DailyBean forecastBase = daily_forecast.get(0);
String condCodeD = forecastBase.getIconDay();
String condCodeN = forecastBase.getIconNight();
String tmpMin = forecastBase.getTempMin();
String tmpMax = forecastBase.getTempMax();
sunrise = forecastBase.getSunrise();
sunset = forecastBase.getSunset();
moonRise = forecastBase.getMoonRise();
moonSet = forecastBase.getMoonSet();
sunView.setTimes(sunrise, sunset, currentTime);
moonView.setTimes(moonRise, moonSet, currentTime);
todayMaxTmp = tmpMax;
todayMinTmp = tmpMin;
tvTodayMax.setText(tmpMax + "°");
tvTodayMin.setText(tmpMin + "°");
ivTodayDay.setImageResource(IconUtils.getDayIconDark(condCodeD));
ivTodayNight.setImageResource(IconUtils.getNightIconDark(condCodeN));
if (forecastAdapter == null) {
forecastAdapter = new ForecastAdapter(getActivity(), daily_forecast);
rvForecast.setAdapter(forecastAdapter);
LinearLayoutManager forecastManager = new LinearLayoutManager(getActivity());
forecastManager.setOrientation(LinearLayoutManager.VERTICAL);
rvForecast.setLayoutManager(forecastManager);
} else {
forecastAdapter.refreshData(getActivity(), daily_forecast);
}
}
}
@SuppressLint("SetTextI18n")
@Override
public void getWarning(WarningBean.WarningBeanBase alarmBase) {
if (alarmBase != null) {
tvAlarm.setVisibility(View.VISIBLE);
String level = alarmBase.getLevel();
String type = alarmBase.getType();
if (ContentUtil.SYS_LANG.equals("en")) {
tvAlarm.setText(type);
} else {
tvAlarm.setText(type + "预警");
}
if (!TextUtils.isEmpty(level)) {
switch (level) {
case "蓝色":
case "Blue":
tvAlarm.setBackground(getResources().getDrawable(R.drawable.shape_blue_alarm));
tvAlarm.setTextColor(getResources().getColor(R.color.white));
break;
case "黄色":
case "Yellow":
tvAlarm.setBackground(getResources().getDrawable(R.drawable.shape_yellow_alarm));
tvAlarm.setTextColor(getResources().getColor(R.color.white));
break;
case "橙色":
case "Orange":
tvAlarm.setBackground(getResources().getDrawable(R.drawable.shape_orange_alarm));
tvAlarm.setTextColor(getResources().getColor(R.color.white));
break;
case "红色":
case "Red":
tvAlarm.setBackground(getResources().getDrawable(R.drawable.shape_red_alarm));
tvAlarm.setTextColor(getResources().getColor(R.color.white));
break;
case "白色":
case "White":
tvAlarm.setBackground(getResources().getDrawable(R.drawable.shape_white_alarm));
tvAlarm.setTextColor(getResources().getColor(R.color.black));
break;
}
}
} else {
tvAlarm.setVisibility(View.GONE);
}
}
@Override
public void getAirNow(AirNowBean bean) {
if (bean != null && bean.getNow() != null) {
ivLine.setVisibility(View.VISIBLE);
gridAir.setVisibility(View.VISIBLE);
rvAir.setVisibility(View.VISIBLE);
tvAirTitle.setVisibility(View.VISIBLE);
AirNowBean.NowBean airNowCity = bean.getNow();
String qlty = airNowCity.getCategory();
String aqi = airNowCity.getAqi();
String pm25 = airNowCity.getPm2p5();
String pm10 = airNowCity.getPm10();
String so2 = airNowCity.getSo2();
String no2 = airNowCity.getNo2();
String co = airNowCity.getCo();
String o3 = airNowCity.getO3();
tvAir.setText(qlty);
tvAirNum.setText(aqi);
tvTodayPm25.setText(pm25);
tvTodayPm10.setText(pm10);
tvTodaySo2.setText(so2);
tvTodayNo2.setText(no2);
tvTodayCo.setText(co);
tvTodayO3.setText(o3);
rvAir.setBackground(getAirBackground(aqi));
} else {
ivLine.setVisibility(View.GONE);
gridAir.setVisibility(View.GONE);
rvAir.setVisibility(View.GONE);
tvAirTitle.setVisibility(View.GONE);
}
}
private Drawable getAirBackground(String aqi) {
int num = Integer.parseInt(aqi);
if (getActivity() != null) {
if (num <= 50) {
return getActivity().getResources().getDrawable(R.drawable.shape_aqi_excellent);
} else if (num <= 100) {
return getActivity().getResources().getDrawable(R.drawable.shape_aqi_good);
} else if (num <= 150) {
return getActivity().getResources().getDrawable(R.drawable.shape_aqi_low);
} else if (num <= 200) {
return getActivity().getResources().getDrawable(R.drawable.shape_aqi_mid);
} else if (num <= 300) {
return getActivity().getResources().getDrawable(R.drawable.shape_aqi_bad);
} else {
return getActivity().getResources().getDrawable(R.drawable.shape_aqi_serious);
}
} else {
return MyApplication.getContext().getResources().getDrawable(R.drawable.shape_aqi_excellent);
}
}
@SuppressLint("SetTextI18n")
@Override
public void getWeatherHourly(WeatherHourlyBean bean) {
if (bean != null && bean.getHourly() != null) {
weatherHourlyBean = bean;
List<WeatherHourlyBean.HourlyBean> hourlyWeatherList = bean.getHourly();
List<WeatherHourlyBean.HourlyBean> data = new ArrayList<>();
if (hourlyWeatherList.size() > 23) {
for (int i = 0; i < 24; i++) {
data.add(hourlyWeatherList.get(i));
String condCode = data.get(i).getIcon();
String time = data.get(i).getFxTime();
time = time.substring(time.length() - 11, time.length() - 9);
int hourNow = Integer.parseInt(time);
if (hourNow >= 6 && hourNow <= 19) {
data.get(i).setIcon(condCode + "d");
} else {
data.get(i).setIcon(condCode + "n");
}
}
} else {
for (int i = 0; i < hourlyWeatherList.size(); i++) {
data.add(hourlyWeatherList.get(i));
String condCode = data.get(i).getIcon();
String time = data.get(i).getFxTime();
time = time.substring(time.length() - 11, time.length() - 9);
int hourNow = Integer.parseInt(time);
if (hourNow >= 6 && hourNow <= 19) {
data.get(i).setIcon(condCode + "d");
} else {
data.get(i).setIcon(condCode + "n");
}
}
}
int minTmp = Integer.parseInt(data.get(0).getTemp());
int maxTmp = minTmp;
for (int i = 0; i < data.size(); i++) {
int tmp = Integer.parseInt(data.get(i).getTemp());
minTmp = Math.min(tmp, minTmp);
maxTmp = Math.max(tmp, maxTmp);
}
//设置当天的最高最低温度
hourlyForecastView.setHighestTemp(maxTmp);
hourlyForecastView.setLowestTemp(minTmp);
if (maxTmp == minTmp) {
hourlyForecastView.setLowestTemp(minTmp - 1);
}
hourlyForecastView.initData(data);
tvLineMax.setText(maxTmp + "°");
tvLineMin.setText(minTmp + "°");
if (ContentUtil.APP_SETTING_UNIT.equals("hua")) {
tvLineMax.setText(TransUnitUtil.getF(String.valueOf(maxTmp)) + "°");
tvLineMin.setText(TransUnitUtil.getF(String.valueOf(minTmp)) + "°");
}
}
}
/**
* 获取星期
*
* @param num 0-6
* @return 星期
*/
private String getWeek(int num) {
String week = " ";
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
switch (num) {
case 1:
week = "Mon";
break;
case 2:
week = "Tues";
break;
case 3:
week = "Wed";
break;
case 4:
week = "Thur";
break;
case 5:
week = "Fri";
break;
case 6:
week = "Sat";
break;
case 7:
week = "Sun";
break;
}
} else {
switch (num) {
case 1:
week = "周一";
break;
case 2:
week = "周二";
break;
case 3:
week = "周三";
break;
case 4:
week = "周四";
break;
case 5:
week = "周五";
break;
case 6:
week = "周六";
break;
case 7:
week = "周日";
break;
}
}
return week;
}
private void smallLarge(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 11 / 8);
}
}
private void smallMid(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 5 / 4);
}
}
private void midSmall(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 4 / 5);
}
}
private void midLarge(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 11 / 10);
}
}
private void largeSmall(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 8 / 11);
}
}
private void largeMid(List<TextView> tvList) {
for (TextView textView : tvList) {
float textSize = textView.getTextSize();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize * 10 / 11);
}
}
private void changeLang() {
initData(location);
// setWeeks(tvWeekList);
if (forecastAdapter != null) {
forecastAdapter.notifyDataSetChanged();
}
tvTodayTitle.setText(R.string.today_title);
tvForecastTitle.setText(R.string.forecast);
tvMin.setText(R.string.min_tmp);
tvMax.setText(R.string.max_tmp);
tvHum.setText(R.string.hum);
tvRain.setText(R.string.rainfall);
tvPressure.setText(R.string.pressure);
tvVisible.setText(R.string.visible);
tvAirTitle.setText(R.string.air_quality);
tvSunTitle.setText(R.string.sun_moon);
if (!TextUtils.isEmpty(sunrise) && !TextUtils.isEmpty(sunset) && !TextUtils.isEmpty(moonRise) && !TextUtils.isEmpty(moonSet)) {
DateTime now = DateTime.now(DateTimeZone.UTC);
float a = Float.valueOf(tz);
float minute = a * 60;
now = now.plusMinutes(((int) minute));
currentTime = now.toString("HH:mm");
sunView.setTimes(sunrise, sunset, currentTime);
moonView.setTimes(moonRise, moonSet, currentTime);
hasAni = true;
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (rootView != null && rootView.getParent() != null) {
((ViewGroup) rootView.getParent()).removeView(rootView);
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !TextUtils.isEmpty(condCode)) {
DataUtil.changeBack(condCode);
}
if (!hasAni && !TextUtils.isEmpty(sunrise) && !TextUtils.isEmpty(sunset) && !TextUtils.isEmpty(moonRise) && !TextUtils.isEmpty(moonSet)) {
DateTime now = DateTime.now(DateTimeZone.UTC);
float a = Float.valueOf(tz);
float minute = a * 60;
now = now.plusMinutes(((int) minute));
currentTime = now.toString("HH:mm");
sunView.setTimes(sunrise, sunset, currentTime);
moonView.setTimes(moonRise, moonSet, currentTime);
hasAni = true;
}
}
private void startUri() {
Uri uri = Uri.parse("https://www.heweather.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}

View File

@ -0,0 +1,601 @@
package com.heweather.owp.view.horizonview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import com.heweather.owp.R;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.DisplayUtil;
import com.heweather.owp.utils.IconUtils;
import com.heweather.owp.utils.TransUnitUtil;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import interfaces.heweather.com.interfacesmodule.bean.weather.WeatherHourlyBean;
/**
* Created by niu on 18/11/22.
*/
public class HourlyForecastView extends View implements ScrollWatcher {
private Context mContext;
//折线
private Paint foldLinePaint;
private Paint backPaint;
//底线
private Paint baseLinePaint;
//虚线
private Paint dashPaint;
//文字
private Paint textPaint;
//图片
private Paint bitmapPaint;
//文本的大小
private int textSize;
//数据
private List<WeatherHourlyBean.HourlyBean> hourlyWeatherList;
//画虚线的点的index
private List<Integer> dashLineList;
private int screenWidth;
//每个item的宽度
private int itemWidth;
//温度基准高度
private int lowestTempHeight;
//温度基准高度
private int highestTempHeight;
//最低温
private int lowestTemp;
//最高温
private int highestTemp;
//默认图片绘制位置
float bitmapHeight;
//默认图片宽高
float bitmapXY;
//View宽高
private int mWidth;
private int mHeight;
//默认高
private int defHeightPixel = 0;
private int defWidthPixel = 0;
private int paddingL = 0;
private int paddingT = 0;
private int paddingR = 0;
private int paddingB = 0;
private int mScrollX = 0;
private float baseLineHeight;
private Paint paint1;
private boolean isDark = false;
public HourlyForecastView(Context context) {
this(context, null);
}
public HourlyForecastView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, -1);
}
public HourlyForecastView(final Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public HourlyForecastView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
mContext = context;
if (ContentUtil.APP_SETTING_THEME.equals("深色")) {
isDark = true;
} else {
isDark = false;
}
initDefValue();
initPaint();
}
private static int ITEM_SIZE = 24;
public void initData(List<WeatherHourlyBean.HourlyBean> weatherData) {
hourlyWeatherList = weatherData;
int size = weatherData.size();
ITEM_SIZE = size;
dashLineList = new ArrayList<>();
Iterator iterator = weatherData.iterator();
WeatherHourlyBean.HourlyBean hourlyBase;
String lastText = "";
int idx = 0;
while (iterator.hasNext()) {
hourlyBase = (WeatherHourlyBean.HourlyBean) iterator.next();
if (!hourlyBase.getIcon().equals(lastText)) {
if (idx != size - 1) {
dashLineList.add(idx);//从0开始添加虚线位置的索引值idx
lastText = hourlyBase.getIcon();
}
}
idx++;
}
dashLineList.add(size - 1);//添加最后一条虚线位置的索引值idx
invalidate();
}
private void initDefValue() {
DisplayMetrics dm = getResources().getDisplayMetrics();
screenWidth = dm.widthPixels;
itemWidth = DisplayUtil.dp2px(mContext, 30);
defWidthPixel = itemWidth * (ITEM_SIZE - 1);
defHeightPixel = DisplayUtil.dp2px(mContext, 80);
lowestTempHeight = DisplayUtil.dp2px(mContext, 40);//长度 非y轴值
highestTempHeight = DisplayUtil.dp2px(mContext, 70);
//defPadding
paddingT = DisplayUtil.dp2px(mContext, 20);
paddingL = DisplayUtil.dp2px(mContext, 10);
paddingR = DisplayUtil.dp2px(mContext, 15);
textSize = DisplayUtil.sp2px(mContext, 12);
bitmapHeight = 1 / 2f * (2 * defHeightPixel - lowestTempHeight) + DisplayUtil.dp2px(mContext, 2);//- 给文字留地方
bitmapXY = 18;
}
private TextPaint textLinePaint;
private void initPaint() {
// setLayerType(View.LAYER_TYPE_SOFTWARE, null);//关闭硬件加速
paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setColor(mContext.getResources().getColor(R.color.line_back_dark));
paint1.setStyle(Paint.Style.FILL);
foldLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
foldLinePaint.setStyle(Paint.Style.STROKE);
foldLinePaint.setStrokeWidth(5);
foldLinePaint.setColor(mContext.getResources().getColor(R.color.line_color));
backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
backPaint.setStrokeWidth(2);
backPaint.setAntiAlias(true);
dashPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dashPaint.setColor(mContext.getResources().getColor(R.color.back_white));
DashPathEffect pathEffect = new DashPathEffect(new float[]{8, 8, 8, 8}, 1);
dashPaint.setPathEffect(pathEffect);
dashPaint.setStrokeWidth(3);
dashPaint.setAntiAlias(true);
dashPaint.setStyle(Paint.Style.STROKE);
textPaint = new Paint();
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTextSize(textSize);
textLinePaint = new TextPaint();
textLinePaint.setTextSize(DisplayUtil.sp2px(getContext(), 12));
textLinePaint.setAntiAlias(true);
textLinePaint.setColor(mContext.getResources().getColor(R.color.black));
textPaint.setColor(mContext.getResources().getColor(R.color.search_light_un_color));
baseLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
baseLinePaint.setStrokeWidth(3);
baseLinePaint.setStyle(Paint.Style.STROKE);
baseLinePaint.setColor(mContext.getResources().getColor(R.color.slategray));
bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapPaint.setFilterBitmap(true);//图像滤波处理
bitmapPaint.setDither(true);//防抖动
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//当设置的padding值小于默认值是设置为默认值
paddingT = DisplayUtil.dp2px(mContext, 20);
paddingL = DisplayUtil.dp2px(mContext, 10);
paddingR = DisplayUtil.dp2px(mContext, 15);
paddingB = Math.max(paddingB, getPaddingBottom());
//获取测量模式
//注意 HorizontalScrollView的子View 在没有明确指定dp值的情况下 widthMode总是MeasureSpec.UNSPECIFIED
//同理 ScrollView的子View的heightMode
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//获取测量大小
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
mWidth = widthSize + paddingL + paddingR;
mHeight = heightSize;
}
//如果为wrap_content 那么View大小为默认值
if (widthMode == MeasureSpec.UNSPECIFIED && heightMode == MeasureSpec.AT_MOST) {
mWidth = defWidthPixel + paddingL + paddingR;
mHeight = defHeightPixel + paddingT + paddingB;
}
//设置视图的大小
setMeasuredDimension(mWidth, mHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initDefValue();
initPaint();
if (hourlyWeatherList != null && hourlyWeatherList.size() != 0) {
drawLines(canvas);
drawBitmaps(canvas);
drawTemp(canvas);
}
}
private void drawTemp(Canvas canvas) {
for (int i = 0; i < hourlyWeatherList.size(); i++) {
if (currentItemIndex == i) {
//计算提示文字的运动轨迹
// int Y = getTempBarY(i);
String tmp = hourlyWeatherList.get(i).getTemp();
float temp = Integer.parseInt(tmp);
int Y = (int) (tempHeightPixel(temp) + paddingT);
//画出温度提示
int offset = itemWidth / 4;
Rect targetRect = new Rect(getScrollBarX(), Y - DisplayUtil.dip2px(getContext(), 24)
, getScrollBarX() + offset, Y - DisplayUtil.dip2px(getContext(), 4));
Paint.FontMetricsInt fontMetrics = textLinePaint.getFontMetricsInt();
int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
textLinePaint.setTextAlign(Paint.Align.LEFT);
if (ContentUtil.APP_SETTING_UNIT.equals("hua")) {
tmp = String.valueOf(TransUnitUtil.getF(tmp));
}
canvas.drawText(tmp + "°", targetRect.centerX(), baseline, textLinePaint);
}
}
}
private void drawBitmaps(Canvas canvas) {
int scrollX = mScrollX;
boolean leftHide;
boolean rightHide;
for (int i = 0; i < dashLineList.size() - 1; i++) {
leftHide = true;
rightHide = true;
int left = itemWidth * dashLineList.get(i) + paddingL;
int right = itemWidth * dashLineList.get(i + 1) + paddingL;
//图的中间位置 drawBitmap是左边开始画
float drawPoint = 0;
if (left > scrollX && left < scrollX + screenWidth) {
leftHide = false;//左边缘显示
}
if (right > scrollX && right < scrollX + screenWidth) {
rightHide = false;
}
if (!leftHide && !rightHide) {//左右边缘都显示
drawPoint = (left + right) / 2f;
} else if (leftHide && !rightHide) {//右边缘与屏幕左边
drawPoint = (scrollX + right) / 2f;
} else if (!leftHide) {//左边缘与屏幕右边
//rightHide is True when reach this statement
drawPoint = (left + screenWidth + scrollX) / 2f;
} else {//左右边缘都不显示
if (right < scrollX + screenWidth) { //左右边缘都在屏幕左边
continue;
} else if (left > scrollX + screenWidth) {//左右边缘都在屏幕右边
continue;
} else {
drawPoint = (screenWidth) / 2f + scrollX;
}
}
String code = hourlyWeatherList.get(dashLineList.get(i)).getIcon();
BitmapDrawable bd;
if (code.contains("d")) {
bd = (BitmapDrawable) mContext.getResources().getDrawable(IconUtils.getDayIconDark(code.replace("d", "")));
} else {
bd = (BitmapDrawable) mContext.getResources().getDrawable(IconUtils.getNightIconDark(code.replace("n", "")));
}
assert bd != null;
Bitmap bitmap = DisplayUtil.bitmapResize(bd.getBitmap(),
DisplayUtil.dp2px(mContext, bitmapXY), DisplayUtil.dp2px(mContext, bitmapXY));
//越界判断
if (drawPoint >= right - bitmap.getWidth() / 2f) {
drawPoint = right - bitmap.getWidth() / 2f;
}
if (drawPoint <= left + bitmap.getWidth() / 2f) {
drawPoint = left + bitmap.getWidth() / 2f;
}
drawBitmap(canvas, bitmap, drawPoint, bitmapHeight);
// String text = hourlyWeatherList.get(dashLineList.get(i)).getCond_txt();
// textPaint.setTextSize(DisplayUtil.sp2px(mContext, 8));
// canvas.drawText(text, drawPoint, bitmapHeight + bitmap.getHeight() + 100 / 3f, textPaint);
}
}
private void drawBitmap(Canvas canvas, Bitmap bitmap, float left, float top) {
canvas.save();
canvas.drawBitmap(bitmap, left - bitmap.getWidth() / 2, top, bitmapPaint);
canvas.restore();
}
private void drawLines(Canvas canvas) {
//底部的线的高度 高度为控件高度减去text高度的1.5倍
baseLineHeight = mHeight - 1.5f * textSize;
Path path = new Path();
List<Float> dashWidth = new ArrayList<>();
List<Float> dashHeight = new ArrayList<>();
List<Point> mPointList = new ArrayList<>();
for (int i = 0; i < hourlyWeatherList.size(); i++) {
float temp = Integer.parseInt(hourlyWeatherList.get(i).getTemp());
float w = itemWidth * i + paddingL;
float h = tempHeightPixel(temp) + paddingT;
Point point = new Point((int) w, (int) h);
mPointList.add(point);
//画虚线
if (dashLineList.contains(i)) {
dashWidth.add(w);
dashHeight.add(h);
}
}
float prePreviousPointX = Float.NaN;
float prePreviousPointY = Float.NaN;
float previousPointX = Float.NaN;
float previousPointY = Float.NaN;
float currentPointX = Float.NaN;
float currentPointY = Float.NaN;
float nextPointX;
float nextPointY;
for (int valueIndex = 0; valueIndex < hourlyWeatherList.size(); ++valueIndex) {
if (Float.isNaN(currentPointX)) {
Point point = mPointList.get(valueIndex);
currentPointX = point.x;
currentPointY = point.y;
}
if (Float.isNaN(previousPointX)) {
//是否是第一个点
if (valueIndex > 0) {
Point point = mPointList.get(valueIndex - 1);
previousPointX = point.x;
previousPointY = point.y;
} else {
//是的话就用当前点表示上一个点
previousPointX = currentPointX;
previousPointY = currentPointY;
}
}
if (Float.isNaN(prePreviousPointX)) {
//是否是前两个点
if (valueIndex > 1) {
Point point = mPointList.get(valueIndex - 2);
prePreviousPointX = point.x;
prePreviousPointY = point.y;
} else {
//是的话就用当前点表示上上个点
prePreviousPointX = previousPointX;
prePreviousPointY = previousPointY;
}
}
// 判断是不是最后一个点了
if (valueIndex < hourlyWeatherList.size() - 1) {
Point point = mPointList.get(valueIndex + 1);
nextPointX = point.x;
nextPointY = point.y;
} else {
//是的话就用当前点表示下一个点
nextPointX = currentPointX;
nextPointY = currentPointY;
}
if (valueIndex == 0) {
// 将Path移动到开始点
path.moveTo(currentPointX, currentPointY);
} else {
// 求出控制点坐标
final float firstDiffX = (currentPointX - prePreviousPointX);
final float firstDiffY = (currentPointY - prePreviousPointY);
final float secondDiffX = (nextPointX - previousPointX);
final float secondDiffY = (nextPointY - previousPointY);
final float firstControlPointX = previousPointX + (0.2F * firstDiffX);
final float firstControlPointY = previousPointY + (0.2F * firstDiffY);
final float secondControlPointX = currentPointX - (0.2F * secondDiffX);
final float secondControlPointY = currentPointY - (0.2F * secondDiffY);
//画出曲线
path.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY,
currentPointX, currentPointY);
}
// 更新值,
prePreviousPointX = previousPointX;
prePreviousPointY = previousPointY;
previousPointX = currentPointX;
previousPointY = currentPointY;
currentPointX = nextPointX;
currentPointY = nextPointY;
}
//画折线
canvas.drawPath(path, foldLinePaint);
path.lineTo(mWidth - paddingR, baseLineHeight);
path.lineTo(paddingL, baseLineHeight);
//画阴影
int[] shadeColors = new int[]{
Color.argb(100, 145, 145, 145), Color.argb(30, 145, 145, 145),
Color.argb(18, 237, 238, 240)};
Shader mShader = new LinearGradient(0, 0, 0, getHeight(), shadeColors, null, Shader.TileMode.CLAMP);
backPaint.setShader(mShader);
canvas.drawPath(path, backPaint);
//画虚线
drawDashLine(dashWidth, dashHeight, canvas);
for (int i = 0; i < hourlyWeatherList.size(); i++) {
float temp = Integer.parseInt(hourlyWeatherList.get(i).getTemp());
float w = itemWidth * i + paddingL;
float h = tempHeightPixel(temp) + paddingT;
//画时间
String time = hourlyWeatherList.get(i).getFxTime();
//画时间
if (ITEM_SIZE > 8) {
if (i % 2 == 0) {
if (i == 0) {
textPaint.setTextAlign(Paint.Align.LEFT);
} else {
textPaint.setTextAlign(Paint.Align.CENTER);
}
canvas.drawText(time.substring(time.length() - 11, time.length() - 6), w, baseLineHeight + textSize + DisplayUtil.dip2px(mContext, 3), textPaint);
}
} else {
textPaint.setTextAlign(Paint.Align.CENTER);
if (i == 0) {
canvas.drawText(mContext.getString(R.string.now), w, baseLineHeight + textSize + DisplayUtil.dip2px(mContext, 3), textPaint);
} else {
canvas.drawText(time.substring(time.length() - 11, time.length() - 6), w, baseLineHeight + textSize + DisplayUtil.dip2px(mContext, 3), textPaint);
}
}
}
}
//画虚线
private void drawDashLine(List<Float> dashWidth, List<Float> dashHeight, Canvas canvas) {
if (dashHeight != null && dashHeight.size() > 1) {
for (int i = 1; i < dashHeight.size() - 1; i++) {
canvas.drawLine(dashWidth.get(i), dashHeight.get(i) + 3, dashWidth.get(i), baseLineHeight, dashPaint);
}
}
}
public float tempHeightPixel(float tmp) {
float res = ((tmp - lowestTemp) / (highestTemp - lowestTemp)) * (highestTempHeight - lowestTempHeight) + lowestTempHeight;
return defHeightPixel - res;//y从上到下
}
@Override
public void update(int scrollX) {
mScrollX = scrollX;
}
public void setLowestTemp(int lowestTemp) {
this.lowestTemp = lowestTemp;
}
public void setHighestTemp(int highestTemp) {
this.highestTemp = highestTemp;
}
private int maxScrollOffset = 0;//滚动条最长滚动距离
private int scrollOffset = 0; //滚动条偏移量
private int currentItemIndex = 0; //当前滚动的位置所对应的item下标
//设置scrollerView的滚动条的位置通过位置计算当前的时段
public void setScrollOffset(int offset, int maxScrollOffset) {
this.maxScrollOffset = maxScrollOffset + DisplayUtil.dp2px(mContext, 50);
scrollOffset = offset;
currentItemIndex = calculateItemIndex();
invalidate();
}
//通过滚动条偏移量计算当前选择的时刻
private int calculateItemIndex() {
int x = getScrollBarX();
int sum = paddingL - itemWidth / 2;
for (int i = 0; i < ITEM_SIZE - 1; i++) {
sum += itemWidth;
if (x < sum)
return i;
}
return ITEM_SIZE - 1;
}
private int getScrollBarX() {
int x = (ITEM_SIZE - 1) * itemWidth * scrollOffset / maxScrollOffset;
x = x - DisplayUtil.dp2px(mContext, 3);
return x;
}
}

View File

@ -0,0 +1,42 @@
package com.heweather.owp.view.horizonview;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.HorizontalScrollView;
import com.heweather.owp.utils.DisplayUtil;
/**
* Created by niu on 2018/11/22.
*/
public class IndexHorizontalScrollView extends HorizontalScrollView {
private HourlyForecastView hourlyForecastView;
public IndexHorizontalScrollView(Context context) {
this(context, null);
}
public IndexHorizontalScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public IndexHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int offset = computeHorizontalScrollOffset();
int maxOffset = computeHorizontalScrollRange() - DisplayUtil.getScreenWidth(getContext());
if(hourlyForecastView != null){
hourlyForecastView.setScrollOffset(offset, maxOffset);
}
}
public void setToday24HourView(HourlyForecastView today24HourView){
this.hourlyForecastView = today24HourView;
}
}

View File

@ -0,0 +1,11 @@
package com.heweather.owp.view.horizonview;
/**
* Created by dongua on 17-9-11.
*/
public interface ScrollWatched {
void addWatcher(ScrollWatcher watcher);
void removeWatcher(ScrollWatcher watcher);
void notifyWatcher(int x);
}

View File

@ -0,0 +1,9 @@
package com.heweather.owp.view.horizonview;
/**
* Created by dongua on 17-9-11.
*/
public interface ScrollWatcher {
void update(int scrollX);
}

View File

@ -0,0 +1,400 @@
package com.heweather.owp.view.skyview;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowManager;
import com.heweather.owp.R;
import com.heweather.owp.utils.ContentUtil;
import com.heweather.owp.utils.DisplayUtil;
import java.text.DecimalFormat;
public class SunView extends View {
private int mWidth; //屏幕宽度
private int marginTop = 50;//离顶部的高度
private int mCircleColor; //圆弧颜色
private int mFontColor; //字体颜色
private int mRadius; //圆的半径
private float mCurrentAngle; //当前旋转的角度
private float mTotalMinute; //总时间(日落时间减去日出时间的总分钟数)
private float mNeedMinute; //当前时间减去日出时间后的总分钟数
private float mPercentage; //根据所给的时间算出来的百分占比
private float positionX, positionY; //太阳图片的xy坐标
private float mFontSize; //字体大小
private String mStartTime; //开始时间(日出时间)
private String mEndTime; //结束时间日落时间
private String mCurrentTime; //当前时间
private Paint mTextPaint; //画笔
private Paint mLinePaint; //画笔
private Paint mTimePaint; //画笔
private RectF mRectF; //半圆弧所在的矩形
private Bitmap mSunIcon; //太阳图片
private WindowManager wm;
private Paint mShadePaint;
private Paint mPathPaint;
private Context mContext;
private boolean isSun = true;
private float endHour;
private Paint shadePaint;
private Paint pathPaint;
public SunView(Context context) {
this(context, null);
}
public SunView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SunView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs);
}
private void initView(Context context, @Nullable AttributeSet attrs) {
mContext = context;
marginTop = DisplayUtil.dip2px(context, 30);
@SuppressLint("CustomViewStyleable") TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.SunAnimationView);
mCircleColor = type.getColor(R.styleable.SunAnimationView_sun_circle_color, getContext().getResources().getColor(R.color.dark_text_color));
mFontColor = type.getColor(R.styleable.SunAnimationView_sun_font_color, getContext().getResources().getColor(R.color.colorAccent));
mRadius = type.getInteger(R.styleable.SunAnimationView_sun_circle_radius, DisplayUtil.dp2px(getContext(), 130));
mRadius = DisplayUtil.dp2px(getContext(), mRadius);
mFontSize = type.getDimension(R.styleable.SunAnimationView_sun_font_size, DisplayUtil.dp2px(getContext(), 10));
mFontSize = DisplayUtil.dp2px(getContext(), mFontSize);
isSun = type.getBoolean(R.styleable.SunAnimationView_type, true);
type.recycle();
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTimePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
shadePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
public void setType(boolean isSun, int circleColor, int fontColor) {
this.isSun = isSun;
mCircleColor = circleColor;
mFontColor = fontColor;
}
public void setTimes(String startTime, String endTime, String currentTime) {
mStartTime = startTime;
mEndTime = endTime;
mCurrentTime = currentTime;
String currentTimes[] = currentTime.split(":");
String startTimes[] = startTime.split(":");
String endTimes[] = endTime.split(":");
float currentHour = Float.parseFloat(currentTimes[0]);
float currentMinute = Float.parseFloat(currentTimes[1]);
float startHour = Float.parseFloat(startTimes[0]);
endHour = Float.parseFloat(endTimes[0]);
if (!isSun && endHour < startHour) {
endHour += 24;
}
float endMinute = Float.parseFloat(endTimes[1]);
if (isSun) {
if (currentHour > endHour) {
mCurrentTime = endTime;
} else if (currentHour == endHour && currentMinute >= endMinute) {
mCurrentTime = endTime;
}
}
mTotalMinute = calculateTime(mStartTime, mEndTime, false);//计算总时间单位分钟
mNeedMinute = calculateTime(mStartTime, mCurrentTime, true);//计算当前所给的时间 单位分钟
mPercentage = Float.parseFloat(formatTime(mTotalMinute, mNeedMinute));//当前时间的总分钟数占日出日落总分钟数的百分比
mCurrentAngle = 180 * mPercentage;
setAnimation(0, mCurrentAngle, 2000);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
mWidth = wm.getDefaultDisplay().getWidth() / 2;
positionX = mWidth / 2 - mRadius - DisplayUtil.dip2px(mContext, 9); // 太阳图片的初始x坐标
positionY = mRadius; // 太阳图片的初始y坐标
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, mWidth / 2 - mRadius, marginTop, mWidth / 2 + mRadius, mRadius * 2 + marginTop);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
// 渐变遮罩的画笔
shadePaint.setColor(mContext.getResources().getColor(R.color.back_white));
shadePaint.setStyle(Paint.Style.FILL);
mShadePaint = shadePaint;
pathPaint.setColor(mContext.getResources().getColor(R.color.attention_text_light));
if (isSun) {
mSunIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_sun);
} else {
mSunIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_moon);
}
mSunIcon = DisplayUtil.bitmapResize(mSunIcon, DisplayUtil.dp2px(mContext, 18), DisplayUtil.dp2px(mContext, 18));
pathPaint.setStyle(Paint.Style.STROKE);
pathPaint.setStrokeWidth(2);
mPathPaint = pathPaint;
mLinePaint.setStyle(Paint.Style.STROKE);
mLinePaint.setDither(true);//防止抖动
mLinePaint.setStrokeWidth(2);
//第一步画半圆
drawSemicircle(canvas);
canvas.save();
mLinePaint.setColor(mContext.getResources().getColor(R.color.attention_text_light));
canvas.drawLine(mWidth / 2 - mRadius - DisplayUtil.dip2px(mContext, 10), mRadius + marginTop, mWidth / 2 + mRadius + DisplayUtil.dip2px(mContext, 10), mRadius + marginTop, mLinePaint);
//第二步绘制太阳的初始位置 以及 后面在动画中不断的更新太阳的XY坐标来改变太阳图片在视图中的显示
//第三部绘制图上的文字
drawSunPosition(canvas);
drawFont(canvas);
super.onDraw(canvas);
}
/**
* 绘制半圆
*/
private void drawSemicircle(Canvas canvas) {
mRectF = new RectF(mWidth / 2 - mRadius, marginTop, mWidth / 2 + mRadius, mRadius * 2 + marginTop);
mTextPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setDither(true);//防止抖动
mTextPaint.setColor(mCircleColor);
canvas.drawArc(mRectF, 180, 180, true, mTextPaint);
}
/**
* 绘制太阳的位置
*/
private void drawSunPosition(Canvas canvas) {
// canvas.drawRect(positionX + DisplayUtil.dp2px(mContext, 10), marginTop, mWidth / 2 + mRadius, mRadius * 2 + marginTop, mShadePaint);
canvas.drawArc(mRectF, 180, 180, true, mPathPaint);
canvas.drawBitmap(mSunIcon, positionX, positionY, mLinePaint);
}
/**
* 绘制底部左右边的日出时间和日落时间
*
* @param canvas
*/
private void drawFont(Canvas canvas) {
if (ContentUtil.APP_SETTING_TESI.equalsIgnoreCase("mid")) {
mFontSize = DisplayUtil.dp2px(getContext(), 10);
} else if (ContentUtil.APP_SETTING_TESI.equalsIgnoreCase("large")) {
mFontSize = DisplayUtil.dp2px(getContext(), 13);
} else {
mFontSize = DisplayUtil.dp2px(getContext(), 12);
}
mTextPaint.setColor(mFontColor);
mTextPaint.setTextSize(mFontSize);
if (ContentUtil.APP_SETTING_THEME.equals("深色")) {
mTimePaint.setColor(getResources().getColor(R.color.aqi_color_light));
} else {
mTimePaint.setColor(getResources().getColor(R.color.air_text_common_light));
}
mTimePaint.setTextSize(mFontSize);
String startTime = TextUtils.isEmpty(mStartTime) ? "" : mStartTime;
String endTime = TextUtils.isEmpty(mEndTime) ? "" : mEndTime;
String sunrise = "日出";
String sunset = "日落";
if (!isSun) {
sunrise = "月出";
sunset = "月落";
}
if (ContentUtil.APP_SETTING_LANG.equals("en") || ContentUtil.APP_SETTING_LANG.equals("sys") && ContentUtil.SYS_LANG.equals("en")) {
sunrise = "Sunrise";
sunset = "Sunset";
if (!isSun) {
sunrise = "Moonrise";
sunset = "Moonset";
}
}
mTimePaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(sunrise, mWidth / 2 - mRadius + DisplayUtil.dip2px(mContext, 8), mRadius + DisplayUtil.dip2px(mContext, 16) + marginTop, mTextPaint);
canvas.drawText(startTime, mWidth / 2 - mRadius + DisplayUtil.dip2px(mContext, 8), mRadius + DisplayUtil.dip2px(mContext, 32) + marginTop, mTimePaint);
canvas.drawText(sunset, mWidth / 2 + mRadius - DisplayUtil.dip2px(mContext, 8), mRadius + DisplayUtil.dip2px(mContext, 16) + marginTop, mTextPaint);
canvas.drawText(endTime, mWidth / 2 + mRadius - DisplayUtil.dip2px(mContext, 8), mRadius + DisplayUtil.dip2px(mContext, 32) + marginTop, mTimePaint);
}
/**
* 精确计算文字宽度
*
* @param paint 画笔
* @param str 字符串文本
*/
public static int getTextWidth(Paint paint, String str) {
int iRet = 0;
if (str != null && str.length() > 0) {
int len = str.length();
float[] widths = new float[len];
paint.getTextWidths(str, widths);
for (int j = 0; j < len; j++) {
iRet += (int) Math.ceil(widths[j]);
}
}
return iRet;
}
/**
* 根据日出和日落时间计算出一天总共的时间:单位为分钟
*
* @param startTime 日出时间
* @param endTime 日落时间
* @return
*/
private float calculateTime(String startTime, String endTime, boolean isCurrent) {
String startTimes[] = startTime.split(":");
String endTimes[] = endTime.split(":");
float startHour = Float.parseFloat(startTimes[0]);
float startMinute = Float.parseFloat(startTimes[1]);
float endHour = Float.parseFloat(endTimes[0]);
float endMinute = Float.parseFloat(endTimes[1]);
if (!isCurrent && !isSun && endHour < startHour) {
endHour += 24;
}
if (isSun) {
if (startHour > endHour) {
return 0;
} else if (startHour == endHour && startMinute >= endMinute) {
return 0;
}
} else {
if (isCurrent) {
if (startHour > endHour) {
return 0;
} else if (startHour == endHour && startMinute >= endMinute) {
return 0;
}
} else {
if (startHour >= endHour + 24) {
return 0;
}
}
}
if (checkTime(startTime, endTime)) {
return (endHour - startHour - 1) * 60 + (60 - startMinute) + endMinute;
}
return 0;
}
/**
* 对所给的时间做一下简单的数据校验
*
* @param startTime
* @param endTime
* @return
*/
private boolean checkTime(String startTime, String endTime) {
if (TextUtils.isEmpty(startTime) || TextUtils.isEmpty(endTime)
|| !startTime.contains(":") || !endTime.contains(":")) {
return false;
}
String startTimes[] = startTime.split(":");
String endTimes[] = endTime.split(":");
float startHour = Float.parseFloat(startTimes[0]);
float startMinute = Float.parseFloat(startTimes[1]);
float endHour = Float.parseFloat(endTimes[0]);
float endMinute = Float.parseFloat(endTimes[1]);
//如果所给的时间(hour)小于日出时间hour或者大于日落时间hour
if ((startHour < Float.parseFloat(mStartTime.split(":")[0]))
|| (endHour > this.endHour)) {
return false;
}
//如果所给时间与日出时间hour相等minute小于日出时间
if ((startHour == Float.parseFloat(mStartTime.split(":")[0]))
&& (startMinute < Float.parseFloat(mStartTime.split(":")[1]))) {
return false;
}
//如果所给时间与日落时间hour相等minute大于日落时间
if ((startHour == this.endHour)
&& (endMinute > Float.parseFloat(mEndTime.split(":")[1]))) {
return false;
}
if (startHour < 0 || endHour < 0
|| startHour > 23 || endHour > 23
|| startMinute < 0 || endMinute < 0
|| startMinute > 60 || endMinute > 60) {
return false;
}
return true;
}
/**
* 根据具体的时间日出日落的时间差值 计算出所给时间的百分占比
*
* @param totalTime 日出日落的总时间差
* @param needTime 当前时间与日出时间差
* @return
*/
private String formatTime(float totalTime, float needTime) {
if (totalTime == 0)
return "0.00";
DecimalFormat decimalFormat = new DecimalFormat("0.00");//保留2位小数构造方法的字符格式这里如果小数不足2位,会以0补足.
return decimalFormat.format(needTime / totalTime);//format 返回的是字符串
}
private void setAnimation(float startAngle, float currentAngle, int duration) {
ValueAnimator sunAnimator = ValueAnimator.ofFloat(startAngle, currentAngle);
sunAnimator.setDuration(duration);
sunAnimator.setTarget(currentAngle);
sunAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//每次要绘制的圆弧角度
mCurrentAngle = (float) animation.getAnimatedValue();
invalidateView();
}
});
sunAnimator.start();
}
private void invalidateView() {
//绘制太阳的x坐标和y坐标
positionX = mWidth / 2 - (float) (mRadius * Math.cos((mCurrentAngle) * Math.PI / 180)) - DisplayUtil.dp2px(mContext, 10);
positionY = mRadius - (float) (mRadius * Math.sin((mCurrentAngle) * Math.PI / 180)) + DisplayUtil.dip2px(mContext, 18);
invalidate();
}
}

View File

@ -0,0 +1,78 @@
package com.heweather.owp.view.window;
import android.content.Intent;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import com.heweather.owp.R;
import com.heweather.owp.adapter.LocLIstAdapter;
import com.heweather.owp.bean.CityBean;
import com.heweather.owp.view.activity.MainActivity;
import com.heweather.owp.view.activity.SearchActivity;
import java.util.ArrayList;
import java.util.List;
public class LocListWindow extends PopupWindow {
private View view;
private MainActivity context;
public LocListWindow(View contentView, int width, int height, MainActivity context) {
super(contentView, width, height);
this.view = contentView;
this.context = context;
}
public void show() {
RelativeLayout rcSearch = view.findViewById(R.id.rv_search);
rcSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, SearchActivity.class);
context.startActivity(intent);
LocListWindow.this.dismiss();
}
});
RecyclerView recyclerView = view.findViewById(R.id.rc_loc_list);
List<CityBean> list = new ArrayList<>();
list.add(getCity("CN101010100",context.getString(R.string.beijing)));
list.add(getCity("CN101020100",context.getString(R.string.shanghai)));
list.add(getCity("CN101280601",context.getString(R.string.shenzhen)));
list.add(getCity("GB2643741",context.getString(R.string.London)));
list.add(getCity("US3290117",context.getString(R.string.Ner_York)));
list.add(getCity("CN101320101",context.getString(R.string.HongKong)));
list.add(getCity("SG1880252",context.getString(R.string.Singapore)));
list.add(getCity("AU2147714",context.getString(R.string.Sydney)));
list.add(getCity("FR2988507",context.getString(R.string.Paris)));
list.add(getCity("JP1850147",context.getString(R.string.Tokyo)));
list.add(getCity("AE292223",context.getString(R.string.Dubai)));
list.add(getCity("DE2950159",context.getString(R.string.Berlin)));
list.add(getCity("NL2759794",context.getString(R.string.Amsterdam)));
list.add(getCity("KR1835848",context.getString(R.string.Seoul)));
list.add(getCity("RU524901",context.getString(R.string.Moscow)));
list.add(getCity("CH2657896",context.getString(R.string.Zurich)));
list.add(getCity("CA6167865",context.getString(R.string.Toronto)));
list.add(getCity("ZA2499011",context.getString(R.string.Cape_Town)));
list.add(getCity("TH1609350",context.getString(R.string.Bangkok)));
list.add(getCity("ES3117735",context.getString(R.string.Madrid)));
recyclerView.setLayoutManager(new GridLayoutManager(context, 3));
recyclerView.setAdapter(new LocLIstAdapter(LocListWindow.this, list, context));
}
private CityBean getCity(String id,String name){
CityBean cityBean = new CityBean();
cityBean.setCityId(id);
cityBean.setCityName(name);
return cityBean;
}
}

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
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="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/enable" android:state_enabled="true" />
<item android:drawable="@drawable/disable" android:state_enabled="false" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

View File

@ -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:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_air_bad" />
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_air_excellent" />
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_air_good" />
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_air_low" />
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_air_mid" />
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_air_serious" />
<corners android:topLeftRadius="3dp"
android:topRightRadius="3dp"
android:bottomRightRadius="3dp"
android:bottomLeftRadius="3dp"/>
</shape>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_6eac5d" />
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp"
android:topLeftRadius="4dp"
android:topRightRadius="4dp" />
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blue_alarm" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/orange_alarm" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/red_alarm" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_ececec" />
<corners android:topLeftRadius="4dp"
android:topRightRadius="4dp"
android:bottomRightRadius="4dp"
android:bottomLeftRadius="4dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:topLeftRadius="20dp"
android:topRightRadius="20dp"
android:bottomRightRadius="20dp"
android:bottomLeftRadius="20dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/yellow_alarm" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/color_ececec"
tools:context=".view.activity.AboutActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/back_white">
<ImageView
android:id="@+id/iv_about_back"
android:layout_width="38dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:paddingStart="16dp"
android:paddingEnd="10dp"
android:src="@mipmap/icon_back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/about"
android:textColor="@color/color_212121"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="80dp">
<ImageView
android:id="@+id/iv_about1"
android:layout_width="103dp"
android:layout_height="88dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/icon_icon" />
<TextView
android:id="@+id/tv_app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_about1"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="@string/app_name"
android:textColor="@color/color_212121"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_hua"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_marginTop="52dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_version"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/now_version"
android:textColor="@color/color_4a4a4a"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_version_num"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="1.1.2"
android:textColor="@color/color_a4a4a4"
android:layout_alignParentEnd="true"
android:layout_marginEnd="32dp"
android:textSize="14sp" />
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_ececec"
android:orientation="vertical"
tools:context=".view.activity.ControlCityActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/back_white">
<ImageView
android:id="@+id/iv_control_back"
android:layout_width="38dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:paddingStart="16dp"
android:paddingEnd="10dp"
android:src="@mipmap/icon_back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/control_city"
android:textColor="@color/color_212121"
android:textSize="17sp" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycle_control"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.activity.MainActivity">
<ImageView
android:id="@+id/iv_main_back"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/back_100d" />
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="52dp" />
<RelativeLayout
android:id="@+id/rv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_loc"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_marginStart="16dp"
android:layout_marginTop="18dp"
android:src="@mipmap/icon_loc" />
<TextView
android:id="@+id/tv_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="34dp"
android:layout_marginTop="13dp"
android:textColor="@color/white"
android:textSize="16sp" />
<ImageView
android:id="@+id/iv_add_city"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="8dp"
android:layout_toRightOf="@+id/tv_location"
android:padding="8dp"
android:src="@mipmap/icon_add_city" />
<LinearLayout
android:id="@+id/ll_round"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_below="@+id/tv_location"
android:layout_marginStart="36dp"
android:layout_marginTop="7dp"
android:orientation="horizontal" />
<ImageView
android:id="@+id/iv_set"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_alignParentEnd="true"
android:padding="14dp"
android:src="@mipmap/icon_set" />
</RelativeLayout>
</RelativeLayout>

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_ececec"
android:orientation="vertical"
tools:context=".view.activity.SearchActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/back_white">
<ImageView
android:id="@+id/iv_search_back"
android:layout_width="38dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:paddingEnd="10dp"
android:paddingStart="16dp"
android:src="@mipmap/icon_back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/add_city"
android:textColor="@color/color_212121"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/back_white">
<AutoCompleteTextView
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:background="@drawable/shape_search"
android:gravity="center_vertical"
android:hint="@string/add_city"
android:maxLength="20"
android:paddingStart="30dp"
android:singleLine="true"
android:textColor="@color/color_212121"
android:textColorHint="@color/color_a4a4a4"
android:textSize="16sp" />
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:src="@mipmap/icon_search" />
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_history"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/nearly_search" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycle_history"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycle_search"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:background="@color/back_white">
</android.support.v7.widget.RecyclerView>
</LinearLayout>

View File

@ -0,0 +1,366 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".view.activity.SettingActivity">
<RelativeLayout
android:background="@color/back_white"
android:layout_width="match_parent"
android:layout_height="44dp">
<ImageView
android:id="@+id/iv_setting_back"
android:layout_width="38dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:paddingStart="16dp"
android:paddingEnd="10dp"
android:src="@mipmap/icon_back" />
<TextView
android:id="@+id/tv_setting_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/setting"
android:textColor="@color/color_212121"
android:textSize="17sp" />
</RelativeLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_ececec"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rv_control"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="16dp"
android:background="@color/color_fafafa">
<TextView
android:id="@+id/tv_control"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/control_city"
android:textColor="@color/color_4a4a4a"
android:textSize="14sp" />
<ImageView
android:layout_width="7dp"
android:layout_height="11dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="30dp"
android:src="@mipmap/icon_into" />
</RelativeLayout>
<TextView
android:id="@+id/tv_choose_lang"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:text="@string/choose_lang"
android:textColor="@color/color_7A7A7A"
android:textSize="12sp" />
<RelativeLayout
android:id="@+id/rv_system_language"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_sys_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/system_lang"
android:textColor="@color/color_4a4a4a"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_sys_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_chinese_language"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="1dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_ch_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/chinese"
android:textColor="@color/color_a4a4a4"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_ch_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right"
android:visibility="gone" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_english_language"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="1dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_en_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/english"
android:textColor="@color/color_a4a4a4"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_en_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right"
android:visibility="gone" />
</RelativeLayout>
<TextView
android:id="@+id/tv_choose_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:text="@string/choose_unit"
android:textColor="@color/color_7A7A7A"
android:textSize="12sp" />
<RelativeLayout
android:id="@+id/rv_hua"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_hua_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/hua"
android:textColor="@color/color_4a4a4a"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_hua_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_she"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="1dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_she_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/she"
android:textColor="@color/color_a4a4a4"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_she_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right"
android:visibility="gone" />
</RelativeLayout>
<TextView
android:id="@+id/tv_choose_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:text="@string/choose_text_size"
android:textColor="@color/color_7A7A7A"
android:textSize="12sp" />
<RelativeLayout
android:id="@+id/rv_small"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_small_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/small"
android:textColor="@color/color_4a4a4a"
android:textSize="13sp" />
<ImageView
android:id="@+id/iv_small_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_mid"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="1dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_mid_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/mid"
android:textColor="@color/color_a4a4a4"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_mid_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right"
android:visibility="gone" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_large"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="1dp"
android:background="@color/color_fafafa"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_large_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/large"
android:textColor="@color/color_a4a4a4"
android:textSize="15sp" />
<ImageView
android:id="@+id/iv_large_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:padding="2dp"
android:src="@mipmap/icon_right"
android:visibility="gone" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rv_about"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="44dp"
android:background="@color/color_fafafa">
<TextView
android:id="@+id/tv_about"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:gravity="center"
android:text="@string/about"
android:textColor="@color/color_4a4a4a"
android:textSize="14sp" />
<ImageView
android:layout_width="7dp"
android:layout_height="11dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="30dp"
android:src="@mipmap/icon_into" />
</RelativeLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.activity.SplashActivity">
<TextView
android:gravity="center"
android:text="欢迎"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/back_white"
tools:context=".view.fragment.WeatherFragment">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_back"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="-54dp"
android:scaleType="centerCrop"
android:src="@mipmap/back_100d" />
<ImageView
android:layout_width="match_parent"
android:layout_height="650dp"
android:layout_below="@+id/iv_back"
android:layout_marginTop="-90dp"
android:scaleType="fitXY"
android:src="@mipmap/back" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="400dp">
<TextView
android:id="@+id/tv_today_tmp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="154dp"
android:text="20°"
android:textColor="@color/white"
android:textSize="60sp" />
<TextView
android:id="@+id/tv_today_cond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_today_tmp"
android:layout_centerHorizontal="true"
android:text="多云"
android:textColor="@color/white80"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_today_alarm"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_below="@+id/tv_today_cond"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:background="@drawable/shape_blue_alarm"
android:gravity="center"
android:paddingLeft="14dp"
android:paddingRight="14dp"
android:text="暴雨预警"
android:textColor="@color/white80"
android:textSize="12sp"
android:visibility="gone" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_forecast_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:paddingBottom="16dp"
android:paddingStart="16dp"
android:paddingTop="13dp"
android:text="@string/forecast"
android:textColor="@color/color_212121"
android:textSize="16sp"
tools:ignore="RtlSymmetry" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/tv_line_max_tmp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="16dp"
android:text="21°"
android:textColor="@color/color_ababab"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_line_min_tmp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="66dp"
android:text="11°"
android:textColor="@color/color_ababab"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="98dp"
android:layout_marginLeft="50dp"
android:orientation="horizontal">
<com.heweather.owp.view.horizonview.IndexHorizontalScrollView
android:id="@+id/hsv"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.heweather.owp.view.horizonview.HourlyForecastView
android:id="@+id/hourly"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.heweather.owp.view.horizonview.IndexHorizontalScrollView>
</LinearLayout>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_forecast"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
<include
android:id="@+id/today_detail"
layout="@layout/layout_today_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/back_white" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:id="@+id/iv_item_delete"
android:padding="10dp"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginStart="17dp"
android:layout_centerVertical="true"
android:src="@mipmap/icon_delete" />
<TextView
android:id="@+id/tv_item_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="56dp"
android:ellipsize="end"
android:singleLine="true"
android:gravity="center"
android:text="北京"
android:layout_marginEnd="40dp"
android:textColor="@color/color_4a4a4a"
android:textSize="14sp" />
<ImageView
android:layout_marginStart="56dp"
android:background="@color/color_ececec"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="1dp" />
</RelativeLayout>

Some files were not shown because too many files have changed in this diff Show More