com.ruesga.rview.widget.PagerControllerLayout.java Source code

Java tutorial

Introduction

Here is the source code for com.ruesga.rview.widget.PagerControllerLayout.java

Source

/*
 * Copyright (C) 2016 Jorge Ruesga
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ruesga.rview.widget;

import android.content.Context;
import android.database.DataSetObserver;
import android.databinding.DataBindingUtil;
import android.support.annotation.IdRes;
import android.support.annotation.Keep;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;

import com.ruesga.rview.R;
import com.ruesga.rview.databinding.PagerControllerLayoutBinding;

public class PagerControllerLayout extends FrameLayout {

    private static final String FRAGMENT_TAG = "pager_fragment";

    public static final int INVALID_PAGE = -1;

    public static abstract class PagerControllerAdapter<T> {
        private DataSetObserver mObserver;

        public abstract FragmentManager getFragmentManager();

        public abstract CharSequence getPageTitle(int position);

        public abstract T getItem(int position);

        public abstract int getCount();

        public abstract Fragment getFragment(int position);

        public abstract @IdRes int getTarget();

        public void notifyDataSetChanged() {
            mObserver.onChanged();
        }

        private void registerObserver(DataSetObserver observer) {
            mObserver = observer;
        }
    }

    public interface OnPageSelectionListener {
        void onPageSelected(int position, boolean fromUser);
    }

    @Keep
    public static class Model {
        public CharSequence prev;
        public CharSequence next;
    }

    @Keep
    @SuppressWarnings("UnusedParameters")
    public static class EventHandlers {
        private PagerControllerLayout mView;

        EventHandlers(PagerControllerLayout view) {
            mView = view;
        }

        public void onPrevPressed(View v) {
            mView.performMovePrev();
        }

        public void onNextPressed(View v) {
            mView.performMoveNext();
        }
    }

    private DataSetObserver mObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            pageSelected(mCurrentItem, true);
        }
    };

    private PagerControllerLayoutBinding mBinding;
    private OnPageSelectionListener mOnPageSelectionListener;
    private PagerControllerAdapter mAdapter;
    private int mCurrentItem = INVALID_PAGE;

    private final Model mModel = new Model();

    public PagerControllerLayout(Context context) {
        this(context, null);
    }

    public PagerControllerLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PagerControllerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.pager_controller_layout, this,
                false);
        mBinding.setHandlers(new EventHandlers(this));
        addView(mBinding.getRoot());
    }

    public PagerControllerLayout listenOn(OnPageSelectionListener cb) {
        mOnPageSelectionListener = cb;
        return this;
    }

    public PagerControllerLayout with(PagerControllerAdapter adapter) {
        mAdapter = adapter;
        if (mAdapter == null) {
            currentPage(INVALID_PAGE, false);
        } else {
            mAdapter.registerObserver(mObserver);
        }
        return this;
    }

    private void currentPage(int position, boolean fromUser) {
        currentPage(position, false, fromUser);
    }

    public void currentPage(int position, boolean force, boolean fromUser) {
        if (!force && mCurrentItem == position) {
            return;
        }

        if (mAdapter != null && mAdapter.getCount() > 0) {
            if (position < 0) {
                position = 0;
            }
            if (position >= mAdapter.getCount() - 1) {
                position = mAdapter.getCount() - 1;
            }

            mModel.prev = position <= 0 ? null : mAdapter.getPageTitle(position - 1);
            mModel.next = position >= mAdapter.getCount() - 1 ? null : mAdapter.getPageTitle(position + 1);
            mBinding.setModel(mModel);
            pageSelected(position, fromUser);
        } else {
            mModel.prev = null;
            mModel.next = null;
            mBinding.setModel(mModel);
        }
    }

    private void pageSelected(int position, boolean fromUser) {
        if (mOnPageSelectionListener != null) {
            mOnPageSelectionListener.onPageSelected(position, fromUser);
        }

        FragmentTransaction tx = mAdapter.getFragmentManager().beginTransaction().setReorderingAllowed(false);
        Fragment oldFragment = mAdapter.getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        if (oldFragment != null) {
            tx.remove(oldFragment);
        }
        if (position != INVALID_PAGE) {
            tx.replace(mAdapter.getTarget(), mAdapter.getFragment(position), FRAGMENT_TAG);
        }
        tx.commit();
        mCurrentItem = position;
    }

    private void performMovePrev() {
        currentPage(mCurrentItem - 1, true);
    }

    private void performMoveNext() {
        currentPage(mCurrentItem + 1, true);
    }
}