ListView尝试从Activity退出后刷新

时间:2014-11-27 14:52:15

标签: android android-activity android-listview android-5.0-lollipop

我们在Lollipop遇到了一些非常奇怪的事情。

我们有一个搜索屏幕,一个列表屏幕,然后是一个详细信息屏幕。

执行搜索后,将显示列表。然后,用户可以选择一个条目并获得更多详细信息。 在KK以上的Android版本上,一切都很棒。

然而,在Lollipop从列表屏幕退出到搜索屏幕时,我们有时会崩溃。 这发生在列表适配器的getCount()中 - 它试图访问我们设置为null的项。

我不明白为什么在退出活动后更新列表视图。 为了检查操作的顺序,我注册了一个ActivityLifecycleCallbacks并打印出每个条目的条目。

我看到以下内容(从详细信息屏幕开始 - >列表屏幕 - >搜索屏幕。

onActivityPaused    com.applicat.meuchedet.DoctorSearchScreen@43db605
onActivityCreated   com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityStarted   com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityResumed   com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityStopped   com.applicat.meuchedet.DoctorSearchScreen@43db605
onActivityPaused    com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityCreated   com.applicat.meuchedet.DoctorSwipeableDetailsScreen@35b3ff59
onActivityStarted   com.applicat.meuchedet.DoctorSwipeableDetailsScreen@35b3ff59
onActivityResumed   com.applicat.meuchedet.DoctorSwipeableDetailsScreen@35b3ff59
onActivityStopped   com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityPaused    com.applicat.meuchedet.DoctorSwipeableDetailsScreen@35b3ff59
onActivityStarted   com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityResumed   com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityStopped   com.applicat.meuchedet.DoctorSwipeableDetailsScreen@35b3ff59
onActivityDestroyed com.applicat.meuchedet.DoctorSwipeableDetailsScreen@35b3ff59
onActivityPaused    com.applicat.meuchedet.DoctorListScreen@108d4747
onActivityStarted   com.applicat.meuchedet.DoctorSearchScreen@43db605
onActivityResumed   com.applicat.meuchedet.DoctorSearchScreen@43db605

可以看出,当从详细信息活动转到列表活动时,一切正常 - 它会暂停详细信息活动,然后恢复列表活动,最后停止并销毁详细信息活动。

但是,当从列表移动到搜索时,它不会到达列表活动的停止和销毁。 搜索活动将恢复并显示,然后由于列表活动尝试更新适配器中的内容而导致应用程序崩溃。 更奇怪的是,即使在棒棒糖上也不会发生这种情况。

将适配器连接到列表视图:

        this._adapter = new ArrayAdapter<ViewGroup>(this, android.R.layout.simple_expandable_list_item_1) {
        // We want to force at least NUM_OF_ITEMS_DISPLAYED rows on the screen. So, we set getCount to return NUM_OF_ITEMS_DISPLAYED
        // if there are less than NUM_OF_ITEMS_DISPLAYED rows.
        // getView then chooses the required view for the row depending on whether it is a row with data or an empty one.
        @Override
        public int getCount() {
            return Math.max(ListScreen.this._maxNumOfItemsToDisplay, ListScreen.this.getActualNumOfItemsInList());
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Update the number of items that are visible as this screen is displayed:
            ListScreen.this._numOfItemsDisplayedOnStart = Math.max(ListScreen.this._numOfItemsDisplayedOnStart, position);

            // Choose the view to use depending on the type of row to be displayed
            // The input convertview, if it is not null, will always be the one that matches the type given.
            // This is due to the code in getItemViewType returning the type of view required for this row.
            int viewType = getItemViewType(position);
            boolean isEnabled = itemIsClickable(position);

            switch (viewType){
                case ROW_WITH_DATA:  // Normal data view

                    convertView = ListScreen.this.getConvertView(convertView, parent, viewType, position);
                    _viewHolder.position = position;

                    MeuchedetApplication.setBackgroundDrawable(convertView, getResources().getDrawable(isEnabled ? ListScreen.this.getClickableItemBackground() :
                                                                                                                   ListScreen.this.getNonClickableItemBackground()));


                    setRecordData(position, (ViewGroup) convertView, _viewHolder);
                    _viewHolder.setClickable(itemIsClickable(position));
                    break;
                case ROW_WITHOUT_DATA:  // Empty row
                    if (convertView == null) {
                        convertView = (ViewGroup) li.inflate(ListScreen.this.getEmptyItemLayout(), parent, false);
                    }
                    ListScreen.this.makeInvisible(convertView);
                    break;
            }

            if (itemIsClickable(position)) {
                convertView.setClickable(false);
                convertView.setFocusable(false);
            } else {
                convertView.setClickable(true);
                convertView.setFocusable(true);
            }

            return convertView;
        }

        // This method indicates that we have two different view layouts with the ListView.
        // In our case, one if for the normal row and one is for the empty row
        @Override
        public int getViewTypeCount() {
            return 2;
        }

        // This method returns which type of view to use for which row.
        // We will use the normal type for the original rows and the empty type for any overflow rows.
        // So, type 0 = normal, type 1 = empty
        //
        // This method is called automatically by ListView to determine what type of view to fetch from the recycler.
        // It is then called in our getView code to determine what type of view we have or should create.

        @Override
        public int getItemViewType(int position) {
            return (position < ListScreen.this._results._resultsList.size()) ? ROW_WITH_DATA : ROW_WITHOUT_DATA;
        }
    };
    _lv.setAdapter(this._adapter);

&#34; getConvertView&#34;是一个获取此行的填充视图的方法。在扩展此方法的类中重写此方法。

0 个答案:

没有答案