Viewpager, Cursor and Fragment

前端 未结 2 1411
无人及你
无人及你 2021-01-07 09:45

I am new to the viewpager and was wondering if anyone could point me to a tutorial or source code of a project that uses a viewpager with fragments and a database. I\'ve see

2条回答
  •  礼貌的吻别
    2021-01-07 10:23

    You need to create abstract class adapter to use both cursor and pager adapter and extend to your own adapter and bind the view.

    public abstract class CursorPagerAdapter extends PagerAdapter {
    
    public static final String TAG = CursorPagerAdapter.class.getSimpleName();
    
    protected WeakReference ctxRef;
    
    protected boolean mDataValid;
    protected boolean mAutoRequery;
    protected Cursor mCursor;
    protected int mRowIDColumn;
    
    protected ChangeObserver mChangeObserver;
    protected DataSetObserver mDataSetObserver;
    
    /**
     * If set the adapter will call requery() on the cursor whenever a content change notification is
     * delivered. Implies {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
     *
     * @deprecated This option is discouraged, as it results in Cursor queries being performed on the
     *             application's UI thread and thus can cause poor responsiveness or even Application
     *             Not Responding errors. As an alternative, use {@link android.app.LoaderManager} with
     *             a {@link android.content.CursorLoader}.
     */
    @Deprecated
    public static final int FLAG_AUTO_REQUERY = 0x01;
    
    /**
     * If set the adapter will register a content observer on the cursor and will call {@link
     * # onContentChanged()} when a notification comes in. Be careful when using this flag: you will
     * need to unset the current Cursor from the adapter to avoid leaks due to its registered
     * observers. This flag is not needed when using a CursorAdapter with a {@link
     * android.content.CursorLoader}.
     */
    public static final int FLAG_REGISTER_CONTENT_OBSERVER = 0x02;
    
    public CursorPagerAdapter(Context context, Cursor c, int flags) {
        init(context, c, flags);
    }
    
    void init(Context context, Cursor c, int flags) {
        if ((flags & FLAG_AUTO_REQUERY) == FLAG_AUTO_REQUERY) {
            flags |= FLAG_REGISTER_CONTENT_OBSERVER;
            mAutoRequery = true;
        } else {
            mAutoRequery = false;
        }
    
        boolean cursorPresent = c != null;
        mCursor = c;
        mDataValid = cursorPresent;
        ctxRef = new WeakReference<>(context);
        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
    
        if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
            mChangeObserver = new ChangeObserver();
            mDataSetObserver = new MyDataSetObserver();
        } else {
            mChangeObserver = null;
            mDataSetObserver = null;
        }
    
        if (cursorPresent) {
            if (mChangeObserver != null) {
                c.registerContentObserver(mChangeObserver);
            }
    
            if (mDataSetObserver != null) {
                c.registerDataSetObserver(mDataSetObserver);
            }
        }
    }
    
    public Cursor getCursor() {
        return mCursor;
    }
    
    @Override
    public int getCount() {
        if (mDataValid && mCursor != null)
            return mCursor.getCount();
        else
            return 0;
    }
    
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (!mDataValid) {
            throw new IllegalStateException("this should only be called when the cursor is valid");
        }
    
        if (!mCursor.moveToPosition(position)) {
            throw new IllegalStateException("couldn't move cursor to position " + position);
        }
    
        Context context = ctxRef.get();
        if (context != null) {
            View v = newView(context, mCursor, (ViewGroup) container);
            bindView(v, context, mCursor);
    
            ((ViewPager) container).addView(v);
    
            return v;
        } else {
            throw new IllegalStateException("context is null");
        }
    }
    
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((View) object);
    }
    
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
    
    @Override
    public boolean isViewFromObject(View view, Object o) {
        return view == o;
    }
    
    public abstract View newView(Context context, Cursor cursor, ViewGroup parent);
    
    public abstract void bindView(View view, Context context, Cursor cursor);
    
    public void changeCursor(Cursor cursor) {
        Cursor old = swapCursor(cursor);
        if (old != null) {
            old.close();
        }
    }
    
    public Cursor swapCursor(Cursor newCursor) {
        if (newCursor == mCursor) return null;
    
        Cursor oldCursor = mCursor;
        if (oldCursor != null) {
            if (mChangeObserver != null) {
                oldCursor.unregisterContentObserver(mChangeObserver);
            }
            if (mDataSetObserver != null) {
                oldCursor.unregisterDataSetObserver(mDataSetObserver);
            }
        }
    
        mCursor = newCursor;
        if (newCursor != null) {
            if (mChangeObserver != null) {
                newCursor.registerContentObserver(mChangeObserver);
            }
    
            if (mDataSetObserver != null) {
                newCursor.registerDataSetObserver(mDataSetObserver);
            }
    
            mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
            mDataValid = true;
            // notify the observers about the new cursor
            notifyDataSetChanged();
        } else {
            mRowIDColumn = -1;
            mDataValid = false;
            notifyDataSetChanged();
        }
    
        return oldCursor;
    }
    
    private void onContentChange() {
        if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
            mDataValid = mCursor.requery();
        }
    }
    
    private class ChangeObserver extends ContentObserver {
    
        public ChangeObserver() {
            super(new Handler());
        }
    
        /**
         *
         * @return True if self-change notifications should be delivered to the observer.
         */
        @Override
        public boolean deliverSelfNotifications() {
            return true;
        }
    
        /**
         * This method is called when a content change occurs.
         * @param selfChange
         */
        @Override
        public void onChange(boolean selfChange) {
            onContentChange();
        }
    }
    
    private class MyDataSetObserver extends DataSetObserver {
    
        @Override
        public void onChanged() {
            mDataValid = true;
            notifyDataSetChanged();
        }
    
        @Override
        public void onInvalidated() {
            mDataValid = false;
            notifyDataSetChanged();
        }
    }
    

    }

    Sample Adapter (in kotlin):

    class SampleAdapter(context: Context, cursor: Cursor?, autoQuery: Int): CursorPagerAdapter(context, cursor, autoQuery) {
    
    internal var mContext: Context
    internal var mLayoutInflater: LayoutInflater
    internal var aQuery: AQuery
    val imageWidth = Helper.getDisplayWidth(context)
    init {
        mContext = context
        mLayoutInflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        aQuery = AQuery(context)
    }
    
    override fun newView(context: Context?, cursor: Cursor?, parent: ViewGroup?): View {
        return mLayoutInflater.inflate(R.layout.your_item_row, parent, false)
    }
    
    override fun bindView(view: View?, context: Context?, cursor: Cursor?) {
        val sampleVo = SampleVo.getValueFromCursor(cursor)
        val tvTitle = view?.findViewById(R.id.tvTitle)
        tvTitle?.text = sampleVo.title
    }
    

    Original Source: link

提交回复
热议问题