更新的 json 数据未在 android 中显示

Posted

技术标签:

【中文标题】更新的 json 数据未在 android 中显示【英文标题】:updated json data not showing in android 【发布时间】:2021-12-13 06:49:17 【问题描述】:

从我的服务器检索 json 数据。第一次在我的应用程序中显示数据。但是在更新新数据时,它没有显示。只显示旧数据..当我从应用程序中清除缓存时,它会显示更新的数据。但我想同时显示实时数据。我必须做什么?请帮帮我。

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> 
    private Context mContext ;
    private List<Anime> mData ;
    RequestOptions option;

    public RecyclerViewAdapter(Context mContext, List<Anime> mData) 
        this.mContext = mContext;
        this.mData = mData;

        // Request option for Glide
        option = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
    

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 

        View view ;
        LayoutInflater inflater = LayoutInflater.from(mContext);
        view = inflater.inflate(R.layout.anime_row_item,parent,false) ;
        final MyViewHolder viewHolder = new MyViewHolder(view) ;
        viewHolder.view_container.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 

                Intent i = new Intent(mContext, Read.class);
                i.putExtra("news_title",mData.get(viewHolder.getAdapterPosition()).getName());
                i.putExtra("news_description",mData.get(viewHolder.getAdapterPosition()).getDescription());
                i.putExtra("anime_studio",mData.get(viewHolder.getAdapterPosition()).getAuthor());
                i.putExtra("anime_category",mData.get(viewHolder.getAdapterPosition()).getCategorie());
                i.putExtra("anime_img",mData.get(viewHolder.getAdapterPosition()).getImage_url());

                mContext.startActivity(i);

            
        );

        return viewHolder;
    

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) 

        holder.post_title.setText(mData.get(position).getName());
        holder.date.setText(mData.get(position).getDate());
        holder.author.setText(mData.get(position).getAuthor());
        holder.cat_name.setText(mData.get(position).getCategorie());

        // Load Image from the internet and set it into Imageview using Glide
        Glide.with(mContext).load(mData.get(position).getImage_url()).apply(option).into(holder.thumbnail);

    

    @Override
    public int getItemCount() 
        return mData.size();
    

    public static class MyViewHolder extends RecyclerView.ViewHolder 

        TextView post_title ;
        TextView date ;
        TextView author ;
        TextView cat_name;
        ImageView thumbnail;
        LinearLayout view_container;

        public MyViewHolder(View itemView) 
            super(itemView);

            view_container = itemView.findViewById(R.id.container);
            post_title = itemView.findViewById(R.id.post_title);
            cat_name = itemView.findViewById(R.id.cat_name);
            date = itemView.findViewById(R.id.date);
            author = itemView.findViewById(R.id.author);
            thumbnail = itemView.findViewById(R.id.thumbnail);

        
    

Home.java

