【问题标题】:JSON Increased in Fragment whenever I press back button每当我按下返回按钮时,JSON 的片段就会增加
【发布时间】:2021-12-27 04:47:47
【问题描述】:

我有一个名为 HomeFragment 的片段,其中包含来自 JSON 的 GridView 列表,该列表使用 Volley 请求。并且它成功显示 JSON 没有任何问题,但问题是当我转到另一个片段或活动然后再次返回 HomeFragment 后,GridView 中的 JSON 再次增加/添加相同的数据。

如何阻止这种情况,以免数据增加。

HomeFragment 中有我的代码

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.fragment_home, container, false);;
    getActivity().setTitle("Dashboard");

    final HashMap<String, String> role = sharedPreference.getDetails();
    String url = "http://myurl";

    RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                JSONObject obj = new JSONObject(response);
                JSONArray array = obj.getJSONArray("data");
                for (int i = 0; i < array.length(); i++) {
                    JSONObject data = array.getJSONObject(i);
                    String menu_id = data.getString("menu_id");
                    String menu_name = data.getString("menu_name");

                    HashMap<String, String> row = new HashMap<>();
                    row.put("menu_id", menu_id);
                    row.put("menu_name", menu_name);

                    menulist.add(row);

                    Log.e(TAG, "onResponse: " + menulist );

                    GridView gridView = (GridView) view.findViewById(R.id.menu_item_grid);
                    ListAdapter listAdapter = new SimpleAdapter(getContext(), menulist,
                            R.layout.home_menu, new String[]{"menu_name"},
                            new int[]{R.id.item_grid});
                    gridView.setAdapter(listAdapter);
                }
            } catch (JSONException ex) {
                ex.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getContext(), "error : " + error, Toast.LENGTH_SHORT).show();
        }
    });

    queue.add(stringRequest);
    return view;
}

the result

谢谢..

【问题讨论】:

    标签: android android-studio android-volley


    【解决方案1】:

    当您从HomeFragmnt 转到OtherFragment 并按下onCreateView() 再次调用HomeFragment 时,您的请求再次调用,因此您的数据是重复的。

    您应该让 BaseFragment 执行以下代码。它会帮助你。

    Java 帮助

    BaseFragment.java

    public class BaseFragment<T> extends Fragment {
    
        public boolean hasInitializedRootView = false;
    
        private View rootView;
    
        public View getPersistentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState, int layout){
            if (rootView == null) {
                rootView = inflater.inflate(layout, container, false);
            } else {
                ((ViewGroup) rootView.getParent()).removeView(rootView);
            }
    
            return rootView;
        }
        
    }
    

    HomeFragment.java

    public class HomeFragment extends BaseFragment<View> {
    
        public View onCreateView(@NonNull LayoutInflater inflater,
                                 ViewGroup container, Bundle savedInstanceState) {
    
            return getPersistentView(inflater, container, savedInstanceState, R.layout.fragment_home);
        }
    
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
            if (!hasInitializedRootView) {
                hasInitializedRootView = true;
    
                // Do your work here
    
            }
    
        }
    }
    

    Kotlin 帮助

    BaseFragment.kt

    open class BaseFragment<T : View> : Fragment() {
    
        var hasInitializedRootView = false
        private var rootView: View? = null
    
        fun getPersistentView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?,
            layout: Int
        ): View? {
            if (rootView == null) {
                rootView = inflater.inflate(layout, container, false)
            } else {
    
                (rootView?.parent as? ViewGroup)?.removeView(rootView)
            }
    
            return rootView
        }
    
    }
    

    HomeFragment.kt

    class HomeFragment : BaseFragment<View>() {
        
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return getPersistentView(inflater, container, savedInstanceState, R.layout.fragment_home)
        }
    
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            if (!hasInitializedRootView) {
                hasInitializedRootView = true
    
                // Do your work here
    
            }
        }
    }
    

    【讨论】:

    • 我明白了,所以在创建片段时会调用请求。谢谢
    【解决方案2】:

    当您转到另一个片段/活动时,您的 HomeFragment 不会立即被销毁,因此其值 (menulist) 仍会保留。但是当您返回时,会再次创建视图,并将来自 API 的新数据添加到之前的列表中。

    在您的onResponse() 方法中,使用menulist.clear() 清除menulist

    menulist.clear();
    JSONObject obj = new JSONObject(response);
    JSONArray array = obj.getJSONArray("data");
    

    这不会减少 API 调用,但会保持数据一致。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 2021-12-18
      • 2016-10-02
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多