简体   繁体   中英

RecyclerView doesn't Update and shows on screen until Soft Keyboard is Open/Close

I have one problem with my RecyclerView - it doesn't update on the main screen after pressing on the button. It can only appear after close/open soft keeboard. I looked a lot of solutions overe here but nothing helped me. I have just a simple app which sends a request "String" to server and gets one JSON Object and next inserts it on RecyclerView. But the data in RecyclerView don't apear immediately. I'm in deadlock. Help me.

Code in the activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/sky"
    tools:context=".MainActivity">

        <EditText
            android:id="@+id/editTextRequestCity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="@string/write_name_of_city_or_index"
            android:inputType="textPersonName"
            android:maxLength="30"
            android:minHeight="48dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/recyclerViewListForecast"
            app:layout_constraintEnd_toStartOf="@+id/buttonShowWeather"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/buttonShowWeather"
            android:layout_width="54dp"
            android:layout_height="48dp"
            android:background="@drawable/search_city"
            android:onClick="onClickShowWeather"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/recyclerViewListForecast"
            app:layout_constraintStart_toEndOf="@+id/editTextRequestCity"
            app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewListForecast"
        app:layoutManager="LinearLayoutManager"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextRequestCity"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Code in the weather_item.xml:

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardViewItem"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_margin="1dp"
    app:cardCornerRadius="1dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textViewDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:background="#00FFFFFF"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewFallout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewDegree"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewPressure"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewHumidity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewSpeedWind"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewGustWind"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/textViewDirectionWind"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:textSize="15sp" />
    </LinearLayout>
</androidx.cardview.widget.CardView>

Code in WeatherItem:

package com.example.forecast;

public class WeatherItem {
    private String date;
    private String time;
    private String fallout;
    private String degree;
    private String pressure;
    private String humidity;
    private String speedWind;
    private String gustWind;
    private String directionWind;

    public WeatherItem(String date, String time, String fallout, String degree, String pressure, String humidity, String speedWind, String gustWind, String directionWind) {
        this.date = date;
        this.time = time;
        this.fallout = fallout;
        this.degree = degree;
        this.pressure = pressure;
        this.humidity = humidity;
        this.speedWind = speedWind;
        this.gustWind = gustWind;
        this.directionWind = directionWind;
    }

    public String getDate() {
        return date;
    }
    public String getTime() {
        return time;
    }
    public String getFallout() {
        return fallout;
    }
    public String getDegree() {
        return degree;
    }
    public String getPressure() {
        return pressure;
    }
    public String getHumidity() {
        return humidity;
    }
    public String getSpeedWind() {
        return speedWind;
    }
    public String getGustWind() {
        return gustWind;
    }
    public String getDirectionWind() {
        return directionWind;
    }
  }

Code in WeatherAdapter:

package com.example.forecast;

public class WeatherAdapter extends RecyclerView.Adapter<WeatherAdapter.WeatherViewHolder> {
    public ArrayList<WeatherItem> weatherItems;
    Context context;

    public WeatherAdapter(Context context, ArrayList <WeatherItem> weatherItems) {
        this.context = context;
        this.weatherItems = weatherItems;
    }

    @NonNull
    @Override
    public WeatherViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.weather_item, parent, false);
            return new WeatherViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final WeatherViewHolder holder, int position) {
        WeatherItem weatherItem = weatherItems.get(position);
        holder.textViewDate.setText(weatherItem.getDate());
        holder.textViewTime.setText(weatherItem.getTime());
        holder.textView.setText(weatherItem.getFallout());
        holder.textViewDegree.setText(weatherItem.getDegree());
        holder.textViewPressure.setText(weatherItem.getPressure());
        holder.textViewHumidity.setText(weatherItem.getHumidity());
        holder.textViewSpeedWind.setText(weatherItem.getSpeedWind());
        holder.textViewGustWind.setText(weatherItem.getGustWind());
        holder.textViewDirectionWind.setText(weatherItem.getDirectionWind());
        }

    @Override
    public int getItemCount() {
        return weatherItems.size();
    }


    static class WeatherViewHolder extends RecyclerView.ViewHolder {
        private TextView textViewDate;
        private TextView textViewTime;
        private TextView textView;
        private TextView textViewDegree;
        private TextView textViewPressure;
        private TextView textViewHumidity;
        private TextView textViewSpeedWind;
        private TextView textViewGustWind;
        private TextView textViewDirectionWind;

        public WeatherViewHolder(@NonNull View itemView) {
            super(itemView);

            textViewDate = itemView.findViewById(R.id.textViewDate);
            textViewTime = itemView.findViewById(R.id.textViewTime);
            textView = itemView.findViewById(R.id.textViewFallout);
            textViewDegree = itemView.findViewById(R.id.textViewDegree);
            textViewPressure = itemView.findViewById(R.id.textViewPressure);
            textViewHumidity = itemView.findViewById(R.id.textViewHumidity);
            textViewSpeedWind = itemView.findViewById(R.id.textViewSpeedWind);
            textViewGustWind = itemView.findViewById(R.id.textViewGustWind);
            textViewDirectionWind = itemView.findViewById(R.id.textViewDirectionWind);

        }
    }
}