public class Home extends Fragment 

    private final String JSON_URL = "https://mywebsite.org/news/api.php";
    private JsonArrayRequest request ;
    private RequestQueue requestQueue ;
    private List<Anime> lstAnime ;
    private RecyclerView recyclerView ;
    ProgressBar loading;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        loading = (ProgressBar)root.findViewById(R.id.bar);
        loading.setMax(100);
        lstAnime = new ArrayList<>() ;
        recyclerView = root.findViewById(R.id.recyclerviewid);

        jsonrequest();

        return root;
    

    private void jsonrequest() 

        request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() 
            @Override
            public void onResponse(JSONArray response) 
                loading.setVisibility(View.GONE);
                JSONObject jsonObject  = null ;

                for (int i = 0 ; i < response.length(); i++ ) 

                    try 
                        jsonObject = response.getJSONObject(i) ;
                        Anime anime = new Anime() ;
                        anime.setName(jsonObject.getString("title"));
                        anime.setDescription(jsonObject.getString("description"));
                        anime.setDate(jsonObject.getString("date"));
                        anime.setCategorie(jsonObject.getString("category"));
                        anime.setAuthor(jsonObject.getString("admin"));
                        anime.setImage_url(jsonObject.getString("thumbnail"));
                        lstAnime.add(anime);

                     catch (JSONException e) 
                        e.printStackTrace();
                    
                
                setuprecyclerview(lstAnime);
            
        , new Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 

                if (error instanceof TimeoutError || error instanceof NoConnectionError) 
                    //This indicates that the request has either time out or there is no connection
                    Toast.makeText(getActivity(), "TimeOut...! No Internet",
                            Toast.LENGTH_LONG).show();

                 else if (error instanceof AuthFailureError) 
                    // Error indicating that there was an Authentication Failure while performing the request
                    Toast.makeText(getActivity(), "Failed To Receive Data",
                            Toast.LENGTH_LONG).show();

                 else if (error instanceof ServerError) 
                    //Indicates that the server responded with a error response
                    Toast.makeText(getActivity(), "Our Server Under Maintenance",
                            Toast.LENGTH_LONG).show();
                 else if (error instanceof NetworkError) 
                    //Indicates that there was network error while performing the request
                    Toast.makeText(getActivity(), "Network Not Responding",
                            Toast.LENGTH_LONG).show();
                 else if (error instanceof ParseError) 
                    // Indicates that the server response could not be parsed
                    Toast.makeText(getActivity(), "Please Reload Again!",
                            Toast.LENGTH_LONG).show();
                
            
        );

        requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.add(request);
    

    private void setuprecyclerview(List<Anime> lstAnime) 

        RecyclerViewAdapter myadapter = new RecyclerViewAdapter(getActivity(),lstAnime);
        recyclerView.setAdapter(myadapter);

        // grid columns is 2
        GridLayoutManager manager = new GridLayoutManager(getActivity(), 2);
        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() 
            @Override
            public int getSpanSize(int position) 
                // 0 is first one and 9 is first one all of others are 2 columns
                if (position == 0 || position == 9) 
                    return 2;
                
                return 1;
        );
        recyclerView.setItemAnimator(null);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(myadapter);
        recyclerView.setLayoutManager(manager);
    

    public interface OnFragmentInteractionListener 
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);

    


fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipeContainer"
    android:layout_
    android:layout_>

<androidx.core.widget.NestedScrollView
    android:layout_
    android:layout_
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_
        android:layout_
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".fragments.Home"
        android:orientation="vertical">

        <!-- TODO: Update blank fragment layout -->

        <ProgressBar
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:id="@+id/bar"/>

            <androidx.recyclerview.widget.RecyclerView
                android:layout_
                android:layout_
                android:id="@+id/recyclerviewid">

            </androidx.recyclerview.widget.RecyclerView>
    </LinearLayout>

</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

对不起,我的英语不好。 提前致谢。

【问题讨论】:

您的回收站视图没有显示更新的数据吗? 你如何“更新数据”?我看到对服务器的请求只在“onCreateView()”中发出一次,所以只有在创建片段时才会发出请求。因此,如果您更新服务器的数据,您必须重新执行请求...... @emandt 你能帮我做吗?我不知道如何重新执行请求。请通过编辑我的代码发布答案,这将对我和其他人有所帮助。 @Danish no...只显示旧数据...但是当我清除缓存时,然后显示新数据。但我想在更新新数据时立即显示。 分享你的回收视图适配器代码。 【参考方案1】:

在您的 jsonrequest() 方法中使用 notifyDataSetChanged 通知您的回收站视图。使用 requestQueue.getCache().clear() 清除缓存; 检查以下代码:

