BoundRemoteViews.java :  » Network » android-sonet » mobi » intuitit » android » widget » Android Open Source

Android Open Source » Network » android sonet 
android sonet » mobi » intuitit » android » widget » BoundRemoteViews.java
package mobi.intuitit.android.widget;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
import android.view.View.OnClickListener;

public class BoundRemoteViews extends SimpleRemoteViews {

  class CursorCache {

    final ArrayList<HashMap<Action, Object>> mCache;
    final HashMap<Action, Object> mDefaults;

    public Object getValueOrDefault(int index, Action target) {
      HashMap<Action, Object> row = mCache.get(index);
      Object result = null;
      if (row.containsKey(target))
         result = row.get(target);
      if (result == null)
        result = mDefaults.get(target);
      return result;
    }

    public CursorCache(Cursor cursor, Context context) {
      final int cacheSize = cursor != null ? cursor.getCount() : 0;

      mCache = new ArrayList<HashMap<Action,Object>>(cacheSize);
      mDefaults = new HashMap<Action, Object>();

      final ArrayList<Action> actions = BoundRemoteViews.this.mActions;

      for (int i = 0; i < actions.size(); i++) {
        Action act = actions.get(i);
        if (act instanceof BindingAction)
          mDefaults.put(act, ((BindingAction)act).getDefault(context));
        else if (act instanceof SetBoundOnClickIntent)
          mDefaults.put(act, null);
      }

      if (cursor != null) {
        cursor.moveToFirst();

        while(!cursor.isAfterLast()) {

          HashMap<Action, Object> row = new HashMap<Action, Object>();


          for (int i = 0; i < actions.size(); i++) {
            Action act = actions.get(i);
            if (act instanceof BindingAction)
              row.put(act, ((BindingAction)act).readValue(cursor, context));
            else if (act instanceof SetBoundOnClickIntent)
              row.put(act, ((SetBoundOnClickIntent)act).readValue(cursor));
          }

          mCache.add(row);
          cursor.moveToNext();
        }
      }
    }
  }


  protected class BindingAction extends SimpleRemoteViews.ReflectionAction
  {
    public static final int tag = 99;

    private int mCursorIndex;
    private int mDefaultResource;

    public BindingAction(int viewId, String methodName, int type, int cursorIndex, int defaultResource) {
      super(viewId, methodName, type);
      mCursorIndex = cursorIndex;
      mDefaultResource = defaultResource;
      }

    public BindingAction(Parcel in) {
      super(in);
    }

    @Override
      protected int getTag() {
        return tag;
      }

    @Override
    protected void readValue(Parcel in) {
      mCursorIndex = in.readInt();
      mDefaultResource = in.readInt();
    }

    @Override
    protected void writeValue(Parcel out, int flags) {
      out.writeInt(mCursorIndex);
      out.writeInt(mDefaultResource);
    }

    @Override
    protected Object getValue(Context context) {
      return mCursor.getValueOrDefault(mCursorPos, this);
    }

    public Object readValue(Cursor cursor, Context context) {
      try
      {
        switch(this.type) {
          case STRING:
          case CHAR_SEQUENCE:
            return cursor.getString(mCursorIndex);
          case BYTE:
            return (byte)cursor.getInt(mCursorIndex);
          case SHORT:
            return (short)cursor.getInt(mCursorIndex);
          case INT:
            return cursor.getInt(mCursorIndex);
          case LONG:
            return cursor.getLong(mCursorIndex);
          case FLOAT:
            return cursor.getFloat(mCursorIndex);
          case DOUBLE:
            return cursor.getDouble(mCursorIndex);
          case CHAR:
            return cursor.getString(mCursorIndex).charAt(0);
          case URI:
            return Uri.parse(cursor.getString(mCursorIndex));
          case BITMAP:
            byte[] blob = cursor.getBlob(mCursorIndex);
                    return BitmapFactory.decodeByteArray(blob, 0, blob.length);
        }
      }
      catch(Exception e) {
        return null;
      }
      return null;
    }

    public Object getDefault(Context context) {
      try
      {
        switch(this.type) {
          case STRING:
          case CHAR_SEQUENCE:
            return context.getString(mDefaultResource);
          case BITMAP:
            return BitmapFactory.decodeResource(context.getResources(), mDefaultResource);
        }
      }
      catch(Exception e) {
        return null;
      }
      return null;
    }

    @Override
    public void apply(View root) {
      super.apply(root);
    }
  }

  protected class SetBoundOnClickIntent extends Action {
    private static final int TAG = 100;

    private final String mExtraName;
    private final int mExtraCursorIndex;
    private final int mViewId;
    private final PendingIntent mIntent;

        public SetBoundOnClickIntent(int id, PendingIntent intent,
            String extraName, int extraCursorIndex) {
          mViewId = id;
          mIntent = intent;
          mExtraName = extraName;
          mExtraCursorIndex = extraCursorIndex;
        }

