ViewPager PagerAdapter with cursor - CursorLoader.onLoadFinished doesnt get called with different query

匆匆过客 提交于 2020-01-20 17:41:07

问题


I am doing like a quote application that pulls the quotes from the database and I need to display quotes in a ViewPager.

I have created my CursorPagerAdapter which seems to work well.

public class MyCursorPagerAdapter extends PagerAdapter {

    private Cursor cursor;
    private LayoutInflater inflater;

public MyCursorPagerAdapter(Context context, Cursor cursor) {

    Log.d(MainActivity.TAG, "MyCursorPagerAdapter.onCreate()");

    this.cursor = cursor;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public void swapCursor(Cursor cursor) {
    //if(cursor != null) {

        Log.d(MainActivity.TAG, "swapCursor().");

        this.cursor = cursor;
        //notifyDataSetChanged();
    //}
}

/**
 * Metóda destroyItem
 */
@Override
public void destroyItem(View view, int position, Object object) {

    //cursor.moveToPosition(position);
    ((ViewPager) view).removeView((LinearLayout) object);
}

/**
 * Vráti počet prvkov
 */
@Override
public int getCount() {
    if(cursor == null) {
        return 0;
    } else {
        //return cursor.getCount();
        return 1000;
    }
}


@Override
public Object instantiateItem(View view, int position) {

    position = position % cursor.getCount();

    cursor.moveToPosition(position);

    LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.pager_item, null);

    TextView messageTextView = (TextView) layout.findViewById(R.id.message_textview);
    TextView authorTextView = (TextView) layout.findViewById(R.id.author_textview);

    messageTextView.setText(cursor.getString(cursor.getColumnIndex(QuoteDatabaseHelper.COLUMN_MESSAGE)));
    authorTextView.setText(cursor.getString(cursor.getColumnIndex(QuoteDatabaseHelper.COLUMN_AUTHOR)));

    ((ViewPager) view).addView(layout);
    return layout;
}

/**
 * Metóda isViewFromObject
 */
@Override
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

}

I am also using CursorLoader to async-load the database

public class MainActivity extends FragmentActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myCursorPagerAdapter = new MyCursorPagerAdapter(this, null);

    pager = (ViewPager) findViewById(R.id.viewPager);
    pager.setAdapter(myCursorPagerAdapter);

    getSupportLoaderManager().initLoader(-1, null, this);

}

@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
    return new CursorLoader(this, QuoteContentProvider.CONTENT_URI, null, null, null, null);
}

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {

    Log.d(MainActivity.TAG, "onLoadFinished()");

    myCursorPagerAdapter.swapCursor(cursor);
    this.cursor = cursor;

    pager.setCurrentItem((int) (myCursorPagerAdapter.getCount() / 2), false);
    pager.startAnimation(animation);
}

@Override
public void onLoaderReset(Loader<Cursor> arg0) {
    myCursorPagerAdapter.swapCursor(null);
}   

}

With ContentProvider

public class QuoteContentProvider extends ContentProvider {

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    Cursor cursor = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, "RANDOM()");
    cursor.setNotificationUri(getContext().getContentResolver(), uri);

    Log.d(MainActivity.TAG, "QuoteContentProvider.query() - cursor.getCount(): " + cursor.getCount());
    // getContext().getContentResolver().notifyChange(uri, null);
    return cursor;
}

}

Everything works well, it loads all quotes nicely, but now I need to perform search. So I make a method that queries the database

public void search(String keyword) {

    Log.d(MainActivity.TAG, "Search keyword: " + keyword);
    getContentResolver().query(QuoteContentProvider.CONTENT_URI, null, QuoteContentProvider.COLUMN_AUTHOR + " LIKE '%" + keyword + "%' OR " + QuoteContentProvider.COLUMN_MESSAGE + " LIKE '%" + keyword + "%'", null, null);

}

The query is good, I can see ContentProvider.query() getting called and prints out cursor.getCount(),

HOWEVER now the onLoadFinished in MainActivity doesnt get called even though the cursor.setNotificationUri() is set, and I presume its working because it works the first time when the application starts.

I actually tried to insert some data with content provider and calling getContext().getContentResolver().notifyChange(uri, null); and it HAS triggered the OnLoadFinished so I have no idea why this different query doesnt fire the OnLoadFinished.

Thank you very much who will make sense of this.


回答1:


MainActivity - add/modify:

String getSelection(){
    if(null != mSearchKeyword && mSearchKeyword.getLength()>0) {
        return QuoteContentProvider.COLUMN_AUTHOR + " LIKE '%" + mSearchKeyword + "%' OR " +    
            QuoteContentProvider.COLUMN_MESSAGE + " LIKE '%" + mSearchKeyword + "%'";
    } else {
        return null;
    }       
}

String mSearchKeyword = null;

public void search(String keyword) {
    mSearchKeyword = keyword;
    Log.d(MainActivity.TAG, "Search keyword: " + keyword);
    getLoaderManager().restartLoader(-1, null, this);
}

@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
    return new CursorLoader(this, QuoteContentProvider.CONTENT_URI, null, getSelection(), null, null);
}

Once the method search is fired, call getLoaderManager().restartLoader() on your Loader. Your old data will be discarded and restartLoader will trigger onCreateLoader to be called again.


Do not forget close old cursor after it is swapped



来源:https://stackoverflow.com/questions/12760647/viewpager-pageradapter-with-cursor-cursorloader-onloadfinished-doesnt-get-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!