public class Home extends Fragment 

    private final String JSON_URL = "https://mywebsite.org/news/api.php";
    private JsonArrayRequest request ;
    private RequestQueue requestQueue ;
    private List<Anime> lstAnime ;
    private RecyclerView recyclerView ;
    ProgressBar loading;
    RecyclerViewAdapter myadapter;
    **SwipeRefreshLayout swipeRefreshLayout;**
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        loading = (ProgressBar)root.findViewById(R.id.bar);
        loading.setMax(100);
        lstAnime = new ArrayList<>() ;
        recyclerView = root.findViewById(R.id.recyclerviewid);

        jsonrequest();
        setuprecyclerview(lstAnime);
         **swipeRefreshLayout=view.findViewById(R.id.swipeContainer);
            swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() 
                @Override
                public void onRefresh()
                
                    jsonrequest();
                    myAdapter.notifyDataSetChanged();
                    swipeRefreshLayout.setRefreshing(false);
                
            );**
        return root;
    

    private void jsonrequest() 

        request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() 
            @Override
            public void onResponse(JSONArray response) 
                loading.setVisibility(View.GONE);
                JSONObject jsonObject  = null ;

                for (int i = 0 ; i < response.length(); i++ ) 

                    try 
                        jsonObject = response.getJSONObject(i) ;
                        Anime anime = new Anime() ;
                        anime.setName(jsonObject.getString("title"));
                        anime.setDescription(jsonObject.getString("description"));
                        anime.setDate(jsonObject.getString("date"));
                        anime.setCategorie(jsonObject.getString("category"));
                        anime.setAuthor(jsonObject.getString("admin"));
                        anime.setImage_url(jsonObject.getString("thumbnail"));
                        lstAnime.add(anime);

                     catch (JSONException e) 
                        e.printStackTrace();
                    
                
                if(myadapter != null)
                myadapter.notifyDataSetChanged();
            
        , new Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 

                if (error instanceof TimeoutError || error instanceof NoConnectionError) 
                    //This indicates that the request has either time out or there is no connection
                    Toast.makeText(getActivity(), "TimeOut...! No Internet",
                            Toast.LENGTH_LONG).show();

                 else if (error instanceof AuthFailureError) 
                    // Error indicating that there was an Authentication Failure while performing the request
                    Toast.makeText(getActivity(), "Failed To Receive Data",
                            Toast.LENGTH_LONG).show();

                 else if (error instanceof ServerError) 
                    //Indicates that the server responded with a error response
                    Toast.makeText(getActivity(), "Our Server Under Maintenance",
                            Toast.LENGTH_LONG).show();
                 else if (error instanceof NetworkError) 
                    //Indicates that there was network error while performing the request
                    Toast.makeText(getActivity(), "Network Not Responding",
                            Toast.LENGTH_LONG).show();
                 else if (error instanceof ParseError) 
                    // Indicates that the server response could not be parsed
                    Toast.makeText(getActivity(), "Please Reload Again!",
                            Toast.LENGTH_LONG).show();
                
            
        );

        requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.getCache().clear();//add this line
        requestQueue.add(request);
    

    private void setuprecyclerview(List<Anime> lstAnime) 

         myadapter = new RecyclerViewAdapter(getActivity(),lstAnime);
        recyclerView.setAdapter(myadapter);

        // grid columns is 2
        GridLayoutManager manager = new GridLayoutManager(getActivity(), 2);
        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() 
            @Override
            public int getSpanSize(int position) 
                // 0 is first one and 9 is first one all of others are 2 columns
                if (position == 0 || position == 9) 
                    return 2;
                
                return 1;
        );
        recyclerView.setItemAnimator(null);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(myadapter);
        recyclerView.setLayoutManager(manager);
    

    public interface OnFragmentInteractionListener 
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);

    


同样在你的 recyclerviewadapter.java 中添加这一行到 recycler 适配器构造函数:

   public RecyclerViewAdapter(Context mContext, List<Anime> mData) 
    this.mContext = mContext;
    this.mData = mData;
    this.notifyDataSetChanged();
    // Request option for Glide
    option = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);

从 xml 文件中删除嵌套的滚动视图:

  <?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/swipeContainer"
 android:layout_
 android:layout_>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_
        android:layout_
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".fragments.Home"
        android:orientation="vertical">

        <!-- TODO: Update blank fragment layout -->

        <ProgressBar
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:id="@+id/bar"/>

        <androidx.recyclerview.widget.RecyclerView
            android:layout_
            android:layout_
            android:id="@+id/recview">
        </androidx.recyclerview.widget.RecyclerView>
    </LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

【讨论】:

它不工作。同样的问题。 你试过清除浏览器缓存吗? 哪个浏览器?如果我清除应用程序缓存,它会显示新数据。但用户不会每次都这样做。 添加后 this.notifyDataSetChanged();到我的 recyclerviewadapter.java,它也不起作用。 实际上,当您重新启动应用程序时,数据正在从缓存中加载,而缓存实际上保存着您的旧数据。

以上是关于更新的 json 数据未在 android 中显示的主要内容,如果未能解决你的问题,请参考以下文章

来自 JSON 的数据未在 UICollectionView 中更新

JSON响应未在单元格内显示

反应本机选择器未在android上显示

Json数据在uitableview ios中没有更新?

www.text 未在 android 中显示完整数据

屏幕关闭时,前台服务未在 Android 7.0+ 中接收位置更新