        public SetBoundOnClickIntent(Parcel parcel) {
          mViewId = parcel.readInt();
          mExtraName = parcel.readString();
          mExtraCursorIndex = parcel.readInt();
          mIntent = PendingIntent.CREATOR.createFromParcel(parcel);
        }

        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(TAG);
            dest.writeInt(mViewId);
            dest.writeString(mExtraName);
            dest.writeInt(mExtraCursorIndex);
            mIntent.writeToParcel(dest, 0 /* no flags */);
        }

        @Override
        public void apply(View root) {
            final View target = root.findViewById(mViewId);
            if (target != null && mIntent != null) {
                target.setOnClickListener(new BoundOnClickListener(mCursorPos));
            }
        }

        private class BoundOnClickListener implements OnClickListener {

          private final int myCursorPos;

          public BoundOnClickListener(int cursorPos) {
            myCursorPos = cursorPos;
          }

          public void onClick(View v) {
                // Find target view location in screen coordinates and
                // fill into PendingIntent before sending.
                final int[] location = new int[2];
                v.getLocationOnScreen(location);
                Rect srcRect = new Rect();
                srcRect.left = location[0];
                srcRect.top = location[1];
                srcRect.right = srcRect.left + v.getWidth();
                srcRect.bottom = srcRect.top + v.getHeight();
                Intent intent = new Intent();
                intent.setSourceBounds(srcRect);
                prepareIntent(intent);
                try {
                  mIntent.send(v.getContext(), 0, intent, null, null);
                } catch (PendingIntent.CanceledException e) {
                    android.util.Log.e("SetOnClickPendingIntent", "Cannot send pending intent: ", e);
                }
            }

            protected void prepareIntent(Intent intent) {
              String value = (String)mCursor.getValueOrDefault(myCursorPos, SetBoundOnClickIntent.this);
              intent.putExtra(mExtraName, value);
            }
        }

        public String readValue(Cursor cursor) {
          return cursor.getString(mExtraCursorIndex);
        }
  }

  private CursorCache mCursor;
  private int mCursorPos;

  public BoundRemoteViews(Parcel parcel) {
    super(parcel);
  }

  public BoundRemoteViews(int layoutId) {
    super(layoutId);
  }

  public void setBindingCursor(Cursor cursor, Context context) {
    mCursor = new CursorCache(cursor,context);
  }

  public int getCursorCacheSize() {
    if (mCursor != null)
      return mCursor.mCache.size();
    else
      return 0;
  }

  public void moveCursor(int newPosition) {
    mCursorPos = newPosition;
  }

  @Override
  protected Action loadActionFromParcel(int tag, Parcel parcel) {
    if (tag == BoundRemoteViews.BindingAction.tag)
      return new BindingAction(parcel);
    else if (tag == SetBoundOnClickIntent.TAG)
      return new SetBoundOnClickIntent(parcel);
    else
      return super.loadActionFromParcel(tag, parcel);
  }

  public void reapplyBinding(View v) {
      try
      {
          if (mActions != null) {
              final int count = mActions.size();
              for (int i = 0; i < count; i++) {
                  Action a = mActions.get(i);
                  if (a instanceof BindingAction || a instanceof SetBoundOnClickIntent)
                    a.apply(v);
              }
          }
      } catch (OutOfMemoryError e) {
            System.gc();
      }
  }

    public void setBoundString(int viewId, String methodName, int cursorIndex, int defaultResource) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.STRING,
                    cursorIndex, defaultResource));
    }

    public void setBoundCharSequence(int viewId, String methodName, int cursorIndex, int defaultResource) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE,
                    cursorIndex, defaultResource));
    }

    public void setBoundByte(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.BYTE,
                    cursorIndex,0));
    }

    public void setBoundShort(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.SHORT,
                    cursorIndex,0));
    }

    public void setBoundInt(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.INT,
                    cursorIndex,0));
    }

    public void setBoundLong(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.LONG,
                    cursorIndex,0));
    }

    public void setBoundFloat(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.FLOAT,
                    cursorIndex,0));
    }

    public void setBoundDouble(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.DOUBLE,
                    cursorIndex,0));
    }

    public void setBoundChar(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.CHAR,
                    cursorIndex,0));
    }

    public void setBoundUri(int viewId, String methodName, int cursorIndex) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.URI,
                    cursorIndex,0));
    }

    public void setBoundBitmap(int viewId, String methodName, int cursorIndex, int defaultResource) {
      addAction(new BindingAction(viewId, methodName, ReflectionAction.BITMAP,
                    cursorIndex, defaultResource));
    }

    public void SetBoundOnClickIntent(int viewId, PendingIntent intent,
        String extraName, int extraCursorIndex) {
        addAction(new SetBoundOnClickIntent(viewId, intent, extraName, extraCursorIndex));
    }

    /**
     * Parcelable.Creator that instantiates RemoteViews objects
     */
    public static final Parcelable.Creator<BoundRemoteViews> CREATOR = new Parcelable.Creator<BoundRemoteViews>() {
        public BoundRemoteViews createFromParcel(Parcel parcel) {
            return new BoundRemoteViews(parcel);
        }

        public BoundRemoteViews[] newArray(int size) {
            return new BoundRemoteViews[size];
        }
    };
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.