java - 当我旋转 Android 手机时,Fragment 中的自定义 ListView 就会出现

标签 java android android-activity android-fragments android-listview

我创建了一个 fragment 作为我的应用程序的主要提要。列表数据(ArrayList)是通过Activity实现的fragment内部接口(interface)从主Activity加载的。

我的问题:

  1. 当我旋转手机时,只会显示我的自定义 ListView。
  2. 旋转时,OnCreateView 和 OnActivityCreate 会被调用两次。
  3. 如果在旋转手机并点击后显示 ListView,我会收到下一个错误:

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. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131034209, class android.widget.ListView) with Adapter(class com.fb.newcomersapp.CustomListAdapter)]

这是我的主要 fragment 方法:

public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);
    listView = (ListView) getView().findViewById(R.id.event_list_view);
    mCallback.parseQueryEvents();
    ArrayList<Event> eventList = mCallback.getEventList();
    Log.d("FeedActivity", eventList.size()+"");
    CustomListAdapter adapter = new CustomListAdapter(getActivity(), eventList);
    listView.setAdapter(adapter);

    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // TODO Auto-generated method stub
            mCallback.openEvent(position);

        }
    });

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View view = inflater.inflate(R.layout.fragment_feed, container, false);

    textView = (TextView) view.findViewById(R.id.tv_header);
    textView.setText(mCallback.getLocal()); 
    return view;
}

主要 Activity 方法:

public void parseQueryEvents () {
    eventList = new ArrayList<Event>();
    ParseQuery<ParseObject> query = ParseQuery.getQuery("Event");
    query.orderByAscending("startDate") ;
    query.whereGreaterThanOrEqualTo("endDate", new Date()) ;
    query.findInBackground(new FindCallback<ParseObject>() {
        public void done(List<ParseObject> parseEventList, ParseException e) {
            if (e == null) {
                ParseObject temp ;
                Iterator<ParseObject> i = parseEventList.iterator() ;
                while(i.hasNext()) {
                    temp = i.next();
                    eventList.add(new Event(temp)) ;
                }
            } else {
                Log.d("FeedActivity", e.getMessage());
            }
        }
    });
}

public ArrayList<Event> getEventList() {
    // TODO Auto-generated method stub
    return eventList;
}

日志:

02-04 13:36:06.844: D/GPS(7237): GPS 02-04 13:36:07.110: D/FeedActivity(7237): 0 02-04 13:36:07.145: D/GPS(7237): GPS 02-04 13:36:07.409: D/FeedActivity(7237): 0 02-04 13:36:07.420: I/Choreographer(7237): Skipped 39 frames! The application may be doing too much work on its main thread. 02-04 13:36:07.451: W/View(7237): requestLayout() improperly called by android.widget.ListView{42079068 IFED.VC. ......ID -360,0-0,778 #7f050041 app:id/list_slidermenu} during layout: running second layout pass

那么,有人可以帮助我吗?谢谢:D

最佳答案

不久前我在处理方向变化时遇到了这个问题。很抱歉没有给出完整的答案 atm,但基本上将适配器(以及 ListView,如果您愿意)保存为类变量。然后,在 onActivityCreated 内部,将有关创建和设置适配器的行放入 if 语句中,检查适配器是否为 null。所以,像这样的事情......

private CustomListAdapter mAdapter; // Add this variable

public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);
    listView = (ListView) getView().findViewById(R.id.event_list_view);
    mCallback.parseQueryEvents();
    ArrayList<Event> eventList = mCallback.getEventList();
    Log.d("FeedActivity", eventList.size()+"");

    // Add this conditional
    if(mAdapter == null) {
       CustomListAdapter adapter = new CustomListAdapter(getActivity(), eventList);
       listView.setAdapter(adapter);
    }

    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // TODO Auto-generated method stub
            mCallback.openEvent(position);

        }
    }
}

我相信这个问题起源于它在重新创建 Activity+Fragment 时试图通过缓存变量(例如带有 ID 的 View ,如 ListView)来节省我们的时间 - 然而,在这一切之中,设置新适配器会导致问题。

关于java - 当我旋转 Android 手机时,Fragment 中的自定义 ListView 就会出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28324429/

相关文章:

javascript - 屏幕宽度 + android

android - 使用向上按钮在 Activity 之间导航

android - 具有新 Activity 的 ListView OnItemClickListener

android - 如何从子 Activity 完成父 Activity

java - JEdi​​torPane 从图像链接中删除边框

Java:方法等待另一个类中的 ActionListener

android - 通过 AsyncHttpClient 将 JSON 作为 POST 请求发送到服务器

java - 从另一个类中的方法获取参数值

java - hibernate - ServiceRegistryBuilder

android - Android Studio : coordinator layout and appbarlayout 渲染问题