微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试显示我的应用的天气图标时出现问题

如何解决尝试显示我的应用的天气图标时出现问题

这最初是在大约 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);
    }
}

解决方法

也许试试这样:

  1. 使用枚举指定要显示的图标创建一个天气类。
  2. 下载数据后,转换为创建的类
  3. 一个单独的函数,它将决定为给定的枚举显示什么

已编辑:

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 举报,一经查实,本站将立刻删除。