【问题标题】:Link weather data connection between Fragment and Activity在 Fragment 和 Activity 之间链接天气数据连接
【发布时间】:2021-05-20 20:50:30
【问题描述】:

我正在使用https://openweathermap.org/current 构建一个天气应用程序,到目前为止,一切进展顺利。该应用程序的活动部分使用我的界面中的城市查询来提供在编辑文本上搜索的任何城市的当前数据。现在的问题是我只使用了一个搜索按钮(在我的活动上),但我也想在片段类中接收相同的数据。例如,我将活动用于: 1.搜索和显示城市名称。 2. 显示这些城市的当前时间。

以及用于获取在活动中搜索的城市的温度、日出和日落、湿度和其他数据的片段。

所以我不能实现双重搜索按钮(在活动和片段中)只是为了获取数据。我的目标是只使用自己的活动来获取两个类中的城市数据,因为我的片段类也包含用于接收数据的文本视图,我会很感激任何方法来实现这一点,因为我自己不知道如何做到这一点。

我尝试在片段类上调用相同的方法,但我从片段中的这段代码中得到编译错误:

private void getWeatherData(String name) {

            ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

            Call<Example> call = apiInterface.getWeatherData(name);

说:'getWeatherData' is never usedcannot resolve symbol 'name'(因为我的搜索按钮和编辑文本仅用于活动)

我在 Activity 中没有收到任何错误

这是我的完整代码:

HomeActivity.java

public class HomeActivity extends AppCompatActivity {
    // User current time
    TextView time_field;
    ImageView Search;
    EditText textfield;
    ConstraintLayout constraintLayout;
    public static int count=0;
    int[] drawable =new int[]{R.drawable.dubai,R.drawable.central_bank_of_nigeria,R.drawable.eiffel_tower,R.drawable.hong_kong,R.drawable.statue_of_liberty};
    Timer _t;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        time_field = findViewById(R.id.textView9);
        Search = findViewById(R.id.imageView4);
        textfield = findViewById(R.id.textfield);

        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
        NavController navController = Navigation.findNavController(this, R.id.fragment);
        NavigationUI.setupWithNavController(bottomNavigationView, navController);

        Search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                getWeatherData(textfield.getText().toString().trim());


                            constraintLayout = findViewById(R.id.layout);
                            constraintLayout.setBackgroundResource(R.drawable.dubai);
                            _t = new Timer();
                            _t.scheduleAtFixedRate(new TimerTask() {
                                @Override
                                public void run() {
                                    // run on ui thread
                                    runOnUiThread(() -> {
                                        if (count < drawable.length) {

                                            constraintLayout.setBackgroundResource(drawable[count]);
                                            count = (count + 1) % drawable.length;
                                        }
                                    });
                                }
                            }, 5000, 5000);
                        }

            private void getWeatherData(String name) {

                ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

                Call<Example> call = apiInterface.getWeatherData(name);

                call.enqueue(new Callback<Example>() {
                    @Override
                    public void onResponse(@NotNull Call<Example> call, @NotNull Response<Example> response) {

                        assert response.body() != null;
                        time_field.setText(String.valueOf(response.body().getDt()));



                    }

                    @Override
                    public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                        t.printStackTrace();
                    }


                });
            }




        });
    }
}

FirstFragment.java

public class FirstFragment extends Fragment {
    // User current time, current temperature, current condition, sunrise, sunset, temperature, pressure, humidity, wind_speed, visibility, clouds
    TextView current_temp, current_output, rise_time, set_time, temp_out, Press_out, Humid_out, Ws_out, Visi_out, Cloud_out;
    // TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public FirstFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment SecondFragment.
     */
// TODO: Rename and change types and number of parameters
    public static FirstFragment newInstance(String param1, String param2) {
        FirstFragment fragment = new FirstFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);

        }
    }

    @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);
        current_temp = rootView.findViewById(R.id.textView10);
        current_output = rootView.findViewById(R.id.textView11);
        rise_time = rootView.findViewById(R.id.textView25);
        set_time = rootView.findViewById(R.id.textView26);
        temp_out = rootView.findViewById(R.id.textView28);
        Press_out = rootView.findViewById(R.id.textView29);
        Humid_out = rootView.findViewById(R.id.textView30);
        Ws_out = rootView.findViewById(R.id.textView33);
        Visi_out = rootView.findViewById(R.id.textView34);
        Cloud_out = rootView.findViewById(R.id.textView35);

        private void getWeatherData(String name) {

            ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

            Call<Example> call = apiInterface.getWeatherData(name);

            call.enqueue(new Callback<Example>() {
                @Override
                public void onResponse(@NotNull Call<Example> call, @NotNull Response<Example> response) {
                    current_temp.setText(response.body().getMain().getTemp() + " ℃");
                    current_output.setText(response.body().getWeatherList().get(0).getDescription());
                    rise_time.setText(response.body().getSys().getSunrise() + " ");
                    set_time.setText(response.body().getSys().getSunset() + " ");
                    temp_out.setText(response.body().getMain().getTemp() + " ℃");
                    Press_out.setText(response.body().getMain().getPressure() + " hpa");
                    Humid_out.setText(response.body().getMain().getHumidity() + " %");
                    Ws_out.setText(response.body().getWind().getSpeed() + " Km/h");
                    Visi_out.setText(response.body().getVisibility() + " m");
                    Cloud_out.setText(response.body().getClouds().getAll()+ " %");
        }

                @Override
                public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                    t.printStackTrace();
                }
            });
    }
            return rootView;
    }
}

