Android Open Source - RecipeBook Recipe Detail Instruction Fragment






From Project

Back to project page RecipeBook.

License

The source code is released under:

Copyright (c) 2013, Ian Lake All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Red...

If you think the Android project RecipeBook listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.ianhanniballake.recipebook.ui;
//from  w w w .j a  v  a  2  s.  c om
import java.util.ArrayList;
import java.util.List;

import android.app.ListFragment;
import android.app.LoaderManager;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;

import com.ianhanniballake.recipebook.R;
import com.ianhanniballake.recipebook.model.Instruction;
import com.ianhanniballake.recipebook.provider.RecipeContract;

/**
 * Fragment which displays the list of instructions for a given recipe
 */
public class RecipeDetailInstructionFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>
{
  /**
   * Manages the list of instructions as an Array backed list
   */
  public class InstructionArrayAdapter extends ArrayAdapter<Instruction>
  {
    private final int textViewResourceId;

    /**
     * Constructor
     * 
     * @param context
     *            The current context.
     * @param resource
     *            The resource ID for a layout file containing a layout to use when instantiating views.
     * @param textViewResourceId
     *            The id of the TextView within the layout resource to be populated
     */
    public InstructionArrayAdapter(final Context context, final int resource, final int textViewResourceId)
    {
      super(context, resource, textViewResourceId);
      this.textViewResourceId = textViewResourceId;
    }

    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent)
    {
      // Need to ensure the correct position is set before super.getView sets the text
      if (convertView != null)
        convertView.setTag(position);
      final View view = super.getView(position, convertView, parent);
      final String action = getActivity().getIntent().getAction();
      final boolean isEdit = Intent.ACTION_INSERT.equals(action) || Intent.ACTION_EDIT.equals(action);
      if (isEdit)
      {
        final EditText editText = (EditText) view.findViewById(textViewResourceId);
        editText.addTextChangedListener(new TextWatcher()
        {
          @Override
          public void afterTextChanged(final Editable s)
          {
            // Nothing to do
          }

          @Override
          public void beforeTextChanged(final CharSequence s, final int start, final int count,
              final int after)
          {
            // Nothing to do
          }

          @Override
          public void onTextChanged(final CharSequence s, final int start, final int before, final int count)
          {
            final int savedPosition = view.getTag() == null ? position : (Integer) view.getTag();
            getItem(savedPosition).setInstruction(s.toString());
          }
        });
        final ImageButton deleteInstruction = (ImageButton) view.findViewById(R.id.delete_instruction);
        deleteInstruction.setOnClickListener(new OnClickListener()
        {
          @Override
          public void onClick(final View v)
          {
            final int savedPosition = view.getTag() == null ? position : (Integer) view.getTag();
            remove(getItem(savedPosition));
          }
        });
      }
      return view;
    }
  }

  /**
   * Adapter to display the list's data
   */
  private InstructionArrayAdapter adapter;
  /**
   * Current list of instructions
   */
  List<Instruction> instructions = new ArrayList<Instruction>();

  /**
   * Gets a ContentValues object for each instruction
   * 
   * @return ContentValues for each instruction
   */
  public ContentValues[] getContentValuesArray()
  {
    final long recipeId = ContentUris.parseId(getActivity().getIntent().getData());
    final int instructionCount = adapter.getCount();
    final List<ContentValues> instructionContentValuesList = new ArrayList<ContentValues>();
    for (int position = 0; position < instructionCount; position++)
    {
      final Instruction instruction = adapter.getItem(position);
      if (!instruction.toString().isEmpty())
        instructionContentValuesList.add(instruction.toContentValues(recipeId));
    }
    final ContentValues[] instructionContentValuesArray = new ContentValues[instructionContentValuesList.size()];
    return instructionContentValuesList.toArray(instructionContentValuesArray);
  }

  @Override
  public void onActivityCreated(final Bundle savedInstanceState)
  {
    super.onActivityCreated(savedInstanceState);
    final String action = getActivity().getIntent().getAction();
    final boolean isEdit = Intent.ACTION_INSERT.equals(action) || Intent.ACTION_EDIT.equals(action);
    final int layoutId = isEdit ? R.layout.list_item_instruction_edit : R.layout.list_item_instruction;
    setHasOptionsMenu(isEdit);
    adapter = new InstructionArrayAdapter(getActivity(), layoutId, R.id.instruction);
    setListAdapter(adapter);
    getListView().setChoiceMode(AbsListView.CHOICE_MODE_NONE);
    if (savedInstanceState != null)
    {
      // No longer need the loader as we have valid local copies (which may have changes) from now on
      getLoaderManager().destroyLoader(0);
      final List<String> instructionList = savedInstanceState
          .getStringArrayList(RecipeContract.Instructions.COLUMN_NAME_INSTRUCTION);
      for (final String instruction : instructionList)
        instructions.add(new Instruction(instruction));
      updateViews();
    }
    else if (!Intent.ACTION_INSERT.equals(getActivity().getIntent().getAction()))
      getLoaderManager().initLoader(0, null, this);
    else
      updateViews();
  }

  @Override
  public Loader<Cursor> onCreateLoader(final int id, final Bundle args)
  {
    final long recipeId = ContentUris.parseId(getActivity().getIntent().getData());
    return new CursorLoader(getActivity(), RecipeContract.Instructions.CONTENT_URI, null,
        RecipeContract.Instructions.COLUMN_NAME_RECIPE_ID + "=?", new String[] { Long.toString(recipeId) },
        null);
  }

  @Override
  public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater)
  {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.instruction_edit, menu);
  }

  @Override
  public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
  {
    return inflater.inflate(R.layout.fragment_instruction_detail, container, false);
  }

  @Override
  public void onLoaderReset(final Loader<Cursor> loader)
  {
    adapter.clear();
    updateViews();
  }

  @Override
  public void onLoadFinished(final Loader<Cursor> loader, final Cursor data)
  {
    final int instructionColumnIndex = data.getColumnIndex(RecipeContract.Instructions.COLUMN_NAME_INSTRUCTION);
    instructions.clear();
    data.moveToPosition(-1);
    while (data.moveToNext())
      instructions.add(new Instruction(data.getString(instructionColumnIndex)));
    updateViews();
  }

  @Override
  public boolean onOptionsItemSelected(final MenuItem item)
  {
    switch (item.getItemId())
    {
      case R.id.add_instruction:
        final Instruction newInstruction = new Instruction("");
        instructions.add(newInstruction);
        adapter.add(newInstruction);
        getListView().setSelection(adapter.getPosition(newInstruction));
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  @Override
  public void onSaveInstanceState(final Bundle outState)
  {
    super.onSaveInstanceState(outState);
    final int instructionCount = adapter.getCount();
    final ArrayList<String> instructionList = new ArrayList<String>();
    for (int position = 0; position < instructionCount; position++)
    {
      final String rawInstruction = adapter.getItem(position).toString();
      if (!rawInstruction.isEmpty())
        instructionList.add(rawInstruction);
    }
    outState.putStringArrayList(RecipeContract.Instructions.COLUMN_NAME_INSTRUCTION, instructionList);
  }

  private void updateViews()
  {
    adapter.setNotifyOnChange(false);
    adapter.clear();
    adapter.addAll(instructions);
    adapter.notifyDataSetChanged();
  }
}




Java Source Code List

com.ianhanniballake.recipebook.auth.AuthorizedActivity.java
com.ianhanniballake.recipebook.auth.SyncDriveAsyncTask.java
com.ianhanniballake.recipebook.model.Ingredient.java
com.ianhanniballake.recipebook.model.Instruction.java
com.ianhanniballake.recipebook.model.Recipe.java
com.ianhanniballake.recipebook.provider.RecipeContract.java
com.ianhanniballake.recipebook.provider.RecipeProvider.java
com.ianhanniballake.recipebook.sync.SyncAdapter.java
com.ianhanniballake.recipebook.sync.SyncService.java
com.ianhanniballake.recipebook.ui.RecipeDetailActivity.java
com.ianhanniballake.recipebook.ui.RecipeDetailIngredientFragment.java
com.ianhanniballake.recipebook.ui.RecipeDetailInstructionFragment.java
com.ianhanniballake.recipebook.ui.RecipeDetailSummaryFragment.java
com.ianhanniballake.recipebook.ui.RecipeEditActivity.java
com.ianhanniballake.recipebook.ui.RecipeListActivity.java