And finaly my code in MainActivity:

public class MainActivity extends AppCompatActivity {
    EditText editTextRequestCity;
    private RecyclerView recyclerViewListForecast;
    WeatherAdapter adapter;
    private ArrayList<WeatherItem> weatherItems = new ArrayList<>();
    private final String WEATHER_URL = "https://api.openweathermap.org/data/2.5/forecast?q=%s&lang=ru&units=metric&appid=ce288368c68807e060c17369bfbef3b3";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editTextRequestCity = findViewById(R.id.editTextRequestCity);
        recyclerViewListForecast = findViewById(R.id.recyclerViewListForecast);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerViewListForecast.setLayoutManager(linearLayoutManager);
        adapter = new WeatherAdapter(getApplicationContext(), weatherItems = new ArrayList<>());
        recyclerViewListForecast.setAdapter(adapter);
        }

    public void onClickShowWeather(View view) {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        weatherItems.clear();
        adapter.notifyDataSetChanged();
       String city = editTextRequestCity.getText().toString().trim();
       String request = String.format(WEATHER_URL,city);
               DownLoadWeatherTask task = new DownLoadWeatherTask();
                task.execute(request);
        }

    private class DownLoadWeatherTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {
            URL url = null;

            HttpURLConnection urlConnection = null;
            StringBuilder result = new StringBuilder();
            try {
                url = new URL(strings[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                  InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                  BufferedReader reader = new BufferedReader(inputStreamReader);
                  String line = reader.readLine();
                  while (line != null) {
                      result.append(line);
                      line = reader.readLine();
                  }
                  return result.toString();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (s != null) {
                try {
                    JSONObject jsonObjectMain = new JSONObject(s);
                    JSONArray jsonArray = jsonObjectMain.getJSONArray("list");
                    for (int i = 0; i < jsonArray.length(); i++) {
                        ArrayList<WeatherItem> weatherItemDay = new ArrayList<>();
                        JSONObject jsonObjectDay = jsonArray.getJSONObject(i);

                        String dateTime = jsonObjectDay.getString("dt_txt");
                        String date = dateTime.substring(0, 10).trim();
                        String time = dateTime.substring(11, 16).trim();
                        String fallout = jsonObjectDay.getJSONArray("weather").getJSONObject(0).getString("description").trim();
                        String degree = String.format("" + jsonObjectDay.getJSONObject("main").getInt("temp")).trim();
                        String pressure = String.format("" + jsonObjectDay.getJSONObject("main").getInt("pressure")).trim();
                        String humidity = String.format("" + jsonObjectDay.getJSONObject("main").getInt("humidity")).trim();
                        String speedWind = String.format("" + jsonObjectDay.getJSONObject("wind").getInt("speed")).trim();
                        String gustWind = String.format("" + jsonObjectDay.getJSONObject("wind").getInt("gust")).trim();
                        String directionWind = String.format("" + jsonObjectDay.getJSONObject("wind").getInt("deg")).trim();

                        weatherItems.add(new WeatherItem(date, time, fallout, degree, pressure, humidity, speedWind, gustWind, directionWind));

                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

Call notifyDataSetChanged() when you add a new item to your list. Based on your code, this needs to happen in onPostExecute for you.

You are already calling notifyDataSetChanged() in the onClick but this is before the task has finished, therefore the item doesn't show because it hasn't been added to the list yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM