Tuesday 3 August 2021

Having problem trying to display my app's weather icons

This was Initially asked about 20 days ago, I was trying to display weather icons on my app according to its city's response(from the drawable folder) from the number of weather conditions listed on the weather's official API doc https://openweathermap.org/weather-conditions (which you can always view by checking the edit history). There are 9 main weather conditions from the API.

This still remains my goal:

  • 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 in that city, display the Mist icon.

With Magdalena Rowicka's help, I've been able to achieve a few things but the issue has still not been fully solved even after trying to fix it myself and that's why I'm re-bountying the post.

The first thing I did was to create a separate enum class with the following sets of data:

public enum WeatherIcon {
    Sun, Cloud1, Cloud2, Cloud3, Rain1, Rain2, Thunder, Snow, Mist
}

Then I added this code final ImageView imageofWeather = rootView.findViewById(R.id.imageView2); in the place where i declared my textviews on fragment.

Then I added this int drawableResource; // here define default icon for example R.drawable.default_weather_icon after the viewModel.getWeatherDataLiveData().observe(getViewLifecycleOwner(), data -> { on fragment.

Then i finally added this code:

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);
            }

Under the if statement in fragment to access the API directly and display the weather icons. (The respective 9 icons are currently shown visibly on the numbering line of the firstfragment class).

The issues from this current setup is that:

  • For each case statement, I get the following error:

The value R.drawable.sun(and the rest) assigned to 'drawableResource' is never used.

and

  • The line imageofWeather.setImageDrawable(drawableResource); shows this error:

Required type: Drawable, Provided: int

I will surely appreciate it if anyone can help.

Here's My Fragment code:

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);
    }
}


from Having problem trying to display my app's weather icons

No comments:

Post a Comment