I'm done with almost every other setup for my app, and I've been trying for days to figure out how I can display weather icons for my app according to its city's response but I still have no idea how to do that. To my surprise, I haven't seen anyone with the same issue. I've checked this site, searched several sites for tutorials on it, checked youtube, visited code Project for help https://www.codeproject.com/Questions/5307462/How-to-setup-my-app-weather-icons, asked on quora and discord and Checked different weather open sources on Github but I found no place where they tried to achieve a similar thing. So I eventually decided to come here for help. And I will surely appreciate it if anyone can help.
Following the API instructions, I'm using https://openweathermap.org/weather-conditions. There are 9 main weather conditions. This is my goal while using it:
- When the app is open at first, display no icon.
- If a user searches for a city and the response he gets is a clear sky, display the Clear Sky icon;
- Otherwise, if the response is Few Clouds in that city, display the Few Clouds icon
- Otherwise, if the response is Scattered clouds in that city, display the Scattered clouds icon
- Otherwise, if the response is Broken Clouds in that city, display the Broken Clouds icon
- Otherwise, if the response is Shower rain in that city, display the Shower rain icon
- Otherwise, if the response is Rain in that city, display the Rain icon
- Otherwise, if the response is Thunderstorm in that city, display the Thunderstorm icon
- Otherwise, if the response is Snow in that city, display the Snow icon
- Otherwise, if the response is Mist there, display the Mist icon.
OpenWeatherMap https://openweathermap.org/current only made provisions for setting up the weather icons if you're using their own icons i.e weather.icon
. But I only want to make use of the Icons I have in my Drawable. I have all the 9 icons I want to use in my drawable.
I feel I may need to create a method, along with if-else and maybe a case statement, but still, I don't know the way to do that in a way it will rightly work with the app. I lack experience with that specifically.
I don't have a specific response on the app, as it can search for any city, but an example of the response it gets is like this:
...
"weather":[
{
"id":801,
"main":"Clouds",
"description":"few clouds",
"icon":"02n"
}
],
...
Here is my code:
FirstFragment.java:
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
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);
// Get our ViewModel instance
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// And whenever the data changes, refresh the UI
viewModel.getWeatherDataLiveData().observe(getViewLifecycleOwner(), data -> {
if (data != null) {
current_temp.setVisibility(View.VISIBLE);
current_temp.setText(data.getMain().getTemp() + " ℃");
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() + " %");
} 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);
}
}
For my ViewModel:
WeatherDataViewModel:
public class WeatherDataViewModel extends ViewModel {
// This will save the city name
private SavedStateHandle state;
// This is where we'll store our result from the server
private MutableLiveData<Example> mutableWeatherData = new MutableLiveData<>();
public WeatherDataViewModel(SavedStateHandle savedStateHandle) {
state = savedStateHandle;
String savedCityName = state.get("name");
if (savedCityName != null) {
// We already had a previously saved name, so we'll
// start loading right away
loadData();
}
}
// This is what our Fragment will use to get the latest weather data
public LiveData<Example> getWeatherDataLiveData() {
return mutableWeatherData;
}
// When you get a new city name, we'll save that in our
// state, then load the new data from the server
public void setCityName(String name) {
state.set("name", name);
loadData();
}
private void loadData() {
// Get the last name that was set
String name = state.get("name");
// Now kick off a load from the server
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(@NonNull Call<Example> call, @NonNull Response<Example> response) {
// Save the response we've gotten
// This will automatically update our UI
mutableWeatherData.setValue(response.body());
}
@Override
public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
t.printStackTrace();
}
});
}
}
from Having problem trying to display my app's weather icons
No comments:
Post a Comment