Skip to content
This repository has been archived by the owner on Jul 11, 2024. It is now read-only.

AdapterDataSetObserver.onChanged() performs a layout #81

Open
xxv opened this issue Oct 31, 2012 · 0 comments
Open

AdapterDataSetObserver.onChanged() performs a layout #81

xxv opened this issue Oct 31, 2012 · 0 comments

Comments

@xxv
Copy link

xxv commented Oct 31, 2012

When swapCursor() is called on a SimpleCursorAdapter and the cursor is transitioning from null to populated, the app encounters a NPE. This is due to requestFocus() being called from AdapterDataSetObserver.onChanged(), where other adapters (in particular AdapterView.AdapterDataSetObserver) call requestLayout() instead.

Ideally, the layout should not happen until onLayout().

This is using the Android v4 support library.

Demo:

(make sure to add <uses-permission android:name="android.permission.READ_CONTACTS"/> and at least one contact)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <org.taptwo.android.widget.ViewFlow
        android:id="@+id/contacts"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
package com.example.viewflowtest;

import org.taptwo.android.widget.ViewFlow;

import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;

public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {

    private ViewFlow mViewFlow;
    private SimpleCursorAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mViewFlow = (ViewFlow) findViewById(R.id.contacts);

        mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null,
                new String[] { Contacts.DISPLAY_NAME_PRIMARY }, new int[] { android.R.id.text1 }, 0);
        mViewFlow.setAdapter(mAdapter);

        getSupportLoaderManager().restartLoader(0, null, this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
        final String[] projection = new String[] { Contacts._ID, Contacts.DISPLAY_NAME_PRIMARY };

        return new CursorLoader(this, Contacts.CONTENT_URI, projection, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor c) {
        mAdapter.swapCursor(c);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        // XXX this is the start of the crash
        mAdapter.swapCursor(null);
    }
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant