Android Open Source - GuiLib Open Array Adapter






From Project

Back to project page GuiLib.

License

The source code is released under:

Apache License

If you think the Android project GuiLib 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.gandulf.guilib.data;
//  w  ww. j a va2s .  c om
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Filterable;
import android.widget.TextView;

import com.gandulf.guilib.util.Debug;
import com.nhaarman.listviewanimations.util.Swappable;

/**
 * A ListAdapter that manages a ListView backed by an array of arbitrary objects. By default this class expects that the
 * provided resource id references a single TextView. If you want to use a more complex layout, use the constructors
 * that also takes a field id. That field id should reference a TextView in the larger layout resource.
 * 
 * However the TextView is referenced, it will be filled with the toString() of each object in the array. You can add
 * lists or arrays of custom objects. Override the toString() method of your objects to determine what text will be
 * displayed for the item in the list.
 * 
 * To use something other than TextViews for the array display, for instance, ImageViews, or to have some of data
 * besides toString() results fill the views, override {@link #getView(int, View, ViewGroup)} to return the type of view
 * you want.
 */
public class OpenArrayAdapter<T> extends BaseAdapter implements Filterable, Swappable {
  /**
   * Contains the list of objects that represent the data of this ArrayAdapter. The content of this list is referred
   * to as "the array" in the documentation.
   */
  protected List<T> mObjects;

  /**
   * Lock used to modify the content of {@link #mObjects}. Any write operation performed on the array should be
   * synchronized on this lock. This lock is also used by the filter (see {@link #getFilter()} to make a synchronized
   * copy of the original array of data.
   */
  final Object mLock = new Object();

  /**
   * The resource indicating what views to inflate to display the content of this array adapter.
   */
  protected int mResource;

  /**
   * The resource indicating what views to inflate to display the content of this array adapter in a drop down widget.
   */
  protected int mDropDownResource;

  /**
   * If the inflated resource is not a TextView, {@link #mFieldId} is used to find a TextView inside the inflated
   * views hierarchy. This field must contain the identifier that matches the one defined in the resource file.
   */
  private int mFieldId = 0;

  /**
   * Indicates whether or not {@link #notifyDataSetChanged()} must be called whenever {@link #mObjects} is modified.
   */
  private boolean mNotifyOnChange = true;

  private Context mContext;

  protected List<T> mOriginalValues;

  private OpenFilter<T> mFilter;

  protected LayoutInflater mInflater;

  /**
   * Constructor
   * 
   * @param context
   *            The current context.
   * @param textViewResourceId
   *            The resource ID for a layout file containing a TextView to use when instantiating views.
   */
  public OpenArrayAdapter(Context context, int textViewResourceId) {
    init(context, textViewResourceId, 0, new ArrayList<T>());
  }

  /**
   * 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 OpenArrayAdapter(Context context, int resource, int textViewResourceId) {
    init(context, resource, textViewResourceId, new ArrayList<T>());
  }

  /**
   * Constructor
   * 
   * @param context
   *            The current context.
   * @param textViewResourceId
   *            The resource ID for a layout file containing a TextView to use when instantiating views.
   * @param objects
   *            The objects to represent in the ListView.
   */
  public OpenArrayAdapter(Context context, int textViewResourceId, T[] objects) {
    init(context, textViewResourceId, 0, Arrays.asList(objects));
  }

