ca.rmen.android.scrumchatter.meeting.detail.MeetingPagerAdapter.java Source code

Java tutorial

Introduction

Here is the source code for ca.rmen.android.scrumchatter.meeting.detail.MeetingPagerAdapter.java

Source

/*
 * Copyright 2013, 2017 Carmen Alvarez
 *
 * This file is part of Scrum Chatter.
 *
 * Scrum Chatter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scrum Chatter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scrum Chatter. If not, see <http://www.gnu.org/licenses/>.
 */
package ca.rmen.android.scrumchatter.meeting.detail;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.WorkerThread;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;

import ca.rmen.android.scrumchatter.settings.Prefs;
import ca.rmen.android.scrumchatter.util.Log;
import ca.rmen.android.scrumchatter.Constants;
import ca.rmen.android.scrumchatter.meeting.Meetings;
import ca.rmen.android.scrumchatter.provider.MeetingColumns;
import ca.rmen.android.scrumchatter.provider.MeetingCursorWrapper;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 * Adapter for the list of meetings
 */
class MeetingPagerAdapter extends FragmentStatePagerAdapter {
    private static final String TAG = Constants.TAG + "/" + MeetingPagerAdapter.class.getSimpleName();

    private MeetingCursorWrapper mCursor;
    private final Context mContext;
    private final MeetingObserver mMeetingObserver;
    private final int mTeamId;

    private MeetingPagerAdapter(FragmentActivity activity, int teamId, MeetingCursorWrapper cursor) {
        super(activity.getSupportFragmentManager());
        Log.v(TAG, "Constructor");
        mContext = activity;
        mTeamId = teamId;
        mMeetingObserver = new MeetingObserver(new Handler(Looper.getMainLooper()));
        mCursor = cursor;
        mCursor.registerContentObserver(mMeetingObserver);
    }

    static Single<MeetingPagerAdapter> create(FragmentActivity activity) {
        return Single.fromCallable(() -> {
            int teamId = Prefs.getInstance(activity).getTeamId();
            // Closing the cursor wrapper also closes the cursor
            @SuppressLint("Recycle")
            Cursor cursor = activity.getContentResolver().query(MeetingColumns.CONTENT_URI, null,
                    MeetingColumns.TEAM_ID + "=?", new String[] { String.valueOf(teamId) },
                    MeetingColumns.MEETING_DATE + " DESC");
            MeetingCursorWrapper meetingCursorWrapper = new MeetingCursorWrapper(cursor);
            meetingCursorWrapper.getCount();
            return new MeetingPagerAdapter(activity, teamId, meetingCursorWrapper);
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Fragment getItem(int position) {
        Log.v(TAG, "getItem at position " + position);
        MeetingFragment fragment = new MeetingFragment();
        Bundle args = new Bundle(1);
        mCursor.moveToPosition(position);
        args.putLong(Meetings.EXTRA_MEETING_ID, mCursor.getId());
        args.putSerializable(Meetings.EXTRA_MEETING_STATE, mCursor.getState());
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public int getCount() {
        return mCursor.getCount();
    }

    int getPositionForMeetingId(long meetingId) {
        Log.v(TAG, "getPositionForMeetingId " + meetingId);

        if (mCursor.moveToFirst()) {
            do {
                if (mCursor.getId() == meetingId)
                    return mCursor.getPosition();
            } while (mCursor.moveToNext());
        }
        return -1;
    }

    Meeting getMeetingAt(int position) {
        mCursor.moveToPosition(position);
        return Meeting.read(mContext, mCursor);
    }

    void destroy() {
        Log.v(TAG, "destroy");
        mCursor.unregisterContentObserver(mMeetingObserver);
        mCursor.close();
    }

    private class MeetingObserver extends ContentObserver {

        private final String TAG = MeetingPagerAdapter.TAG + "/" + MeetingObserver.class.getSimpleName();

        MeetingObserver(Handler handler) {
            super(handler);
            Log.v(TAG, "Constructor");
        }

        /**
         * The Meeting table changed. We need to update our cursor and notify about the change.
         */
        @Override
        public void onChange(boolean selfChange) {
            Log.v(TAG, "MeetingObserver onChange, selfChange: " + selfChange);
            super.onChange(selfChange);
            Single.fromCallable(() -> read(mTeamId)).subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread()).subscribe(meetingCursorWrapper -> {
                        mCursor.unregisterContentObserver(mMeetingObserver);
                        mCursor.close();
                        mCursor = meetingCursorWrapper;
                        notifyDataSetChanged();
                        mCursor.registerContentObserver(mMeetingObserver);
                    });
        }

        @WorkerThread
        private MeetingCursorWrapper read(int teamId) {
            // Closing the cursorWrapper also closes the cursor
            @SuppressLint("Recycle")
            Cursor cursor = mContext.getContentResolver().query(MeetingColumns.CONTENT_URI, null,
                    MeetingColumns.TEAM_ID + "=?", new String[] { String.valueOf(teamId) },
                    MeetingColumns.MEETING_DATE + " DESC");
            MeetingCursorWrapper cursorWrapper = new MeetingCursorWrapper(cursor);
            cursorWrapper.getCount();
            return cursorWrapper;
        }
    }

}