com.agateau.equiv.ui.MealItemDetailActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.agateau.equiv.ui.MealItemDetailActivity.java

Source

/*
Copyright 2015 Aurlien Gteau
    
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.agateau.equiv.ui;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.agateau.equiv.R;
import com.agateau.equiv.core.Constants;
import com.agateau.equiv.core.FormatUtils;
import com.agateau.equiv.core.Meal;
import com.agateau.equiv.core.MealItem;
import com.agateau.equiv.core.Product;
import com.agateau.equiv.core.ProductStore;
import com.agateau.equiv.core.ProteinWeightUnit;
import com.agateau.utils.ui.ActionBarViewTabBuilder;

import java.util.Locale;
import java.util.UUID;

public class MealItemDetailActivity extends AppCompatActivity {
    public static final String EXTRA_MEAL_TAG = "com.agateau.equiv.MEAL_TAG";
    public static final String EXTRA_MEAL_ITEM_POSITION = "com.agateau.equiv.MEAL_ITEM_POSITION";

    private static final int NEW_MEAL_ITEM_POSITION = -1;

    private Kernel mKernel;

    private ProductStore mProductStore;
    private ProductListAdapter mFullListAdapter;
    private ProductListAdapter mFavoritesListAdapter;
    private Meal mMeal;
    private Product mProduct = null;
    private MenuItem mSaveMenuItem;
    private int mMealItemPosition = NEW_MEAL_ITEM_POSITION;
    private TextView mProductNameView;
    private LinearLayout mDetailsLayout;
    private EditText mQuantityEdit;
    private TextView mQuantityUnitView;
    private EditText mQuantityEquivEdit;
    private TextView mQuantityEquivUnitView;
    private boolean mUpdating = false;

    public static void addMealItem(Context context, Meal meal) {
        Intent intent = new Intent(context, MealItemDetailActivity.class);
        intent.putExtra(EXTRA_MEAL_TAG, meal.getTag());
        context.startActivity(intent);
    }

    public static void editMealItem(Context context, Meal meal, int position) {
        Intent intent = new Intent(context, MealItemDetailActivity.class);
        intent.putExtra(EXTRA_MEAL_TAG, meal.getTag());
        intent.putExtra(EXTRA_MEAL_ITEM_POSITION, position);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.meal_item_detail_activity);

        mKernel = Kernel.getInstance(this);
        mProductStore = mKernel.getProductStore();

        String mealTag = null;
        if (savedInstanceState != null) {
            mealTag = savedInstanceState.getString("meal");
        }
        if (TextUtils.isEmpty(mealTag)) {
            mealTag = getIntent().getStringExtra(EXTRA_MEAL_TAG);
        }
        if (!TextUtils.isEmpty(mealTag)) {
            mMeal = mKernel.getDay().getMealByTag(mealTag);
            mMealItemPosition = getIntent().getIntExtra(EXTRA_MEAL_ITEM_POSITION, -1);

            setupTabs();
            setupMealEditor();
        }
    }

    private void setupTabs() {
        ListView fullListView = new ListView(this);
        ListView favoriteListView = new ListView(this);

        mFullListAdapter = new ProductListAdapter(this, mKernel, mProductStore.getItems());
        mFavoritesListAdapter = new ProductListAdapter(this, mKernel, mProductStore.getFavoriteItems());
        mProductStore.setOnProductStoreChangedListener(new ProductStore.OnProductStoreChangedListener() {
            @Override
            public void onFavoriteChanged() {
                mFavoritesListAdapter.notifyDataSetChanged();

                // Notify mFullListAdapter as well because it must update the state of its checkboxes
                mFullListAdapter.notifyDataSetChanged();
            }

            @Override
            public void onItemListChanged() {
                mFullListAdapter.notifyDataSetChanged();
            }
        });

        fullListView.setAdapter(mFullListAdapter);
        favoriteListView.setAdapter(mFavoritesListAdapter);

        AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Product product = (Product) parent.getAdapter().getItem(position);
                onSelectProduct(product);
            }
        };
        fullListView.setOnItemClickListener(listener);
        favoriteListView.setOnItemClickListener(listener);

        AdapterView.OnItemLongClickListener longClickListener = new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                Product product = (Product) parent.getItemAtPosition(position);
                editCustomProduct(product);
                return true;
            }
        };

        fullListView.setLongClickable(true);
        favoriteListView.setLongClickable(true);

        fullListView.setOnItemLongClickListener(longClickListener);
        favoriteListView.setOnItemLongClickListener(longClickListener);

        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        ActionBarViewTabBuilder builder = new ActionBarViewTabBuilder(actionBar, viewPager);
        builder.addTab(fullListView).setText(R.string.add_meal_item_tab_all);
        builder.addTab(favoriteListView).setText(R.string.add_meal_item_tab_favorites);
    }

    private void setupMealEditor() {
        TextView.OnEditorActionListener onEditorActionListener = new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    save();
                    return true;
                }
                return false;
            }
        };
        mProductNameView = (TextView) findViewById(R.id.product_name_view);
        mDetailsLayout = (LinearLayout) findViewById(R.id.details_layout);
        mQuantityEdit = (EditText) findViewById(R.id.quantity_edit);
        mQuantityEdit.setOnEditorActionListener(onEditorActionListener);
        mQuantityEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                updateQuantityEquivEdit();
            }
        });

        mQuantityUnitView = (TextView) findViewById(R.id.quantity_unit);

        mQuantityEquivEdit = (EditText) findViewById(R.id.quantity_equiv_edit);
        mQuantityEquivEdit.setOnEditorActionListener(onEditorActionListener);
        mQuantityEquivEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                updateQuantityEdit();
            }
        });

        mQuantityEquivUnitView = (TextView) findViewById(R.id.quantity_equiv_unit);

        if (mMealItemPosition != NEW_MEAL_ITEM_POSITION) {
            setTitle(R.string.edit_meal_item_title);
            initFromMealItem(mMeal.getItems().get(mMealItemPosition));
        }
    }

    @Override
    public void onRestoreInstanceState(@NonNull Bundle bundle) {
        super.onRestoreInstanceState(bundle);
        String productUuid = bundle.getString("productUuid", "");
        if (!TextUtils.equals(productUuid, "")) {
            Product product = mProductStore.findByUuid(UUID.fromString(productUuid));
            onSelectProduct(product);
            mQuantityEquivEdit.setText(bundle.getString("quantityEquiv"));
        }
    }

    @Override
    public void onSaveInstanceState(Bundle bundle) {
        bundle.putString("meal", mMeal.getTag());
        if (mProduct != null) {
            bundle.putString("productUuid", mProduct.getUuid().toString());
            bundle.putString("quantityEquiv", mQuantityEquivEdit.getText().toString());
        }
        mKernel.writeFavorites(this);
        super.onSaveInstanceState(bundle);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.meal_item_detail_activity_actions, menu);
        if (mMealItemPosition == NEW_MEAL_ITEM_POSITION) {
            MenuItem removeMenuItem = menu.findItem(R.id.action_remove);
            removeMenuItem.setVisible(false);
        }
        mSaveMenuItem = menu.findItem(R.id.action_save);

        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                mFullListAdapter.getFilter().filter(newText);
                mFavoritesListAdapter.getFilter().filter(newText);
                return false;
            }
        });

        updateMenuItems();
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_save) {
            save();
            return true;
        } else if (id == R.id.action_remove) {
            remove();
            return true;
        } else if (id == R.id.action_search) {
            onSearchRequested();
            return true;
        } else if (id == R.id.action_add_custom) {
            addCustomProduct();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void initFromMealItem(MealItem mealItem) {
        mProduct = mealItem.getProduct();
        updateDetailsLayout();
        mQuantityEdit.setText(String.valueOf(mealItem.getQuantity()));
    }

    private void onSelectProduct(Product product) {
        mProduct = product;
        updateDetailsLayout();
        updateMenuItems();
    }

    private void editCustomProduct(final Product product) {
        if (product.hasDefaultDetails() && !product.hasCustomDetails()) {
            // About to edit a default product for the first time, warn the user
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(getString(R.string.dialog_edit_default_product))
                    .setPositiveButton(R.string.dialog_continue, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            doEditCustomProduct(product);
                        }
                    }).setNegativeButton(android.R.string.cancel, null).setCancelable(true).show();
        } else {
            doEditCustomProduct(product);
        }
    }

    private void doEditCustomProduct(Product product) {
        CustomProductActivity.startActivityWithProduct(this, product);
    }

    private void addCustomProduct() {
        CustomProductActivity.startActivity(this);
    }

    private void save() {
        float quantity = Float.valueOf(mQuantityEdit.getText().toString());
        MealItem item = new MealItem(mProduct, quantity);
        if (mMealItemPosition == -1) {
            mMeal.add(item);
        } else {
            mMeal.set(mMealItemPosition, item);
        }

        NavUtils.navigateUpFromSameTask(this);
    }

    private void remove() {
        mMeal.remove(mMealItemPosition);
        NavUtils.navigateUpFromSameTask(this);
    }

    private void updateMenuItems() {
        if (mSaveMenuItem == null) {
            return;
        }
        mSaveMenuItem.setEnabled(mProduct != null && !TextUtils.isEmpty(mQuantityEdit.getText()));
    }

    private float getEquivRatio() {
        if (mKernel.getProteinUnit() == ProteinWeightUnit.POTATO) {
            return mProduct.getProteins() / Constants.PROTEIN_FOR_POTATO;
        } else {
            return mProduct.getProteins();
        }
    }

    private void updateQuantityEquivEdit() {
        if (mProduct == null) {
            return;
        }
        updateQuantityEdits(mQuantityEdit, mQuantityEquivEdit, getEquivRatio());
    }

    private void updateQuantityEdit() {
        if (mProduct == null) {
            return;
        }
        updateQuantityEdits(mQuantityEquivEdit, mQuantityEdit, 1 / getEquivRatio());
    }

    private void updateQuantityEdits(TextView from, TextView to, float ratio) {
        if (mUpdating) {
            return;
        }
        mUpdating = true;
        try {
            float quantity;
            try {
                quantity = Float.valueOf(from.getText().toString());
            } catch (NumberFormatException e) {
                to.setText("");
                return;
            }
            String txt = FormatUtils.naturalRound(Locale.ENGLISH, quantity * ratio);
            to.setText(txt);
        } finally {
            updateMenuItems();
            mUpdating = false;
        }
    }

    private void updateDetailsLayout() {
        mDetailsLayout.setVisibility(View.VISIBLE);
        mProductNameView.setText(mProduct.getName());

        mQuantityEdit.setText("");
        String unit = mProduct.getUnit().toString();
        mQuantityUnitView.setText(unit);

        unit = mKernel.getWeightFormatter().getUnitString(WeightFormatter.UnitFormat.FULL);
        mQuantityEquivUnitView.setText(unit);
    }
}