at.florian_lentsch.expirysync.ProductAdapter.java Source code

Java tutorial

Introduction

Here is the source code for at.florian_lentsch.expirysync.ProductAdapter.java

Source

/*
* This file is part of ExpirySync.
*
* ExpirySync 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.
    
* ExpirySync 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 ExpirySync.  If not, see <http://www.gnu.org/licenses/>
*/

package at.florian_lentsch.expirysync;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.joda.time.DateTime;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;

import at.florian_lentsch.expirysync.model.ProductEntry;

/**
 * List adapter for product entry lists
 * 
 * @author Florian Lentsch <office@florian-lentsch.at>
 * 
 */
public class ProductAdapter extends ArrayAdapter<ProductEntry> implements Filterable {
    /**
     * entries that are in the list (and thus can be filtered or sorted)
     */
    private ArrayList<ProductEntry> allEntries;

    /**
     * listener for changes to an item's checked state
     */
    private ProductListActivity.ListItemCheckedChange checkedChangeListener;

    /**
     * 
     * @param context
     * @param itemTemplateId
     *            id of a list item's template
     * @param productEntries
     *            the product entries to be displayed in the list
     * @param checkedChange
     *            listener for changes to an item's checked state
     */
    public ProductAdapter(Context context, int itemTemplateId, List<ProductEntry> productEntries,
            ProductListActivity.ListItemCheckedChange checkedChange) {
        super(context, itemTemplateId, productEntries);
        this.checkedChangeListener = checkedChange;

        this.setAllEntries(productEntries);
    }

    /**
     * sets the list entries
     * 
     * @param productEntries
     */
    protected void setAllEntries(List<ProductEntry> productEntries) {
        // Need to clone this list, since filtering will kick entries out of
        // this.objects:
        this.allEntries = new ArrayList<ProductEntry>(productEntries);
    }

    @Override
    @SuppressLint("InflateParams")
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (view == null) {
            LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = vi.inflate(R.layout.product_list_item, null);
        }

        final ProductEntry productEntry = getItem(position);
        if (productEntry == null) {
            return view;
        }

        // set the product entry's contents:
        TextView nameTxt = (TextView) view.findViewById(R.id.product_list_item_name);
        nameTxt.setText(productEntry.amount + "x " + productEntry.article.name);

        if (productEntry.expiration_date != null) {
            displayExpirationDate(productEntry, view);
        }

        // set the checkbox listener:
        CheckBox chkbx = (CheckBox) view.findViewById(R.id.product_list_item_checkbox);
        chkbx.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                ProductAdapter.this.checkedChangeListener.checkedChange(productEntry, position, isChecked);
            }
        });

        return view;
    }

    /**
     * Displays the expiration date according to the thresholds found in the
     * shared preferences
     * 
     * @param productEntry
     *            product entry to display the expiration date for
     * @param view
     *            list item view
     */
    private void displayExpirationDate(ProductEntry productEntry, View view) {
        TextView expirationDateTxt = (TextView) view.findViewById(R.id.product_list_item_expiration_date);
        final Resources res = getContext().getResources();

        // coloring:
        final SharedPreferences sharedPref = getContext().getSharedPreferences("main", Context.MODE_PRIVATE);
        int daysBeforeMedium = sharedPref.getInt(SettingsActivity.KEY_DAYS_BEFORE_MEDIUM, 0);
        int daysBeforeBad = sharedPref.getInt(SettingsActivity.KEY_DAYS_BEFORE_BAD, 0);

        expirationDateTxt.setTextColor(res.getColor(R.color.expiration_date_good));

        if ((new DateTime(productEntry.expiration_date)).minusDays(daysBeforeMedium).isBeforeNow()) {
            expirationDateTxt.setTextColor(res.getColor(R.color.expiration_date_medium));
        }

        if ((new DateTime(productEntry.expiration_date)).minusDays(daysBeforeBad).isBeforeNow()) {
            expirationDateTxt.setTextColor(res.getColor(R.color.expiration_date_bad));
        }

        // set the date (formatted for the current locale):
        java.text.DateFormat formatter = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT,
                Locale.getDefault());
        String localPattern = ((SimpleDateFormat) formatter).toLocalizedPattern();
        SimpleDateFormat df = new SimpleDateFormat(localPattern);
        expirationDateTxt
                .setText(res.getText(R.string.expiration_date) + ": " + df.format(productEntry.expiration_date));
    }

    /**
     * (non-Javadoc) 
     * filters by name and barcode
     */
    @Override
    public Filter getFilter() {

        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                final String searchStr = constraint.toString().toLowerCase();

                FilterResults results = new FilterResults();
                ArrayList<ProductEntry> filteredEntries = new ArrayList<ProductEntry>();

                for (int i = 0; i < ProductAdapter.this.allEntries.size(); i++) {
                    ProductEntry entry = ProductAdapter.this.allEntries.get(i);

                    // add entries to filter result, where name or barcode
                    // matches the search text (case-insensitive):
                    if (entry.article.name.toLowerCase().contains(searchStr) || (entry.article.barcode != null
                            && entry.article.barcode.toLowerCase().contains(searchStr))) {
                        filteredEntries.add(entry);
                    }
                }

                results.count = filteredEntries.size();
                results.values = filteredEntries;

                return results;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                notifyDataSetChanged();

                // Clear the list of items...:
                clear();

                // ... then add the items matching the filter back in:
                for (Iterator<ProductEntry> iterator = ((ArrayList<ProductEntry>) results.values)
                        .iterator(); iterator.hasNext();) {
                    ProductEntry entry = (ProductEntry) iterator.next();
                    add(entry);
                }
            }
        };

        return filter;
    }
}