我已经做出了最善良的kris larson建议的更改,而我现在没有从onCreateLoader返回正确的类型
return new StoriesLoader(getContext(), uriBuilder.toString());
StoriesLoader:
import android.content.AsyncTaskLoader;
import android.content.Context;
import java.util.List;
/**
* Loads a list of news stories by using an AsyncTask to perform the
* network request to the given URL.
*/
public class StoriesLoader extends AsyncTaskLoader<List<NewsStory>> {
/** Tag for log messages */
private static final String LOG_TAG = StoriesLoader.class.getName();
/** Query URL */
private String mUrl;
/**
* Constructs a new {@link StoriesLoader}.
*
* @param context of the activity
* @param url to load data from
*/
public StoriesLoader(Context context, String url) {
super(context);
mUrl = url;
}
@Override
protected void onStartLoading() {
forceLoad();
}
/**
* This is on a background thread.
*/
@Override
public List<NewsStory> loadInBackground() {
if (mUrl == null) {
return null;
}
// Perform the network request, parse the response, and extract a list of news stories.
List<NewsStory> newsStories = QueryUtils.fetchNewsStoryData(mUrl);
return newsStories;
}
}
我认为我使用AsyncTaskLoader是正确的,但我不知道如何包装/投射返回的内容,因此它是
Loader<List<NewsStory>>
我的想法错了吗?我是否必须抛弃AsyncTaskLoader? ~~~
StoriesLoader从
返回List /**
* This is on a background thread.
*/
@Override
public List<NewsStory> loadInBackground() {
if (mUrl == null) {
return null;
}
// Perform the network request, parse the response, and extract a list of earthquakes.
List<NewsStory> newsStories = QueryUtils.fetchNewsStoryData(mUrl);
return newsStories;
}
我试过这些,但无济于事:
return new Loader<(new StoriesLoader(getContext(), uriBuilder.toString()))>();
return new Loader<>(new StoriesLoader(getContext(), uriBuilder.toString()));
如果你在那里克里斯,你的更正很受欢迎。
~~~~~~~~~ 工作室抱怨
错误的第三个参数类型。实测: &#39; com.newsreader.guardian.guardiantech.ListOfStoriesFragment&#39 ;, 需要: &#39; android.support.v4.app.LoaderManager.LoaderCallbacks&#39;
遇到这个
loaderManager.initLoader(mPage, null, this);
我相信它想要一种方法来引用加载器回调作为第三个参数,它需要一个映射到它们的位置,这是对的吗?
我在一个片段中使用了Loader,因此它已经脱轨了。我尝试将第三个参数更改为getActivity(),getContext(),尝试使用ListOfStoriesFragment,但都无济于事。
Fragment确实实现了LoaderCallbacks接口 - 回调就在它下面,那为什么它不起作用呢?
我尝试了Android Studio的建议修复程序。实现v4.app.LoadManager回调,但这打破了一个世界的东西。
我该如何解决这个问题?我可以通过导入不同的东西来解决这个问题吗? 对这个问题道歉。
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import static com.newsreader.guardian.guardiantech.BuildConfig.API_KEY;
/**
* Initiates a loader to get JSON from The Guardian
* updates UI with info when the data has returned
*/
public class ListOfStoriesFragment extends Fragment
implements android.app.LoaderManager.LoaderCallbacks<List<NewsStory>> {
/** String for tabs */
public static final String ARG_PAGE = "ARG_PAGE";
private int mPage;
private static final String TAG = ListOfStoriesFragment.class.getName();
/** URL for earthquake data from the USGS dataset */
private static final String GUARDIAN_REQUEST_URL =
"http://content.guardianapis.com/search";
/**
* Constant value for the news story loader ID. We can choose any integer.
* This really only comes into play if you're using multiple loaders.
*/
private static final int NEWSSTORY_LOADER_ID = 1;
/** Adapter for the list of newsStories */
private NewsStoryAdapter mAdapter;
/** TextView that is displayed when the list is empty */
private TextView mEmptyStateTextView;
/** more tabs stuff */
public static ListOfStoriesFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
ListOfStoriesFragment fragment = new ListOfStoriesFragment();
fragment.setArguments(args);
return fragment;
}
/** needed for tabs?! */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARG_PAGE);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_stories, container, false);
// Find a reference to the {@link ListView} in the layout
ListView newsStoryListView = (ListView) rootView.findViewById(R.id.list);
mEmptyStateTextView = (TextView) rootView.findViewById(R.id.empty_view);
newsStoryListView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of NewsStory as input
mAdapter = new NewsStoryAdapter(getContext(), new ArrayList<NewsStory>());
// Set the adapter on the {@link ListView}
// so the list can be populated in the user interface
newsStoryListView.setAdapter(mAdapter);
// Get a reference to the ConnectivityManager to check state of network connectivity
ConnectivityManager connMgr = (ConnectivityManager)
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
// Get details on the currently active default data network
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
// If there is a network connection, fetch data
if (networkInfo != null && networkInfo.isConnected()) {
// Get a reference to the LoaderManager, in order to interact with loaders.
LoaderManager loaderManager = getLoaderManager();
// Initialize the loader. Pass in the int ID constant defined above and pass in null for
// the bundle. Pass in this activity for the LoaderCallbacks parameter (which is valid
// because this activity implements the LoaderCallbacks interface).
//loaderManager.initLoader(NEWSSTORY_LOADER_ID, null, this);
// number the loaderManager with mPage as may be requesting up to three lots of JSON for each tab
loaderManager.initLoader(mPage, null, this);
} else {
// Otherwise, display error
// First, hide loading indicator so error message will be visible
View loadingIndicator = rootView.findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
// Update empty state with no connection error message
mEmptyStateTextView.setText(R.string.no_internet_connection);
}
return rootView;
}
@Override
public Loader<List<NewsStory>> onCreateLoader(int i, Bundle bundle) {
String searchTerm;
switch(mPage) {
case 0:
searchTerm = "windows";
break;
case 1:
searchTerm = "android";
break;
default:
searchTerm = "android wear";
}
Uri baseUri = Uri.parse(GUARDIAN_REQUEST_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter("q", searchTerm);
uriBuilder.appendQueryParameter("api-key", API_KEY);
uriBuilder.build();
Log.wtf(TAG, uriBuilder.toString());
return new StoriesLoader(getContext(), uriBuilder.toString());
}
@Override
public void onLoadFinished(Loader<List<NewsStory>> loader, List<NewsStory> newsStories) {
// Hide loading indicator because the data has been loaded
View loadingIndicator = getView().findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
// Set empty state text to display "No stories found."
mEmptyStateTextView.setText(R.string.no_news_stories);
// Clear the adapter of previous newsStories
mAdapter.clear();
// If there is a valid list of {@link NewsStory}s, then add them to the adapter's
// data set. This will trigger the ListView to update.
if (newsStories != null && !newsStories.isEmpty()) {
mAdapter.addAll(newsStories);
}
}
@Override
public void onLoaderReset(Loader<List<NewsStory>> loader) {
// Loader reset, so we can clear out our existing data.
mAdapter.clear();
}
}
答案 0 :(得分:6)
Fragment确实实现了LoaderCallbacks接口 - 回调在它下面,为什么它不起作用呢?
因为您正在将支持库类与平台类混合在一起。
android.content.Loader
与android.support.v4.app.LoaderManager
该行
LoaderManager loaderManager = getLoaderManager();
正在为
返回android.support.v4.app.LoaderManager
loaderManager.initLoader(mPage, null, this);
要编译,您的片段需要实现android.support.v4.app.LoaderManager.LoaderCallbacks
,而不是android.app.LoaderManager.LoaderCallbacks
。
我多次遇到这个问题。
我假设您需要支持库类。
更改
import android.content.Loader;
到
import android.support.v4.content.Loader;
更改
public class ListOfStoriesFragment extends Fragment
implements android.app.LoaderManager.LoaderCallbacks<List<NewsStory>> {
到
public class ListOfStoriesFragment extends Fragment
implements LoaderManager.LoaderCallbacks<List<NewsStory>> {
这应该可以解决你的问题。
确保StoriesLoader
延伸android.support.v4.app.Loader
而非android.app.Loader
。检查您的导入声明。