在应用程序启动时,主要活动是USNameFragment。该片段启动Asynctask,并在Asynctask完成后,将结果列表通过界面发送回片段。然后,Fragment在onDataRetrieved()中获取此列表,然后应显示此列表。
在USNameFragment onCreate()之后,片段列表视图为空。但是onDataRetrieved()中的Toast表示从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);
}
}
编辑 认为片段布局是在onDataRetrieved()中检索列表之前创建的。也许应该刷新listview些什么?
EDIT2 问题在于刷新列表视图适配器,而不是从片段向asynctask发送上下文。
答案 0 :(得分:0)
问题在于片段中的onDataRetrieved()中的asynctask完成后没有更新ListView适配器。
因此,解决方案是如此简单:
将此字段添加到USNameFragment:
private ArrayAdapter<String> listAdapter;
然后在onCreateView()中初始化此适配器并将其分配给listview:
@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);
listAdapter = new ArrayAdapter<String>(
getActivity(), R.layout.item_us_name, R.id.usName, usNames);
listUSNames.setAdapter(listAdapter);
return rootView;
}
然后在onDataRetrieved()中重新初始化此适配器:
@Override
public void onDataRetrieved(List<USDto> usDtos) {
this.usNames = new USColumns().getUSNames(usDtos);
listAdapter = new ArrayAdapter<String>(
getActivity(), R.layout.item_us_name, R.id.usName, usNames);
listUSNames.setAdapter(listAdapter);
}
还将asynctask的开始从USNameFragment中的onCreate()移到onAttach():
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = new WeakReference<>((IActivityRef) this);
usTask = new USTask(this);
usTask = usTask.execute("params");
}
就这样。