如何解决尝试显示我的应用的天气图标时出现问题
这最初是在大约 20 天前被问到的,我试图根据城市的响应(来自 drawable 文件夹)在我的应用程序上显示天气图标 来自天气官方 API 文档 https://openweathermap.org/weather-conditions 中列出的天气条件数量(您可以随时通过查看编辑历史来查看)。 API 提供了 9 种主要天气条件。
这仍然是我的目标:
-
当应用程序第一次打开时,不显示任何图标。
-
否则,如果响应是该城市的几朵云,则显示几朵云图标
-
否则,如果响应是该城市的云散乱,则显示云散乱图标
-
否则,如果响应是该城市的碎云,则显示碎云图标
-
否则,如果响应是该城市的阵雨,则显示阵雨图标
-
否则,如果响应是该城市的下雨,则显示下雨图标
-
否则,如果响应是该城市的雷暴,则显示雷暴图标
-
否则,如果响应是该城市的雪,则显示雪图标
-
否则,如果该城市的响应为 Mist,则显示 Mist 图标。
在 MagDalena Rowicka 的帮助下,我已经完成了一些事情,但即使在尝试自己修复后问题仍未完全解决,这就是我重新悬赏帖子的原因。
我做的第一件事是使用以下数据集创建一个单独的枚举类:
public enum WeatherIcon {
Sun,Cloud1,Cloud2,Cloud3,Rain1,Rain2,Thunder,SNow,Mist
}
然后我在我在片段上声明我的文本视图的地方添加了这个代码 final ImageView imageofWeather = rootView.findViewById(R.id.imageView2);
。
然后我添加了这个 int drawableResource;
// 在这里定义默认图标例如
片段上 viewmodel.getWeatherDataLiveData().observe(getViewLifecycleOwner(),data -> {
之后的 R.drawable.default_weather_icon。
switch (data.getWeather().get(0).getIcon()) {
case WeatherIcon.Sun:
drawableResource = R.drawable.sun; //reference to drawable id
break;
case WeatherIcon.Cloud1:
drawableResource = R.drawable.broken_clouds; //reference to drawable id
break;
case WeatherIcon.Cloud2:
drawableResource = R.drawable.few_clouds; //reference to drawable id
break;
case WeatherIcon.Cloud3:
drawableResource = R.drawable.scattered_clouds; //reference to drawable id
break;
case WeatherIcon.Rain1:
drawableResource = R.drawable.small_rain; //reference to drawable id
break;
case WeatherIcon.Rain2:
drawableResource = R.drawable.shower_rain; //reference to drawable id
break;
case WeatherIcon.Thunder:
drawableResource = R.drawable.thunderstorm; //reference to drawable id
break;
case WeatherIcon.SNow:
drawableResource = R.drawable.sNow; //reference to drawable id
break;
case WeatherIcon.Mist:
drawableResource = R.drawable.mist; //reference to drawable id
break;
imageofWeather.setimageDrawable(drawableResource);
}
fragment 中的 if 语句下直接访问 API 并显示天气图标。 (相应的 9 个图标目前显示在 firstfragment 类的编号线上)。
当前设置的问题在于:
- 对于每个 case 语句,我收到以下错误:
分配给'drawableResource'的值R.drawable.sun(和其余的) 从未使用过。
和
必需类型:Drawable,提供:int
如果有人能提供帮助,我将不胜感激。
这是我的片段代码:
public class FirstFragment extends Fragment {
private WeatherDataviewmodel viewmodel;
public FirstFragment() {
// required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_first,container,false);
// For displaying weather data
// all field in Java should be type in camelCase,so not current_temp but currentTemp,not Cloud_out but cloudOut
// Capitalize name is for class not field
final TextView current_temp = rootView.findViewById(R.id.textView10);
final TextView current_output = rootView.findViewById(R.id.textView11);
final TextView rise_time = rootView.findViewById(R.id.textView25);
final TextView set_time = rootView.findViewById(R.id.textView26);
final TextView temp_out = rootView.findViewById(R.id.textView28);
final TextView Press_out = rootView.findViewById(R.id.textView29);
final TextView Humid_out = rootView.findViewById(R.id.textView30);
final TextView Ws_out = rootView.findViewById(R.id.textView33);
final TextView Visi_out = rootView.findViewById(R.id.textView34);
final TextView Cloud_out = rootView.findViewById(R.id.textView35);
final ImageView imageofWeather = rootView.findViewById(R.id.imageView2);
// Get our viewmodel instance
viewmodel = new viewmodelProvider(this).get(WeatherDataviewmodel.class);
// And whenever the data changes,refresh the UI
viewmodel.getWeatherDataLiveData().observe(getViewLifecycleOwner(),data -> {
int drawableResource; // here define default icon for example R.drawable.default_weather_icon
if (data != null) {
current_temp.setVisibility(View.VISIBLE);
current_temp.setText(data.getMain().getTemp() + " ℃"); // for that you can use strings resource and templates more in https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings
current_output.setVisibility(View.VISIBLE);
current_output.setText(data.getWeather().get(0).getDescription());
rise_time.setVisibility(View.VISIBLE);
rise_time.setText(data.getSys().getSunrise() + " ");
set_time.setVisibility(View.VISIBLE);
set_time.setText(data.getSys().getSunset() + " ");
temp_out.setVisibility(View.VISIBLE);
temp_out.setText(data.getMain().getTemp() + " ℃");
Press_out.setVisibility(View.VISIBLE);
Press_out.setText(data.getMain().getPressure() + " hpa");
Humid_out.setVisibility(View.VISIBLE);
Humid_out.setText(data.getMain().getHumidity() + " %");
Ws_out.setVisibility(View.VISIBLE);
Ws_out.setText(data.getwind().getSpeed() + " Km/h");
Visi_out.setVisibility(View.VISIBLE);
Visi_out.setText(data.getVisibility() + " m");
Cloud_out.setVisibility(View.VISIBLE);
Cloud_out.setText(data.getClouds().getAll() + " %");
// get actual weather.
switch (data.getWeather().get(0).getIcon()) { //or data.getWeather()[0].getIcon() i don't remember how it work in Java
case WeatherIcon.Sun:
drawableResource = R.drawable.sun; //reference to drawable id
break;
case WeatherIcon.Cloud1:
drawableResource = R.drawable.broken_clouds; //reference to drawable id
break;
case WeatherIcon.Cloud2:
drawableResource = R.drawable.few_clouds; //reference to drawable id
break;
case WeatherIcon.Cloud3:
drawableResource = R.drawable.scattered_clouds; //reference to drawable id
break;
case WeatherIcon.Rain1:
drawableResource = R.drawable.small_rain; //reference to drawable id
break;
case WeatherIcon.Rain2:
drawableResource = R.drawable.shower_rain; //reference to drawable id
break;
case WeatherIcon.Thunder:
drawableResource = R.drawable.thunderstorm; //reference to drawable id
break;
case WeatherIcon.SNow:
drawableResource = R.drawable.sNow; //reference to drawable id
break;
case WeatherIcon.Mist:
drawableResource = R.drawable.mist; //reference to drawable id
break;
imageofWeather.setimageDrawable(drawableResource);
}
} else {
Log.e("TAG","No City found");
current_temp.setVisibility(View.GONE);
current_output.setVisibility(View.GONE);
rise_time.setVisibility(View.GONE);
set_time.setVisibility(View.GONE);
temp_out.setVisibility(View.GONE);
Press_out.setVisibility(View.GONE);
Humid_out.setVisibility(View.GONE);
Ws_out.setVisibility(View.GONE);
Visi_out.setVisibility(View.GONE);
Cloud_out.setVisibility(View.GONE);
Toast.makeText(requireActivity(),"No City found",Toast.LENGTH_SHORT).show();
}
});
return rootView;
}
public void getWeatherData(String name) {
// The viewmodel controls loading the data,so we just
// tell it what the new name is - this kicks off loading
// the data,which will automatically call through to
// our observe() call when the data load completes
viewmodel.setCityName(name);
}
}
解决方法
也许试试这样:
- 使用枚举指定要显示的图标创建一个天气类。
- 下载数据后,转换为创建的类
- 一个单独的函数,它将决定为给定的枚举显示什么
已编辑:
public class Example{
// add to your definition
private WeaterIcon icon;
public WeaterIcon getIcon() {
return icon;
}
public void setIcon(WeaterIcon icon) {
this.icon = icon;
}
}
enum WeaterIcon {
SUN,FROG,//type all what want
}
在 onCreateView
//there are yor reference to xml object
final ImageView imageOfWeather = rootView.findViewById(R.id.imageView); // add this reference
并选择正确的图标
int drawableResource; // here define default icon or not
switch(data.getIcon()) {
case WeaterIcon.SUN:
drawableResource = R.drawable.sun_icon //reference to drawable id
break;
case WeaterIcon.FROG:
drawableResource = R.drawable.frog_icon//reference to drawable id
break;
//add all
}
imageOfWeather.setImageDrawable(drawableResource);
,
线 imageofWeather.setImageDrawable(drawableResource);显示此错误:
Required type: Drawable,Provided: int
这意味着 setImageDrawable()
需要(期望)一个 Drawable 参数,但提供的(找到的)参数是一个 int
。
要解决此问题,请改用 setImageResource()
,它采用 int
可绘制资源而不是 Drawable
对于每个 case 语句,我收到以下错误:
The value R.drawable.sun(and the rest) assigned to 'drawableResource' is never used.
这是由于之前的错误而引发的,它认为 drawableResource
的行未使用 setImageDrawable()
,因此它警告您您为其分配了一个值但从未使用过它。
这个警告应该通过修复第一个来修复;虽然,我建议用一个私有构造函数重写 enum
,该构造函数接受一个 int
可绘制资源值,它将处理 switch 语句,而不是让片段这样做。
新的枚举:
public enum WeatherIcon {
Sun(R.drawable.sun),Cloud1(R.drawable.broken_clouds),Cloud2(R.drawable.few_clouds),Cloud3(R.drawable.scattered_clouds),Rain1(R.drawable.small_rain),Rain2(R.drawable.shower_rain),Thunder(R.drawable.thunderstorm),Snow(R.drawable.snow),Mist(R.drawable.mist);
private int drawable;
WeatherIcon(int drawable) {
this.drawable = drawable;
}
public int getDrawable() {
return drawable;
}
}
然后,您可以删除它并通过使用枚举的 switch
方法获取可绘制对象来代替片段中的 getDrawable()
语句,如下所示:
WeatherIcon icon = data.getWeather().get(0).getIcon();
int drawableResource = icon.getDrawable();
imageofWeather.setImageResource(drawableResource);
,
您必须在清单文件中制作 activity-alias
,您可以根据天气条件在其中设置图标。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.erikjhordanrey.livebinding">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name="io.github.erikjhordanrey.livebinding.view.DcCharacterActivity">
<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>
<activity-alias
android:name=".MainActivityAlias"
android:enabled="false"
android:icon="@drawable/R.drawable.sun"
android:label="@string/app_name"
android:roundIcon="@drawable/R.drawable.sun"
android:targetActivity="io.github.erikjhordanrey.livebinding.view.DcCharacterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".MainActivityAlias"
android:enabled="false"
android:icon="@drawable/R.drawable.broken_clouds"
android:label="@string/app_name"
android:roundIcon="@drawable/R.drawable.broken_clouds"
android:targetActivity="io.github.erikjhordanrey.livebinding.view.DcCharacterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".MainActivityAlias"
android:enabled="false"
android:icon="@drawable/R.drawable.few_clouds"
android:label="@string/app_name"
android:roundIcon="@drawable/R.drawable.few_clouds"
android:targetActivity="io.github.erikjhordanrey.livebinding.view.DcCharacterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!--and so on....-->
</application>
</manifest>
在 MainActivity 文件中,您必须根据天气情况更改图标。
private void newicon() {
// enable old icon
PackageManager manager=getPackageManager();
manager.setComponentEnabledSetting(new ComponentName(MainActivity.this,"com.prepare.makedirectory.MainActivity"),PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
// enable new icon
manager.setComponentEnabledSetting(new ComponentName(MainActivity.this,"com.prepare.makedirectory.MainActivityAlias"),PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
Toast.makeText(MainActivity.this,"Enable New Icon",Toast.LENGTH_LONG).show();
}
您可以在此链接中找到整篇文章: https://www.geeksforgeeks.org/how-to-change-app-icon-of-android-programmatically-in-android/
,请试试这个代码。
public class FirstFragment extends Fragment {
private WeatherDataViewModel viewModel;
public FirstFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_first,container,false);
// For displaying weather data
// all field in Java should be type in camelCase,so not current_temp but currentTemp,not Cloud_out but cloudOut
// Capitalize name is for class not field
final TextView current_temp = rootView.findViewById(R.id.textView10);
final TextView current_output = rootView.findViewById(R.id.textView11);
final TextView rise_time = rootView.findViewById(R.id.textView25);
final TextView set_time = rootView.findViewById(R.id.textView26);
final TextView temp_out = rootView.findViewById(R.id.textView28);
final TextView Press_out = rootView.findViewById(R.id.textView29);
final TextView Humid_out = rootView.findViewById(R.id.textView30);
final TextView Ws_out = rootView.findViewById(R.id.textView33);
final TextView Visi_out = rootView.findViewById(R.id.textView34);
final TextView Cloud_out = rootView.findViewById(R.id.textView35);
final ImageView imageofWeather = rootView.findViewById(R.id.imageView2);
// Get our ViewModel instance
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// And whenever the data changes,refresh the UI
viewModel.getWeatherDataLiveData().observe(getViewLifecycleOwner(),data -> {
Drawble drawableResource; // default added in switch
if (data != null) {
current_temp.setVisibility(View.VISIBLE);
current_temp.setText(data.getMain().getTemp() + " ℃"); // for that you can use strings resource and templates more in https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings
current_output.setVisibility(View.VISIBLE);
current_output.setText(data.getWeather().get(0).getDescription());
rise_time.setVisibility(View.VISIBLE);
rise_time.setText(data.getSys().getSunrise() + " ");
set_time.setVisibility(View.VISIBLE);
set_time.setText(data.getSys().getSunset() + " ");
temp_out.setVisibility(View.VISIBLE);
temp_out.setText(data.getMain().getTemp() + " ℃");
Press_out.setVisibility(View.VISIBLE);
Press_out.setText(data.getMain().getPressure() + " hpa");
Humid_out.setVisibility(View.VISIBLE);
Humid_out.setText(data.getMain().getHumidity() + " %");
Ws_out.setVisibility(View.VISIBLE);
Ws_out.setText(data.getWind().getSpeed() + " Km/h");
Visi_out.setVisibility(View.VISIBLE);
Visi_out.setText(data.getVisibility() + " m");
Cloud_out.setVisibility(View.VISIBLE);
Cloud_out.setText(data.getClouds().getAll() + " %");
Drawable drawableResource; // default icon is set in the switch
switch (data.getWeather().get(0).getIcon()) {
case WeaterIcon.SUN:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.sun);
break;
case WeatherIcon.Cloud1:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.broken_clouds); //reference to drawable id
break;
case WeatherIcon.Cloud2:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.few_clouds); //reference to drawable id
break;
case WeatherIcon.Cloud3:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.scattered_clouds); //reference to drawable id
break;
case WeatherIcon.Rain1:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.small_rain); //reference to drawable id
break;
case WeatherIcon.Rain2:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.shower_rain); //reference to drawable id
break;
case WeatherIcon.Thunder:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.thunderstorm); //reference to drawable id
break;
case WeatherIcon.Snow:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.snow); //reference to drawable id
break;
case WeatherIcon.Mist:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.mist); //reference to drawable id
break;
//add a default of any background if error occurs
default:
drawableResource = ContextCompat.getDrawable(requireActivity(),R.drawable.any_background);
break;
}
imageOfWeather.setImageDrawable(drawableResource);
} else {
Log.e("TAG","No City found");
current_temp.setVisibility(View.GONE);
current_output.setVisibility(View.GONE);
rise_time.setVisibility(View.GONE);
set_time.setVisibility(View.GONE);
temp_out.setVisibility(View.GONE);
Press_out.setVisibility(View.GONE);
Humid_out.setVisibility(View.GONE);
Ws_out.setVisibility(View.GONE);
Visi_out.setVisibility(View.GONE);
Cloud_out.setVisibility(View.GONE);
Toast.makeText(requireActivity(),"No City found",Toast.LENGTH_SHORT).show();
}
});
return rootView;
}
public void getWeatherData(String name) {
// The ViewModel controls loading the data,so we just
// tell it what the new name is - this kicks off loading
// the data,which will automatically call through to
// our observe() call when the data load completes
viewModel.setCityName(name);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。