  /**
   * 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
   * @param objects
   *            The objects to represent in the ListView.
   */
  public OpenArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects) {
    init(context, resource, textViewResourceId, Arrays.asList(objects));
  }

  /**
   * Constructor
   * 
   * @param context
   *            The current context.
   * @param textViewResourceId
   *            The resource ID for a layout file containing a TextView to use when instantiating views.
   * @param objects
   *            The objects to represent in the ListView.
   */
  public OpenArrayAdapter(Context context, int textViewResourceId, Collection<T> objects) {
    init(context, textViewResourceId, 0, new ArrayList<T>(objects));
  }

  /**
   * 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
   * @param objects
   *            The objects to represent in the ListView.
   */
  public OpenArrayAdapter(Context context, int resource, int textViewResourceId, Collection<T> objects) {
    init(context, resource, textViewResourceId, new ArrayList<T>(objects));
  }

  public void addAll(Collection<? extends T> objects) {
    if (objects == null || objects.isEmpty())
      return;

    boolean notify = mNotifyOnChange;

    setNotifyOnChange(false);

    if (mOriginalValues != null) {
      for (T object : objects) {
        add(object);
      }
    } else {
      mObjects.addAll(objects);
    }

    if (notify) {
      notifyDataSetChanged();
    }
  }

  /**
   * Adds the specified object at the end of the array.
   * 
   * @param object
   *            The object to add at the end of the array.
   */
  public void add(T object) {
    if (mOriginalValues != null) {

      synchronized (mLock) {
        mOriginalValues.add(object);

        // add object to current filtered objects too if it passes the filter
        if (mOriginalValues != mObjects && getFilter().filter(object))
          mObjects.add(object);

        if (mNotifyOnChange)
          notifyDataSetChanged();
      }

    } else {
      mObjects.add(object);
      if (mNotifyOnChange)
        notifyDataSetChanged();
    }
  }

  /**
   * Inserts the specified object at the specified index in the array.
   * 
   * @param object
   *            The object to insert into the array.
   * @param index
   *            The index at which the object must be inserted.
   */
  public void insert(T object, int index) {
    if (mOriginalValues != null) {
      synchronized (mLock) {
        mOriginalValues.add(index, object);

        // add object to current filtered objects too if it passes the
        // filter, index has to be ignored since it's different,
        // TODO find better solution for filter
        if (mOriginalValues != mObjects && getFilter().filter(object))
          mObjects.add(object);

        if (mNotifyOnChange)
          notifyDataSetChanged();
      }
    } else {
      mObjects.add(index, object);
      if (mNotifyOnChange)
        notifyDataSetChanged();
    }
  }

  /**
   * Removes the element at the specified position in the list
   */
  public T remove(int position) {
    T result = null;
    if (mOriginalValues != null) {
      synchronized (mLock) {
        result = mOriginalValues.remove(position);
        mObjects.remove(result);
      }
    } else {
      result = mObjects.remove(position);
    }
    if (result != null && mNotifyOnChange)
      notifyDataSetChanged();

    return result;
  }

  /**
   * Removes the specified object from the array.
   * 
   * @param object
   *            The object to remove.
   */
  public boolean remove(T object) {
    boolean result;
    if (mOriginalValues != null) {
      synchronized (mLock) {
        result = mOriginalValues.remove(object);
        mObjects.remove(object);
      }
    } else {
      result = mObjects.remove(object);
    }
    if (result && mNotifyOnChange)
      notifyDataSetChanged();

    return result;
  }

  /**
   * Remove all elements from the list.
   */
  public void clear() {
    if (mOriginalValues != null) {
      synchronized (mLock) {
        mOriginalValues.clear();
        mObjects.clear();
      }
    } else {
      mObjects.clear();
    }
    if (mNotifyOnChange)
      notifyDataSetChanged();
  }

  /**
   * Sorts the content of this adapter using the specified comparator.
   * 
   * @param comparator
   *            The comparator used to sort the objects contained in this adapter.
   */
  public void sort(Comparator<? super T> comparator) {
    Collections.sort(mObjects, comparator);
    if (mNotifyOnChange)
      notifyDataSetChanged();
  }

  public void notifyDataSetChanged(boolean refiler) {
    if (refiler && getFilter().isFilterSet()) {
      mNotifyOnChange = false;
      refilter();
    } else {
      super.notifyDataSetChanged();
    }
    mNotifyOnChange = true;
  }

  @Override
  public void swapItems(int positionOne, int positionTwo) {
    Debug.verbose("swap " + positionOne + ", " + positionTwo);
    Debug.verbose("before " + mObjects);
    if (mOriginalValues != null && mOriginalValues != mObjects) {
      synchronized (mLock) {
        T temp = mObjects.get(positionOne);

        int pos1 = mOriginalValues.indexOf(temp);
        int pos2 = mOriginalValues.indexOf(mObjects.get(positionTwo));

        mObjects.set(positionOne, mObjects.get(positionTwo));
        mObjects.set(positionTwo, temp);

        if (pos1 >= 0 && pos2 >= 0) {
          mOriginalValues.set(pos1, mOriginalValues.get(pos2));
          mOriginalValues.set(pos2, temp);
        }
      }
    } else {
      T temp = mObjects.get(positionOne);
      mObjects.set(positionOne, mObjects.get(positionTwo));
      mObjects.set(positionTwo, temp);
    }

    Debug.verbose("after  " + mObjects);

    if (mNotifyOnChange)
      notifyDataSetChanged();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void notifyDataSetChanged() {
    notifyDataSetChanged(true);
  }

  /**
   * Control whether methods that change the list ({@link #add}, {@link #insert}, {@link #remove}, {@link #clear})
   * automatically call {@link #notifyDataSetChanged}. If set to false, caller must manually call
   * notifyDataSetChanged() to have the changes reflected in the attached view.
   * 
   * The default is true, and calling notifyDataSetChanged() resets the flag to true.
   * 
   * @param notifyOnChange
   *            if true, modifications to the list will automatically call {@link #notifyDataSetChanged}
   */
  public void setNotifyOnChange(boolean notifyOnChange) {
    mNotifyOnChange = notifyOnChange;
  }

  private void init(Context context, int resource, int textViewResourceId, List<T> objects) {
    mContext = context;
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mResource = mDropDownResource = resource;
    mObjects = objects;
    mFieldId = textViewResourceId;
  }

  /**
   * Returns the context associated with this array adapter. The context is used to create views from the resource
   * passed to the constructor.
   * 
   * @return The Context associated with this adapter.
   */
  public Context getContext() {
    return mContext;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int getCount() {
    return mObjects.size();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public T getItem(int position) {
    if (position >= 0 && position < mObjects.size())
      return mObjects.get(position);
    else
      return null;
  }

  public List<T> getItems() {
    if (mOriginalValues != null)
      return mOriginalValues;
    else
      return mObjects;
  }

  /**
   * Returns the position of the specified item in the array.
   * 
   * @param item
   *            The item to retrieve the position of.
   * 
   * @return The position of the specified item.
   */
  public int indexOf(T item) {
    return mObjects.indexOf(item);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long getItemId(int position) {
    if (position < 0 || position >= mObjects.size())
      return AdapterView.INVALID_ROW_ID;
    else
      return mObjects.get(position).hashCode();
  }

  @Override
  public boolean hasStableIds() {
    return true;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(position, convertView, parent, mResource);
  }

  private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
    View view;
    TextView text;

    if (convertView == null) {
      view = mInflater.inflate(resource, parent, false);
    } else {
      view = convertView;
    }

    try {
      if (mFieldId == 0) {
        // If no custom field is assigned, assume the whole resource is
        // a TextView
        text = (TextView) view;
      } else {
        // Otherwise, find the TextView field within the layout
        text = (TextView) view.findViewById(mFieldId);
      }
    } catch (ClassCastException e) {
      Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
      throw new IllegalStateException("ArrayAdapter requires the resource ID to be a TextView", e);
    }

    T item = getItem(position);
    if (item instanceof CharSequence) {
      text.setText((CharSequence) item);
    } else {
      text.setText(item.toString());
    }

    return view;
  }

  /**
   * <p>
   * Sets the layout resource to create the drop down views.
   * </p>
   * 
   * @param resource
   *            the layout resource defining the drop down views
   * @see #getDropDownView(int, android.view.View, android.view.ViewGroup)
   */
  public void setDropDownViewResource(int resource) {
    this.mDropDownResource = resource;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public View getDropDownView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(position, convertView, parent, mDropDownResource);
  }

  /**
   * Creates a new ArrayAdapter from external resources. The content of the array is obtained through
   * {@link android.content.res.Resources#getTextArray(int)}.
   * 
   * @param context
   *            The application's environment.
   * @param textArrayResId
   *            The identifier of the array to use as the data source.
   * @param textViewResId
   *            The identifier of the layout used to create views.
   * 
   * @return An ArrayAdapter<CharSequence>.
   */
  public static OpenArrayAdapter<CharSequence> createFromResource(Context context, int textArrayResId,
      int textViewResId) {
    CharSequence[] strings = context.getResources().getTextArray(textArrayResId);
    return new OpenArrayAdapter<CharSequence>(context, textViewResId, strings);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public OpenFilter<T> getFilter() {
    if (mFilter == null) {
      mFilter = new OpenFilter<T>(this);
    }
    return mFilter;
  }

  public void refilter() {
    if (getFilter().isFilterSet()) {
      getFilter().filter(getFilter().constraint);
    }
  }

  /**
   * <p>
   * An array filter constrains the content of the array adapter with a prefix. Each item that does not start with the
   * supplied prefix is removed from the list.
   * </p>
   */
  // private class ArrayFilter extends Filter {
  // @Override
  // protected FilterResults performFiltering(CharSequence prefix) {
  // FilterResults results = new FilterResults();
  //
  // if (mOriginalValues == null) {
  // synchronized (mLock) {
  // mOriginalValues = new ArrayList<T>(mObjects);
  // }
  // }
  //
  // if (prefix == null || prefix.length() == 0) {
  // synchronized (mLock) {
  // ArrayList<T> list = new ArrayList<T>(mOriginalValues);
  // results.values = list;
  // results.count = list.size();
  // }
  // } else {
  // String prefixString = prefix.toString().toLowerCase(Locale.GERMAN);
  //
  // final List<T> values = mOriginalValues;
  // final int count = values.size();
  //
  // final ArrayList<T> newValues = new ArrayList<T>(count);
  //
  // for (int i = 0; i < count; i++) {
  // final T value = values.get(i);
  // final String valueText = value.toString().toLowerCase(Locale.GERMAN);
  //
  // // First match against the whole, non-splitted value
  // if (valueText.startsWith(prefixString)) {
  // newValues.add(value);
  // } else {
  // final String[] words = valueText.split(" ");
  // final int wordCount = words.length;
  //
  // for (int k = 0; k < wordCount; k++) {
  // if (words[k].startsWith(prefixString)) {
  // newValues.add(value);
  // break;
  // }
  // }
  // }
  // }
  //
  // results.values = newValues;
  // results.count = newValues.size();
  // }
  //
  // return results;
  // }
  //
  // @SuppressWarnings("unchecked")
  // @Override
  // protected void publishResults(CharSequence constraint, FilterResults
  // results) {
  // // noinspection unchecked
  // mObjects = (List<T>) results.values;
  // if (results.count > 0) {
  // notifyDataSetChanged();
  // } else {
  // notifyDataSetInvalidated();
  // }
  // }
  // }
}




Java Source Code List

au.com.bytecode.opencsv.CSVReader.java
com.ecloud.pulltozoomview.PullToZoomScrollView.java
com.gandulf.guilib.data.OpenArrayAdapter.java
com.gandulf.guilib.data.OpenFilter.java
com.gandulf.guilib.download.AbstractDownloader.java
com.gandulf.guilib.download.DownloadBroadcastReceiver.java
com.gandulf.guilib.download.DownloaderGinger.java
com.gandulf.guilib.download.DownloaderWrapper.java
com.gandulf.guilib.download.Downloader.java
com.gandulf.guilib.download.MediaScannerWrapper.java
com.gandulf.guilib.download.UnzipIntentService.java
com.gandulf.guilib.listener.CheckableListenable.java
com.gandulf.guilib.listener.OnCheckedChangeListener.java
com.gandulf.guilib.util.ColorUtil.java
com.gandulf.guilib.util.Debug.java
com.gandulf.guilib.util.DefaultTextWatcher.java
com.gandulf.guilib.util.DirectoryFileFilter.java
com.gandulf.guilib.util.FileFileFilter.java
com.gandulf.guilib.util.ListViewCompat.java
com.gandulf.guilib.util.MathUtil.java
com.gandulf.guilib.util.ResUtil.java
com.gandulf.guilib.view.ColorPickerDialog.java
com.gandulf.guilib.view.DynamicListViewEx.java
com.gandulf.guilib.view.HackeyDrawerLayout.java
com.gandulf.guilib.view.SeekBarEx.java
com.gandulf.guilib.view.VersionInfoDialog.java
com.gandulf.guilib.view.ViewScroller.java
com.gandulf.guilib.view.adapter.MultiFragmentPagerAdapter.java
com.getbase.floatingactionbutton.AddFloatingActionButton.java
com.getbase.floatingactionbutton.FloatingActionButton.java
com.getbase.floatingactionbutton.FloatingActionsMenu.java
com.github.amlcurran.showcaseview.AnimationFactory.java
com.github.amlcurran.showcaseview.AnimatorAnimationFactory.java
com.github.amlcurran.showcaseview.ApiUtils.java
com.github.amlcurran.showcaseview.Calculator.java
com.github.amlcurran.showcaseview.NewShowcaseDrawer.java
com.github.amlcurran.showcaseview.OnShowcaseEventListener.java
com.github.amlcurran.showcaseview.ShotStateStore.java
com.github.amlcurran.showcaseview.ShowcaseAreaCalculator.java
com.github.amlcurran.showcaseview.ShowcaseDrawer.java
com.github.amlcurran.showcaseview.ShowcaseView.java
com.github.amlcurran.showcaseview.StandardShowcaseDrawer.java
com.github.amlcurran.showcaseview.TextDrawer.java
com.github.amlcurran.showcaseview.targets.ActionBarReflector.java
com.github.amlcurran.showcaseview.targets.ActionBarViewWrapper.java
com.github.amlcurran.showcaseview.targets.ActionItemTarget.java
com.github.amlcurran.showcaseview.targets.ActionViewTarget.java
com.github.amlcurran.showcaseview.targets.AppCompatReflector.java
com.github.amlcurran.showcaseview.targets.PointTarget.java
com.github.amlcurran.showcaseview.targets.ReflectorFactory.java
com.github.amlcurran.showcaseview.targets.Reflector.java
com.github.amlcurran.showcaseview.targets.SherlockReflector.java
com.github.amlcurran.showcaseview.targets.Target.java
com.github.amlcurran.showcaseview.targets.ViewTarget.java
com.sothree.slidinguppanel.SlidingUpPanelLayout.java
com.sothree.slidinguppanel.ViewDragHelper.java
com.thebnich.floatinghintedittext.FloatingHintEditText.java
com.thebnich.floatinghintedittext.FloatingHintTextView.java
com.wefika.flowlayout.FlowLayout.java
de.hdodenhof.circleimageview.CircleImageView.java
uk.co.senab.photoview.Compat.java
uk.co.senab.photoview.PhotoViewAttacher.java
uk.co.senab.photoview.PhotoView.java
uk.co.senab.photoview.SDK16.java
uk.co.senab.photoview.ScrollerProxy.java
uk.co.senab.photoview.VersionedGestureDetector.java
uk.me.lewisdeane.ldialogs.BaseDialog.java
uk.me.lewisdeane.ldialogs.CustomDialog.java
uk.me.lewisdeane.ldialogs.CustomListAdapter.java