de.aw.monma.views.SpinnerAccount.java Source code

Java tutorial

Introduction

Here is the source code for de.aw.monma.views.SpinnerAccount.java

Source

/*
 * MonMa: Eine freie Android-Application fuer die Verwaltung privater Finanzen
 *
 * Copyright [2015] [Alexander Winkler, 2373 Dahme/Germany]
 *
 * This program 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.
 *
 * This program 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 this program; if
 * not, see <http://www.gnu.org/licenses/>.
 */
package de.aw.monma.views;

import android.content.Context;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.databinding.BindingAdapter;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;

import de.aw.awlib.application.AWApplication;
import de.aw.monma.R;
import de.aw.monma.database.DBDefinition;
import de.aw.monma.database.TableColums;
import de.aw.monma.enums.Kontotyp;

/**
 * Spinner fuer die Auswahl von Konten. Es kann gesteuert werden, ob nur nicht-ausgeblendete Konten
 * (Default) oder die gesamte Kontolist gezeigt wird. Welche Konten gezeigt werden, kann wie folgt
 * gesteuert werden: Ueber {@link de.aw.monma.views.SpinnerAccount#setModus(Modus)} kann der Modus
 * gesetzt werden. Alternativ kann auch ueber xml der Modus gesetzt werden. Folgende Varioanten sind
 * moeglich: app:modus="cash"  - entspricht {@link de.aw.monma.views.SpinnerAccount.Modus#Cash}
 * app:modus="verrechnung"  - entspricht {@link de.aw.monma.views.SpinnerAccount.Modus#Verrechnung}
 * app:modus="offline"  - entspricht {@link de.aw.monma.views.SpinnerAccount.Modus#Offline}
 */
public class SpinnerAccount extends android.support.v7.widget.AppCompatSpinner
        implements LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemSelectedListener, TableColums {
    protected static final DBDefinition tbd = DBDefinition.Account;
    protected String[] projection;
    protected String selectionNotAusgeblendet;
    protected boolean showOnlyAusgeblendet = true;
    protected String userOrderBy;
    protected String userSelection;
    protected String[] userSelectionArgs;
    private boolean showSelectedItem = false;
    private SimpleCursorAdapter adapter;
    private LoaderManager mLoaderManager;
    private Modus mModus;
    private OnItemSelectionListener mOnItemSelectedListener;
    private Integer selectedAccountID;

    public SpinnerAccount(Context context) {
        this(context, Spinner.MODE_DROPDOWN);
    }

    public SpinnerAccount(Context context, int mode) {
        super(context, mode);
        init(context, null);
    }

    public SpinnerAccount(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public SpinnerAccount(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, Spinner.MODE_DROPDOWN);
        init(context, attrs);
    }

    public SpinnerAccount(Context context, AttributeSet attrs, int defStyleAttr, int mode) {
        super(context, attrs, defStyleAttr, mode);
        init(context, attrs);
    }

    @BindingAdapter({ "onItemSelected" })
    public static void onItemSelected(SpinnerAccount view, OnItemSelectionListener listener) {
        view.setOnItemSelectedListener(listener);
    }

    @BindingAdapter({ "value" })
    public static void setValue(SpinnerAccount view, int accountID) {
        view.setSelectedAccountID(accountID);
    }

    private Integer getPosition(int accountID, Cursor cursor) {
        Integer position = null;
        if (cursor.moveToFirst()) {
            int i = 0;
            do {
                int mID = cursor.getInt(0);
                if (mID == accountID) {
                    position = i;
                    break;
                }
                i++;
            } while (cursor.moveToNext());
        }
        return position;
    }

    private void init(Context context, AttributeSet attrs) {
        if (!isInEditMode()) {
            mLoaderManager = ((AppCompatActivity) context).getSupportLoaderManager();
            projection = new String[] { _id, column_accountname };
            selectionNotAusgeblendet = " NOT " + column_ausgeblendet;
            if (mModus == null) {
                TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpinnerAccount);
                try {
                    int modus = a.getInteger(R.styleable.SpinnerAccount_modus, Modus.Cash.ordinal());
                    mModus = Modus.values()[modus];
                } finally {
                    a.recycle();
                }
            }
            int[] adapterRowViews = new int[] { android.R.id.text1 };
            String[] adapterCols = new String[] { column_accountname };
            adapter = new SimpleCursorAdapter(getContext(), android.R.layout.simple_spinner_item, null, adapterCols,
                    adapterRowViews, 0);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            setAdapter(adapter);
            super.setOnItemSelectedListener(this);
            if (getVisibility() == VISIBLE) {
                startOrRestartLoader(getId());
            }
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        String selection = userSelection;
        if (showOnlyAusgeblendet) {
            if (selection != null) {
                selection = "(" + selection + ") AND " + selectionNotAusgeblendet;
            } else {
                selection = selectionNotAusgeblendet;
            }
        }
        switch (mModus) {
        case Offline:
            selection += " AND " + column_accounttyp + " != '" + Kontotyp.Port.name() + "'";
            break;
        case Cash:
        case Verrechnung:
            selection += " AND " + column_accounttyp + " != '" + Kontotyp.Port.name() + "'";
            break;
        }
        return new CursorLoader(getContext(), tbd.getUri(), projection, selection, userSelectionArgs, userOrderBy);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        selectedAccountID = ((Long) id).intValue();
        if (mOnItemSelectedListener != null) {
            mOnItemSelectedListener.onItemSelected(this, position, selectedAccountID);
        }
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (adapter != null) {
            adapter.swapCursor(data);
            if (selectedAccountID != null) {
                Integer position = getPosition(selectedAccountID, data);
                if (position != null) {
                    setSelection(position);
                }
            }
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        if (adapter != null) {
            adapter.swapCursor(null);
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    /**
     * Initializer fur Konten gemaess {@link de.aw.monma.views.SpinnerAccount.Modus}
     *
     * @param modus
     *         Modus
     */
    public void setModus(Modus modus) {
        mModus = modus;
        startOrRestartLoader(getId());
    }

    public void setOnItemSelectedListener(OnItemSelectionListener listener) {
        mOnItemSelectedListener = listener;
    }

    public void setSelectedAccountID(Integer accountID) {
        selectedAccountID = accountID;
        setSelection(accountID);
    }

    private void startOrRestartLoader(int loaderID) {
        AWApplication.Log("SpinnerAccount: Loading Cursor");
        if (mLoaderManager != null) {
            Loader<Cursor> loader = mLoaderManager.getLoader(loaderID);
            if (loader != null && !loader.isReset()) {
                mLoaderManager.initLoader(loaderID, null, this);
            } else {
                mLoaderManager.restartLoader(loaderID, null, this);
            }
        }
    }

    /**
     * Modus des Spinner.
     */
    public enum Modus {
        /**
        * Zeigt nur Cashkonten. xml: app:modus="cash"
        */
        Cash
        /**
         * Zeigt nur moegliche Gegenkonten fuer Depots. xml: app:modus="verrechnung"
         */
        , Verrechnung
        /**
         * Zeigt nur Offline-CashKonten. xml: app:modus="offline"
         */
        ,Offline,
    }

    public interface OnItemSelectionListener {
        void onItemSelected(SpinnerAccount view, int position, int accountID);
    }
}