Связь данных о погоде связь между Фрагментом и активностью

#java #android #android-fragments #android-activity #weather

#java #Android #android-фрагменты #android-активность #Погода

Вопрос:

Я создаю приложение погоды, используя https://openweathermap.org/current и до сих пор все шло гладко. Часть активности приложения использует запрос города из моего интерфейса, чтобы предоставить текущие данные любого города, который был найден в edittext. Проблема сейчас в том, что я использую только кнопку поиска (в моей активности), но я также хочу получать те же данные в классе fragment. Например, я использую действие для: 1. Поиска и отображения названия города. 2. Отображение текущего времени в этих городах.

И фрагмент для получения температуры, восхода и захода солнца, влажности и других данных для городов, которые искали по активности.

Поэтому я не могу реализовать двойную кнопку поиска (в activity и fragment) только для получения данных. Я стремлюсь использовать только activity own для получения данных о городе в обоих классах, потому что мой класс fragment также содержит текстовые представления для получения данных, я буду признателен за любой способ добиться этого, потому что я понятия не имею, как это сделать сам.

Я попытался вызвать тот же метод в классе fragment, но я получаю ошибку компиляции из этого кода во фрагменте:

 private void getWeatherData(String name) {

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

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

Говоря: 'getWeatherData' is never used и cannot resolve symbol 'name' (Потому что моя кнопка поиска и edittext используются только в 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;
    }
}
 

Интерфейс ApiInterface:

 public interface ApiInterface {

    @GET("weather?amp;appid=(My app key)amp;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;

    }
}
 

Ответ №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()
 

Комментарии:

1. Это не сработало. Ошибок стало еще больше. Если вы действительно уверены в том, как это сделать, я бы хотел, чтобы вы подробно показали мне пошаговую процедуру, которую нужно выполнить. За пределами oncreate не является конкретным.

2. Когда вы переместили свой метод за пределы вашего onCreateView в свой фрагмент, какую ошибку вы получили?

3. Все мои текстовые просмотры стали красными, увеличитель макета стал недействительным

4. По крайней мере, вы не должны получать эту ошибку, если вы переместились правильно, см. Мое редактирование и обратите внимание на следующие проблемы, если вы получите

5. При тестировании настройка была в порядке, но ту часть «Бла-бла-бла», которую вы написали, я заменил на textfield.getText().toString().trim(), чтобы получить данные с помощью моего поиска edittext. Проблема теперь в том, что представление edittext находится в действии, а не во фрагменте. Итак, я не могу разрешить текстовое поле символа как ошибку.