在软键盘打开/关闭之前,RecyclerView 不会更新并显示在屏幕上

Posted

技术标签:

【中文标题】在软键盘打开/关闭之前,RecyclerView 不会更新并显示在屏幕上【英文标题】:RecyclerView doesn't Update and shows on screen until Soft Keyboard is Open/Close 【发布时间】:2022-01-04 01:58:10 【问题描述】:

我的 RecyclerView 有一个问题 - 按下按钮后它不会在主屏幕上更新。它只能在关闭/打开软踢板后出现。我在这里看了很多解决方案,但没有任何帮助。我只有一个简单的应用程序,它向服务器发送请求“字符串”并获取一个 JSON 对象,然后将其插入 RecyclerView。但是 RecyclerView 中的数据不会立即出现。我陷入僵局。帮帮我。

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_
    android:layout_
    android:background="@drawable/sky"
    tools:context=".MainActivity">

        <EditText
            android:id="@+id/editTextRequestCity"
            android:layout_
            android:layout_
            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_
            android:layout_
            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_
        android:layout_
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextRequestCity"/>
</androidx.constraintlayout.widget.ConstraintLayout>

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_
    android:layout_
    android:layout_margin="1dp"
    app:cardCornerRadius="1dp">

    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="vertical">

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

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

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

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

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

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

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

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

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

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;
    
  

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

        
    

最后是我在 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();
                
            

        
    

【问题讨论】:

【参考方案1】:

当您向列表中添加新项目时,请致电 notifyDataSetChanged()。根据您的代码,这需要在 onPostExecute 中为您完成。

您已经在 onClick 中调用了notifyDataSetChanged(),但这是在任务完成之前,因此该项目不会显示,因为它尚未添加到列表中。

【讨论】:

是的,谢谢@Naveed!我在 onPostExecute 方法的末尾添加了几行:adapter = new WeatherAdapter(getApplicationContext(), weatherItems); recyclerViewListForecast.setAdapter(adapter); adapter.notifyDataSetChanged();,它对我有帮助!

以上是关于在软键盘打开/关闭之前,RecyclerView 不会更新并显示在屏幕上的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms.UWP 数字键盘仅在软键盘上

Fragment中的ScrollView在软键盘出现时不滚动

Android view显示在软键盘上方

在键盘打开时将项目添加到 RecyclerView 时向下滚动

Android - 如何在软键盘出现时调整弹出窗口

android 动态改变界面 软键盘覆盖了界面