我有一个ListFragment
,它使用Loader
从网络中提取数据。我在ListFragment
的每个页面中使用了此ViewPager
的新实例。它工作正常,但当我使用TabLayout
或快速移动页面时,Fragment
会继续加载,并且不会在ListView
中显示数据。
当我使用日志消息检查时,我发现ListFragment
在onLoadFinished()
方法中跳过了一些代码行。它不会使ProgressBar
不可见。它会向Adapter
添加项目,但不会显示在ListView
中。此问题也发生在ViewPager
的第一页。
在ListFragment
中使用ViewPager
时是否需要遵循任何具体规则?
这是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 :(得分:0)
您的Fragment
班级正在使用Activity
的{{1}}:
LoaderManager
每个实例在其getActivity().getSupportLoaderManager().restartLoader(...);
调用中使用相同的ID:
restartLoader()
这意味着每个final private int game_loader = 0;
实例都在反复使用并重新启动相同的Fragment
,从而导致您观察到的奇怪行为。
解决方案非常简单:使用Loader
的本地Fragment
,而不是LoaderManager
。
Activity
有了这个,您无需担心在每个实例中更改ID,因为getLoaderManager().restartLoader(...);
对于Loader
是唯一的,并且Fragment
将被正确处理Loader
的生命周期,使用Fragment
Activity
时可能不会出现这种情况。