Когда приложение запускается в основном действии USNameFragment. Этот фрагмент запускает Asynctask и после завершения Asynctask отправляет список результатов обратно фрагменту через интерфейс. Затем фрагмент возвращает этот список в onDataRetrieved () и затем должен отобразить этот список.
Hovewer после USNameFragment onCreate () просмотр списка фрагментов пуст. Но Toast в onDataRetrieved () говорит, что из Asynctask получено 3 объекта.
Я нашел трюк, чтобы показать это, но это не так, как должно работать.
Элементы списка отображаются в виде списка только после изменения конфигурации, например изменения ориентации устройства, но не при создании фрагмента.
Что здесь не так? Спасибо за предложение.
Вот мой интерфейс для связи между Fragment и AsyncTask:
public interface IActivityRef {
void onDataRetrieved(List<USDto> usDtos);
}
Вот мой фрагмент, который реализует интерфейс IActivityRef:
public class USNameFragment extends Fragment
implements IActivityRef {
private AsyncTask<String, Void, USResponse> usTask;
private WeakReference<IActivityRef> context;
private ListView listUSNames;
private List<String> usNames;
public USNameFragment() {
// Required empty public constructor
usNames = new ArrayList<>();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = new WeakReference<>((IActivityRef) this);
}
@Override
public void onDetach() {
super.onDetach();
context = null;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this fragment across configuration changes.
setRetainInstance(true);
usTask = new USTask(this);
usTask = usTask.execute("params");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_us_name, container, false);
listUSNames = rootView.findViewById(R.id.listUS);
listUSNames.setAdapter(new ArrayAdapter<String>(
getActivity(), R.layout.item_us_name, R.id.usName, usNames));
return rootView;
}
@Override
public void onStop() {
if (usTask != null && usTask.getStatus() == AsyncTask.Status.RUNNING) {
usTask.cancel(true);
}
usTask = null;
super.onStop();
}
@Override
public void onDataRetrieved(List<USDto> usDtos) {
this.usNames = new USColumns().getUSNames(usDtos);
Toast.makeText(getActivity(), "Data retrieved! List size = " + usDtos.size(),
Toast.LENGTH_LONG).show();
}
}
А вот Asynctask:
public class USTask extends AsyncTask<String, Void, USResponse> {
private WeakReference<IActivityRef> context;
private TwApiClient twApiClient;
public USTask(IActivityRef context) {
this.context = new WeakReference<>(context);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected USResponse doInBackground(String... params) {
// do http code here
}
@Override
protected void onPostExecute(USResponse usResponse) {
super.onPostExecute(usResponse);
if(context != null && usResponse != null) {
IActivityRef activity = context.get();
activity.onDataRetrieved(usResponse.getUS());
}
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
EDIT
Подумайте, макет фрагмента создан до получения списка в onDataRetrieved (). Может, стоит обновить список просмотра как-нибудь?
EDIT2
Проблема была в обновлении адаптера списка, а не в отправке контекста из фрагмента в asynctask.