1

나는 ListFragment을 가지고 있는데, Loader을 사용하여 그물에서 데이터를 가져옵니다. 내 ViewPager의 모든 페이지에서이 ListFragment의 새 인스턴스를 사용합니다. 그것은 완벽하게 작동하지만 TabLayout을 사용하거나 페이지를 빨리 이동하면 Fragment은로드를 유지하고 ListView에 데이터를 표시하지 않습니다.ListFragment가 로더의 onLoadFinished() 메소드에서 코드를 건너 뛸 때

로그 메시지를 사용하여 확인한 결과 ListFragmentonLoadFinished() 메서드에서 일부 코드 줄을 건너 뜁니다. ProgressBar은 보이지 않습니다. Adapter에 항목을 추가하지만 ListView에는 표시되지 않습니다. 이 문제는 ViewPager의 첫 번째 페이지에서도 발생합니다.

ViewPager에서 ListFragment을 사용할 때 따라야 할 특별한 규칙이 있습니까?

여기에 ListFragment 클래스가 있습니다. 당신이 onLoadFinished() 방법을 보면, 당신은 원인이 라인을 볼 수 있습니다 문제 :

public class ListViewFragment extends ListFragment 
    implements LoaderManager.LoaderCallbacks<List<GameNews>> { 

    public static ListViewFragment newInstance(String url) { 
     Log.d("ListViewFragment", "newInstance created"); 
     ListViewFragment f = new ListViewFragment(); 

     // Supply url input as an argument. 
     Bundle args = new Bundle(); 
     args.putString("url", url); 
     f.setArguments(args); 
     return f; 
    } 

    List<GameNews> TotalNews; 
    ListView gameListView; 
    LinearLayout emptyView; 
    Button retryButton; 
    ListAdapter adapter ; 
    private View progressBar; 
    final private int game_loader = 0; 
    ArrayList<String> urls = new ArrayList<>(); 
    String mUrlString; 
    int index; 

    //LIFE CYCLE OF FRAGMENT 
    //------------------------------------------------------------------ 
    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mUrlString = getArguments().getString("url"); 
     urls.add(mUrlString); 
     TotalNews = new ArrayList<GameNews>(); 
    } 

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

     ArrayList<GameNews> gameList = new ArrayList<>(); 
     adapter = new ListAdapter(getActivity(), gameList); 
     return rootView; 
    } 

    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 
     emptyView = (LinearLayout) 
      view.findViewById(R.id.no_internet_view); 
     progressBar = view.findViewById(R.id.progress_bar); 
     retryButton = (Button) view.findViewById(R.id.retry_button); 
     gameListView = getListView(); 
     emptyView.setVisibility(View.INVISIBLE); 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     setListAdapter(adapter); 

     //If connected to net start the loader 
     if (isConnected()) { 
      getActivity().getSupportLoaderManager().restartLoader(game_loader, 
                    null, 
                    ListViewFragment.this); 
     } 
    } 

    //OVERRIDED METHODS OF LOADERMANAGER 
    //--------------------------------------------------------------------- 
    @Override 
    public android.support.v4.content.Loader<List<GameNews>> onCreateLoader(int i, Bundle bundle) { 
     AdManager manager = new AdManager(getActivity()); 
     return new FragmentLoader(getActivity(), urls, 1000); 

    } 

    //HERE IS THE PROBLEM PLEASE FOCUS INSIDE THIS METHOD 
    //------------------------------------------------------- 
    @Override 
    public void onLoadFinished(Loader<List<GameNews>> loader, List<GameNews> games) { 

     progressBar.setVisibility(View.INVISIBLE); //This line of code is not executed 
     adapter.clear(); 
     TotalNews.addAll(games); 
     adapter.addAll(games);//And the listView is not populated 
    } 
    //------------------------------------------------------- 

    @Override 
    public void onLoaderReset(Loader<List<GameNews>> loader) { 
     adapter.clear(); 
    } 

    //REUSABLE METHODS 
    //------------------------------------------------------------------ 
    //Method checks if there is internet 
    public boolean isConnected() { 
     ConnectivityManager manager = (ConnectivityManager) 
      getActivity().getSystemService(CONNECTIVITY_SERVICE); 
     NetworkInfo info = manager.getActiveNetworkInfo(); 
     if (info != null && info.isConnected()) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
} 
+0

죄송합니다. 질문을 쉽게 읽을 수있는 방법을 모르 셨습니다. 조언을 주셔서 감사합니다. 나는 이제 시험해 보겠습니다. –

+1

고맙습니다. 선생님, 지금 큰 일을하고 계십니다. 기꺼이 감사 드리며 기쁘게 생각합니다. –

+1

답변으로 작성하면 동의하겠습니다. –

답변

0

귀하의 Fragment 클래스 사용하는 ActivityLoaderManager :

getActivity().getSupportLoaderManager().restartLoader(...); 

그리고 각 인스턴스는 동일한 ID에 사용하고 그 restartLoader() 호출 :

final private int game_loader = 0; 

이 각 Fragment 인스턴스가 사용되었음을 의미 동일한 Loader을 계속해서 다시 시작하면 관찰 된 이상한 행동으로 이어집니다.

해결책은 매우 간단합니다. Activity 대신 Fragment의 로컬 LoaderManager을 사용하십시오. 하는 것,이와

getLoaderManager().restartLoader(...); 

, 당신은 Loader의 자신의 Fragment에 고유 한 이후, 각 인스턴스의 ID를 변경에 대해 걱정할 필요가 없습니다, 그리고 Loader 제대로 Fragment의 수명 기간 동안 처리됩니다 ActivityLoaderManager을 사용할 때 그럴 가능성이 적습니다.