我已经设法组装了一个自定义 BaseAdapter。此适配器用于为每个列表项显示三个 TextView。当活动中有一个ListView时,工作绝对完美。
但是,我正在使用带有 3 个片段的碎片活动 - 其中 2 个包含需要使用我的自定义适配器和 XML 的 ListView。
在加载这两个 ListView 时,在加载的第一个ListView 上触发 onItemClickListener 会导致以下错误:
11-20 18:02:15.295: E/AndroidRuntime(18563): java.lang.IllegalStateException:
The content of the adapter has changed but ListView did not receive a
notification. Make sure the content of your adapter is not modified from
a background thread, but only from the UI thread. [in ListView(2131165192,
class android.widget.ListView) with
Adapter(class com.my.project.Adapter_CustomList)]
我不希望适配器发生变化 - 每个 ListView 适配器都使用一个新的 Adapter_CustomList() 所以我不确定为什么它们被引用为同一个适配器?
适配器将 getActivity() 作为上下文 - 因为这对两者都是一样的,这会导致问题吗?有没有办法解决这个问题,或者这是碎片的另一个缺点?
自定义适配器大致如下,我已经取出了一些任意的代码块......
public class Adapter_CustomList extends BaseAdapter {
private static ArrayList<Custom> results;
private LayoutInflater mInflater;
public Adapter_CustomList(Context context, ArrayList<Custom> res) {
results = res;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return results.size();
}
public Object getItem(int position) {
return results.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row_view, null);
holder = new ViewHolder();
//Set ViewHolder vars from inflated view
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//Sets the TextViews
return convertView;
}
static class ViewHolder {
//Contains the TextView text vars
}
}
该活动正在使用 FragmentPagerAdapter(由 Eclipse 生成):
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment;
switch (i){
case 1:
fragment = new Frag_ListOne();
break;
case 2:
fragment = new Frag_ListTwo();
break;
default:
fragment = new Frag_Temporary();
break;
}
return fragment;
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: return getString(R.string.main_fragment1).toUpperCase();
case 1: return getString(R.string.main_fragment2).toUpperCase();
case 2: return getString(R.string.main_fragment3).toUpperCase();
}
return null;
}
}
片段示例,两者几乎相同,但具有独特的布局文件。
public class Frag_ListOne extends Fragment {
private ListView ListView;
private Adapter_CustomList listAdapter;
private Fetcher fetcher;
public Frag_ListOne(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.frag_list_one, container, false);
}
@Override
public void onStart(){
super.onStart();
ListView = (ListView) getActivity().findViewById(R.id.frag_one_list);
ListView.setEmptyView(getActivity().findViewById(R.id.frag_one_list_spinner));
if (listAdapter != null){
setListAdapter();
} else {
//This will always be called for now....
sendRequest();
}
}
private void sendRequest(){
fetcher = new Fetcher();
fetcher.execute("http://myapiurl.com");
}
private void cancelFetch(){
if (fetcher != null &&
(fetcher.getStatus() == AsyncTask.Status.PENDING || fetcher.getStatus() == AsyncTask.Status.RUNNING)){
fetcher.cancel(true);
}
}
private void displayError(String errMsg){
//Log errMsg
}
private void createListAdapter(ArrayList<Result> res){
listAdapter = new Adapter_CustomList(getActivity(), res);
setListAdapter();
}
private void setListAdapter(){
ListView.setAdapter(listAdapter);
ListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Result r = (Result) ListView.getItemAtPosition(position);
Intent intent = new Intent(getActivity(), ViewResultActivity.class);
intent.putExtra(F_List.INTENT_VIEW_RESULT_OBJ, r);
startActivity(intent);
}
});
}
//Extended AsyncTask, essentially
public class Fetcher extends JSONRequest{
@Override
protected void onSuccess(JSONObject req, JSONObject res){
if (req != null && res != null){
try{
JSONArray jsons = res.getJSONArray("results");
ArrayList<Result> res = new ArrayList<Result>();
if (jsons.length() > 0){
for (int i=0;i<jsons.length();i++){
JSONObject jo = jsons.getJSONObject(i);
r = new Result();
r.setLineOne(jo.getInt("line1"));
r.setLineTwo(jo.getString("line2"));
r.setLineThree(jo.getString("line3"));
res.add(r);
}
createListAdapter(res);
} else {
//Nothing found
}
} catch (JSONException e){}
} else {
//Null received
}
}
@Override
protected void onError(String errMsg){}
@Override
protected void onCancel(){}
}
}