Como obter o loaderManager.initLoader trabalhando em um fragmento?
Fiz as alterações sugeridas pelo mais gentil kris larson e agora não estou retornando o tipo certo de 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;
}
}
Acho que estou certo em usar um AsyncTaskLoader, mas não entendo como agrupar / converter o que é retornado, por isso é um
Loader<List<NewsStory>>
Meu pensamento está errado? Preciso abandonar o AsyncTaskLoader? ~~~
StoriesLoader retorna List, de
/**
* 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;
}
Eu tentei estes, sem sucesso:
return new Loader<(new StoriesLoader(getContext(), uriBuilder.toString()))>();
return new Loader<>(new StoriesLoader(getContext(), uriBuilder.toString()));
Se você está por aí, Kris, suas correções são bem-vindas.
~~~~~~~~~ Studio está reclamando
Terceiro tipo de argumento errado. Encontrado: 'com.newsreader.guardian.guardiantech.ListOfStoriesFragment', necessário: 'android.support.v4.app.LoaderManager.LoaderCallbacks'
Quando encontrado com este
loaderManager.initLoader(mPage, null, this);
Eu acredito que ele quer uma maneira de referenciar os retornos de chamada do carregador como o terceiro parâmetro, ele precisa de um mapa para onde eles estão, está certo?
Estou usando o Loader em um fragmento para que o descarrilou. Eu tentei alterar o terceiro parâmetro para getActivity (), getContext (), tentei ListOfStoriesFragment, tudo sem sucesso.
O Fragment implementa a interface LoaderCallbacks - os retornos de chamada estão abaixo dele, então por que não funciona?
Tentei as correções sugeridas do Android Studio. Implemente retornos de chamada v4.app.LoadManager, mas isso quebrou um mundo de coisas.
Como faço para corrigir isso? Posso corrigir isso importando algo diferente?
Desculpas pela pergunta.
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&g,t;());
// 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();
}
}