API接口:

public interface ApiInterface {

    @GET("weather?&appid=(My app key)&units=metric")
    Call<Example> getWeatherData(@Query("q") String name);
}

ApiClient:

public class ApiClient {

    private static Retrofit retrofit = null;

    public static  Retrofit getClient(){ //creating object

        if (retrofit == null) {

            retrofit = new Retrofit.Builder()
                    .baseUrl("https://api.openweathermap.org/data/2.5/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }

        return retrofit;

    }
}

【问题讨论】:

    标签: java android android-fragments android-activity weather


    【解决方案1】:

    您使用的 java 方法与其语法不同:

    您的活动中没有任何错误,因为您已在匿名类中定义它,但您的片段中出现错误,因为您已将其写入另一个在 java 中不合适的方法中。

    所以,从另一个(onCreateView 之外)写出你的方法,然后在那里调用它。

    public class FirstFragment extends Fragment {
        // User current time, current temperature, current condition, sunrise, sunset, temperature, pressure, humidity, wind_speed, visibility, clouds
        TextView current_temp, current_output, rise_time, set_time, temp_out, Press_out, Humid_out, Ws_out, Visi_out, Cloud_out;
        // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
        private static final String ARG_PARAM1 = "param1";
        private static final String ARG_PARAM2 = "param2";
    
        // TODO: Rename and change types of parameters
        private String mParam1;
        private String mParam2;
    
        public FirstFragment() {
            // Required empty public constructor
        }
    
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment SecondFragment.
         */
    // TODO: Rename and change types and number of parameters
        public static FirstFragment newInstance(String param1, String param2) {
            FirstFragment fragment = new FirstFragment();
            Bundle args = new Bundle();
            args.putString(ARG_PARAM1, param1);
            args.putString(ARG_PARAM2, param2);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getArguments() != null) {
                mParam1 = getArguments().getString(ARG_PARAM1);
                mParam2 = getArguments().getString(ARG_PARAM2);
    
            }
        }
    
        @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);
            current_temp = rootView.findViewById(R.id.textView10);
            current_output = rootView.findViewById(R.id.textView11);
            rise_time = rootView.findViewById(R.id.textView25);
            set_time = rootView.findViewById(R.id.textView26);
            temp_out = rootView.findViewById(R.id.textView28);
            Press_out = rootView.findViewById(R.id.textView29);
            Humid_out = rootView.findViewById(R.id.textView30);
            Ws_out = rootView.findViewById(R.id.textView33);
            Visi_out = rootView.findViewById(R.id.textView34);
            Cloud_out = rootView.findViewById(R.id.textView35);
            getWeatherData("Blah blah blah");
            return rootView;
        }
    
        private void getWeatherData(String name) {
    
            ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
    
            Call<Example> call = apiInterface.getWeatherData(name);
    
            call.enqueue(new Callback<Example>() {
                @Override
                public void onResponse(@NotNull Call<Example> call, @NotNull Response<Example> response) {
                    current_temp.setText(response.body().getMain().getTemp() + " ℃");
                    current_output.setText(response.body().getWeatherList().get(0).getDescription());
                    rise_time.setText(response.body().getSys().getSunrise() + " ");
                    set_time.setText(response.body().getSys().getSunset() + " ");
                    temp_out.setText(response.body().getMain().getTemp() + " ℃");
                    Press_out.setText(response.body().getMain().getPressure() + " hpa");
                    Humid_out.setText(response.body().getMain().getHumidity() + " %");
                    Ws_out.setText(response.body().getWind().getSpeed() + " Km/h");
                    Visi_out.setText(response.body().getVisibility() + " m");
                    Cloud_out.setText(response.body().getClouds().getAll()+ " %");
                }
    
                @Override
                public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                    t.printStackTrace();
                }
            });
        }
    }
    

    另外,如果您想从片段访问活动小部件,您可以使用:

    editText editText = getActivity().findViewById(R.id.textfield);
    editText.getText().toString()
    

    【讨论】:

    • 这不起作用。错误甚至变得更大。如果您真的确定如何操作,我希望您向我详细展示要采取的分步程序。在 oncreate 之外是不确定的。
    • 当您将方法移到片段中的 onCreateView 之外时,您遇到了什么样的错误?
    • 我所有的文本视图都变红了,布局充气器失效了
    • 如果你已经正确移动了,至少你不能得到那个错误,如果你得到了,请查看我的编辑并注意下一个问题
    • 我测试时设置很好,但是你写的“Blah blah blah”部分,我用 textfield.getText().toString().trim() 替换它以使用我的 edittext 获取数据搜索。现在的问题是edittext视图位于活动中,而不是片段中。所以我现在无法将符号文本字段解析为错误。
    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多