Commit 9d9b6fcc authored by Sajal Narang's avatar Sajal Narang

Reformat code

parent 1b9d3f22
...@@ -40,9 +40,9 @@ ...@@ -40,9 +40,9 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data <data
android:scheme="https"
android:host="insti.app" android:host="insti.app"
android:pathPattern="/org/.*" /> android:pathPattern="/org/.*"
android:scheme="https" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
...@@ -51,9 +51,9 @@ ...@@ -51,9 +51,9 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data <data
android:scheme="https"
android:host="insti.app" android:host="insti.app"
android:pathPattern="/user/.*" /> android:pathPattern="/user/.*"
android:scheme="https" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
...@@ -62,9 +62,9 @@ ...@@ -62,9 +62,9 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data <data
android:scheme="https"
android:host="insti.app" android:host="insti.app"
android:pathPattern="/event/.*" /> android:pathPattern="/event/.*"
android:scheme="https" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
...@@ -73,9 +73,9 @@ ...@@ -73,9 +73,9 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data <data
android:scheme="http"
android:host="insti.app" android:host="insti.app"
android:pathPattern="/org/.*" /> android:pathPattern="/org/.*"
android:scheme="http" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
...@@ -84,9 +84,9 @@ ...@@ -84,9 +84,9 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data <data
android:scheme="http"
android:host="insti.app" android:host="insti.app"
android:pathPattern="/user/.*" /> android:pathPattern="/user/.*"
android:scheme="http" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
...@@ -95,9 +95,9 @@ ...@@ -95,9 +95,9 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data <data
android:scheme="http"
android:host="insti.app" android:host="insti.app"
android:pathPattern="/event/.*" /> android:pathPattern="/event/.*"
android:scheme="http" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
} }
</style> </style>
</head> </head>
......
package app.insti; package app.insti;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage; import com.google.firebase.messaging.RemoteMessage;
......
...@@ -22,7 +22,6 @@ import android.view.MotionEvent; ...@@ -22,7 +22,6 @@ import android.view.MotionEvent;
import android.view.ScaleGestureDetector; import android.view.ScaleGestureDetector;
import android.view.View; import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.OverScroller; import android.widget.OverScroller;
import android.widget.Scroller; import android.widget.Scroller;
...@@ -50,42 +49,33 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -50,42 +49,33 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
// saved prior to the screen rotating. // saved prior to the screen rotating.
// //
private Matrix matrix, prevMatrix; private Matrix matrix, prevMatrix;
private static enum State { NONE, DRAG, ZOOM, FLING, ANIMATE_ZOOM };
private State state; private State state;
;
private float minScale; private float minScale;
private float maxScale; private float maxScale;
private float superMinScale; private float superMinScale;
private float superMaxScale; private float superMaxScale;
private float[] m; private float[] m;
private Context context; private Context context;
private Fling fling; private Fling fling;
private ScaleType mScaleType; private ScaleType mScaleType;
private boolean imageRenderedAtLeastOnce; private boolean imageRenderedAtLeastOnce;
private boolean onDrawReady; private boolean onDrawReady;
private ZoomVariables delayedZoomVariables; private ZoomVariables delayedZoomVariables;
// //
// Size of view and previous view size (ie before rotation) // Size of view and previous view size (ie before rotation)
// //
private int viewWidth, viewHeight, prevViewWidth, prevViewHeight; private int viewWidth, viewHeight, prevViewWidth, prevViewHeight;
// //
// Size of image when it is stretched to fit view. Before and After rotation. // Size of image when it is stretched to fit view. Before and After rotation.
// //
private float matchViewWidth, matchViewHeight, prevMatchViewWidth, prevMatchViewHeight; private float matchViewWidth, matchViewHeight, prevMatchViewWidth, prevMatchViewHeight;
private ScaleGestureDetector mScaleDetector; private ScaleGestureDetector mScaleDetector;
private GestureDetector mGestureDetector; private GestureDetector mGestureDetector;
private GestureDetector.OnDoubleTapListener doubleTapListener = null; private GestureDetector.OnDoubleTapListener doubleTapListener = null;
private OnTouchListener userTouchListener = null; private OnTouchListener userTouchListener = null;
private OnTouchImageViewListener touchImageViewListener = null; private OnTouchImageViewListener touchImageViewListener = null;
public TouchImageView(Context context) { public TouchImageView(Context context) {
super(context); super(context);
sharedConstructing(context); sharedConstructing(context);
...@@ -165,6 +155,11 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -165,6 +155,11 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
fitImageToView(); fitImageToView();
} }
@Override
public ScaleType getScaleType() {
return mScaleType;
}
@Override @Override
public void setScaleType(ScaleType type) { public void setScaleType(ScaleType type) {
if (type == ScaleType.FIT_START || type == ScaleType.FIT_END) { if (type == ScaleType.FIT_START || type == ScaleType.FIT_END) {
...@@ -185,13 +180,9 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -185,13 +180,9 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
} }
} }
@Override
public ScaleType getScaleType() {
return mScaleType;
}
/** /**
* Returns false if image is in initial, unzoomed state. False, otherwise. * Returns false if image is in initial, unzoomed state. False, otherwise.
*
* @return true if image is zoomed * @return true if image is zoomed
*/ */
public boolean isZoomed() { public boolean isZoomed() {
...@@ -200,6 +191,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -200,6 +191,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Return a Rect representing the zoomed image. * Return a Rect representing the zoomed image.
*
* @return rect representing zoomed image * @return rect representing zoomed image
*/ */
public RectF getZoomedRect() { public RectF getZoomedRect() {
...@@ -282,6 +274,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -282,6 +274,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Get the max zoom multiplier. * Get the max zoom multiplier.
*
* @return max zoom multiplier. * @return max zoom multiplier.
*/ */
public float getMaxZoom() { public float getMaxZoom() {
...@@ -290,6 +283,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -290,6 +283,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Set the max zoom multiplier. Default value: 3. * Set the max zoom multiplier. Default value: 3.
*
* @param max max zoom multiplier. * @param max max zoom multiplier.
*/ */
public void setMaxZoom(float max) { public void setMaxZoom(float max) {
...@@ -299,23 +293,16 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -299,23 +293,16 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Get the min zoom multiplier. * Get the min zoom multiplier.
*
* @return min zoom multiplier. * @return min zoom multiplier.
*/ */
public float getMinZoom() { public float getMinZoom() {
return minScale; return minScale;
} }
/**
* Get the current zoom. This is the zoom relative to the initial
* scale, not the original resource.
* @return current zoom multiplier.
*/
public float getCurrentZoom() {
return normalizedScale;
}
/** /**
* Set the min zoom multiplier. Default value: 1. * Set the min zoom multiplier. Default value: 1.
*
* @param min min zoom multiplier. * @param min min zoom multiplier.
*/ */
public void setMinZoom(float min) { public void setMinZoom(float min) {
...@@ -323,6 +310,16 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -323,6 +310,16 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
superMinScale = SUPER_MIN_MULTIPLIER * minScale; superMinScale = SUPER_MIN_MULTIPLIER * minScale;
} }
/**
* Get the current zoom. This is the zoom relative to the initial
* scale, not the original resource.
*
* @return current zoom multiplier.
*/
public float getCurrentZoom() {
return normalizedScale;
}
/** /**
* Reset zoom and translation to initial state. * Reset zoom and translation to initial state.
*/ */
...@@ -333,6 +330,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -333,6 +330,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Set zoom to the specified scale. Image will be centered by default. * Set zoom to the specified scale. Image will be centered by default.
*
* @param scale * @param scale
*/ */
public void setZoom(float scale) { public void setZoom(float scale) {
...@@ -344,6 +342,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -344,6 +342,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
* (focusX, focusY). These floats range from 0 to 1 and denote the focus point * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
* as a fraction from the left and top of the view. For example, the top left * as a fraction from the left and top of the view. For example, the top left
* corner of the image would be (0, 0). And the bottom right corner would be (1, 1). * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
*
* @param scale * @param scale
* @param focusX * @param focusX
* @param focusY * @param focusY
...@@ -357,6 +356,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -357,6 +356,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
* (focusX, focusY). These floats range from 0 to 1 and denote the focus point * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
* as a fraction from the left and top of the view. For example, the top left * as a fraction from the left and top of the view. For example, the top left
* corner of the image would be (0, 0). And the bottom right corner would be (1, 1). * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
*
* @param scale * @param scale
* @param focusX * @param focusX
* @param focusY * @param focusY
...@@ -389,6 +389,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -389,6 +389,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Set zoom parameters equal to another TouchImageView. Including scale, position, * Set zoom parameters equal to another TouchImageView. Including scale, position,
* and ScaleType. * and ScaleType.
*
* @param TouchImageView * @param TouchImageView
*/ */
public void setZoom(TouchImageView img) { public void setZoom(TouchImageView img) {
...@@ -401,6 +402,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -401,6 +402,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
* in value between 0 and 1 and the focus point is denoted as a fraction from the left * in value between 0 and 1 and the focus point is denoted as a fraction from the left
* and top of the view. For example, the top left corner of the image would be (0, 0). * and top of the view. For example, the top left corner of the image would be (0, 0).
* And the bottom right corner would be (1, 1). * And the bottom right corner would be (1, 1).
*
* @return PointF representing the scroll position of the zoomed image. * @return PointF representing the scroll position of the zoomed image.
*/ */
public PointF getScrollPosition() { public PointF getScrollPosition() {
...@@ -420,6 +422,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -420,6 +422,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Set the focus point of the zoomed image. The focus points are denoted as a fraction from the * Set the focus point of the zoomed image. The focus points are denoted as a fraction from the
* left and top of the view. The focus points can range in value between 0 and 1. * left and top of the view. The focus points can range in value between 0 and 1.
*
* @param focusX * @param focusX
* @param focusY * @param focusY
*/ */
...@@ -672,13 +675,13 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -672,13 +675,13 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
* After rotating, the matrix needs to be translated. This function finds the area of image * After rotating, the matrix needs to be translated. This function finds the area of image
* which was previously centered and adjusts translations so that is again the center, post-rotation. * which was previously centered and adjusts translations so that is again the center, post-rotation.
* *
* @param axis Matrix.MTRANS_X or Matrix.MTRANS_Y * @param axis Matrix.MTRANS_X or Matrix.MTRANS_Y
* @param trans the value of trans in that axis before the rotation * @param trans the value of trans in that axis before the rotation
* @param prevImageSize the width/height of the image before the rotation * @param prevImageSize the width/height of the image before the rotation
* @param imageSize width/height of the image after rotation * @param imageSize width/height of the image after rotation
* @param prevViewSize width/height of view before rotation * @param prevViewSize width/height of view before rotation
* @param viewSize width/height of view after rotation * @param viewSize width/height of view after rotation
* @param drawableSize width/height of drawable * @param drawableSize width/height of drawable
*/ */
private void translateMatrixAfterRotate(int axis, float trans, float prevImageSize, float imageSize, int prevViewSize, int viewSize, int drawableSize) { private void translateMatrixAfterRotate(int axis, float trans, float prevImageSize, float imageSize, int prevViewSize, int viewSize, int drawableSize) {
if (imageSize < viewSize) { if (imageSize < viewSize) {
...@@ -730,32 +733,123 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -730,32 +733,123 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
return true; return true;
} }
private void scaleImage(double deltaScale, float focusX, float focusY, boolean stretchImageToSuper) {
float lowerScale, upperScale;
if (stretchImageToSuper) {
lowerScale = superMinScale;
upperScale = superMaxScale;
} else {
lowerScale = minScale;
upperScale = maxScale;
}
float origScale = normalizedScale;
normalizedScale *= deltaScale;
if (normalizedScale > upperScale) {
normalizedScale = upperScale;
deltaScale = upperScale / origScale;
} else if (normalizedScale < lowerScale) {
normalizedScale = lowerScale;
deltaScale = lowerScale / origScale;
}
matrix.postScale((float) deltaScale, (float) deltaScale, focusX, focusY);
fixScaleTrans();
}
/**
* This function will transform the coordinates in the touch event to the coordinate
* system of the drawable that the imageview contain
*
* @param x x-coordinate of touch event
* @param y y-coordinate of touch event
* @param clipToBitmap Touch event may occur within view, but outside image content. True, to clip return value
* to the bounds of the bitmap size.
* @return Coordinates of the point touched, in the coordinate system of the original drawable.
*/
private PointF transformCoordTouchToBitmap(float x, float y, boolean clipToBitmap) {
matrix.getValues(m);
float origW = getDrawable().getIntrinsicWidth();
float origH = getDrawable().getIntrinsicHeight();
float transX = m[Matrix.MTRANS_X];
float transY = m[Matrix.MTRANS_Y];
float finalX = ((x - transX) * origW) / getImageWidth();
float finalY = ((y - transY) * origH) / getImageHeight();
if (clipToBitmap) {
finalX = Math.min(Math.max(finalX, 0), origW);
finalY = Math.min(Math.max(finalY, 0), origH);
}
return new PointF(finalX, finalY);
}
/**
* Inverse of transformCoordTouchToBitmap. This function will transform the coordinates in the
* drawable's coordinate system to the view's coordinate system.
*
* @param bx x-coordinate in original bitmap coordinate system
* @param by y-coordinate in original bitmap coordinate system
* @return Coordinates of the point in the view's coordinate system.
*/
private PointF transformCoordBitmapToTouch(float bx, float by) {
matrix.getValues(m);
float origW = getDrawable().getIntrinsicWidth();
float origH = getDrawable().getIntrinsicHeight();
float px = bx / origW;
float py = by / origH;
float finalX = m[Matrix.MTRANS_X] + getImageWidth() * px;
float finalY = m[Matrix.MTRANS_Y] + getImageHeight() * py;
return new PointF(finalX, finalY);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void compatPostOnAnimation(Runnable runnable) {
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
postOnAnimation(runnable);
} else {
postDelayed(runnable, 1000 / 60);
}
}
private void printMatrixInfo() {
float[] n = new float[9];
matrix.getValues(n);
Log.d(DEBUG, "Scale: " + n[Matrix.MSCALE_X] + " TransX: " + n[Matrix.MTRANS_X] + " TransY: " + n[Matrix.MTRANS_Y]);
}
private static enum State {NONE, DRAG, ZOOM, FLING, ANIMATE_ZOOM}
public interface OnTouchImageViewListener {
public void onMove();
}
/** /**
* Gesture Listener detects a single click or long click and passes that on * Gesture Listener detects a single click or long click and passes that on
* to the view's listener. * to the view's listener.
* @author Ortiz
* *
* @author Ortiz
*/ */
private class GestureListener extends GestureDetector.SimpleOnGestureListener { private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override @Override
public boolean onSingleTapConfirmed(MotionEvent e) public boolean onSingleTapConfirmed(MotionEvent e) {
{ if (doubleTapListener != null) {
if(doubleTapListener != null) {
return doubleTapListener.onSingleTapConfirmed(e); return doubleTapListener.onSingleTapConfirmed(e);
} }
return performClick(); return performClick();
} }
@Override @Override
public void onLongPress(MotionEvent e) public void onLongPress(MotionEvent e) {
{
performLongClick(); performLongClick();
} }
@Override @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
{
if (fling != null) { if (fling != null) {
// //
// If a previous fling is still active, it should be cancelled so that two flings // If a previous fling is still active, it should be cancelled so that two flings
...@@ -771,7 +865,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -771,7 +865,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
@Override @Override
public boolean onDoubleTap(MotionEvent e) { public boolean onDoubleTap(MotionEvent e) {
boolean consumed = false; boolean consumed = false;
if(doubleTapListener != null) { if (doubleTapListener != null) {
consumed = doubleTapListener.onDoubleTap(e); consumed = doubleTapListener.onDoubleTap(e);
} }
if (state == State.NONE) { if (state == State.NONE) {
...@@ -785,22 +879,18 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -785,22 +879,18 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
@Override @Override
public boolean onDoubleTapEvent(MotionEvent e) { public boolean onDoubleTapEvent(MotionEvent e) {
if(doubleTapListener != null) { if (doubleTapListener != null) {
return doubleTapListener.onDoubleTapEvent(e); return doubleTapListener.onDoubleTapEvent(e);
} }
return false; return false;
} }
} }
public interface OnTouchImageViewListener {
public void onMove();
}
/** /**
* Responsible for all touch events. Handles the heavy lifting of drag and also sends * Responsible for all touch events. Handles the heavy lifting of drag and also sends
* touch events to Scale Detector and Gesture Detector. * touch events to Scale Detector and Gesture Detector.
* @author Ortiz
* *
* @author Ortiz
*/ */
private class PrivateOnTouchListener implements OnTouchListener { private class PrivateOnTouchListener implements OnTouchListener {
...@@ -848,7 +938,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -848,7 +938,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
// //
// User-defined OnTouchListener // User-defined OnTouchListener
// //
if(userTouchListener != null) { if (userTouchListener != null) {
userTouchListener.onTouch(v, event); userTouchListener.onTouch(v, event);
} }
...@@ -868,8 +958,8 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -868,8 +958,8 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* ScaleListener detects user two finger scaling and scales image. * ScaleListener detects user two finger scaling and scales image.
* @author Ortiz
* *
* @author Ortiz
*/ */
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override @Override
...@@ -913,42 +1003,16 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -913,42 +1003,16 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
} }
} }
private void scaleImage(double deltaScale, float focusX, float focusY, boolean stretchImageToSuper) {
float lowerScale, upperScale;
if (stretchImageToSuper) {
lowerScale = superMinScale;
upperScale = superMaxScale;
} else {
lowerScale = minScale;
upperScale = maxScale;
}
float origScale = normalizedScale;
normalizedScale *= deltaScale;
if (normalizedScale > upperScale) {
normalizedScale = upperScale;
deltaScale = upperScale / origScale;
} else if (normalizedScale < lowerScale) {
normalizedScale = lowerScale;
deltaScale = lowerScale / origScale;
}
matrix.postScale((float) deltaScale, (float) deltaScale, focusX, focusY);
fixScaleTrans();
}
/** /**
* DoubleTapZoom calls a series of runnables which apply * DoubleTapZoom calls a series of runnables which apply
* an animated zoom in/out graphic to the image. * an animated zoom in/out graphic to the image.
* @author Ortiz
* *
* @author Ortiz
*/ */
private class DoubleTapZoom implements Runnable { private class DoubleTapZoom implements Runnable {
private long startTime;
private static final float ZOOM_TIME = 500; private static final float ZOOM_TIME = 500;
private long startTime;
private float startZoom, targetZoom; private float startZoom, targetZoom;
private float bitmapX, bitmapY; private float bitmapX, bitmapY;
private boolean stretchImageToSuper; private boolean stretchImageToSuper;
...@@ -1008,6 +1072,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -1008,6 +1072,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
* Interpolate between where the image should start and end in order to translate * Interpolate between where the image should start and end in order to translate
* the image so that the point that is touched is what ends up centered at the end * the image so that the point that is touched is what ends up centered at the end
* of the zoom. * of the zoom.
*
* @param t * @param t
*/ */
private void translateImageToCenterTouchPosition(float t) { private void translateImageToCenterTouchPosition(float t) {
...@@ -1019,6 +1084,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -1019,6 +1084,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Use interpolator to get t * Use interpolator to get t
*
* @return * @return
*/ */
private float interpolate() { private float interpolate() {
...@@ -1031,6 +1097,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -1031,6 +1097,7 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
/** /**
* Interpolate the current targeted zoom and get the delta * Interpolate the current targeted zoom and get the delta
* from the current zoom. * from the current zoom.
*
* @param t * @param t
* @return * @return
*/ */
...@@ -1040,56 +1107,12 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -1040,56 +1107,12 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
} }
} }
/**
* This function will transform the coordinates in the touch event to the coordinate
* system of the drawable that the imageview contain
* @param x x-coordinate of touch event
* @param y y-coordinate of touch event
* @param clipToBitmap Touch event may occur within view, but outside image content. True, to clip return value
* to the bounds of the bitmap size.
* @return Coordinates of the point touched, in the coordinate system of the original drawable.
*/
private PointF transformCoordTouchToBitmap(float x, float y, boolean clipToBitmap) {
matrix.getValues(m);
float origW = getDrawable().getIntrinsicWidth();
float origH = getDrawable().getIntrinsicHeight();
float transX = m[Matrix.MTRANS_X];
float transY = m[Matrix.MTRANS_Y];
float finalX = ((x - transX) * origW) / getImageWidth();
float finalY = ((y - transY) * origH) / getImageHeight();
if (clipToBitmap) {
finalX = Math.min(Math.max(finalX, 0), origW);
finalY = Math.min(Math.max(finalY, 0), origH);
}
return new PointF(finalX , finalY);
}
/**
* Inverse of transformCoordTouchToBitmap. This function will transform the coordinates in the
* drawable's coordinate system to the view's coordinate system.
* @param bx x-coordinate in original bitmap coordinate system
* @param by y-coordinate in original bitmap coordinate system
* @return Coordinates of the point in the view's coordinate system.
*/
private PointF transformCoordBitmapToTouch(float bx, float by) {
matrix.getValues(m);
float origW = getDrawable().getIntrinsicWidth();
float origH = getDrawable().getIntrinsicHeight();
float px = bx / origW;
float py = by / origH;
float finalX = m[Matrix.MTRANS_X] + getImageWidth() * px;
float finalY = m[Matrix.MTRANS_Y] + getImageHeight() * py;
return new PointF(finalX , finalY);
}
/** /**
* Fling launches sequential runnables which apply * Fling launches sequential runnables which apply
* the fling graphic to the image. The values for the translation * the fling graphic to the image. The values for the translation
* are interpolated by the Scroller. * are interpolated by the Scroller.
* @author Ortiz
* *
* @author Ortiz
*/ */
private class Fling implements Runnable { private class Fling implements Runnable {
...@@ -1232,16 +1255,6 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -1232,16 +1255,6 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
} }
} }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void compatPostOnAnimation(Runnable runnable) {
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
postOnAnimation(runnable);
} else {
postDelayed(runnable, 1000/60);
}
}
private class ZoomVariables { private class ZoomVariables {
public float scale; public float scale;
public float focusX; public float focusX;
...@@ -1255,11 +1268,5 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView ...@@ -1255,11 +1268,5 @@ public class TouchImageView extends android.support.v7.widget.AppCompatImageView
this.scaleType = scaleType; this.scaleType = scaleType;
} }
} }
private void printMatrixInfo() {
float[] n = new float[9];
matrix.getValues(n);
Log.d(DEBUG, "Scale: " + n[Matrix.MSCALE_X] + " TransX: " + n[Matrix.MTRANS_X] + " TransY: " + n[Matrix.MTRANS_Y]);
}
} }
...@@ -33,11 +33,11 @@ public class LoginActivity extends AppCompatActivity { ...@@ -33,11 +33,11 @@ public class LoginActivity extends AppCompatActivity {
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private final String redirectUri = "https://redirecturi"; private final String redirectUri = "https://redirecturi";
private final String guestUri = "https://guesturi"; private final String guestUri = "https://guesturi";
private boolean loggingIn = false;
public String authCode = null; public String authCode = null;
public String fcmId = null; public String fcmId = null;
SessionManager session; SessionManager session;
Context mContext = this; Context mContext = this;
private boolean loggingIn = false;
private ProgressDialog progressDialog; private ProgressDialog progressDialog;
@Override @Override
...@@ -70,7 +70,7 @@ public class LoginActivity extends AppCompatActivity { ...@@ -70,7 +70,7 @@ public class LoginActivity extends AppCompatActivity {
webview.loadUrl("file:///android_asset/login.html"); webview.loadUrl("file:///android_asset/login.html");
// Get FCM Id // Get FCM Id
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( new OnSuccessListener<InstanceIdResult>() { FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override @Override
public void onSuccess(InstanceIdResult instanceIdResult) { public void onSuccess(InstanceIdResult instanceIdResult) {
fcmId = instanceIdResult.getToken(); fcmId = instanceIdResult.getToken();
......
...@@ -80,6 +80,17 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -80,6 +80,17 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private boolean showNotifications = false; private boolean showNotifications = false;
private BackHandledFragment selectedFragment; private BackHandledFragment selectedFragment;
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
...@@ -140,7 +151,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -140,7 +151,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
int importance = NotificationManager.IMPORTANCE_HIGH; int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = null; NotificationChannel mChannel = null;
mChannel = new NotificationChannel(id, name,importance); mChannel = new NotificationChannel(id, name, importance);
// Configure the notification channel. // Configure the notification channel.
mChannel.setDescription(description); mChannel.setDescription(description);
...@@ -227,7 +238,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -227,7 +238,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} }
} }
/** Update FCM Id and update profile */ /**
* Update FCM Id and update profile
*/
private void updateFCMId() { private void updateFCMId() {
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() { FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override @Override
...@@ -248,7 +261,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -248,7 +261,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} }
@Override @Override
public void onFailure(Call<User> call, Throwable t) { } public void onFailure(Call<User> call, Throwable t) {
}
}); });
} }
}); });
...@@ -290,7 +304,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -290,7 +304,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
@Override @Override
public void onBackPressed() { public void onBackPressed() {
if(selectedFragment == null || !selectedFragment.onBackPressed()) { if (selectedFragment == null || !selectedFragment.onBackPressed()) {
// Selected fragment did not consume the back press event. // Selected fragment did not consume the back press event.
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) { if (drawer.isDrawerOpen(GravityCompat.START)) {
...@@ -310,7 +324,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -310,7 +324,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
return true; return true;
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId(); int id = item.getItemId();
...@@ -509,17 +522,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -509,17 +522,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
return false; return false;
} }
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override @Override
public void setSelectedFragment(BackHandledFragment backHandledFragment) { public void setSelectedFragment(BackHandledFragment backHandledFragment) {
this.selectedFragment = backHandledFragment; this.selectedFragment = backHandledFragment;
......
...@@ -51,7 +51,7 @@ public class BodyAdapter extends RecyclerView.Adapter<BodyAdapter.ViewHolder> { ...@@ -51,7 +51,7 @@ public class BodyAdapter extends RecyclerView.Adapter<BodyAdapter.ViewHolder> {
Body body = bodyList.get(position); Body body = bodyList.get(position);
holder.name.setText(body.getBodyName()); holder.name.setText(body.getBodyName());
holder.description.setText(body.getBodyShortDescription()); holder.description.setText(body.getBodyShortDescription());
Picasso.get().load(body.getBodyImageURL()).resize(0,200).into(holder.image); Picasso.get().load(body.getBodyImageURL()).resize(0, 200).into(holder.image);
} }
...@@ -60,6 +60,10 @@ public class BodyAdapter extends RecyclerView.Adapter<BodyAdapter.ViewHolder> { ...@@ -60,6 +60,10 @@ public class BodyAdapter extends RecyclerView.Adapter<BodyAdapter.ViewHolder> {
return bodyList.size(); return bodyList.size();
} }
public void setBodyList(List<Body> bodyList) {
this.bodyList = bodyList;
}
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name; public TextView name;
public TextView description; public TextView description;
...@@ -72,8 +76,4 @@ public class BodyAdapter extends RecyclerView.Adapter<BodyAdapter.ViewHolder> { ...@@ -72,8 +76,4 @@ public class BodyAdapter extends RecyclerView.Adapter<BodyAdapter.ViewHolder> {
image = (ImageView) itemView.findViewById(R.id.object_picture); image = (ImageView) itemView.findViewById(R.id.object_picture);
} }
} }
public void setBodyList(List<Body> bodyList) {
this.bodyList = bodyList;
}
} }
package app.insti.adapter; package app.insti.adapter;
import android.content.Context; import android.content.Context;
import android.media.Image;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
...@@ -97,6 +96,10 @@ public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.ViewHolder> { ...@@ -97,6 +96,10 @@ public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.ViewHolder> {
return events.size(); return events.size();
} }
public void setEvents(List<Event> events) {
this.events = events;
}
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView eventPicture; private ImageView eventPicture;
private TextView eventTitle; private TextView eventTitle;
...@@ -112,8 +115,4 @@ public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.ViewHolder> { ...@@ -112,8 +115,4 @@ public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.ViewHolder> {
eventBigPicture = (ImageView) itemView.findViewById(R.id.big_object_picture); eventBigPicture = (ImageView) itemView.findViewById(R.id.big_object_picture);
} }
} }
public void setEvents(List<Event> events) {
this.events = events;
}
} }
...@@ -3,7 +3,6 @@ package app.insti.adapter; ...@@ -3,7 +3,6 @@ package app.insti.adapter;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -110,6 +109,15 @@ public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { ...@@ -110,6 +109,15 @@ public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
return NewsFragment.showLoader ? (newsArticles.size() + 1) : newsArticles.size(); return NewsFragment.showLoader ? (newsArticles.size() + 1) : newsArticles.size();
} }
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar) v.findViewById(R.id.blog_load_item);
}
}
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {
private TextView articleTitle; private TextView articleTitle;
private TextView articleBody; private TextView articleBody;
...@@ -125,12 +133,4 @@ public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { ...@@ -125,12 +133,4 @@ public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
articleContent = (TextView) itemView.findViewById(R.id.article_content); articleContent = (TextView) itemView.findViewById(R.id.article_content);
} }
} }
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar)v.findViewById(R.id.blog_load_item);
}
}
} }
...@@ -2,7 +2,6 @@ package app.insti.adapter; ...@@ -2,7 +2,6 @@ package app.insti.adapter;
import android.content.Context; import android.content.Context;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -25,6 +24,13 @@ import ru.noties.markwon.Markwon; ...@@ -25,6 +24,13 @@ import ru.noties.markwon.Markwon;
public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_ITEM = 1; private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0; private final int VIEW_PROG = 0;
private List<PlacementBlogPost> posts;
private Context context;
private ItemClickListener itemClickListener;
public PlacementBlogAdapter(List<PlacementBlogPost> posts, ItemClickListener itemClickListener) {
this.posts = posts;
this.itemClickListener = itemClickListener;
}
public List<PlacementBlogPost> getPosts() { public List<PlacementBlogPost> getPosts() {
return posts; return posts;
...@@ -34,15 +40,6 @@ public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.View ...@@ -34,15 +40,6 @@ public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.View
this.posts = posts; this.posts = posts;
} }
private List<PlacementBlogPost> posts;
private Context context;
private ItemClickListener itemClickListener;
public PlacementBlogAdapter(List<PlacementBlogPost> posts, ItemClickListener itemClickListener) {
this.posts = posts;
this.itemClickListener = itemClickListener;
}
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
context = parent.getContext(); context = parent.getContext();
...@@ -101,6 +98,14 @@ public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.View ...@@ -101,6 +98,14 @@ public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.View
} }
} }
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar) v.findViewById(R.id.blog_load_item);
}
}
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {
private TextView postTitle; private TextView postTitle;
...@@ -116,13 +121,4 @@ public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.View ...@@ -116,13 +121,4 @@ public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.View
} }
} }
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar) v.findViewById(R.id.blog_load_item);
}
}
} }
...@@ -2,7 +2,6 @@ package app.insti.adapter; ...@@ -2,7 +2,6 @@ package app.insti.adapter;
import android.content.Context; import android.content.Context;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -100,6 +99,15 @@ public class TrainingBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewH ...@@ -100,6 +99,15 @@ public class TrainingBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
return TrainingBlogFragment.showLoader ? (posts.size() + 1) : posts.size(); return TrainingBlogFragment.showLoader ? (posts.size() + 1) : posts.size();
} }
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar) v.findViewById(R.id.blog_load_item);
}
}
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {
private TextView postTitle; private TextView postTitle;
private TextView postPublished; private TextView postPublished;
...@@ -113,12 +121,4 @@ public class TrainingBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewH ...@@ -113,12 +121,4 @@ public class TrainingBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
postContent = (TextView) itemView.findViewById(R.id.post_content); postContent = (TextView) itemView.findViewById(R.id.post_content);
} }
} }
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar)v.findViewById(R.id.blog_load_item);
}
}
} }
...@@ -66,6 +66,10 @@ public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> { ...@@ -66,6 +66,10 @@ public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
return userList.size(); return userList.size();
} }
public void setUserList(List<User> userList) {
this.userList = userList;
}
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {
public TextView userName; public TextView userName;
public TextView role; public TextView role;
...@@ -78,8 +82,4 @@ public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> { ...@@ -78,8 +82,4 @@ public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
image = (ImageView) itemView.findViewById(R.id.object_picture); image = (ImageView) itemView.findViewById(R.id.object_picture);
} }
} }
public void setUserList(List<User> userList) {
this.userList = userList;
}
} }
package app.insti.api; package app.insti.api;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
......
...@@ -9,16 +9,14 @@ import android.support.v7.widget.Toolbar; ...@@ -9,16 +9,14 @@ import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
import app.insti.R; import app.insti.R;
import de.hdodenhof.circleimageview.CircleImageView;
/** /**
* A simple {@link Fragment} subclass. * A simple {@link Fragment} subclass.
...@@ -55,7 +53,7 @@ public class AboutFragment extends BaseFragment { ...@@ -55,7 +53,7 @@ public class AboutFragment extends BaseFragment {
put(R.id.cheekuimg, "cheeku.jpg"); put(R.id.cheekuimg, "cheeku.jpg");
put(R.id.sarthakimg, "sarthak.jpg"); put(R.id.sarthakimg, "sarthak.jpg");
put(R.id.sohamimg, "soham.jpg"); put(R.id.sohamimg, "soham.jpg");
put(R.id.maitreyaimg,"maitreya.jpg"); put(R.id.maitreyaimg, "maitreya.jpg");
put(R.id.mrunmayiimg, "mrunmayi.jpg"); put(R.id.mrunmayiimg, "mrunmayi.jpg");
put(R.id.owaisimg, "owais.jpg"); put(R.id.owaisimg, "owais.jpg");
put(R.id.hrushikeshimg, "hrushikesh.jpg"); put(R.id.hrushikeshimg, "hrushikesh.jpg");
...@@ -73,11 +71,12 @@ public class AboutFragment extends BaseFragment { ...@@ -73,11 +71,12 @@ public class AboutFragment extends BaseFragment {
/* Show team pics */ /* Show team pics */
for (final Map.Entry<Integer, String> entry : team.entrySet()) { for (final Map.Entry<Integer, String> entry : team.entrySet()) {
CircleImageView circleImageView = getActivity().findViewById(entry.getKey()); CircleImageView circleImageView = getActivity().findViewById(entry.getKey());
Picasso.get().load("https://insti.app/team-pics/" + entry.getValue()).resize(0,300).into(circleImageView); Picasso.get().load("https://insti.app/team-pics/" + entry.getValue()).resize(0, 300).into(circleImageView);
} }
/* Map TextView ids to links */ /* Map TextView ids to links */
final Map<Integer, String> joinUs = new HashMap<Integer, String>() {{; final Map<Integer, String> joinUs = new HashMap<Integer, String>() {{
;
put(R.id.django, "https://github.com/wncc/IITBapp"); put(R.id.django, "https://github.com/wncc/IITBapp");
put(R.id.android, "https://github.com/wncc/InstiApp"); put(R.id.android, "https://github.com/wncc/InstiApp");
put(R.id.angular, "https://github.com/pulsejet/iitb-app-angular"); put(R.id.angular, "https://github.com/pulsejet/iitb-app-angular");
......
...@@ -25,8 +25,8 @@ import android.widget.Toast; ...@@ -25,8 +25,8 @@ import android.widget.Toast;
import com.google.gson.Gson; import com.google.gson.Gson;
import app.insti.Constants; import app.insti.Constants;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
import app.insti.data.Body; import app.insti.data.Body;
...@@ -37,9 +37,8 @@ import retrofit2.Response; ...@@ -37,9 +37,8 @@ import retrofit2.Response;
public class AddEventFragment extends BaseFragment { public class AddEventFragment extends BaseFragment {
private ProgressDialog progressDialog;
public ValueCallback<Uri[]> uploadMessage; public ValueCallback<Uri[]> uploadMessage;
private ProgressDialog progressDialog;
public AddEventFragment() { public AddEventFragment() {
// Required empty public constructor // Required empty public constructor
...@@ -98,6 +97,7 @@ public class AddEventFragment extends BaseFragment { ...@@ -98,6 +97,7 @@ public class AddEventFragment extends BaseFragment {
webView.setOnTouchListener(new View.OnTouchListener() { webView.setOnTouchListener(new View.OnTouchListener() {
float m_downX; float m_downX;
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
if (event.getPointerCount() > 1) { if (event.getPointerCount() > 1) {
...@@ -128,7 +128,39 @@ public class AddEventFragment extends BaseFragment { ...@@ -128,7 +128,39 @@ public class AddEventFragment extends BaseFragment {
return view; return view;
} }
public class MyWebViewClient extends WebViewClient{ void openEvent(Event event) {
String eventJson = new Gson().toJson(event);
Bundle bundle = getArguments();
if (bundle == null)
bundle = new Bundle();
bundle.putString(Constants.EVENT_JSON, eventJson);
EventFragment eventFragment = new EventFragment();
eventFragment.setArguments(bundle);
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left, R.anim.slide_in_right, R.anim.slide_out_right);
transaction.replace(R.id.framelayout_for_fragment, eventFragment, eventFragment.getTag());
transaction.addToBackStack(eventFragment.getTag()).commit();
}
void openBody(Body body) {
BodyFragment bodyFragment = BodyFragment.newInstance(body);
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left, R.anim.slide_in_right, R.anim.slide_out_right);
transaction.replace(R.id.framelayout_for_fragment, bodyFragment, bodyFragment.getTag());
transaction.addToBackStack(bodyFragment.getTag()).commit();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 101) {
if (uploadMessage == null) return;
uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
uploadMessage = null;
}
}
public class MyWebViewClient extends WebViewClient {
@Override @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { public boolean shouldOverrideUrlLoading(WebView view, String url) {
/* Check URL */ /* Check URL */
...@@ -145,7 +177,8 @@ public class AddEventFragment extends BaseFragment { ...@@ -145,7 +177,8 @@ public class AddEventFragment extends BaseFragment {
} }
@Override @Override
public void onFailure(Call<Event> call, Throwable t) { } public void onFailure(Call<Event> call, Throwable t) {
}
}); });
return true; return true;
...@@ -162,7 +195,8 @@ public class AddEventFragment extends BaseFragment { ...@@ -162,7 +195,8 @@ public class AddEventFragment extends BaseFragment {
} }
@Override @Override
public void onFailure(Call<Body> call, Throwable t) { } public void onFailure(Call<Body> call, Throwable t) {
}
}); });
return true; return true;
...@@ -206,36 +240,4 @@ public class AddEventFragment extends BaseFragment { ...@@ -206,36 +240,4 @@ public class AddEventFragment extends BaseFragment {
return true; return true;
} }
} }
void openEvent(Event event) {
String eventJson = new Gson().toJson(event);
Bundle bundle = getArguments();
if (bundle == null)
bundle = new Bundle();
bundle.putString(Constants.EVENT_JSON, eventJson);
EventFragment eventFragment = new EventFragment();
eventFragment.setArguments(bundle);
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left, R.anim.slide_in_right, R.anim.slide_out_right);
transaction.replace(R.id.framelayout_for_fragment, eventFragment, eventFragment.getTag());
transaction.addToBackStack(eventFragment.getTag()).commit();
}
void openBody(Body body) {
BodyFragment bodyFragment = BodyFragment.newInstance(body);
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left, R.anim.slide_in_right, R.anim.slide_out_right);
transaction.replace(R.id.framelayout_for_fragment, bodyFragment, bodyFragment.getTag());
transaction.addToBackStack(bodyFragment.getTag()).commit();
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == 101) {
if (uploadMessage == null) return;
uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
uploadMessage = null;
}
}
} }
...@@ -4,12 +4,13 @@ import android.os.Bundle; ...@@ -4,12 +4,13 @@ import android.os.Bundle;
public abstract class BackHandledFragment extends BaseFragment { public abstract class BackHandledFragment extends BaseFragment {
protected BackHandlerInterface backHandlerInterface; protected BackHandlerInterface backHandlerInterface;
public abstract boolean onBackPressed(); public abstract boolean onBackPressed();
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandlerInterface)) { if (!(getActivity() instanceof BackHandlerInterface)) {
throw new ClassCastException("Hosting activity must implement BackHandlerInterface"); throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
} else { } else {
backHandlerInterface = (BackHandlerInterface) getActivity(); backHandlerInterface = (BackHandlerInterface) getActivity();
......
...@@ -38,9 +38,9 @@ import java.util.List; ...@@ -38,9 +38,9 @@ import java.util.List;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.ShareURLMaker; import app.insti.ShareURLMaker;
import app.insti.activity.MainActivity;
import app.insti.adapter.BodyAdapter; import app.insti.adapter.BodyAdapter;
import app.insti.adapter.FeedAdapter; import app.insti.adapter.FeedAdapter;
import app.insti.adapter.UserAdapter; import app.insti.adapter.UserAdapter;
...@@ -93,16 +93,6 @@ public class BodyFragment extends BackHandledFragment { ...@@ -93,16 +93,6 @@ public class BodyFragment extends BackHandledFragment {
// Required empty public constructor // Required empty public constructor
} }
@Override
public boolean onBackPressed() {
if (zoomMode) {
zoomOut(expandedImageView, startBounds, startScaleFinal, bodyPicture);
zoomMode = false;
return true;
}
return false;
}
/** /**
* Use this factory method to create a new instance of * Use this factory method to create a new instance of
* this fragment using the provided parameters. * this fragment using the provided parameters.
...@@ -119,6 +109,16 @@ public class BodyFragment extends BackHandledFragment { ...@@ -119,6 +109,16 @@ public class BodyFragment extends BackHandledFragment {
return fragment; return fragment;
} }
@Override
public boolean onBackPressed() {
if (zoomMode) {
zoomOut(expandedImageView, startBounds, startScaleFinal, bodyPicture);
zoomMode = false;
return true;
}
return false;
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
...@@ -185,7 +185,7 @@ public class BodyFragment extends BackHandledFragment { ...@@ -185,7 +185,7 @@ public class BodyFragment extends BackHandledFragment {
private void setVisibleIfHasElements(int[] viewIds, List list) { private void setVisibleIfHasElements(int[] viewIds, List list) {
if (list != null && list.size() > 0) { if (list != null && list.size() > 0) {
for (int viewId: viewIds){ for (int viewId : viewIds) {
getActivity().findViewById(viewId).setVisibility(View.VISIBLE); getActivity().findViewById(viewId).setVisibility(View.VISIBLE);
} }
} }
...@@ -194,7 +194,7 @@ public class BodyFragment extends BackHandledFragment { ...@@ -194,7 +194,7 @@ public class BodyFragment extends BackHandledFragment {
private void displayBody() { private void displayBody() {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null || getView() == null) return; if (getActivity() == null || getView() == null) return;
if(!body.equals(min_body)) bodyDisplayed = true; if (!body.equals(min_body)) bodyDisplayed = true;
TextView bodyName = (TextView) getView().findViewById(R.id.body_name); TextView bodyName = (TextView) getView().findViewById(R.id.body_name);
TextView bodyDescription = (TextView) getView().findViewById(R.id.body_description); TextView bodyDescription = (TextView) getView().findViewById(R.id.body_description);
...@@ -408,33 +408,6 @@ public class BodyFragment extends BackHandledFragment { ...@@ -408,33 +408,6 @@ public class BodyFragment extends BackHandledFragment {
return inflater.inflate(R.layout.fragment_body, container, false); return inflater.inflate(R.layout.fragment_body, container, false);
} }
private class updateDbBody extends AsyncTask<Body, Void, Integer> {
@Override
protected Integer doInBackground(Body... body) {
if (appDatabase.dbDao().getBody(body[0].getBodyID()).length > 0) {
appDatabase.dbDao().updateBody(body[0]);
} else {
appDatabase.dbDao().insertBody(body[0]);
}
return 1;
}
}
private class getDbBody extends AsyncTask<String, Void, Body[]> {
@Override
protected Body[] doInBackground(String... id) {
return appDatabase.dbDao().getBody(min_body.getBodyID());
}
@Override
protected void onPostExecute(Body[] result) {
if (result.length > 0 && !bodyDisplayed) {
body = result[0];
displayBody();
}
}
}
private void zoomOut(final ImageView expandedImageView, Rect startBounds, float startScaleFinal, final View thumbView) { private void zoomOut(final ImageView expandedImageView, Rect startBounds, float startScaleFinal, final View thumbView) {
expandedImageView.setBackgroundColor(0x00000000); expandedImageView.setBackgroundColor(0x00000000);
if (mCurrentAnimator != null) { if (mCurrentAnimator != null) {
...@@ -448,7 +421,7 @@ public class BodyFragment extends BackHandledFragment { ...@@ -448,7 +421,7 @@ public class BodyFragment extends BackHandledFragment {
.ofFloat(expandedImageView, View.X, startBounds.left)) .ofFloat(expandedImageView, View.X, startBounds.left))
.with(ObjectAnimator .with(ObjectAnimator
.ofFloat(expandedImageView, .ofFloat(expandedImageView,
View.Y,startBounds.top)) View.Y, startBounds.top))
.with(ObjectAnimator .with(ObjectAnimator
.ofFloat(expandedImageView, .ofFloat(expandedImageView,
View.SCALE_X, startScaleFinal)) View.SCALE_X, startScaleFinal))
...@@ -571,4 +544,31 @@ public class BodyFragment extends BackHandledFragment { ...@@ -571,4 +544,31 @@ public class BodyFragment extends BackHandledFragment {
startScaleFinal = startScale; startScaleFinal = startScale;
zoomMode = true; zoomMode = true;
} }
private class updateDbBody extends AsyncTask<Body, Void, Integer> {
@Override
protected Integer doInBackground(Body... body) {
if (appDatabase.dbDao().getBody(body[0].getBodyID()).length > 0) {
appDatabase.dbDao().updateBody(body[0]);
} else {
appDatabase.dbDao().insertBody(body[0]);
}
return 1;
}
}
private class getDbBody extends AsyncTask<String, Void, Body[]> {
@Override
protected Body[] doInBackground(String... id) {
return appDatabase.dbDao().getBody(min_body.getBodyID());
}
@Override
protected void onPostExecute(Body[] result) {
if (result.length > 0 && !bodyDisplayed) {
body = result[0];
displayBody();
}
}
}
} }
...@@ -29,8 +29,8 @@ import java.util.TimeZone; ...@@ -29,8 +29,8 @@ import java.util.TimeZone;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.FeedAdapter; import app.insti.adapter.FeedAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -92,7 +92,7 @@ public class CalendarFragment extends BaseFragment { ...@@ -92,7 +92,7 @@ public class CalendarFragment extends BaseFragment {
((MainActivity) getActivity()).updateFragment(addEventFragment); ((MainActivity) getActivity()).updateFragment(addEventFragment);
} }
}); });
if (((MainActivity)getActivity()).createEventAccess()) { if (((MainActivity) getActivity()).createEventAccess()) {
fab.setVisibility(View.VISIBLE); fab.setVisibility(View.VISIBLE);
} }
......
...@@ -44,9 +44,9 @@ import java.util.List; ...@@ -44,9 +44,9 @@ import java.util.List;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.ShareURLMaker; import app.insti.ShareURLMaker;
import app.insti.activity.MainActivity;
import app.insti.adapter.BodyAdapter; import app.insti.adapter.BodyAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -92,6 +92,27 @@ public class EventFragment extends BackHandledFragment { ...@@ -92,6 +92,27 @@ public class EventFragment extends BackHandledFragment {
// Required empty public constructor // Required empty public constructor
} }
/**
* Get a spannable with a small count badge to set for an element text
*
* @param text Text to show in the spannable
* @param count integer count to show in the badge
* @return spannable to be used as view.setText(spannable)
*/
static Spannable getCountBadgeSpannable(String text, Integer count) {
// Check for nulls
if (count == null) return new SpannableString(text);
// Make a spannable
String countString = Integer.toString(count);
Spannable spannable = new SpannableString(text + " " + countString);
// Set font face and color of badge
spannable.setSpan(new RelativeSizeSpan(0.75f), text.length(), text.length() + 1 + countString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(Color.DKGRAY), text.length(), text.length() + 1 + countString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
return spannable;
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
...@@ -270,28 +291,6 @@ public class EventFragment extends BackHandledFragment { ...@@ -270,28 +291,6 @@ public class EventFragment extends BackHandledFragment {
goingButton.setText(getCountBadgeSpannable("GOING", event.getEventGoingCount())); goingButton.setText(getCountBadgeSpannable("GOING", event.getEventGoingCount()));
} }
/**
* Get a spannable with a small count badge to set for an element text
*
* @param text Text to show in the spannable
* @param count integer count to show in the badge
* @return spannable to be used as view.setText(spannable)
*/
static Spannable getCountBadgeSpannable(String text, Integer count) {
// Check for nulls
if (count == null) return new SpannableString(text);
// Make a spannable
String countString = Integer.toString(count);
Spannable spannable = new SpannableString(text + " " + countString);
// Set font face and color of badge
spannable.setSpan(new RelativeSizeSpan(0.75f), text.length(), text.length() + 1 + countString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(Color.DKGRAY), text.length(), text.length() + 1 + countString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
return spannable;
}
View.OnClickListener getUESOnClickListener(final int status) { View.OnClickListener getUESOnClickListener(final int status) {
return new View.OnClickListener() { return new View.OnClickListener() {
@Override @Override
...@@ -304,14 +303,26 @@ public class EventFragment extends BackHandledFragment { ...@@ -304,14 +303,26 @@ public class EventFragment extends BackHandledFragment {
if (response.isSuccessful()) { if (response.isSuccessful()) {
/* TODO: Find a better way to change counts */ /* TODO: Find a better way to change counts */
if (endStatus == 0) { if (endStatus == 0) {
if (event.getEventUserUes() == 1) { event.setEventInterestedCount(event.getEventInterestedCount() - 1); } if (event.getEventUserUes() == 1) {
if (event.getEventUserUes() == 2) { event.setEventGoingCount(event.getEventGoingCount() - 1); } event.setEventInterestedCount(event.getEventInterestedCount() - 1);
}
if (event.getEventUserUes() == 2) {
event.setEventGoingCount(event.getEventGoingCount() - 1);
}
} else if (endStatus == 1) { } else if (endStatus == 1) {
if (event.getEventUserUes() != 1) { event.setEventInterestedCount(event.getEventInterestedCount() + 1); } if (event.getEventUserUes() != 1) {
if (event.getEventUserUes() == 2) { event.setEventGoingCount(event.getEventGoingCount() - 1); } event.setEventInterestedCount(event.getEventInterestedCount() + 1);
}
if (event.getEventUserUes() == 2) {
event.setEventGoingCount(event.getEventGoingCount() - 1);
}
} else if (endStatus == 2) { } else if (endStatus == 2) {
if (event.getEventUserUes() != 2) { event.setEventGoingCount(event.getEventGoingCount() + 1); } if (event.getEventUserUes() != 2) {
if (event.getEventUserUes() == 1) { event.setEventInterestedCount(event.getEventInterestedCount() - 1); } event.setEventGoingCount(event.getEventGoingCount() + 1);
}
if (event.getEventUserUes() == 1) {
event.setEventInterestedCount(event.getEventInterestedCount() - 1);
}
} }
event.setEventUserUes(endStatus); event.setEventUserUes(endStatus);
...@@ -329,14 +340,6 @@ public class EventFragment extends BackHandledFragment { ...@@ -329,14 +340,6 @@ public class EventFragment extends BackHandledFragment {
}; };
} }
private class updateDbEvent extends AsyncTask<Event, Void, Integer> {
@Override
protected Integer doInBackground(Event... event) {
appDatabase.dbDao().updateEvent(event[0]);
return 1;
}
}
private void zoomImageFromThumb(final ImageView thumbView) { private void zoomImageFromThumb(final ImageView thumbView) {
// If there's an animation in progress, cancel it // If there's an animation in progress, cancel it
// immediately and proceed with this one. // immediately and proceed with this one.
...@@ -446,7 +449,7 @@ public class EventFragment extends BackHandledFragment { ...@@ -446,7 +449,7 @@ public class EventFragment extends BackHandledFragment {
.ofFloat(expandedImageView, View.X, startBounds.left)) .ofFloat(expandedImageView, View.X, startBounds.left))
.with(ObjectAnimator .with(ObjectAnimator
.ofFloat(expandedImageView, .ofFloat(expandedImageView,
View.Y,startBounds.top)) View.Y, startBounds.top))
.with(ObjectAnimator .with(ObjectAnimator
.ofFloat(expandedImageView, .ofFloat(expandedImageView,
View.SCALE_X, startScaleFinal)) View.SCALE_X, startScaleFinal))
...@@ -473,4 +476,12 @@ public class EventFragment extends BackHandledFragment { ...@@ -473,4 +476,12 @@ public class EventFragment extends BackHandledFragment {
set.start(); set.start();
mCurrentAnimator = set; mCurrentAnimator = set;
} }
private class updateDbEvent extends AsyncTask<Event, Void, Integer> {
@Override
protected Integer doInBackground(Event... event) {
appDatabase.dbDao().updateEvent(event[0]);
return 1;
}
}
} }
...@@ -21,8 +21,8 @@ import java.util.List; ...@@ -21,8 +21,8 @@ import java.util.List;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.BodyAdapter; import app.insti.adapter.BodyAdapter;
import app.insti.adapter.FeedAdapter; import app.insti.adapter.FeedAdapter;
import app.insti.adapter.UserAdapter; import app.insti.adapter.UserAdapter;
...@@ -60,6 +60,7 @@ public class ExploreFragment extends Fragment { ...@@ -60,6 +60,7 @@ public class ExploreFragment extends Fragment {
/** /**
* Use this factory method to create a new instance of * Use this factory method to create a new instance of
* this fragment. * this fragment.
*
* @return A new instance of fragment ExploreFragment. * @return A new instance of fragment ExploreFragment.
*/ */
// TODO: Rename and change types and number of parameters // TODO: Rename and change types and number of parameters
...@@ -96,7 +97,8 @@ public class ExploreFragment extends Fragment { ...@@ -96,7 +97,8 @@ public class ExploreFragment extends Fragment {
} }
@Override @Override
public void onFailure(Call<List<Body>> call, Throwable t) {} public void onFailure(Call<List<Body>> call, Throwable t) {
}
}); });
} else { } else {
getView().findViewById(R.id.loadingPanel).setVisibility(View.GONE); getView().findViewById(R.id.loadingPanel).setVisibility(View.GONE);
...@@ -106,9 +108,12 @@ public class ExploreFragment extends Fragment { ...@@ -106,9 +108,12 @@ public class ExploreFragment extends Fragment {
final EditText searchEditText = getView().findViewById(R.id.explore_search); final EditText searchEditText = getView().findViewById(R.id.explore_search);
searchEditText.addTextChangedListener(new TextWatcher() { searchEditText.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {} public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
......
...@@ -23,8 +23,8 @@ import java.util.List; ...@@ -23,8 +23,8 @@ import java.util.List;
import app.insti.ActivityBuffer; import app.insti.ActivityBuffer;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.FeedAdapter; import app.insti.adapter.FeedAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -124,9 +124,9 @@ public class FeedFragment extends BaseFragment { ...@@ -124,9 +124,9 @@ public class FeedFragment extends BaseFragment {
((MainActivity) getActivity()).updateFragment(addEventFragment); ((MainActivity) getActivity()).updateFragment(addEventFragment);
} }
}); });
feedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){ feedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy){ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) fab.hide(); if (dy > 0) fab.hide();
else if (dy < 0) fab.show(); else if (dy < 0) fab.show();
} }
......
...@@ -87,8 +87,8 @@ import java.util.Locale; ...@@ -87,8 +87,8 @@ import java.util.Locale;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import app.insti.Constants; import app.insti.Constants;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
import app.insti.data.AppDatabase; import app.insti.data.AppDatabase;
...@@ -102,7 +102,33 @@ import static app.insti.Constants.MY_PERMISSIONS_REQUEST_LOCATION; ...@@ -102,7 +102,33 @@ import static app.insti.Constants.MY_PERMISSIONS_REQUEST_LOCATION;
public class MapFragment extends Fragment implements TextWatcher, public class MapFragment extends Fragment implements TextWatcher,
TextView.OnEditorActionListener, AdapterView.OnItemClickListener, View.OnFocusChangeListener, TextView.OnEditorActionListener, AdapterView.OnItemClickListener, View.OnFocusChangeListener,
View.OnTouchListener, ExpandableListView.OnChildClickListener { View.OnTouchListener, ExpandableListView.OnChildClickListener {
public static final PointF MAP_CENTER = new PointF(2971f, 1744f);
public static final long DURATION_INIT_MAP_ANIM = 500;
public static final String FONT_SEMIBOLD = "rigascreen_bold.ttf";
public static final String FONT_REGULAR = "rigascreen_regular.ttf";
public static final int SOUND_ID_RESULT = 0;
public static final int SOUND_ID_ADD = 1;
public static final int SOUND_ID_REMOVE = 2;
private static final String INSTANCE_CARD_STATE = "instanceCardState";
private static final String INSTANCE_VISIBILITY_INDEX = "instanceVisibilityIndex";
private static MapFragment mainactivity; private static MapFragment mainactivity;
private final String firstStackTag = "FIRST_TAG";
private final int MSG_ANIMATE = 1;
private final int MSG_PLAY_SOUND = 2;
private final int MSG_DISPLAY_MAP = 3;
private final long DELAY_ANIMATE = 150;
private final long DELAY_INIT_LAYOUT = 250;
public LinearLayout newSmallCard;
public ImageView placeColor;
public TextView placeNameTextView;
public TextView placeSubHeadTextView;
public EditText editText;
public HashMap<String, com.mrane.data.Marker> data;
public FragmentTransaction transaction;
public CampusMapView campusMapView;
public ImageButton addMarkerIcon;
public SoundPool soundPool;
public int[] soundPoolIds;
private AppDatabase appDatabase; private AppDatabase appDatabase;
private SettingsManager settingsManager; private SettingsManager settingsManager;
private FuzzySearchAdapter adapter; private FuzzySearchAdapter adapter;
...@@ -110,47 +136,21 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -110,47 +136,21 @@ public class MapFragment extends Fragment implements TextWatcher,
private FragmentManager fragmentManager; private FragmentManager fragmentManager;
private ListFragment listFragment; private ListFragment listFragment;
private Fragment fragment; private Fragment fragment;
public LinearLayout newSmallCard;
public ImageView placeColor;
private RelativeLayout fragmentContainer; private RelativeLayout fragmentContainer;
private View actionBarView; private View actionBarView;
public TextView placeNameTextView;
public TextView placeSubHeadTextView;
public EditText editText;
public HashMap<String, com.mrane.data.Marker> data;
private List<com.mrane.data.Marker> markerlist; private List<com.mrane.data.Marker> markerlist;
public FragmentTransaction transaction;
public CampusMapView campusMapView;
public ImageButton addMarkerIcon;
private DrawerLayout mDrawerLayout; private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle; private ActionBarDrawerToggle mDrawerToggle;
private SlidingUpPanelLayout slidingLayout; private SlidingUpPanelLayout slidingLayout;
private CardSlideListener cardSlideListener; private CardSlideListener cardSlideListener;
private boolean noFragments = true; private boolean noFragments = true;
private boolean editTextFocused = false; private boolean editTextFocused = false;
private final String firstStackTag = "FIRST_TAG";
private final int MSG_ANIMATE = 1;
private final int MSG_PLAY_SOUND = 2;
private final int MSG_DISPLAY_MAP = 3;
private final long DELAY_ANIMATE = 150;
private final long DELAY_INIT_LAYOUT = 250;
private Toast toast; private Toast toast;
private String message = "Sorry, no such place in our data."; private String message = "Sorry, no such place in our data.";
public static final PointF MAP_CENTER = new PointF(2971f, 1744f);
public static final long DURATION_INIT_MAP_ANIM = 500;
public static final String FONT_SEMIBOLD = "rigascreen_bold.ttf";
public static final String FONT_REGULAR = "rigascreen_regular.ttf";
public static final int SOUND_ID_RESULT = 0;
public static final int SOUND_ID_ADD = 1;
public static final int SOUND_ID_REMOVE = 2;
public SoundPool soundPool;
public int[] soundPoolIds;
private boolean locationsShown = false; private boolean locationsShown = false;
private boolean GPSIsSetup = false; private boolean GPSIsSetup = false;
private boolean followingUser = false; private boolean followingUser = false;
private Marker user = new Marker("You", "", 0, 0, -10, ""); private Marker user = new Marker("You", "", 0, 0, -10, "");
private Handler mHandler = new Handler() { private Handler mHandler = new Handler() {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
...@@ -172,6 +172,35 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -172,6 +172,35 @@ public class MapFragment extends Fragment implements TextWatcher,
// Required empty public constructor // Required empty public constructor
} }
public static MapFragment getMainActivity() {
return mainactivity;
}
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
RelativeLayout.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
mainactivity = this; mainactivity = this;
...@@ -195,7 +224,7 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -195,7 +224,7 @@ public class MapFragment extends Fragment implements TextWatcher,
/* Initialize */ /* Initialize */
appDatabase = AppDatabase.getAppDatabase(getContext()); appDatabase = AppDatabase.getAppDatabase(getContext());
editText = (EditText)getView().findViewById(R.id.search); editText = (EditText) getView().findViewById(R.id.search);
setFonts(); setFonts();
getAPILocations(); getAPILocations();
...@@ -223,29 +252,6 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -223,29 +252,6 @@ public class MapFragment extends Fragment implements TextWatcher,
}); });
} }
private class updateDatabase extends AsyncTask<List<Venue>, Void, Integer> {
@Override
protected Integer doInBackground(List<Venue>... venues) {
appDatabase.dbDao().deleteVenues();
appDatabase.dbDao().insertVenues(venues[0]);
return 1;
}
}
private class showLocationsFromDB extends AsyncTask<String, Void, List<Venue>> {
@Override
protected List<Venue> doInBackground(String... events) {
return appDatabase.dbDao().getAllVenues();
}
protected void onPostExecute(List<Venue> result) {
if (!locationsShown && result.size() > 0) {
setupWithData(result);
locationsShown = true;
}
}
}
void setupWithData(List<Venue> venues) { void setupWithData(List<Venue> venues) {
if (getView() == null || getActivity() == null) return; if (getView() == null || getActivity() == null) return;
Locations mLocations = new Locations(venues); Locations mLocations = new Locations(venues);
...@@ -302,7 +308,7 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -302,7 +308,7 @@ public class MapFragment extends Fragment implements TextWatcher,
fragmentContainer = (RelativeLayout) getActivity().findViewById(R.id.fragment_container); fragmentContainer = (RelativeLayout) getActivity().findViewById(R.id.fragment_container);
adapter = new FuzzySearchAdapter(getContext(), markerlist); adapter = new FuzzySearchAdapter(getContext(), markerlist);
editText = (EditText)getView().findViewById(R.id.search); editText = (EditText) getView().findViewById(R.id.search);
editText.addTextChangedListener(this); editText.addTextChangedListener(this);
editText.setOnEditorActionListener(this); editText.setOnEditorActionListener(this);
editText.setOnFocusChangeListener(this); editText.setOnFocusChangeListener(this);
...@@ -351,9 +357,9 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -351,9 +357,9 @@ public class MapFragment extends Fragment implements TextWatcher,
} }
private void initShowDefault() { private void initShowDefault() {
String[] keys = { "Convocation Hall", "Hostel 13 House of Titans", String[] keys = {"Convocation Hall", "Hostel 13 House of Titans",
"Hostel 15", "Main Gate no. 2", "Hostel 15", "Main Gate no. 2",
"Market Gate, Y point Gate no. 3", "Lake Side Gate no. 1", }; "Market Gate, Y point Gate no. 3", "Lake Side Gate no. 1",};
for (String key : keys) { for (String key : keys) {
if (data.containsKey(key)) { if (data.containsKey(key)) {
data.get(key).setShowDefault(true); data.get(key).setShowDefault(true);
...@@ -364,13 +370,13 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -364,13 +370,13 @@ public class MapFragment extends Fragment implements TextWatcher,
} }
private void initImageUri() { private void initImageUri() {
String[] keys = { "Convocation Hall", "Guest House/ Jalvihar", String[] keys = {"Convocation Hall", "Guest House/ Jalvihar",
"Guest House/ Vanvihar", "Gulmohar Restaurant", "Hostel 14", "Guest House/ Vanvihar", "Gulmohar Restaurant", "Hostel 14",
"Industrial Design Centre", "Main Building", "Industrial Design Centre", "Main Building",
"Nestle Cafe (Coffee Shack)", "School of Management", "Nestle Cafe (Coffee Shack)", "School of Management",
"Victor Menezes Convention Centre" }; "Victor Menezes Convention Centre"};
String[] uri = { "convo_hall", "jalvihar", "vanvihar", "gulmohar", String[] uri = {"convo_hall", "jalvihar", "vanvihar", "gulmohar",
"h14", "idc", "mainbuilding", "nescafestall", "som", "vmcc" }; "h14", "idc", "mainbuilding", "nescafestall", "som", "vmcc"};
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
if (data.containsKey(keys[i])) { if (data.containsKey(keys[i])) {
data.get(keys[i]).setImageUri(uri[i]); data.get(keys[i]).setImageUri(uri[i]);
...@@ -462,10 +468,6 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -462,10 +468,6 @@ public class MapFragment extends Fragment implements TextWatcher,
return true; return true;
} }
public static MapFragment getMainActivity() {
return mainactivity;
}
private void putFragment(Fragment tempFragment) { private void putFragment(Fragment tempFragment) {
this.dismissCard(); this.dismissCard();
transaction = fragmentManager.beginTransaction(); transaction = fragmentManager.beginTransaction();
...@@ -595,31 +597,6 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -595,31 +597,6 @@ public class MapFragment extends Fragment implements TextWatcher,
} }
} }
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
RelativeLayout.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
private void setChildrenView(LinearLayout parent, Building building) { private void setChildrenView(LinearLayout parent, Building building) {
View childrenView = getLayoutInflater().inflate(R.layout.map_children_view, View childrenView = getLayoutInflater().inflate(R.layout.map_children_view,
parent); parent);
...@@ -678,47 +655,10 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -678,47 +655,10 @@ public class MapFragment extends Fragment implements TextWatcher,
} }
private class CustomListAdapter extends ArrayAdapter<String> {
private Context mContext;
private int id;
private List<String> items;
public CustomListAdapter(Context context, int textViewResourceId,
List<String> list) {
super(context, textViewResourceId, list);
mContext = context;
id = textViewResourceId;
items = list;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
View mView = v;
if (mView == null) {
LayoutInflater vi = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(id, null);
}
TextView text = (TextView) mView.findViewById(R.id.child_name);
Log.d("testing", "position = " + position);
if (items.get(position) != null) {
Typeface regular = Typeface.createFromAsset(getContext().getAssets(),
FONT_REGULAR);
text.setText(items.get(position));
text.setTypeface(regular);
}
return mView;
}
}
private SpannableStringBuilder getDescriptionText(com.mrane.data.Marker marker) { private SpannableStringBuilder getDescriptionText(com.mrane.data.Marker marker) {
String text = marker.getDescription(); String text = marker.getDescription();
SpannableStringBuilder desc = new SpannableStringBuilder(text); SpannableStringBuilder desc = new SpannableStringBuilder(text);
String[] toBoldParts = { "Email", "Phone No.", "Fax No." }; String[] toBoldParts = {"Email", "Phone No.", "Fax No."};
for (String part : toBoldParts) { for (String part : toBoldParts) {
setBold(desc, part); setBold(desc, part);
} }
...@@ -1011,9 +951,6 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -1011,9 +951,6 @@ public class MapFragment extends Fragment implements TextWatcher,
this.expAdapter = expAdapter; this.expAdapter = expAdapter;
} }
private static final String INSTANCE_CARD_STATE = "instanceCardState";
private static final String INSTANCE_VISIBILITY_INDEX = "instanceVisibilityIndex";
public SlidingUpPanelLayout getSlidingLayout() { public SlidingUpPanelLayout getSlidingLayout() {
return slidingLayout; return slidingLayout;
} }
...@@ -1042,50 +979,6 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -1042,50 +979,6 @@ public class MapFragment extends Fragment implements TextWatcher,
} }
} }
/*---------- Listener class to get coordinates ------------- */
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location loc) {
if (getView() == null || getActivity() == null) return;
// Set the origin
double Xn = Constants.MAP_Xn, Yn = Constants.MAP_Yn, Zn = Constants.MAP_Zn, Zyn = Constants.MAP_Zyn;
double x = (loc.getLatitude() - Xn) * 1000;
double y = (loc.getLongitude() - Yn) * 1000;
// Pre-trained weights
double[] A = Constants.MAP_WEIGHTS_X;
int px = (int)(Zn + A[0] + A[1]*x + A[2]*y + A[3]*x*x + A[4]*x*x*y + A[5]*x*x*y*y + A[6]*y*y + A[7]*x*y*y + A[8]*x*y);
A = Constants.MAP_WEIGHTS_Y;
int py = (int)(Zyn + A[0] + A[1]*x + A[2]*y + A[3]*x*x + A[4]*x*x*y + A[5]*x*x*y*y + A[6]*y*y + A[7]*x*y*y + A[8]*x*y);
if (px > 0 && py > 0 && px < 5430 && py < 5375){
if (!campusMapView.isAddedMarker(user)) {
campusMapView.addMarker(user);
}
user.setPoint(new PointF(px, py));
user.setName("You - " + (int)loc.getAccuracy() + "m");
if (followingUser) {
SubsamplingScaleImageView.AnimationBuilder anim = campusMapView.animateCenter(user.getPoint());
if (anim != null) anim.start();
}
campusMapView.invalidate();
}
}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
public void setFollowingUser(boolean followingUser) { public void setFollowingUser(boolean followingUser) {
this.followingUser = followingUser; this.followingUser = followingUser;
} }
...@@ -1109,8 +1002,7 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -1109,8 +1002,7 @@ public class MapFragment extends Fragment implements TextWatcher,
if (result.getLocationSettingsStates().isGpsPresent() && if (result.getLocationSettingsStates().isGpsPresent() &&
result.getLocationSettingsStates().isGpsUsable() && result.getLocationSettingsStates().isGpsUsable() &&
result.getLocationSettingsStates().isLocationPresent() && result.getLocationSettingsStates().isLocationPresent() &&
result.getLocationSettingsStates().isLocationUsable()) result.getLocationSettingsStates().isLocationUsable()) {
{
setupGPS(); setupGPS();
} }
} catch (ApiException ex) { } catch (ApiException ex) {
...@@ -1122,7 +1014,8 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -1122,7 +1014,8 @@ public class MapFragment extends Fragment implements TextWatcher,
resolvableApiException resolvableApiException
.startResolutionForResult(getActivity(), 87); .startResolutionForResult(getActivity(), 87);
setupGPS(); setupGPS();
} catch (IntentSender.SendIntentException e) { } } catch (IntentSender.SendIntentException e) {
}
break; break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Toast.makeText(getContext(), "GPS is not enabled!", Toast.LENGTH_LONG).show(); Toast.makeText(getContext(), "GPS is not enabled!", Toast.LENGTH_LONG).show();
...@@ -1132,5 +1025,112 @@ public class MapFragment extends Fragment implements TextWatcher, ...@@ -1132,5 +1025,112 @@ public class MapFragment extends Fragment implements TextWatcher,
} }
}); });
} }
private class updateDatabase extends AsyncTask<List<Venue>, Void, Integer> {
@Override
protected Integer doInBackground(List<Venue>... venues) {
appDatabase.dbDao().deleteVenues();
appDatabase.dbDao().insertVenues(venues[0]);
return 1;
}
}
private class showLocationsFromDB extends AsyncTask<String, Void, List<Venue>> {
@Override
protected List<Venue> doInBackground(String... events) {
return appDatabase.dbDao().getAllVenues();
}
protected void onPostExecute(List<Venue> result) {
if (!locationsShown && result.size() > 0) {
setupWithData(result);
locationsShown = true;
}
}
}
private class CustomListAdapter extends ArrayAdapter<String> {
private Context mContext;
private int id;
private List<String> items;
public CustomListAdapter(Context context, int textViewResourceId,
List<String> list) {
super(context, textViewResourceId, list);
mContext = context;
id = textViewResourceId;
items = list;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
View mView = v;
if (mView == null) {
LayoutInflater vi = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(id, null);
}
TextView text = (TextView) mView.findViewById(R.id.child_name);
Log.d("testing", "position = " + position);
if (items.get(position) != null) {
Typeface regular = Typeface.createFromAsset(getContext().getAssets(),
FONT_REGULAR);
text.setText(items.get(position));
text.setTypeface(regular);
}
return mView;
}
}
/*---------- Listener class to get coordinates ------------- */
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location loc) {
if (getView() == null || getActivity() == null) return;
// Set the origin
double Xn = Constants.MAP_Xn, Yn = Constants.MAP_Yn, Zn = Constants.MAP_Zn, Zyn = Constants.MAP_Zyn;
double x = (loc.getLatitude() - Xn) * 1000;
double y = (loc.getLongitude() - Yn) * 1000;
// Pre-trained weights
double[] A = Constants.MAP_WEIGHTS_X;
int px = (int) (Zn + A[0] + A[1] * x + A[2] * y + A[3] * x * x + A[4] * x * x * y + A[5] * x * x * y * y + A[6] * y * y + A[7] * x * y * y + A[8] * x * y);
A = Constants.MAP_WEIGHTS_Y;
int py = (int) (Zyn + A[0] + A[1] * x + A[2] * y + A[3] * x * x + A[4] * x * x * y + A[5] * x * x * y * y + A[6] * y * y + A[7] * x * y * y + A[8] * x * y);
if (px > 0 && py > 0 && px < 5430 && py < 5375) {
if (!campusMapView.isAddedMarker(user)) {
campusMapView.addMarker(user);
}
user.setPoint(new PointF(px, py));
user.setName("You - " + (int) loc.getAccuracy() + "m");
if (followingUser) {
SubsamplingScaleImageView.AnimationBuilder anim = campusMapView.animateCenter(user.getPoint());
if (anim != null) anim.start();
}
campusMapView.invalidate();
}
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
} }
...@@ -156,12 +156,14 @@ public class MessMenuFragment extends BaseFragment { ...@@ -156,12 +156,14 @@ public class MessMenuFragment extends BaseFragment {
final List<MessMenu> sortedMenus = new ArrayList<>(); final List<MessMenu> sortedMenus = new ArrayList<>();
final Calendar calendar = Calendar.getInstance(Locale.UK); final Calendar calendar = Calendar.getInstance(Locale.UK);
int today = calendar.get(Calendar.DAY_OF_WEEK) - 2; int today = calendar.get(Calendar.DAY_OF_WEEK) - 2;
if (today == -1) { today = 6; } if (today == -1) {
today = 6;
}
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
final int day = (today + i) % 7 + 1; final int day = (today + i) % 7 + 1;
for(MessMenu menu : messMenus) { for (MessMenu menu : messMenus) {
if(menu.getDay() == day) { if (menu.getDay() == day) {
sortedMenus.add(menu); sortedMenus.add(menu);
} }
} }
......
...@@ -23,8 +23,8 @@ import java.util.List; ...@@ -23,8 +23,8 @@ import java.util.List;
import app.insti.ActivityBuffer; import app.insti.ActivityBuffer;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.FeedAdapter; import app.insti.adapter.FeedAdapter;
import app.insti.data.AppDatabase; import app.insti.data.AppDatabase;
import app.insti.data.Event; import app.insti.data.Event;
...@@ -67,7 +67,7 @@ public class MyEventsFragment extends BaseFragment { ...@@ -67,7 +67,7 @@ public class MyEventsFragment extends BaseFragment {
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
if (((MainActivity)getActivity()).createEventAccess()) { if (((MainActivity) getActivity()).createEventAccess()) {
fab.setVisibility(View.VISIBLE); fab.setVisibility(View.VISIBLE);
} }
......
...@@ -26,8 +26,8 @@ import java.util.List; ...@@ -26,8 +26,8 @@ import java.util.List;
import app.insti.ActivityBuffer; import app.insti.ActivityBuffer;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.NewsAdapter; import app.insti.adapter.NewsAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -42,11 +42,11 @@ import retrofit2.Response; ...@@ -42,11 +42,11 @@ import retrofit2.Response;
*/ */
public class NewsFragment extends BaseFragment { public class NewsFragment extends BaseFragment {
public static boolean showLoader = true;
private RecyclerView newsRecyclerView; private RecyclerView newsRecyclerView;
private SwipeRefreshLayout newsSwipeRefreshLayout; private SwipeRefreshLayout newsSwipeRefreshLayout;
private AppDatabase appDatabase; private AppDatabase appDatabase;
private boolean freshNewsDisplayed = false; private boolean freshNewsDisplayed = false;
public static boolean showLoader = true;
private String searchQuery; private String searchQuery;
public NewsFragment() { public NewsFragment() {
...@@ -177,28 +177,6 @@ public class NewsFragment extends BaseFragment { ...@@ -177,28 +177,6 @@ public class NewsFragment extends BaseFragment {
startActivity(browse); startActivity(browse);
} }
private class updateDatabase extends AsyncTask<List<NewsArticle>, Void, Integer> {
@Override
protected Integer doInBackground(List<NewsArticle>... posts) {
appDatabase.dbDao().deleteNewsArticles();
appDatabase.dbDao().insertNewsArticles(posts[0]);
return 1;
}
}
private class showNewsFromDB extends AsyncTask<String, Void, List<NewsArticle>> {
@Override
protected List<NewsArticle> doInBackground(String... posts) {
return appDatabase.dbDao().getAllNewsArticles();
}
protected void onPostExecute(List<NewsArticle> result) {
if (!freshNewsDisplayed) {
displayNews(result);
}
}
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu); inflater.inflate(R.menu.search_view_menu, menu);
...@@ -215,7 +193,7 @@ public class NewsFragment extends BaseFragment { ...@@ -215,7 +193,7 @@ public class NewsFragment extends BaseFragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)){ if (TextUtils.isEmpty(newText)) {
//Text is cleared, do your thing //Text is cleared, do your thing
searchQuery = null; searchQuery = null;
updateNews(); updateNews();
...@@ -235,4 +213,26 @@ public class NewsFragment extends BaseFragment { ...@@ -235,4 +213,26 @@ public class NewsFragment extends BaseFragment {
updateNews(); updateNews();
showLoader = false; showLoader = false;
} }
private class updateDatabase extends AsyncTask<List<NewsArticle>, Void, Integer> {
@Override
protected Integer doInBackground(List<NewsArticle>... posts) {
appDatabase.dbDao().deleteNewsArticles();
appDatabase.dbDao().insertNewsArticles(posts[0]);
return 1;
}
}
private class showNewsFromDB extends AsyncTask<String, Void, List<NewsArticle>> {
@Override
protected List<NewsArticle> doInBackground(String... posts) {
return appDatabase.dbDao().getAllNewsArticles();
}
protected void onPostExecute(List<NewsArticle> result) {
if (!freshNewsDisplayed) {
displayNews(result);
}
}
}
} }
...@@ -18,8 +18,8 @@ import java.util.List; ...@@ -18,8 +18,8 @@ import java.util.List;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.NotificationsAdapter; import app.insti.adapter.NotificationsAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -58,7 +58,7 @@ public class NotificationsFragment extends BaseFragment { ...@@ -58,7 +58,7 @@ public class NotificationsFragment extends BaseFragment {
toolbar.setTitle("Notifications"); toolbar.setTitle("Notifications");
RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class); RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
retrofitInterface.getNotifications(((MainActivity)getActivity()).getSessionIDHeader()).enqueue(new Callback<List<Notification>>() { retrofitInterface.getNotifications(((MainActivity) getActivity()).getSessionIDHeader()).enqueue(new Callback<List<Notification>>() {
@Override @Override
public void onResponse(Call<List<Notification>> call, Response<List<Notification>> response) { public void onResponse(Call<List<Notification>> call, Response<List<Notification>> response) {
if (response.isSuccessful()) { if (response.isSuccessful()) {
...@@ -68,7 +68,8 @@ public class NotificationsFragment extends BaseFragment { ...@@ -68,7 +68,8 @@ public class NotificationsFragment extends BaseFragment {
} }
@Override @Override
public void onFailure(Call<List<Notification>> call, Throwable t) { } public void onFailure(Call<List<Notification>> call, Throwable t) {
}
}); });
} }
...@@ -87,12 +88,15 @@ public class NotificationsFragment extends BaseFragment { ...@@ -87,12 +88,15 @@ public class NotificationsFragment extends BaseFragment {
/* Mark notification read */ /* Mark notification read */
RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class); RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
String sessId = ((MainActivity)getActivity()).getSessionIDHeader(); String sessId = ((MainActivity) getActivity()).getSessionIDHeader();
retrofitInterface.markNotificationRead(sessId, notification.getNotificationId()).enqueue(new Callback<Void>() { retrofitInterface.markNotificationRead(sessId, notification.getNotificationId()).enqueue(new Callback<Void>() {
@Override @Override
public void onResponse(Call<Void> call, Response<Void> response) { } public void onResponse(Call<Void> call, Response<Void> response) {
}
@Override @Override
public void onFailure(Call<Void> call, Throwable t) { } public void onFailure(Call<Void> call, Throwable t) {
}
}); });
FragmentManager manager = getActivity().getSupportFragmentManager(); FragmentManager manager = getActivity().getSupportFragmentManager();
...@@ -100,7 +104,9 @@ public class NotificationsFragment extends BaseFragment { ...@@ -100,7 +104,9 @@ public class NotificationsFragment extends BaseFragment {
String tag = ""; String tag = "";
Bundle bundle = getArguments(); Bundle bundle = getArguments();
if (bundle == null) { bundle = new Bundle(); } if (bundle == null) {
bundle = new Bundle();
}
bundle.putString(Constants.SESSION_ID, ((MainActivity) getActivity()).getSessionIDHeader()); bundle.putString(Constants.SESSION_ID, ((MainActivity) getActivity()).getSessionIDHeader());
/* Open event */ /* Open event */
......
...@@ -26,8 +26,8 @@ import java.util.List; ...@@ -26,8 +26,8 @@ import java.util.List;
import app.insti.ActivityBuffer; import app.insti.ActivityBuffer;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.PlacementBlogAdapter; import app.insti.adapter.PlacementBlogAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -42,12 +42,12 @@ import retrofit2.Response; ...@@ -42,12 +42,12 @@ import retrofit2.Response;
*/ */
public class PlacementBlogFragment extends BaseFragment { public class PlacementBlogFragment extends BaseFragment {
public static boolean showLoader = true;
private RecyclerView placementFeedRecyclerView; private RecyclerView placementFeedRecyclerView;
private PlacementBlogAdapter placementBlogAdapter; private PlacementBlogAdapter placementBlogAdapter;
private SwipeRefreshLayout feedSwipeRefreshLayout; private SwipeRefreshLayout feedSwipeRefreshLayout;
private AppDatabase appDatabase; private AppDatabase appDatabase;
private boolean freshBlogDisplayed = false; private boolean freshBlogDisplayed = false;
public static boolean showLoader = true;
private String searchQuery; private String searchQuery;
...@@ -177,28 +177,6 @@ public class PlacementBlogFragment extends BaseFragment { ...@@ -177,28 +177,6 @@ public class PlacementBlogFragment extends BaseFragment {
startActivity(browse); startActivity(browse);
} }
private class updateDatabase extends AsyncTask<List<PlacementBlogPost>, Void, Integer> {
@Override
protected Integer doInBackground(List<PlacementBlogPost>... posts) {
appDatabase.dbDao().deletePlacementBlogPosts();
appDatabase.dbDao().insertPlacementBlogPosts(posts[0]);
return 1;
}
}
private class showPlacementBlogFromDB extends AsyncTask<String, Void, List<PlacementBlogPost>> {
@Override
protected List<PlacementBlogPost> doInBackground(String... posts) {
return appDatabase.dbDao().getAllPlacementBlogPosts();
}
protected void onPostExecute(List<PlacementBlogPost> result) {
if (!freshBlogDisplayed) {
displayPlacementFeed(result);
}
}
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu); inflater.inflate(R.menu.search_view_menu, menu);
...@@ -215,7 +193,7 @@ public class PlacementBlogFragment extends BaseFragment { ...@@ -215,7 +193,7 @@ public class PlacementBlogFragment extends BaseFragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)){ if (TextUtils.isEmpty(newText)) {
//Text is cleared, do your thing //Text is cleared, do your thing
searchQuery = null; searchQuery = null;
updatePlacementFeed(); updatePlacementFeed();
...@@ -235,4 +213,26 @@ public class PlacementBlogFragment extends BaseFragment { ...@@ -235,4 +213,26 @@ public class PlacementBlogFragment extends BaseFragment {
updatePlacementFeed(); updatePlacementFeed();
showLoader = false; showLoader = false;
} }
private class updateDatabase extends AsyncTask<List<PlacementBlogPost>, Void, Integer> {
@Override
protected Integer doInBackground(List<PlacementBlogPost>... posts) {
appDatabase.dbDao().deletePlacementBlogPosts();
appDatabase.dbDao().insertPlacementBlogPosts(posts[0]);
return 1;
}
}
private class showPlacementBlogFromDB extends AsyncTask<String, Void, List<PlacementBlogPost>> {
@Override
protected List<PlacementBlogPost> doInBackground(String... posts) {
return appDatabase.dbDao().getAllPlacementBlogPosts();
}
protected void onPostExecute(List<PlacementBlogPost> result) {
if (!freshBlogDisplayed) {
displayPlacementFeed(result);
}
}
}
} }
...@@ -66,6 +66,13 @@ public class ProfileFragment extends BackHandledFragment { ...@@ -66,6 +66,13 @@ public class ProfileFragment extends BackHandledFragment {
// Required empty public constructor // Required empty public constructor
} }
public static ProfileFragment newInstance(String userID) {
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString(Constants.USER_ID, userID);
fragment.setArguments(args);
return fragment;
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
...@@ -221,14 +228,6 @@ public class ProfileFragment extends BackHandledFragment { ...@@ -221,14 +228,6 @@ public class ProfileFragment extends BackHandledFragment {
mCurrentAnimator = set; mCurrentAnimator = set;
} }
public static ProfileFragment newInstance(String userID) {
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString(Constants.USER_ID, userID);
fragment.setArguments(args);
return fragment;
}
private void zoomImageFromThumb(final ImageView thumbView) { private void zoomImageFromThumb(final ImageView thumbView) {
// If there's an animation in progress, cancel it // If there's an animation in progress, cancel it
// immediately and proceed with this one. // immediately and proceed with this one.
......
...@@ -17,13 +17,13 @@ public class QuickLinksFragment extends BaseFragment { ...@@ -17,13 +17,13 @@ public class QuickLinksFragment extends BaseFragment {
// Required empty public constructor // Required empty public constructor
} }
public void onStart(){ public void onStart() {
super.onStart(); super.onStart();
Toolbar toolbar = getActivity().findViewById(R.id.toolbar); Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setTitle("Quick Links"); toolbar.setTitle("Quick Links");
TextView CMS = getActivity().findViewById(R.id.button_CMS); TextView CMS = getActivity().findViewById(R.id.button_CMS);
TextView CMSMaint = getActivity().findViewById(R.id.button_CMSMaint); TextView CMSMaint = getActivity().findViewById(R.id.button_CMSMaint);
TextView CMSNet = getActivity().findViewById(R.id.button_CMSNet); TextView CMSNet = getActivity().findViewById(R.id.button_CMSNet);
TextView ASC = getActivity().findViewById(R.id.button_ASC); TextView ASC = getActivity().findViewById(R.id.button_ASC);
...@@ -47,36 +47,125 @@ public class QuickLinksFragment extends BaseFragment { ...@@ -47,36 +47,125 @@ public class QuickLinksFragment extends BaseFragment {
TextView Hospital = getActivity().findViewById(R.id.button_Hospital); TextView Hospital = getActivity().findViewById(R.id.button_Hospital);
TextView VPN = getActivity().findViewById(R.id.button_VPN); TextView VPN = getActivity().findViewById(R.id.button_VPN);
CMS.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://gymkhana.iitb.ac.in/cms_new/"); } }); CMS.setOnClickListener(new View.OnClickListener() {
CMSMaint.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://support.iitb.ac.in"); } }); public void onClick(View v) {
CMSNet.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://help-cc.iitb.ac.in/"); } }); goToUrl("https://gymkhana.iitb.ac.in/cms_new/");
ASC.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://asc.iitb.ac.in"); } }); }
ASCExt.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://portal.iitb.ac.in/asc"); } }); });
Moodle.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://moodle.iitb.ac.in"); } }); CMSMaint.setOnClickListener(new View.OnClickListener() {
Intern.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://placements.iitb.ac.in/internship/login.jsp"); } }); public void onClick(View v) {
Placement.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://placements.iitb.ac.in/placements/login.jsp"); } }); goToUrl("https://support.iitb.ac.in");
Library.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://www.library.iitb.ac.in/"); } }); }
AcadCal.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://www.iitb.ac.in/newacadhome/toacadcalender.jsp"); } }); });
AcadTime.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://www.iitb.ac.in/newacadhome/timetable.jsp"); } }); CMSNet.setOnClickListener(new View.OnClickListener() {
Holidays.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://www.iitb.ac.in/en/about-iit-bombay/iit-bombay-holidays-list"); } }); public void onClick(View v) {
Circulars.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://www.iitb.ac.in/newacadhome/circular.jsp"); } }); goToUrl("https://help-cc.iitb.ac.in/");
Courses.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://portal.iitb.ac.in/asc/Courses"); } }); }
WebMail.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://webmail.iitb.ac.in"); } }); });
GPO.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://gpo.iitb.ac.in"); } }); ASC.setOnClickListener(new View.OnClickListener() {
CAMP.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://camp.iitb.ac.in/"); } }); public void onClick(View v) {
MSStore.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://msstore.iitb.ac.in/"); } }); goToUrl("https://asc.iitb.ac.in");
BigHome.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://home.iitb.ac.in/"); } }); }
});
ASCExt.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://portal.iitb.ac.in/asc");
}
});
Moodle.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://moodle.iitb.ac.in");
}
});
Intern.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://placements.iitb.ac.in/internship/login.jsp");
}
});
Placement.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://placements.iitb.ac.in/placements/login.jsp");
}
});
Library.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://www.library.iitb.ac.in/");
}
});
AcadCal.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://www.iitb.ac.in/newacadhome/toacadcalender.jsp");
}
});
AcadTime.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://www.iitb.ac.in/newacadhome/timetable.jsp");
}
});
Holidays.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://www.iitb.ac.in/en/about-iit-bombay/iit-bombay-holidays-list");
}
});
Circulars.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://www.iitb.ac.in/newacadhome/circular.jsp");
}
});
Courses.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://portal.iitb.ac.in/asc/Courses");
}
});
WebMail.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://webmail.iitb.ac.in");
}
});
GPO.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://gpo.iitb.ac.in");
}
});
CAMP.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://camp.iitb.ac.in/");
}
});
MSStore.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://msstore.iitb.ac.in/");
}
});
BigHome.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://home.iitb.ac.in/");
}
});
// FTP.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("ftp://ftp.iitb.ac.in/"); } }); // FTP.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("ftp://ftp.iitb.ac.in/"); } });
Intercom.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://portal.iitb.ac.in/TelephoneDirectory/"); } }); Intercom.setOnClickListener(new View.OnClickListener() {
Hospital.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("http://www.iitb.ac.in/hospital/"); } }); public void onClick(View v) {
VPN.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { goToUrl("https://www.cc.iitb.ac.in/engservices/engaccessingiitffromoutside/19-vpn"); } }); goToUrl("https://portal.iitb.ac.in/TelephoneDirectory/");
}
});
Hospital.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("http://www.iitb.ac.in/hospital/");
}
});
VPN.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goToUrl("https://www.cc.iitb.ac.in/engservices/engaccessingiitffromoutside/19-vpn");
}
});
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_quick_links, container, false); return inflater.inflate(R.layout.fragment_quick_links, container, false);
} }
public void goToUrl (String url) { public void goToUrl(String url) {
Uri uriUrl = Uri.parse(url); Uri uriUrl = Uri.parse(url);
Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl); Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(launchBrowser); startActivity(launchBrowser);
......
...@@ -18,9 +18,9 @@ import android.widget.TextView; ...@@ -18,9 +18,9 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import app.insti.Constants; import app.insti.Constants;
import app.insti.activity.LoginActivity;
import app.insti.R; import app.insti.R;
import app.insti.SessionManager; import app.insti.SessionManager;
import app.insti.activity.LoginActivity;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
import app.insti.data.User; import app.insti.data.User;
......
...@@ -26,8 +26,8 @@ import java.util.List; ...@@ -26,8 +26,8 @@ import java.util.List;
import app.insti.ActivityBuffer; import app.insti.ActivityBuffer;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.TrainingBlogAdapter; import app.insti.adapter.TrainingBlogAdapter;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -42,11 +42,11 @@ import retrofit2.Response; ...@@ -42,11 +42,11 @@ import retrofit2.Response;
*/ */
public class TrainingBlogFragment extends BaseFragment { public class TrainingBlogFragment extends BaseFragment {
public static boolean showLoader = true;
private RecyclerView trainingFeedRecyclerView; private RecyclerView trainingFeedRecyclerView;
private SwipeRefreshLayout feedSwipeRefreshLayout; private SwipeRefreshLayout feedSwipeRefreshLayout;
private AppDatabase appDatabase; private AppDatabase appDatabase;
private boolean freshBlogDisplayed = false; private boolean freshBlogDisplayed = false;
public static boolean showLoader = true;
private String searchQuery; private String searchQuery;
...@@ -176,28 +176,6 @@ public class TrainingBlogFragment extends BaseFragment { ...@@ -176,28 +176,6 @@ public class TrainingBlogFragment extends BaseFragment {
startActivity(browse); startActivity(browse);
} }
private class updateDatabase extends AsyncTask<List<TrainingBlogPost>, Void, Integer> {
@Override
protected Integer doInBackground(List<TrainingBlogPost>... posts) {
appDatabase.dbDao().deleteTrainingBlogPosts();
appDatabase.dbDao().insertTrainingBlogPosts(posts[0]);
return 1;
}
}
private class showTrainingBlogFromDB extends AsyncTask<String, Void, List<TrainingBlogPost>> {
@Override
protected List<TrainingBlogPost> doInBackground(String... posts) {
return appDatabase.dbDao().getAllTrainingBlogPosts();
}
protected void onPostExecute(List<TrainingBlogPost> result) {
if (!freshBlogDisplayed) {
displayTrainingFeed(result);
}
}
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu); inflater.inflate(R.menu.search_view_menu, menu);
...@@ -214,7 +192,7 @@ public class TrainingBlogFragment extends BaseFragment { ...@@ -214,7 +192,7 @@ public class TrainingBlogFragment extends BaseFragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)){ if (TextUtils.isEmpty(newText)) {
//Text is cleared, do your thing //Text is cleared, do your thing
searchQuery = null; searchQuery = null;
updateTrainingFeed(); updateTrainingFeed();
...@@ -234,4 +212,26 @@ public class TrainingBlogFragment extends BaseFragment { ...@@ -234,4 +212,26 @@ public class TrainingBlogFragment extends BaseFragment {
updateTrainingFeed(); updateTrainingFeed();
showLoader = false; showLoader = false;
} }
private class updateDatabase extends AsyncTask<List<TrainingBlogPost>, Void, Integer> {
@Override
protected Integer doInBackground(List<TrainingBlogPost>... posts) {
appDatabase.dbDao().deleteTrainingBlogPosts();
appDatabase.dbDao().insertTrainingBlogPosts(posts[0]);
return 1;
}
}
private class showTrainingBlogFromDB extends AsyncTask<String, Void, List<TrainingBlogPost>> {
@Override
protected List<TrainingBlogPost> doInBackground(String... posts) {
return appDatabase.dbDao().getAllTrainingBlogPosts();
}
protected void onPostExecute(List<TrainingBlogPost> result) {
if (!freshBlogDisplayed) {
displayTrainingFeed(result);
}
}
}
} }
...@@ -16,9 +16,9 @@ import java.util.List; ...@@ -16,9 +16,9 @@ import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import app.insti.Constants; import app.insti.Constants;
import app.insti.activity.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.SessionManager; import app.insti.SessionManager;
import app.insti.activity.MainActivity;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
import app.insti.data.Event; import app.insti.data.Event;
...@@ -29,11 +29,11 @@ import retrofit2.Response; ...@@ -29,11 +29,11 @@ import retrofit2.Response;
public class NotificationIntentService extends JobIntentService { public class NotificationIntentService extends JobIntentService {
public static final String ACTION_OPEN_EVENT = "ACTION_OPEN_EVENT";
private static final String ACTION_START = "ACTION_START"; private static final String ACTION_START = "ACTION_START";
private static final String ACTION_DELETE = "ACTION_DELETE"; private static final String ACTION_DELETE = "ACTION_DELETE";
private static final String ACTION_NAVIGATE = "ACTION_NAVIGATE"; private static final String ACTION_NAVIGATE = "ACTION_NAVIGATE";
private static final String ACTION_NOT_GOING = "ACTION_NOT_GOING"; private static final String ACTION_NOT_GOING = "ACTION_NOT_GOING";
public static final String ACTION_OPEN_EVENT = "ACTION_OPEN_EVENT";
private static int NOTIFICATION_ID = 1; private static int NOTIFICATION_ID = 1;
private NotificationManager manager; private NotificationManager manager;
...@@ -97,7 +97,8 @@ public class NotificationIntentService extends JobIntentService { ...@@ -97,7 +97,8 @@ public class NotificationIntentService extends JobIntentService {
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri); Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
startActivity(mapIntent); startActivity(mapIntent);
} }
} finally { } } finally {
}
} }
private void processDeleteNotification(Intent intent) { private void processDeleteNotification(Intent intent) {
......
...@@ -20,111 +20,111 @@ import app.insti.fragment.MapFragment; ...@@ -20,111 +20,111 @@ import app.insti.fragment.MapFragment;
public class ExpandableListAdapter extends BaseExpandableListAdapter { public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context; private Context _context;
private List<String> _listDataHeader; private List<String> _listDataHeader;
private HashMap<String, List<String>> _listDataChild; private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader, public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) { HashMap<String, List<String>> listChildData) {
this._context = context; this._context = context;
this._listDataHeader = listDataHeader; this._listDataHeader = listDataHeader;
this._listDataChild = listChildData; this._listDataChild = listChildData;
} }
@Override @Override
public Object getChild(int groupPosition, int childPosititon) { public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition)) return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon); .get(childPosititon);
} }
@Override @Override
public long getChildId(int groupPosition, int childPosition) { public long getChildId(int groupPosition, int childPosition) {
return childPosition; return childPosition;
} }
@Override @Override
public View getChildView(int groupPosition, final int childPosition, public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) { boolean isLastChild, View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition); String headerTitle = (String) getGroup(groupPosition);
final String childText = (String) getChild(groupPosition, childPosition); final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) { if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.map_list_item, null); convertView = infalInflater.inflate(R.layout.map_list_item, null);
} }
TextView txtListChild = (TextView) convertView TextView txtListChild = (TextView) convertView
.findViewById(R.id.lblListItem); .findViewById(R.id.lblListItem);
View itemGroupColor = (View) convertView.findViewById(R.id.item_group_color); View itemGroupColor = (View) convertView.findViewById(R.id.item_group_color);
int color = Marker.getColor(Marker.getGroupId(headerTitle)); int color = Marker.getColor(Marker.getGroupId(headerTitle));
itemGroupColor.setBackgroundColor(color); itemGroupColor.setBackgroundColor(color);
Typeface regular = Typeface.createFromAsset(_context.getAssets(), MapFragment.FONT_REGULAR); Typeface regular = Typeface.createFromAsset(_context.getAssets(), MapFragment.FONT_REGULAR);
txtListChild.setTypeface(regular); txtListChild.setTypeface(regular);
txtListChild.setText(childText); txtListChild.setText(childText);
return convertView; return convertView;
} }
@Override @Override
public int getChildrenCount(int groupPosition) { public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition)) return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size(); .size();
} }
@Override @Override
public Object getGroup(int groupPosition) { public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition); return this._listDataHeader.get(groupPosition);
} }
@Override @Override
public int getGroupCount() { public int getGroupCount() {
return this._listDataHeader.size(); return this._listDataHeader.size();
} }
@Override @Override
public long getGroupId(int groupPosition) { public long getGroupId(int groupPosition) {
return groupPosition; return groupPosition;
} }
@Override @Override
public View getGroupView(int groupPosition, boolean isExpanded, public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) { View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition); String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) { if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate( convertView = infalInflater.inflate(
R.layout.map_expandable_list_header, null); R.layout.map_expandable_list_header, null);
} }
TextView lblListHeader = (TextView) convertView TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader); .findViewById(R.id.lblListHeader);
Typeface regular = Typeface.createFromAsset(_context.getAssets(), MapFragment.FONT_REGULAR); Typeface regular = Typeface.createFromAsset(_context.getAssets(), MapFragment.FONT_REGULAR);
lblListHeader.setTypeface(regular); lblListHeader.setTypeface(regular);
lblListHeader.setText(headerTitle); lblListHeader.setText(headerTitle);
ImageView iconExpand = (ImageView) convertView ImageView iconExpand = (ImageView) convertView
.findViewById(R.id.icon_expand); .findViewById(R.id.icon_expand);
ImageView groupColor = (ImageView) convertView.findViewById(R.id.group_color); ImageView groupColor = (ImageView) convertView.findViewById(R.id.group_color);
int color = Marker.getColor(Marker.getGroupId(headerTitle)); int color = Marker.getColor(Marker.getGroupId(headerTitle));
groupColor.setImageDrawable(new ColorDrawable(color)); groupColor.setImageDrawable(new ColorDrawable(color));
if (isExpanded) { if (isExpanded) {
iconExpand.setImageResource(R.drawable.ic_action_expand); iconExpand.setImageResource(R.drawable.ic_action_expand);
} else { } else {
iconExpand.setImageResource(R.drawable.ic_action_next_item); iconExpand.setImageResource(R.drawable.ic_action_next_item);
} }
return convertView; return convertView;
} }
@Override @Override
public boolean hasStableIds() { public boolean hasStableIds() {
return false; return false;
} }
@Override @Override
public boolean isChildSelectable(int groupPosition, int childPosition) { public boolean isChildSelectable(int groupPosition, int childPosition) {
return true; return true;
} }
} }
...@@ -24,311 +24,311 @@ import app.insti.fragment.MapFragment; ...@@ -24,311 +24,311 @@ import app.insti.fragment.MapFragment;
public class FuzzySearchAdapter extends BaseAdapter { public class FuzzySearchAdapter extends BaseAdapter {
Context mContext; Context mContext;
LayoutInflater inflater; LayoutInflater inflater;
private List<Marker> resultlist = null; private List<Marker> resultlist = null;
private ArrayList<Marker> inputlist; private ArrayList<Marker> inputlist;
private List<ScoredMarker> map; private List<ScoredMarker> map;
private Locale l; private Locale l;
private String searchedText = ""; private String searchedText = "";
private SettingsManager settingsManager; private SettingsManager settingsManager;
private boolean turnOnResidences; private boolean turnOnResidences;
public FuzzySearchAdapter(Context context, List<Marker> inputlist) { public FuzzySearchAdapter(Context context, List<Marker> inputlist) {
mContext = context; mContext = context;
l = Locale.getDefault(); l = Locale.getDefault();
this.resultlist = inputlist; this.resultlist = inputlist;
Collections.sort(resultlist, new MarkerNameComparator()); Collections.sort(resultlist, new MarkerNameComparator());
inflater = LayoutInflater.from(mContext); inflater = LayoutInflater.from(mContext);
this.inputlist = new ArrayList<Marker>(); this.inputlist = new ArrayList<Marker>();
this.inputlist.addAll(resultlist); this.inputlist.addAll(resultlist);
map = new ArrayList<ScoredMarker>(); map = new ArrayList<ScoredMarker>();
} }
public class ViewHolder { public int getResultSize() {
TextView label; return resultlist.size();
LinearLayout rowContainer; }
}
public class ScoredMarker { @Override
Marker m; public int getCount() {
int score; if (this.getResultSize() == 0) {
return 1;
}
return resultlist.size();
}
public ScoredMarker(int score, Marker m) { @Override
this.m = m; public Marker getItem(int position) {
this.score = score; return resultlist.get(position);
} }
}
public int getResultSize() { @Override
return resultlist.size(); public long getItemId(int position) {
} return position;
}
@Override @Override
public int getCount() { public View getView(final int position, View view, ViewGroup parent) {
if (this.getResultSize() == 0) { final ViewHolder holder;
return 1; if (view == null) {
} holder = new ViewHolder();
return resultlist.size(); view = inflater.inflate(R.layout.map_row_layout, null);
}
@Override holder.label = (TextView) view.findViewById(R.id.label);
public Marker getItem(int position) { Typeface regular = Typeface.createFromAsset(mContext.getAssets(),
return resultlist.get(position); MapFragment.FONT_REGULAR);
} holder.label.setTypeface(regular);
holder.rowContainer = (LinearLayout) view
.findViewById(R.id.row_container);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
@Override if (this.getResultSize() == 0) {
public long getItemId(int position) { if (settingsManager.showResidences()) {
return position; holder.label.setText("Sorry, no results found.");
} } else {
if (turnOnResidences) {
holder.label
.setText("There are results in residences. Select show residences from settings.");
} else {
holder.label.setText("Sorry, no results found.");
}
}
} else {
holder.label.setText(getSpannedText(resultlist.get(position)
.getName(), searchedText));
}
return view;
}
@Override private Spanned getSpannedText(String name, String searchedText2) {
public View getView(final int position, View view, ViewGroup parent) { String smallLetterName = name.toLowerCase(l);
final ViewHolder holder; searchedText2 = searchedText2.toLowerCase(l).replaceAll("\\s", "");
if (view == null) { if (searchedText2.equals("")) {
holder = new ViewHolder(); return Html.fromHtml(name);
view = inflater.inflate(R.layout.map_row_layout, null); } else {
String htmlName = "";
if (isShortForm(smallLetterName, searchedText2)) {
htmlName = getHighlightedShortform(name, searchedText2);
} else {
int i = 0;
int j = 0;
while (i < searchedText2.length()) {
if (smallLetterName.charAt(j) == searchedText2.charAt(i)) {
htmlName += "<b>" + name.charAt(j) + "</b>";
i++;
j++;
} else {
htmlName += name.charAt(j);
j++;
}
}
if (j < name.length()) {
htmlName += name.substring(j, name.length());
}
}
return Html.fromHtml(htmlName);
}
}
holder.label = (TextView) view.findViewById(R.id.label); private String getHighlightedShortform(String name, String searchedText2) {
Typeface regular = Typeface.createFromAsset(mContext.getAssets(), String smallCapsName = name.toLowerCase(l);
MapFragment.FONT_REGULAR); String possibleShortform = "";
holder.label.setTypeface(regular); for (int i = 0; i < searchedText2.length(); i++) {
holder.rowContainer = (LinearLayout) view possibleShortform = "";
.findViewById(R.id.row_container); for (int j = 0; j < searchedText2.length(); j++) {
view.setTag(holder); if (j <= i) {
} else { possibleShortform += searchedText2.charAt(j);
holder = (ViewHolder) view.getTag(); } else {
} possibleShortform += "(.*)" + " " + searchedText2.charAt(j);
// Set the results into TextViews }
}
possibleShortform += "(.*)";
if (smallCapsName.matches(possibleShortform)) {
name = makeBold(name, searchedText2.substring(0, i + 1));
i++;
while (i < searchedText2.length()) {
name = makeBold(name, " " + searchedText2.charAt(i));
i++;
}
}
}
return name;
}
if (this.getResultSize() == 0) { private String makeBold(String name, String substring) {
if (settingsManager.showResidences()) { String smallCapsName = name.toLowerCase(l);
holder.label.setText("Sorry, no results found."); int firstIndex = smallCapsName.indexOf(substring);
} else { if (name.charAt(firstIndex) == ' ') {
if (turnOnResidences) { name = name.substring(0, firstIndex + 1)
holder.label + "<b>"
.setText("There are results in residences. Select show residences from settings."); + name.substring(firstIndex + 1,
} else { firstIndex + substring.length())
holder.label.setText("Sorry, no results found."); + "</b>"
} + name.substring(firstIndex + substring.length(),
} name.length());
} else { } else {
holder.label.setText(getSpannedText(resultlist.get(position) name = name.substring(0, firstIndex)
.getName(), searchedText)); + "<b>"
} + name.substring(firstIndex,
return view; firstIndex + substring.length())
} + "</b>"
+ name.substring(firstIndex + substring.length(),
name.length());
}
return name;
}
private Spanned getSpannedText(String name, String searchedText2) { public void filter(String charText) {
String smallLetterName = name.toLowerCase(l); turnOnResidences = false;
searchedText2 = searchedText2.toLowerCase(l).replaceAll("\\s", ""); charText = charText.toLowerCase(Locale.getDefault());
if (searchedText2.equals("")) { searchedText = charText;
return Html.fromHtml(name); resultlist.clear();
} else { map.clear();
String htmlName = ""; if (charText.length() == 0) {
if (isShortForm(smallLetterName, searchedText2)) { if (settingsManager.showResidences()) {
htmlName = getHighlightedShortform(name, searchedText2); resultlist.addAll(inputlist);
} else { } else {
int i = 0; for (Marker m : inputlist) {
int j = 0; if (m.getGroupIndex() != Marker.RESIDENCES) {
while (i < searchedText2.length()) { resultlist.add(m);
if (smallLetterName.charAt(j) == searchedText2.charAt(i)) { }
htmlName += "<b>" + name.charAt(j) + "</b>"; }
i++; }
j++; } else if (charText.length() > 10) {
} else { for (Marker m : inputlist) {
htmlName += name.charAt(j); if (m.getName().toLowerCase(Locale.getDefault())
j++; .contains(charText)) {
} if (settingsManager.showResidences()) {
} resultlist.add(m);
if (j < name.length()) { } else {
htmlName += name.substring(j, name.length()); if (m.getGroupIndex() != Marker.RESIDENCES) {
} resultlist.add(m);
} } else {
return Html.fromHtml(htmlName); turnOnResidences = true;
} }
} }
}
}
} else {
for (Marker m : inputlist) {
int score = checkModifyMarker(m, charText);
if (score != 0) {
if (settingsManager.showResidences()) {
map.add(new ScoredMarker(score, m));
} else {
if (m.getGroupIndex() != Marker.RESIDENCES) {
map.add(new ScoredMarker(score, m));
} else {
turnOnResidences = true;
}
}
}
}
resultlist = sortByScore(map);
}
notifyDataSetChanged();
}
private String getHighlightedShortform(String name, String searchedText2) { private List<Marker> sortByScore(List<ScoredMarker> tempScore) {
String smallCapsName = name.toLowerCase(l); List<Marker> templist = new ArrayList<Marker>();
String possibleShortform = ""; Collections.sort(tempScore, new MarkerScoreComparator());
for (int i = 0; i < searchedText2.length(); i++) { for (ScoredMarker k : tempScore) {
possibleShortform = ""; templist.add(k.m);
for (int j = 0; j < searchedText2.length(); j++) { }
if (j <= i) { return templist;
possibleShortform += searchedText2.charAt(j); }
} else {
possibleShortform += "(.*)" + " " + searchedText2.charAt(j);
}
}
possibleShortform += "(.*)";
if (smallCapsName.matches(possibleShortform)) {
name = makeBold(name, searchedText2.substring(0, i + 1));
i++;
while (i < searchedText2.length()) {
name = makeBold(name, " " + searchedText2.charAt(i));
i++;
}
}
}
return name;
}
private String makeBold(String name, String substring) { private int checkModifyMarker(Marker m, String charText) {
String smallCapsName = name.toLowerCase(l); int tempScore = 5;
int firstIndex = smallCapsName.indexOf(substring); String tempCharText = "(.*)";
if (name.charAt(firstIndex) == ' ') { for (int i = 0; i < charText.length(); i++) {
name = name.substring(0, firstIndex + 1) tempCharText += charText.charAt(i) + "(.*)";
+ "<b>" }
+ name.substring(firstIndex + 1, if (m.getName().toLowerCase(l).matches(tempCharText)) {
firstIndex + substring.length()) boolean b = false;
+ "</b>" if (m.getName().toLowerCase(l).startsWith(charText)) {
+ name.substring(firstIndex + substring.length(), return 1;
name.length()); }
} else { if (isShortForm(m.getName(), charText)) {
name = name.substring(0, firstIndex) return 2;
+ "<b>" }
+ name.substring(firstIndex, for (String s : m.getName().split(" ")) {
firstIndex + substring.length()) b = b || s.toLowerCase(l).startsWith("" + charText.charAt(0));
+ "</b>" if (!b) {
+ name.substring(firstIndex + substring.length(), tempScore += 10;
name.length()); }
} if (s.startsWith(charText)) {
return name; return 3;
} }
}
if (b) {
return tempScore;
} else {
return 0;
}
} else {
return 0;
}
}
public void filter(String charText) { private boolean isShortForm(String name, String charText) {
turnOnResidences = false; name = name.toLowerCase(l);
charText = charText.toLowerCase(Locale.getDefault()); charText = charText.toLowerCase(l).replaceAll("\\s", "");
searchedText = charText; String possibleShortform = "";
resultlist.clear(); for (int i = 0; i < charText.length(); i++) {
map.clear(); possibleShortform = "";
if (charText.length() == 0) { for (int j = 0; j < charText.length(); j++) {
if (settingsManager.showResidences()) { if (j <= i) {
resultlist.addAll(inputlist); possibleShortform += charText.charAt(j);
} else { } else {
for (Marker m : inputlist) { possibleShortform += "(.*)" + " " + charText.charAt(j);
if (m.getGroupIndex() != Marker.RESIDENCES) { }
resultlist.add(m); }
} possibleShortform += "(.*)";
} if (name.matches(possibleShortform)) {
} return true;
} else if (charText.length() > 10) { }
for (Marker m : inputlist) { }
if (m.getName().toLowerCase(Locale.getDefault()) return false;
.contains(charText)) { }
if (settingsManager.showResidences()) {
resultlist.add(m);
} else {
if (m.getGroupIndex() != Marker.RESIDENCES) {
resultlist.add(m);
} else {
turnOnResidences = true;
}
}
}
}
} else {
for (Marker m : inputlist) {
int score = checkModifyMarker(m, charText);
if (score != 0) {
if (settingsManager.showResidences()) {
map.add(new ScoredMarker(score, m));
} else {
if (m.getGroupIndex() != Marker.RESIDENCES) {
map.add(new ScoredMarker(score, m));
} else {
turnOnResidences = true;
}
}
}
}
resultlist = sortByScore(map);
}
notifyDataSetChanged();
}
private List<Marker> sortByScore(List<ScoredMarker> tempScore) { public SettingsManager getSettingsManager() {
List<Marker> templist = new ArrayList<Marker>(); return settingsManager;
Collections.sort(tempScore, new MarkerScoreComparator()); }
for (ScoredMarker k : tempScore) {
templist.add(k.m);
}
return templist;
}
private int checkModifyMarker(Marker m, String charText) { public void setSettingsManager(SettingsManager settingsManager) {
int tempScore = 5; this.settingsManager = settingsManager;
String tempCharText = "(.*)"; }
for (int i = 0; i < charText.length(); i++) {
tempCharText += charText.charAt(i) + "(.*)";
}
if (m.getName().toLowerCase(l).matches(tempCharText)) {
boolean b = false;
if (m.getName().toLowerCase(l).startsWith(charText)) {
return 1;
}
if (isShortForm(m.getName(), charText)) {
return 2;
}
for (String s : m.getName().split(" ")) {
b = b || s.toLowerCase(l).startsWith("" + charText.charAt(0));
if (!b) {
tempScore += 10;
}
if (s.startsWith(charText)) {
return 3;
}
}
if (b) {
return tempScore;
} else {
return 0;
}
} else {
return 0;
}
}
private boolean isShortForm(String name, String charText) { public class ViewHolder {
name = name.toLowerCase(l); TextView label;
charText = charText.toLowerCase(l).replaceAll("\\s", ""); LinearLayout rowContainer;
String possibleShortform = ""; }
for (int i = 0; i < charText.length(); i++) {
possibleShortform = "";
for (int j = 0; j < charText.length(); j++) {
if (j <= i) {
possibleShortform += charText.charAt(j);
} else {
possibleShortform += "(.*)" + " " + charText.charAt(j);
}
}
possibleShortform += "(.*)";
if (name.matches(possibleShortform)) {
return true;
}
}
return false;
}
public SettingsManager getSettingsManager() { public class ScoredMarker {
return settingsManager; Marker m;
} int score;
public void setSettingsManager(SettingsManager settingsManager) { public ScoredMarker(int score, Marker m) {
this.settingsManager = settingsManager; this.m = m;
} this.score = score;
}
}
public class MarkerScoreComparator implements Comparator<ScoredMarker> { public class MarkerScoreComparator implements Comparator<ScoredMarker> {
public int compare(ScoredMarker m1, ScoredMarker m2) { public int compare(ScoredMarker m1, ScoredMarker m2) {
return m1.score - m2.score; return m1.score - m2.score;
} }
} }
public class MarkerNameComparator implements Comparator<Marker> { public class MarkerNameComparator implements Comparator<Marker> {
public int compare(Marker m1, Marker m2) { public int compare(Marker m1, Marker m2) {
return m1.getName().toLowerCase(l) return m1.getName().toLowerCase(l)
.compareTo(m2.getName().toLowerCase(l)); .compareTo(m2.getName().toLowerCase(l));
} }
} }
} }
...@@ -16,27 +16,27 @@ import app.insti.fragment.MapFragment; ...@@ -16,27 +16,27 @@ import app.insti.fragment.MapFragment;
public class ListFragment extends Fragment { public class ListFragment extends Fragment {
MapFragment mainActivity; MapFragment mainActivity;
FuzzySearchAdapter adapter; FuzzySearchAdapter adapter;
HashMap<String, Marker> data; HashMap<String, Marker> data;
View rootView; View rootView;
ListView list; ListView list;
public ListFragment() { public ListFragment() {
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
mainActivity = MapFragment.getMainActivity(); mainActivity = MapFragment.getMainActivity();
adapter = mainActivity.getAdapter(); adapter = mainActivity.getAdapter();
rootView = inflater.inflate(R.layout.map_list_fragment, container, false); rootView = inflater.inflate(R.layout.map_list_fragment, container, false);
list = (ListView) rootView.findViewById(R.id.suggestion_list); list = (ListView) rootView.findViewById(R.id.suggestion_list);
list.setAdapter(adapter); list.setAdapter(adapter);
list.setOnItemClickListener(mainActivity); list.setOnItemClickListener(mainActivity);
list.setOnTouchListener(mainActivity); list.setOnTouchListener(mainActivity);
list.setFastScrollEnabled(true); list.setFastScrollEnabled(true);
return rootView; return rootView;
} }
} }
...@@ -6,43 +6,41 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; ...@@ -6,43 +6,41 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources; import android.content.res.Resources;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import app.insti.R; public class SettingsManager implements OnSharedPreferenceChangeListener {
private SharedPreferences sharedPrefs;
public class SettingsManager implements OnSharedPreferenceChangeListener{ private String muteKey;
private SharedPreferences sharedPrefs; private String residencesKey;
private String muteKey; private String lastUpdatedKey;
private String residencesKey;
private String lastUpdatedKey; public SettingsManager(Context context) {
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
public SettingsManager(Context context){ sharedPrefs.registerOnSharedPreferenceChangeListener(this);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); Resources res = context.getResources();
sharedPrefs.registerOnSharedPreferenceChangeListener(this); muteKey = "mute";
Resources res = context.getResources(); residencesKey = "residences";
muteKey = "mute"; lastUpdatedKey = "lastupdated";
residencesKey = "residences"; }
lastUpdatedKey = "lastupdated";
} public boolean isMuted() {
return sharedPrefs.getBoolean(muteKey, false);
public boolean isMuted(){ }
return sharedPrefs.getBoolean(muteKey, false);
} public boolean showResidences() {
return sharedPrefs.getBoolean(residencesKey, true);
public boolean showResidences(){ }
return sharedPrefs.getBoolean(residencesKey, true);
}
public long getLastUpdatedOn() { public long getLastUpdatedOn() {
return sharedPrefs.getLong(lastUpdatedKey, 0); return sharedPrefs.getLong(lastUpdatedKey, 0);
} }
public void setLastUpdatedOn(long lastUpdatedOn) { public void setLastUpdatedOn(long lastUpdatedOn) {
sharedPrefs.edit().putLong(lastUpdatedKey, lastUpdatedOn).commit(); sharedPrefs.edit().putLong(lastUpdatedKey, lastUpdatedOn).commit();
} }
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
}
}
} }
package com.mrane.data; package com.mrane.data;
public class Building extends Marker { public class Building extends Marker {
public String[] children; public String[] children;
public Building(String name, String shortName, float x, float y,
int groupIndex, String[] children, String description) {
super(name, shortName, x, y, groupIndex, description);
this.children = children;
}
public String[] getChildren() { public Building(String name, String shortName, float x, float y,
return children; int groupIndex, String[] children, String description) {
} super(name, shortName, x, y, groupIndex, description);
this.children = children;
}
public void setChildren(String[] children) { public String[] getChildren() {
this.children = children; return children;
} }
public void setChildren(String[] children) {
this.children = children;
}
} }
...@@ -7,9 +7,9 @@ import java.util.List; ...@@ -7,9 +7,9 @@ import java.util.List;
import app.insti.data.Venue; import app.insti.data.Venue;
public class Locations { public class Locations {
public HashMap<String, Marker> data = new HashMap<String, Marker>(); public HashMap<String, Marker> data = new HashMap<String, Marker>();
public Locations(List<Venue> venueList) { public Locations(List<Venue> venueList) {
// Add locations // Add locations
for (Venue venue : venueList) { for (Venue venue : venueList) {
Marker marker; Marker marker;
......
...@@ -7,295 +7,292 @@ import java.util.ArrayList; ...@@ -7,295 +7,292 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
public class Marker { public class Marker {
private int id; public static final int COLOR_BLUE = Color.rgb(75, 186, 238);
private String name; public static final int COLOR_YELLOW = Color.rgb(255, 186, 0);
private String shortName; public static final int COLOR_GREEN = Color.rgb(162, 208, 104);
private PointF point; public static final int COLOR_GRAY = Color.rgb(156, 156, 156);
private int groupIndex; public static final int DEPARTMENTS = 1;
private boolean showDefault; public static final int HOSTELS = 2;
private String description; public static final int RESIDENCES = 3;
private String tag; public static final int HALLS_N_AUDITORIUMS = 4;
private String imageUri; public static final int FOOD_STALLS = 5;
private int parentId; public static final int BANKS_N_ATMS = 6;
private String parentRel; public static final int SCHOOLS = 7;
private int[] childIds; public static final int SPORTS = 8;
private long lat; public static final int OTHERS = 9;
private long lng; public static final int GATES = 10;
public static final int PRINT = 11;
public static final int COLOR_BLUE = Color.rgb(75, 186, 238); public static final int LABS = 12;
public static final int COLOR_YELLOW = Color.rgb(255, 186, 0); private static final String DEPARTMENTS_NAME = "Departments";
public static final int COLOR_GREEN = Color.rgb(162, 208, 104); private static final String HOSTELS_NAME = "Hostels";
public static final int COLOR_GRAY = Color.rgb(156, 156, 156); private static final String RESIDENCES_NAME = "Residences";
private static final String HALLS_N_AUDITORIUMS_NAME = "Halls and Auditoriums";
public static final int DEPARTMENTS = 1; private static final String FOOD_STALLS_NAME = "Food Stalls";
public static final int HOSTELS = 2; private static final String BANKS_N_ATMS_NAME = "Banks and Atms";
public static final int RESIDENCES = 3; private static final String SCHOOLS_NAME = "Schools";
public static final int HALLS_N_AUDITORIUMS = 4; private static final String SPORTS_NAME = "Sports";
public static final int FOOD_STALLS = 5; private static final String OTHERS_NAME = "Others";
public static final int BANKS_N_ATMS = 6; private static final String GATES_NAME = "Gates";
public static final int SCHOOLS = 7; private static final String PRINT_NAME = "Printer facility";
public static final int SPORTS = 8; private static final String LABS_NAME = "Labs";
public static final int OTHERS = 9; private int id;
public static final int GATES = 10; private String name;
public static final int PRINT = 11; private String shortName;
public static final int LABS = 12; private PointF point;
private int groupIndex;
private static final String DEPARTMENTS_NAME = "Departments"; private boolean showDefault;
private static final String HOSTELS_NAME = "Hostels"; private String description;
private static final String RESIDENCES_NAME = "Residences"; private String tag;
private static final String HALLS_N_AUDITORIUMS_NAME = "Halls and Auditoriums"; private String imageUri;
private static final String FOOD_STALLS_NAME = "Food Stalls"; private int parentId;
private static final String BANKS_N_ATMS_NAME = "Banks and Atms"; private String parentRel;
private static final String SCHOOLS_NAME = "Schools"; private int[] childIds;
private static final String SPORTS_NAME = "Sports"; private long lat;
private static final String OTHERS_NAME = "Others"; private long lng;
private static final String GATES_NAME = "Gates";
private static final String PRINT_NAME = "Printer facility"; public Marker(String name, String shortName, float x, float y,
private static final String LABS_NAME = "Labs"; int groupIndex, String description) {
this.setPoint(new PointF(x, y));
public Marker(String name, String shortName, float x, float y, this.groupIndex = groupIndex;
int groupIndex, String description) { this.setName(name);
this.setPoint(new PointF(x, y)); this.setShortName(shortName);
this.groupIndex = groupIndex; this.setShowDefault(false);
this.setName(name); this.setDescription(description);
this.setShortName(shortName); this.setImageUri("");
this.setShowDefault(false); }
this.setDescription(description);
this.setImageUri(""); public Marker(int id, String name, String shortName, float pixelX, float pixelY,
} int groupIndex, String description, int parentId, String parentRel,
int[] childIds, long lat, long lng) {
public Marker(int id, String name, String shortName, float pixelX, float pixelY, this.id = id;
int groupIndex, String description, int parentId, String parentRel, this.name = name;
int[] childIds, long lat, long lng) { this.shortName = shortName;
this.id = id; this.point = new PointF(pixelX, pixelY);
this.name = name; this.groupIndex = groupIndex;
this.shortName = shortName; this.description = description;
this.point = new PointF(pixelX, pixelY); this.setParentId(parentId);
this.groupIndex = groupIndex; this.setParentRel(parentRel);
this.description = description; this.setChildIds(childIds);
this.setParentId(parentId); this.setLat(lat);
this.setParentRel(parentRel); this.setLng(lng);
this.setChildIds(childIds); }
this.setLat(lat);
this.setLng(lng); public static int getColor(int group) {
} if (group == -10) {
return -10;
public static int getColor(int group) { }
if (group == -10) {
return -10; Integer[] yellowGroup = new Integer[]{HOSTELS};
} Integer[] blueGroup = new Integer[]{DEPARTMENTS, LABS,
HALLS_N_AUDITORIUMS};
Integer[] yellowGroup = new Integer[] { HOSTELS }; Integer[] greenGroup = new Integer[]{RESIDENCES};
Integer[] blueGroup = new Integer[] { DEPARTMENTS, LABS, Integer[] purpleGroup = new Integer[]{FOOD_STALLS, BANKS_N_ATMS,
HALLS_N_AUDITORIUMS }; SCHOOLS, SPORTS, OTHERS, GATES, PRINT};
Integer[] greenGroup = new Integer[] { RESIDENCES };
Integer[] purpleGroup = new Integer[] { FOOD_STALLS, BANKS_N_ATMS, ArrayList<Integer> yellowList = new ArrayList<Integer>(
SCHOOLS, SPORTS, OTHERS, GATES, PRINT }; Arrays.asList(yellowGroup));
ArrayList<Integer> blueList = new ArrayList<Integer>(
ArrayList<Integer> yellowList = new ArrayList<Integer>( Arrays.asList(blueGroup));
Arrays.asList(yellowGroup)); ArrayList<Integer> greenList = new ArrayList<Integer>(
ArrayList<Integer> blueList = new ArrayList<Integer>( Arrays.asList(greenGroup));
Arrays.asList(blueGroup)); ArrayList<Integer> purpleList = new ArrayList<Integer>(
ArrayList<Integer> greenList = new ArrayList<Integer>( Arrays.asList(purpleGroup));
Arrays.asList(greenGroup));
ArrayList<Integer> purpleList = new ArrayList<Integer>( if (yellowList.contains(group)) {
Arrays.asList(purpleGroup)); return COLOR_YELLOW;
} else if (blueList.contains(group)) {
if (yellowList.contains(group)) { return COLOR_BLUE;
return COLOR_YELLOW; } else if (greenList.contains(group)) {
} else if (blueList.contains(group)) { return COLOR_GREEN;
return COLOR_BLUE; } else if (purpleList.contains(group)) {
} else if (greenList.contains(group)) { return COLOR_GRAY;
return COLOR_GREEN; }
} else if (purpleList.contains(group)) {
return COLOR_GRAY; return 0;
} }
return 0; public static String[] getGroupNames() {
} String[] groupNames = {DEPARTMENTS_NAME, LABS_NAME,
HALLS_N_AUDITORIUMS_NAME, HOSTELS_NAME, RESIDENCES_NAME,
public int getColor() { FOOD_STALLS_NAME, BANKS_N_ATMS_NAME, SCHOOLS_NAME, SPORTS_NAME,
int group = this.groupIndex; PRINT_NAME, GATES_NAME, OTHERS_NAME};
return getColor(group); return groupNames;
} }
public String getGroupName() { public static int getGroupId(String groupName) {
switch (groupIndex) { int result = 0;
case DEPARTMENTS: if (groupName.equals(DEPARTMENTS_NAME))
return DEPARTMENTS_NAME; result = DEPARTMENTS;
case HOSTELS: if (groupName.equals(HOSTELS_NAME))
return HOSTELS_NAME; result = HOSTELS;
case RESIDENCES: if (groupName.equals(RESIDENCES_NAME))
return RESIDENCES_NAME; result = RESIDENCES;
case HALLS_N_AUDITORIUMS: if (groupName.equals(HALLS_N_AUDITORIUMS_NAME))
return HALLS_N_AUDITORIUMS_NAME; result = HALLS_N_AUDITORIUMS;
case FOOD_STALLS: if (groupName.equals(FOOD_STALLS_NAME))
return FOOD_STALLS_NAME; result = FOOD_STALLS;
case BANKS_N_ATMS: if (groupName.equals(BANKS_N_ATMS_NAME))
return BANKS_N_ATMS_NAME; result = BANKS_N_ATMS;
case SCHOOLS: if (groupName.equals(SCHOOLS_NAME))
return SCHOOLS_NAME; result = SCHOOLS;
case SPORTS: if (groupName.equals(SPORTS_NAME))
return SPORTS_NAME; result = SPORTS;
case OTHERS: if (groupName.equals(OTHERS_NAME))
return OTHERS_NAME; result = OTHERS;
case GATES: if (groupName.equals(GATES_NAME))
return GATES_NAME; result = GATES;
case PRINT: if (groupName.equals(PRINT_NAME))
return PRINT_NAME; result = PRINT;
case LABS: if (groupName.equals(LABS_NAME))
return LABS_NAME; result = LABS;
}
return ""; return result;
} }
public static String[] getGroupNames() { public int getColor() {
String[] groupNames = { DEPARTMENTS_NAME, LABS_NAME, int group = this.groupIndex;
HALLS_N_AUDITORIUMS_NAME, HOSTELS_NAME, RESIDENCES_NAME, return getColor(group);
FOOD_STALLS_NAME, BANKS_N_ATMS_NAME, SCHOOLS_NAME, SPORTS_NAME, }
PRINT_NAME, GATES_NAME, OTHERS_NAME };
return groupNames; public String getGroupName() {
} switch (groupIndex) {
case DEPARTMENTS:
public static int getGroupId(String groupName) { return DEPARTMENTS_NAME;
int result = 0; case HOSTELS:
if (groupName.equals(DEPARTMENTS_NAME)) return HOSTELS_NAME;
result = DEPARTMENTS; case RESIDENCES:
if (groupName.equals(HOSTELS_NAME)) return RESIDENCES_NAME;
result = HOSTELS; case HALLS_N_AUDITORIUMS:
if (groupName.equals(RESIDENCES_NAME)) return HALLS_N_AUDITORIUMS_NAME;
result = RESIDENCES; case FOOD_STALLS:
if (groupName.equals(HALLS_N_AUDITORIUMS_NAME)) return FOOD_STALLS_NAME;
result = HALLS_N_AUDITORIUMS; case BANKS_N_ATMS:
if (groupName.equals(FOOD_STALLS_NAME)) return BANKS_N_ATMS_NAME;
result = FOOD_STALLS; case SCHOOLS:
if (groupName.equals(BANKS_N_ATMS_NAME)) return SCHOOLS_NAME;
result = BANKS_N_ATMS; case SPORTS:
if (groupName.equals(SCHOOLS_NAME)) return SPORTS_NAME;
result = SCHOOLS; case OTHERS:
if (groupName.equals(SPORTS_NAME)) return OTHERS_NAME;
result = SPORTS; case GATES:
if (groupName.equals(OTHERS_NAME)) return GATES_NAME;
result = OTHERS; case PRINT:
if (groupName.equals(GATES_NAME)) return PRINT_NAME;
result = GATES; case LABS:
if (groupName.equals(PRINT_NAME)) return LABS_NAME;
result = PRINT; }
if (groupName.equals(LABS_NAME)) return "";
result = LABS; }
return result; public int getId() {
} return id;
}
public int getId() {
return id; public void setId(int id) {
} this.id = id;
}
public void setId(int id) {
this.id = id; public String getName() {
} return name;
}
public String getName() {
return name; public void setName(String name) {
} this.name = name;
}
public void setName(String name) {
this.name = name; public String getShortName() {
} return shortName;
}
public String getShortName() {
return shortName; public void setShortName(String shortName) {
} this.shortName = shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName; public PointF getPoint() {
} return point;
}
public PointF getPoint() {
return point; public void setPoint(PointF point) {
} this.point = point;
}
public void setPoint(PointF point) {
this.point = point; public int getGroupIndex() {
} return groupIndex;
}
public int getGroupIndex() {
return groupIndex; public void setGroupIndex(int groupIndex) {
} this.groupIndex = groupIndex;
}
public void setGroupIndex(int groupIndex) {
this.groupIndex = groupIndex; public boolean isShowDefault() {
} return showDefault;
}
public boolean isShowDefault() {
return showDefault; public void setShowDefault(boolean showDefault) {
} this.showDefault = showDefault;
}
public void setShowDefault(boolean showDefault) {
this.showDefault = showDefault; public String getDescription() {
} return description;
}
public String getDescription() {
return description; public void setDescription(String description) {
} this.description = description;
}
public void setDescription(String description) {
this.description = description; public String getTag() {
} return tag;
}
public String getTag() {
return tag; public void setTag(String tag) {
} this.tag = tag;
}
public void setTag(String tag) {
this.tag = tag; public String getImageUri() {
} return imageUri;
}
public String getImageUri() {
return imageUri; public void setImageUri(String imageUri) {
} this.imageUri = imageUri;
}
public void setImageUri(String imageUri) {
this.imageUri = imageUri; public int[] getChildIds() {
} return childIds;
}
public int[] getChildIds() {
return childIds; public void setChildIds(int[] childIds) {
} this.childIds = childIds;
}
public void setChildIds(int[] childIds) {
this.childIds = childIds; public int getParentId() {
} return parentId;
}
public int getParentId() {
return parentId; public void setParentId(int parentId) {
} this.parentId = parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId; public String getParentRel() {
} return parentRel;
}
public String getParentRel() {
return parentRel; public void setParentRel(String parentRel) {
} this.parentRel = parentRel;
}
public void setParentRel(String parentRel) {
this.parentRel = parentRel; public long getLat() {
} return lat;
}
public long getLat() { public void setLat(long lat) {
return lat; this.lat = lat;
} }
public void setLat(long lat) { public long getLng() {
this.lat = lat; return lng;
} }
public long getLng() { public void setLng(long lng) {
return lng; this.lng = lng;
} }
public void setLng(long lng) {
this.lng = lng;
}
} }
package com.mrane.data; package com.mrane.data;
public class Room extends Marker { public class Room extends Marker {
public String parentKey; public String parentKey;
public String tag; public String tag;
public Room(String fullName, String shortName, float x, float y, public Room(String fullName, String shortName, float x, float y,
int groupId, String parentName, String tag, String desc) { int groupId, String parentName, String tag, String desc) {
super(fullName, shortName, x, y, groupId, desc); super(fullName, shortName, x, y, groupId, desc);
this.tag = tag; this.tag = tag;
this.parentKey = parentName; this.parentKey = parentName;
} }
} }
...@@ -7,39 +7,38 @@ import android.view.View; ...@@ -7,39 +7,38 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import com.mrane.navigation.SlidingUpPanelLayout.PanelSlideListener;
import app.insti.R; import app.insti.R;
import app.insti.fragment.MapFragment; import app.insti.fragment.MapFragment;
import com.mrane.navigation.SlidingUpPanelLayout.PanelSlideListener;
public class CardSlideListener implements PanelSlideListener, public class CardSlideListener implements PanelSlideListener,
ValueAnimator.AnimatorUpdateListener { ValueAnimator.AnimatorUpdateListener {
private MapFragment mainActivity; private static final long TIME_ANIMATION_SHOW = 250;
private SlidingUpPanelLayout slidingLayout; private MapFragment mainActivity;
private EndDetectScrollView scrollView; private SlidingUpPanelLayout slidingLayout;
private ValueAnimator animator; private EndDetectScrollView scrollView;
private ValueAnimator animator;
private static final long TIME_ANIMATION_SHOW = 250;
public CardSlideListener(MapFragment mainActivity) {
public CardSlideListener(MapFragment mainActivity) { this.mainActivity = mainActivity;
this.mainActivity = mainActivity; slidingLayout = mainActivity.getSlidingLayout();
slidingLayout = mainActivity.getSlidingLayout(); scrollView = (EndDetectScrollView) mainActivity.getActivity()
scrollView = (EndDetectScrollView) mainActivity.getActivity() .findViewById(R.id.new_expanded_place_card_scroll);
.findViewById(R.id.new_expanded_place_card_scroll);
animator = new ValueAnimator();
animator = new ValueAnimator(); animator.addUpdateListener(this);
animator.addUpdateListener(this); Interpolator i = new Interpolator() {
Interpolator i = new Interpolator() { public float getInterpolation(float t) {
public float getInterpolation(float t) { t -= 1.0f;
t -= 1.0f; return t * t * t * t * t + 1.0f;
return t * t * t * t * t + 1.0f; }
} };
}; animator.setInterpolator(i);
animator.setInterpolator(i); }
}
@Override
@Override public void onPanelSlide(View panel, float slideOffset) {
public void onPanelSlide(View panel, float slideOffset) {
// setActionBarTranslation(slidingLayout.getCurrentParalaxOffset()); // setActionBarTranslation(slidingLayout.getCurrentParalaxOffset());
// if(slideOffset >= slidingLayout.getAnchorPoint()){ // if(slideOffset >= slidingLayout.getAnchorPoint()){
// mainActivity.getSupportActionBar().hide(); // mainActivity.getSupportActionBar().hide();
...@@ -47,73 +46,73 @@ public class CardSlideListener implements PanelSlideListener, ...@@ -47,73 +46,73 @@ public class CardSlideListener implements PanelSlideListener,
// else{ // else{
// mainActivity.getSupportActionBar().show(); // mainActivity.getSupportActionBar().show();
// } // }
} }
@Override @Override
public void onPanelCollapsed(View panel) { public void onPanelCollapsed(View panel) {
} }
@Override @Override
public void onPanelExpanded(View panel) { public void onPanelExpanded(View panel) {
scrollView.requestDisallowInterceptTouchEvent(false); scrollView.requestDisallowInterceptTouchEvent(false);
scrollView.setScrollingEnabled(true); scrollView.setScrollingEnabled(true);
} }
@Override @Override
public void onPanelAnchored(View panel) { public void onPanelAnchored(View panel) {
scrollView.requestDisallowInterceptTouchEvent(true); scrollView.requestDisallowInterceptTouchEvent(true);
scrollView.setScrollingEnabled(false); scrollView.setScrollingEnabled(false);
} }
@Override @Override
public void onPanelHidden(View panel) { public void onPanelHidden(View panel) {
} }
@TargetApi(Build.VERSION_CODES.HONEYCOMB) @TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setActionBarTranslation(float y) { public void setActionBarTranslation(float y) {
// Figure out the actionbar height // Figure out the actionbar height
int actionBarHeight = 20; int actionBarHeight = 20;
// A hack to add the translation to the action bar // A hack to add the translation to the action bar
ViewGroup content = ((ViewGroup) mainActivity.getActivity().findViewById( ViewGroup content = ((ViewGroup) mainActivity.getActivity().findViewById(
android.R.id.content).getParent()); android.R.id.content).getParent());
int children = content.getChildCount(); int children = content.getChildCount();
for (int i = 0; i < children; i++) { for (int i = 0; i < children; i++) {
View child = content.getChildAt(i); View child = content.getChildAt(i);
if (child.getId() != android.R.id.content) { if (child.getId() != android.R.id.content) {
if (y <= -actionBarHeight) { if (y <= -actionBarHeight) {
child.setVisibility(View.GONE); child.setVisibility(View.GONE);
} else { } else {
child.setVisibility(View.VISIBLE); child.setVisibility(View.VISIBLE);
child.setTranslationY(y); child.setTranslationY(y);
} }
} }
} }
} }
public void dismissCard() { public void dismissCard() {
animator.cancel(); animator.cancel();
int initialPanelHeight = slidingLayout.getPanelHeight(); int initialPanelHeight = slidingLayout.getPanelHeight();
int finalPanelHeight = 0; int finalPanelHeight = 0;
animator.setIntValues(initialPanelHeight, finalPanelHeight); animator.setIntValues(initialPanelHeight, finalPanelHeight);
animator.setDuration(TIME_ANIMATION_SHOW); animator.setDuration(TIME_ANIMATION_SHOW);
animator.start(); animator.start();
} }
public void showCard() { public void showCard() {
animator.cancel(); animator.cancel();
int initialPanelHeight = slidingLayout.getPanelHeight(); int initialPanelHeight = slidingLayout.getPanelHeight();
int finalPanelHeight = mainActivity.getResources() int finalPanelHeight = mainActivity.getResources()
.getDimensionPixelSize(R.dimen.hidden_card_height); .getDimensionPixelSize(R.dimen.hidden_card_height);
animator.setIntValues(initialPanelHeight, finalPanelHeight); animator.setIntValues(initialPanelHeight, finalPanelHeight);
animator.setDuration(TIME_ANIMATION_SHOW); animator.setDuration(TIME_ANIMATION_SHOW);
animator.start(); animator.start();
} }
@Override @Override
public void onAnimationUpdate(ValueAnimator animator) { public void onAnimationUpdate(ValueAnimator animator) {
int panelHeight = (Integer) animator.getAnimatedValue(); int panelHeight = (Integer) animator.getAnimatedValue();
slidingLayout.setPanelHeight(panelHeight); slidingLayout.setPanelHeight(panelHeight);
} }
} }
...@@ -8,105 +8,103 @@ import android.widget.ScrollView; ...@@ -8,105 +8,103 @@ import android.widget.ScrollView;
public class EndDetectScrollView extends ScrollView { public class EndDetectScrollView extends ScrollView {
private enum ScrollState { private ScrollState mCurrState = ScrollState.TOP;
TOP, BETWEEN, BOTTOM private boolean scrollable = true;
} private ScrollEndListener listener;
private ScrollState mCurrState = ScrollState.TOP; public EndDetectScrollView(Context context) {
super(context);
private boolean scrollable = true; // TODO Auto-generated constructor stub
}
public interface ScrollEndListener {
public void onScrollHitBottom(); public EndDetectScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
public void onScrollHitTop(); // TODO Auto-generated constructor stub
}
public void onScrollInBetween();
} public EndDetectScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
private ScrollEndListener listener; // TODO Auto-generated constructor stub
}
public EndDetectScrollView(Context context) {
super(context); public void setScrollEndListener(ScrollEndListener l) {
// TODO Auto-generated constructor stub listener = l;
} }
public EndDetectScrollView(Context context, AttributeSet attrs) { @Override
super(context, attrs); protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated constructor stub View bottomChild = (View) getChildAt(getChildCount() - 1);
} int bottomDiff = (bottomChild.getBottom() - (getHeight() + getScrollY() + bottomChild
.getTop()));// Calculate the scrolldiff
public EndDetectScrollView(Context context, AttributeSet attrs, int defStyle) { if (getScrollY() == 0) { // if scrollY==0 top has been reached
super(context, attrs, defStyle); if (listener != null)
// TODO Auto-generated constructor stub listener.onScrollHitTop();
} mCurrState = ScrollState.TOP;
} else if (bottomDiff == 0) {
public void setScrollEndListener(ScrollEndListener l) { if (listener != null)
listener = l; listener.onScrollHitBottom();
} mCurrState = ScrollState.BOTTOM;
} else {
@Override if (listener != null)
protected void onScrollChanged(int l, int t, int oldl, int oldt) { listener.onScrollInBetween();
View bottomChild = (View) getChildAt(getChildCount() - 1); mCurrState = ScrollState.BETWEEN;
int bottomDiff = (bottomChild.getBottom() - (getHeight() + getScrollY() + bottomChild }
.getTop()));// Calculate the scrolldiff super.onScrollChanged(l, t, oldl, oldt);
if (getScrollY() == 0) { // if scrollY==0 top has been reached }
if (listener != null)
listener.onScrollHitTop(); public boolean isAtTop() {
mCurrState = ScrollState.TOP; return mCurrState == ScrollState.TOP;
} else if (bottomDiff == 0) { }
if (listener != null)
listener.onScrollHitBottom(); public boolean isAtBottom() {
mCurrState = ScrollState.BOTTOM; return mCurrState == ScrollState.BOTTOM;
} else { }
if (listener != null)
listener.onScrollInBetween(); public boolean isInBetween() {
mCurrState = ScrollState.BETWEEN; return mCurrState == ScrollState.BETWEEN;
} }
super.onScrollChanged(l, t, oldl, oldt);
} public void setScrollingEnabled(boolean scrollable) {
this.scrollable = scrollable;
public boolean isAtTop() { }
return mCurrState == ScrollState.TOP;
} public boolean isScrollable() {
return scrollable;
public boolean isAtBottom() { }
return mCurrState == ScrollState.BOTTOM;
} @Override
public boolean onTouchEvent(MotionEvent ev) {
public boolean isInBetween() { switch (ev.getAction()) {
return mCurrState == ScrollState.BETWEEN; case MotionEvent.ACTION_DOWN:
} // if we can scroll pass the event to the superclass
if (scrollable)
public void setScrollingEnabled(boolean scrollable) { return super.onTouchEvent(ev);
this.scrollable = scrollable; // only continue to handle the touch event if scrolling enabled
} return scrollable; // scrollable is always false at this point
default:
public boolean isScrollable() { return super.onTouchEvent(ev);
return scrollable; }
} }
@Override @Override
public boolean onTouchEvent(MotionEvent ev) { public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) { // Don't do anything with intercepted touch events if
case MotionEvent.ACTION_DOWN: // we are not scrollable
// if we can scroll pass the event to the superclass if (!scrollable)
if (scrollable) return false;
return super.onTouchEvent(ev); else
// only continue to handle the touch event if scrolling enabled return super.onInterceptTouchEvent(ev);
return scrollable; // scrollable is always false at this point }
default:
return super.onTouchEvent(ev); private enum ScrollState {
} TOP, BETWEEN, BOTTOM
} }
@Override public interface ScrollEndListener {
public boolean onInterceptTouchEvent(MotionEvent ev) { public void onScrollHitBottom();
// Don't do anything with intercepted touch events if
// we are not scrollable public void onScrollHitTop();
if (!scrollable)
return false; public void onScrollInBetween();
else }
return super.onInterceptTouchEvent(ev);
}
} }
...@@ -32,22 +32,14 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -32,22 +32,14 @@ public class SlidingUpPanelLayout extends ViewGroup {
* Default anchor point height * Default anchor point height
*/ */
private static final float DEFAULT_ANCHOR_POINT = 1.0f; // In relative % private static final float DEFAULT_ANCHOR_POINT = 1.0f; // In relative %
/**
* Default initial state for the component
*/
private static SlideState DEFAULT_SLIDE_STATE = SlideState.COLLAPSED;
/** /**
* Default height of the shadow above the peeking out panel * Default height of the shadow above the peeking out panel
*/ */
private static final int DEFAULT_SHADOW_HEIGHT = 4; // dp; private static final int DEFAULT_SHADOW_HEIGHT = 4; // dp;
/** /**
* If no fade color is given by default it will fade to 80% gray. * If no fade color is given by default it will fade to 80% gray.
*/ */
private static final int DEFAULT_FADE_COLOR = 0x99000000; private static final int DEFAULT_FADE_COLOR = 0x99000000;
/** /**
* Default Minimum velocity that will be detected as a fling * Default Minimum velocity that will be detected as a fling
*/ */
...@@ -59,132 +51,103 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -59,132 +51,103 @@ public class SlidingUpPanelLayout extends ViewGroup {
/** /**
* Default attributes for layout * Default attributes for layout
*/ */
private static final int[] DEFAULT_ATTRS = new int[] { private static final int[] DEFAULT_ATTRS = new int[]{
android.R.attr.gravity android.R.attr.gravity
}; };
/**
* Minimum velocity that will be detected as a fling
*/
private int mMinFlingVelocity = DEFAULT_MIN_FLING_VELOCITY;
/**
* The fade color used for the panel covered by the slider. 0 = no fading.
*/
private int mCoveredFadeColor = DEFAULT_FADE_COLOR;
/** /**
* Default paralax length of the main view * Default paralax length of the main view
*/ */
private static final int DEFAULT_PARALAX_OFFSET = 0; private static final int DEFAULT_PARALAX_OFFSET = 0;
/**
* Default initial state for the component
*/
private static SlideState DEFAULT_SLIDE_STATE = SlideState.COLLAPSED;
/** /**
* The paint used to dim the main layout when sliding * The paint used to dim the main layout when sliding
*/ */
private final Paint mCoveredFadePaint = new Paint(); private final Paint mCoveredFadePaint = new Paint();
/** /**
* Drawable used to draw the shadow between panes. * Drawable used to draw the shadow between panes.
*/ */
private final Drawable mShadowDrawable; private final Drawable mShadowDrawable;
private final ViewDragHelper mDragHelper;
private final Rect mTmpRect = new Rect();
/**
* Minimum velocity that will be detected as a fling
*/
private int mMinFlingVelocity = DEFAULT_MIN_FLING_VELOCITY;
/**
* The fade color used for the panel covered by the slider. 0 = no fading.
*/
private int mCoveredFadeColor = DEFAULT_FADE_COLOR;
/** /**
* The size of the overhang in pixels. * The size of the overhang in pixels.
*/ */
private int mPanelHeight = -1; private int mPanelHeight = -1;
/** /**
* The size of the shadow in pixels. * The size of the shadow in pixels.
*/ */
private int mShadowHeight = -1; private int mShadowHeight = -1;
/** /**
* Paralax offset * Paralax offset
*/ */
private int mParallaxOffset = -1; private int mParallaxOffset = -1;
/** /**
* True if the collapsed panel should be dragged up. * True if the collapsed panel should be dragged up.
*/ */
private boolean mIsSlidingUp; private boolean mIsSlidingUp;
/** /**
* Panel overlays the windows instead of putting it underneath it. * Panel overlays the windows instead of putting it underneath it.
*/ */
private boolean mOverlayContent = DEFAULT_OVERLAY_FLAG; private boolean mOverlayContent = DEFAULT_OVERLAY_FLAG;
/** /**
* If provided, the panel can be dragged by only this view. Otherwise, the entire panel can be * If provided, the panel can be dragged by only this view. Otherwise, the entire panel can be
* used for dragging. * used for dragging.
*/ */
private View mDragView; private View mDragView;
/** /**
* If provided, the panel can be dragged by only this view. Otherwise, the entire panel can be * If provided, the panel can be dragged by only this view. Otherwise, the entire panel can be
* used for dragging. * used for dragging.
*/ */
private int mDragViewResId = -1; private int mDragViewResId = -1;
/** /**
* The child view that can slide, if any. * The child view that can slide, if any.
*/ */
private View mSlideableView; private View mSlideableView;
/** /**
* The main view * The main view
*/ */
private View mMainView; private View mMainView;
/**
* Current state of the slideable view.
*/
private enum SlideState {
EXPANDED,
COLLAPSED,
ANCHORED,
HIDDEN,
DRAGGING
}
private SlideState mSlideState = SlideState.COLLAPSED; private SlideState mSlideState = SlideState.COLLAPSED;
/** /**
* How far the panel is offset from its expanded position. * How far the panel is offset from its expanded position.
* range [0, 1] where 0 = collapsed, 1 = expanded. * range [0, 1] where 0 = collapsed, 1 = expanded.
*/ */
private float mSlideOffset; private float mSlideOffset;
/** /**
* How far in pixels the slideable panel may move. * How far in pixels the slideable panel may move.
*/ */
private int mSlideRange; private int mSlideRange;
/** /**
* A panel view is locked into internal scrolling or another condition that * A panel view is locked into internal scrolling or another condition that
* is preventing a drag. * is preventing a drag.
*/ */
private boolean mIsUnableToDrag; private boolean mIsUnableToDrag;
/** /**
* Flag indicating that sliding feature is enabled\disabled * Flag indicating that sliding feature is enabled\disabled
*/ */
private boolean mIsSlidingEnabled; private boolean mIsSlidingEnabled;
/** /**
* Flag indicating if a drag view can have its own touch events. If set * Flag indicating if a drag view can have its own touch events. If set
* to true, a drag view can scroll horizontally and have its own click listener. * to true, a drag view can scroll horizontally and have its own click listener.
* * <p>
* Default is set to false. * Default is set to false.
*/ */
private boolean mIsUsingDragViewTouchEvents; private boolean mIsUsingDragViewTouchEvents;
private float mInitialMotionX; private float mInitialMotionX;
private float mInitialMotionY; private float mInitialMotionY;
private float mAnchorPoint = 1.f; private float mAnchorPoint = 1.f;
private PanelSlideListener mPanelSlideListener; private PanelSlideListener mPanelSlideListener;
private final ViewDragHelper mDragHelper;
/** /**
* Stores whether or not the pane was expanded the last time it was slideable. * Stores whether or not the pane was expanded the last time it was slideable.
* If expand/collapse operations are invoked this state is modified. Used by * If expand/collapse operations are invoked this state is modified. Used by
...@@ -192,43 +155,6 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -192,43 +155,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
*/ */
private boolean mFirstLayout = true; private boolean mFirstLayout = true;
private final Rect mTmpRect = new Rect();
/**
* Listener for monitoring events about sliding panes.
*/
public interface PanelSlideListener {
/**
* Called when a sliding pane's position changes.
* @param panel The child view that was moved
* @param slideOffset The new offset of this sliding pane within its range, from 0-1
*/
public void onPanelSlide(View panel, float slideOffset);
/**
* Called when a sliding panel becomes slid completely collapsed.
* @param panel The child view that was slid to an collapsed position
*/
public void onPanelCollapsed(View panel);
/**
* Called when a sliding panel becomes slid completely expanded.
* @param panel The child view that was slid to a expanded position
*/
public void onPanelExpanded(View panel);
/**
* Called when a sliding panel becomes anchored.
* @param panel The child view that was slid to a anchored position
*/
public void onPanelAnchored(View panel);
/**
* Called when a sliding panel becomes completely hidden.
* @param panel The child view that was slid to a hidden position
*/
public void onPanelHidden(View panel);
}
public SlidingUpPanelLayout(Context context) { public SlidingUpPanelLayout(Context context) {
this(context, null); this(context, null);
} }
...@@ -240,7 +166,7 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -240,7 +166,7 @@ public class SlidingUpPanelLayout extends ViewGroup {
public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); super(context, attrs, defStyle);
if(isInEditMode()) { if (isInEditMode()) {
mShadowDrawable = null; mShadowDrawable = null;
mDragHelper = null; mDragHelper = null;
return; return;
...@@ -271,7 +197,7 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -271,7 +197,7 @@ public class SlidingUpPanelLayout extends ViewGroup {
mDragViewResId = ta.getResourceId(R.styleable.SlidingUpPanelLayout_dragView, -1); mDragViewResId = ta.getResourceId(R.styleable.SlidingUpPanelLayout_dragView, -1);
mOverlayContent = ta.getBoolean(R.styleable.SlidingUpPanelLayout_overlay,DEFAULT_OVERLAY_FLAG); mOverlayContent = ta.getBoolean(R.styleable.SlidingUpPanelLayout_overlay, DEFAULT_OVERLAY_FLAG);
mAnchorPoint = ta.getFloat(R.styleable.SlidingUpPanelLayout_anchorPoint, DEFAULT_ANCHOR_POINT); mAnchorPoint = ta.getFloat(R.styleable.SlidingUpPanelLayout_anchorPoint, DEFAULT_ANCHOR_POINT);
...@@ -311,6 +237,11 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -311,6 +237,11 @@ public class SlidingUpPanelLayout extends ViewGroup {
mIsSlidingEnabled = true; mIsSlidingEnabled = true;
} }
private static boolean hasOpaqueBackground(View v) {
final Drawable bg = v.getBackground();
return bg != null && bg.getOpacity() == PixelFormat.OPAQUE;
}
/** /**
* Set the Drag View after the view is inflated * Set the Drag View after the view is inflated
*/ */
...@@ -326,6 +257,13 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -326,6 +257,13 @@ public class SlidingUpPanelLayout extends ViewGroup {
return mIsSlidingEnabled && mSlideableView != null; return mIsSlidingEnabled && mSlideableView != null;
} }
/**
* @return The current collapsed panel height
*/
public int getPanelHeight() {
return mPanelHeight;
}
/** /**
* Set the collapsed panel height in pixels * Set the collapsed panel height in pixels
* *
...@@ -338,24 +276,18 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -338,24 +276,18 @@ public class SlidingUpPanelLayout extends ViewGroup {
onPanelDragged(newTop); onPanelDragged(newTop);
} }
/**
* @return The current collapsed panel height
*/
public int getPanelHeight() {
return mPanelHeight;
}
/** /**
* @return The current paralax offset * @return The current paralax offset
*/ */
public int getCurrentParalaxOffset() { public int getCurrentParalaxOffset() {
// Clamp slide offset at zero for parallax computation; // Clamp slide offset at zero for parallax computation;
int offset = (int)(mParallaxOffset * Math.max(mSlideOffset, 0)); int offset = (int) (mParallaxOffset * Math.max(mSlideOffset, 0));
return mIsSlidingUp ? -offset : offset; return mIsSlidingUp ? -offset : offset;
} }
/** /**
* Sets the panel slide listener * Sets the panel slide listener
*
* @param listener * @param listener
*/ */
public void setPanelSlideListener(PanelSlideListener listener) { public void setPanelSlideListener(PanelSlideListener listener) {
...@@ -386,7 +318,8 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -386,7 +318,8 @@ public class SlidingUpPanelLayout extends ViewGroup {
collapsePanel(); collapsePanel();
} }
} }
});; });
;
} }
} }
...@@ -480,11 +413,6 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -480,11 +413,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
} }
} }
private static boolean hasOpaqueBackground(View v) {
final Drawable bg = v.getBackground();
return bg != null && bg.getOpacity() == PixelFormat.OPAQUE;
}
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
...@@ -581,19 +509,19 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -581,19 +509,19 @@ public class SlidingUpPanelLayout extends ViewGroup {
if (mFirstLayout) { if (mFirstLayout) {
switch (mSlideState) { switch (mSlideState) {
case EXPANDED: case EXPANDED:
mSlideOffset = 1.0f; mSlideOffset = 1.0f;
break; break;
case ANCHORED: case ANCHORED:
mSlideOffset = mAnchorPoint; mSlideOffset = mAnchorPoint;
break; break;
case HIDDEN: case HIDDEN:
int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight); int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight);
mSlideOffset = computeSlideOffset(newTop); mSlideOffset = computeSlideOffset(newTop);
break; break;
default: default:
mSlideOffset = 0.f; mSlideOffset = 0.f;
break; break;
} }
} }
...@@ -684,7 +612,7 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -684,7 +612,7 @@ public class SlidingUpPanelLayout extends ViewGroup {
return super.onInterceptTouchEvent(ev); return super.onInterceptTouchEvent(ev);
} }
if ((ady > dragSlop && adx > ady) || !isDragViewUnder((int)mInitialMotionX, (int)mInitialMotionY)) { if ((ady > dragSlop && adx > ady) || !isDragViewUnder((int) mInitialMotionX, (int) mInitialMotionY)) {
mDragHelper.cancel(); mDragHelper.cancel();
mIsUnableToDrag = true; mIsUnableToDrag = true;
return false; return false;
...@@ -814,7 +742,7 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -814,7 +742,7 @@ public class SlidingUpPanelLayout extends ViewGroup {
// height of the main content // height of the main content
if (mSlideOffset <= 0 && !mOverlayContent) { if (mSlideOffset <= 0 && !mOverlayContent) {
// expand the main view // expand the main view
LayoutParams lp = (LayoutParams)mMainView.getLayoutParams(); LayoutParams lp = (LayoutParams) mMainView.getLayoutParams();
lp.height = mIsSlidingUp ? (newTop - getPaddingBottom()) : (getHeight() - getPaddingBottom() - mSlideableView.getMeasuredHeight() - newTop); lp.height = mIsSlidingUp ? (newTop - getPaddingBottom()) : (getHeight() - getPaddingBottom() - mSlideableView.getMeasuredHeight() - newTop);
mMainView.requestLayout(); mMainView.requestLayout();
} }
...@@ -857,7 +785,7 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -857,7 +785,7 @@ public class SlidingUpPanelLayout extends ViewGroup {
* Smoothly animate mDraggingPane to the target X position within its range. * Smoothly animate mDraggingPane to the target X position within its range.
* *
* @param slideOffset position to animate to * @param slideOffset position to animate to
* @param velocity initial velocity in case of fling, or 0. * @param velocity initial velocity in case of fling, or 0.
*/ */
boolean smoothSlideTo(float slideOffset, int velocity) { boolean smoothSlideTo(float slideOffset, int velocity) {
if (!isSlidingEnabled()) { if (!isSlidingEnabled()) {
...@@ -913,7 +841,6 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -913,7 +841,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
} }
} }
@Override @Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() { protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(); return new LayoutParams();
...@@ -953,6 +880,119 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -953,6 +880,119 @@ public class SlidingUpPanelLayout extends ViewGroup {
mSlideState = ss.mSlideState; mSlideState = ss.mSlideState;
} }
/**
* Current state of the slideable view.
*/
private enum SlideState {
EXPANDED,
COLLAPSED,
ANCHORED,
HIDDEN,
DRAGGING
}
/**
* Listener for monitoring events about sliding panes.
*/
public interface PanelSlideListener {
/**
* Called when a sliding pane's position changes.
*
* @param panel The child view that was moved
* @param slideOffset The new offset of this sliding pane within its range, from 0-1
*/
public void onPanelSlide(View panel, float slideOffset);
/**
* Called when a sliding panel becomes slid completely collapsed.
*
* @param panel The child view that was slid to an collapsed position
*/
public void onPanelCollapsed(View panel);
/**
* Called when a sliding panel becomes slid completely expanded.
*
* @param panel The child view that was slid to a expanded position
*/
public void onPanelExpanded(View panel);
/**
* Called when a sliding panel becomes anchored.
*
* @param panel The child view that was slid to a anchored position
*/
public void onPanelAnchored(View panel);
/**
* Called when a sliding panel becomes completely hidden.
*
* @param panel The child view that was slid to a hidden position
*/
public void onPanelHidden(View panel);
}
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
private static final int[] ATTRS = new int[]{
android.R.attr.layout_weight
};
public LayoutParams() {
super(MATCH_PARENT, MATCH_PARENT);
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS);
a.recycle();
}
}
static class SavedState extends BaseSavedState {
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
SlideState mSlideState;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
try {
mSlideState = Enum.valueOf(SlideState.class, in.readString());
} catch (IllegalArgumentException e) {
mSlideState = SlideState.COLLAPSED;
}
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeString(mSlideState.toString());
}
}
private class DragHelperCallback extends ViewDragHelper.Callback { private class DragHelperCallback extends ViewDragHelper.Callback {
@Override @Override
...@@ -1051,66 +1091,4 @@ public class SlidingUpPanelLayout extends ViewGroup { ...@@ -1051,66 +1091,4 @@ public class SlidingUpPanelLayout extends ViewGroup {
} }
} }
} }
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
private static final int[] ATTRS = new int[] {
android.R.attr.layout_weight
};
public LayoutParams() {
super(MATCH_PARENT, MATCH_PARENT);
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS);
a.recycle();
}
}
static class SavedState extends BaseSavedState {
SlideState mSlideState;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
try {
mSlideState = Enum.valueOf(SlideState.class, in.readString());
} catch (IllegalArgumentException e) {
mSlideState = SlideState.COLLAPSED;
}
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeString(mSlideState.toString());
}
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
} }
...@@ -93,13 +93,21 @@ public class ViewDragHelper { ...@@ -93,13 +93,21 @@ public class ViewDragHelper {
private static final int BASE_SETTLE_DURATION = 256; // ms private static final int BASE_SETTLE_DURATION = 256; // ms
private static final int MAX_SETTLE_DURATION = 600; // ms private static final int MAX_SETTLE_DURATION = 600; // ms
/**
* Interpolator defining the animation curve for mScroller
*/
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
}
};
private final Callback mCallback;
private final ViewGroup mParentView;
// Current drag state; idle, dragging or settling // Current drag state; idle, dragging or settling
private int mDragState; private int mDragState;
// Distance to travel before a drag may begin // Distance to travel before a drag may begin
private int mTouchSlop; private int mTouchSlop;
// Last known position/pointer tracking // Last known position/pointer tracking
private int mActivePointerId = INVALID_POINTER; private int mActivePointerId = INVALID_POINTER;
private float[] mInitialMotionX; private float[] mInitialMotionX;
...@@ -110,253 +118,26 @@ public class ViewDragHelper { ...@@ -110,253 +118,26 @@ public class ViewDragHelper {
private int[] mEdgeDragsInProgress; private int[] mEdgeDragsInProgress;
private int[] mEdgeDragsLocked; private int[] mEdgeDragsLocked;
private int mPointersDown; private int mPointersDown;
private VelocityTracker mVelocityTracker; private VelocityTracker mVelocityTracker;
private float mMaxVelocity; private float mMaxVelocity;
private float mMinVelocity; private float mMinVelocity;
private int mEdgeSize; private int mEdgeSize;
private int mTrackingEdges; private int mTrackingEdges;
private ScrollerCompat mScroller; private ScrollerCompat mScroller;
private final Callback mCallback;
private View mCapturedView; private View mCapturedView;
private boolean mReleaseInProgress;
private final ViewGroup mParentView;
/**
* A Callback is used as a communication channel with the ViewDragHelper back to the
* parent view using it. <code>on*</code>methods are invoked on siginficant events and several
* accessor methods are expected to provide the ViewDragHelper with more information
* about the state of the parent view upon request. The callback also makes decisions
* governing the range and draggability of child views.
*/
public static abstract class Callback {
/**
* Called when the drag state changes. See the <code>STATE_*</code> constants
* for more information.
*
* @param state The new drag state
*
* @see #STATE_IDLE
* @see #STATE_DRAGGING
* @see #STATE_SETTLING
*/
public void onViewDragStateChanged(int state) {}
/**
* Called when the captured view's position changes as the result of a drag or settle.
*
* @param changedView View whose position changed
* @param left New X coordinate of the left edge of the view
* @param top New Y coordinate of the top edge of the view
* @param dx Change in X position from the last call
* @param dy Change in Y position from the last call
*/
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {}
/**
* Called when a child view is captured for dragging or settling. The ID of the pointer
* currently dragging the captured view is supplied. If activePointerId is
* identified as {@link #INVALID_POINTER} the capture is programmatic instead of
* pointer-initiated.
*
* @param capturedChild Child view that was captured
* @param activePointerId Pointer id tracking the child capture
*/
public void onViewCaptured(View capturedChild, int activePointerId) {}
/**
* Called when the child view is no longer being actively dragged.
* The fling velocity is also supplied, if relevant. The velocity values may
* be clamped to system minimums or maximums.
*
* <p>Calling code may decide to fling or otherwise release the view to let it
* settle into place. It should do so using {@link #settleCapturedViewAt(int, int)}
* or {@link #flingCapturedView(int, int, int, int)}. If the Callback invokes
* one of these methods, the ViewDragHelper will enter {@link #STATE_SETTLING}
* and the view capture will not fully end until it comes to a complete stop.
* If neither of these methods is invoked before <code>onViewReleased</code> returns,
* the view will stop in place and the ViewDragHelper will return to
* {@link #STATE_IDLE}.</p>
*
* @param releasedChild The captured child view now being released
* @param xvel X velocity of the pointer as it left the screen in pixels per second.
* @param yvel Y velocity of the pointer as it left the screen in pixels per second.
*/
public void onViewReleased(View releasedChild, float xvel, float yvel) {}
/**
* Called when one of the subscribed edges in the parent view has been touched
* by the user while no child view is currently captured.
*
* @param edgeFlags A combination of edge flags describing the edge(s) currently touched
* @param pointerId ID of the pointer touching the described edge(s)
* @see #EDGE_LEFT
* @see #EDGE_TOP
* @see #EDGE_RIGHT
* @see #EDGE_BOTTOM
*/
public void onEdgeTouched(int edgeFlags, int pointerId) {}
/**
* Called when the given edge may become locked. This can happen if an edge drag
* was preliminarily rejected before beginning, but after {@link #onEdgeTouched(int, int)}
* was called. This method should return true to lock this edge or false to leave it
* unlocked. The default behavior is to leave edges unlocked.
*
* @param edgeFlags A combination of edge flags describing the edge(s) locked
* @return true to lock the edge, false to leave it unlocked
*/
public boolean onEdgeLock(int edgeFlags) {
return false;
}
/**
* Called when the user has started a deliberate drag away from one
* of the subscribed edges in the parent view while no child view is currently captured.
*
* @param edgeFlags A combination of edge flags describing the edge(s) dragged
* @param pointerId ID of the pointer touching the described edge(s)
* @see #EDGE_LEFT
* @see #EDGE_TOP
* @see #EDGE_RIGHT
* @see #EDGE_BOTTOM
*/
public void onEdgeDragStarted(int edgeFlags, int pointerId) {}
/**
* Called to determine the Z-order of child views.
*
* @param index the ordered position to query for
* @return index of the view that should be ordered at position <code>index</code>
*/
public int getOrderedChildIndex(int index) {
return index;
}
/**
* Return the magnitude of a draggable child view's horizontal range of motion in pixels.
* This method should return 0 for views that cannot move horizontally.
*
* @param child Child view to check
* @return range of horizontal motion in pixels
*/
public int getViewHorizontalDragRange(View child) {
return 0;
}
/**
* Return the magnitude of a draggable child view's vertical range of motion in pixels.
* This method should return 0 for views that cannot move vertically.
*
* @param child Child view to check
* @return range of vertical motion in pixels
*/
public int getViewVerticalDragRange(View child) {
return 0;
}
/**
* Called when the user's input indicates that they want to capture the given child view
* with the pointer indicated by pointerId. The callback should return true if the user
* is permitted to drag the given view with the indicated pointer.
*
* <p>ViewDragHelper may call this method multiple times for the same view even if
* the view is already captured; this indicates that a new pointer is trying to take
* control of the view.</p>
*
* <p>If this method returns true, a call to {@link #onViewCaptured(android.view.View, int)}
* will follow if the capture is successful.</p>
*
* @param child Child the user is attempting to capture
* @param pointerId ID of the pointer attempting the capture
* @return true if capture should be allowed, false otherwise
*/
public abstract boolean tryCaptureView(View child, int pointerId);
/**
* Restrict the motion of the dragged child view along the horizontal axis.
* The default implementation does not allow horizontal motion; the extending
* class must override this method and provide the desired clamping.
*
*
* @param child Child view being dragged
* @param left Attempted motion along the X axis
* @param dx Proposed change in position for left
* @return The new clamped position for left
*/
public int clampViewPositionHorizontal(View child, int left, int dx) {
return 0;
}
/**
* Restrict the motion of the dragged child view along the vertical axis.
* The default implementation does not allow vertical motion; the extending
* class must override this method and provide the desired clamping.
*
*
* @param child Child view being dragged
* @param top Attempted motion along the Y axis
* @param dy Proposed change in position for top
* @return The new clamped position for top
*/
public int clampViewPositionVertical(View child, int top, int dy) {
return 0;
}
}
/**
* Interpolator defining the animation curve for mScroller
*/
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
}
};
private final Runnable mSetIdleRunnable = new Runnable() { private final Runnable mSetIdleRunnable = new Runnable() {
public void run() { public void run() {
setDragState(STATE_IDLE); setDragState(STATE_IDLE);
} }
}; };
private boolean mReleaseInProgress;
/**
* Factory method to create a new ViewDragHelper.
*
* @param forParent Parent view to monitor
* @param cb Callback to provide information and receive events
* @return a new ViewDragHelper instance
*/
public static ViewDragHelper create(ViewGroup forParent, Callback cb) {
return new ViewDragHelper(forParent.getContext(), forParent, cb);
}
/**
* Factory method to create a new ViewDragHelper.
*
* @param forParent Parent view to monitor
* @param sensitivity Multiplier for how sensitive the helper should be about detecting
* the start of a drag. Larger values are more sensitive. 1.0f is normal.
* @param cb Callback to provide information and receive events
* @return a new ViewDragHelper instance
*/
public static ViewDragHelper create(ViewGroup forParent, float sensitivity, Callback cb) {
final ViewDragHelper helper = create(forParent, cb);
helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity));
return helper;
}
/** /**
* Apps should use ViewDragHelper.create() to get a new instance. * Apps should use ViewDragHelper.create() to get a new instance.
* This will allow VDH to use internal compatibility implementations for different * This will allow VDH to use internal compatibility implementations for different
* platform versions. * platform versions.
* *
* @param context Context to initialize config-dependent params from * @param context Context to initialize config-dependent params from
* @param forParent Parent view to monitor * @param forParent Parent view to monitor
*/ */
private ViewDragHelper(Context context, ViewGroup forParent, Callback cb) { private ViewDragHelper(Context context, ViewGroup forParent, Callback cb) {
...@@ -380,6 +161,32 @@ public class ViewDragHelper { ...@@ -380,6 +161,32 @@ public class ViewDragHelper {
mScroller = ScrollerCompat.create(context, sInterpolator); mScroller = ScrollerCompat.create(context, sInterpolator);
} }
/**
* Factory method to create a new ViewDragHelper.
*
* @param forParent Parent view to monitor
* @param cb Callback to provide information and receive events
* @return a new ViewDragHelper instance
*/
public static ViewDragHelper create(ViewGroup forParent, Callback cb) {
return new ViewDragHelper(forParent.getContext(), forParent, cb);
}
/**
* Factory method to create a new ViewDragHelper.
*
* @param forParent Parent view to monitor
* @param sensitivity Multiplier for how sensitive the helper should be about detecting
* the start of a drag. Larger values are more sensitive. 1.0f is normal.
* @param cb Callback to provide information and receive events
* @return a new ViewDragHelper instance
*/
public static ViewDragHelper create(ViewGroup forParent, float sensitivity, Callback cb) {
final ViewDragHelper helper = create(forParent, cb);
helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity));
return helper;
}
/** /**
* Set the minimum velocity that will be detected as having a magnitude greater than zero * Set the minimum velocity that will be detected as having a magnitude greater than zero
* in pixels per second. Callback methods accepting a velocity will be clamped appropriately. * in pixels per second. Callback methods accepting a velocity will be clamped appropriately.
...@@ -393,6 +200,7 @@ public class ViewDragHelper { ...@@ -393,6 +200,7 @@ public class ViewDragHelper {
/** /**
* Retrieve the current drag state of this helper. This will return one of * Retrieve the current drag state of this helper. This will return one of
* {@link #STATE_IDLE}, {@link #STATE_DRAGGING} or {@link #STATE_SETTLING}. * {@link #STATE_IDLE}, {@link #STATE_DRAGGING} or {@link #STATE_SETTLING}.
*
* @return The current drag state * @return The current drag state
*/ */
public int getViewDragState() { public int getViewDragState() {
...@@ -404,7 +212,7 @@ public class ViewDragHelper { ...@@ -404,7 +212,7 @@ public class ViewDragHelper {
* but {@link Callback#tryCaptureView(android.view.View, int)} will not be asked permission to * but {@link Callback#tryCaptureView(android.view.View, int)} will not be asked permission to
* capture this view. * capture this view.
* *
* @param childView Child view to capture * @param childView Child view to capture
* @param activePointerId ID of the pointer that is dragging the captured child view * @param activePointerId ID of the pointer that is dragging the captured child view
*/ */
public void captureChildView(View childView, int activePointerId) { public void captureChildView(View childView, int activePointerId) {
...@@ -462,13 +270,13 @@ public class ViewDragHelper { ...@@ -462,13 +270,13 @@ public class ViewDragHelper {
* If this method returns true, the caller should invoke {@link #continueSettling(boolean)} * If this method returns true, the caller should invoke {@link #continueSettling(boolean)}
* on each subsequent frame to continue the motion until it returns false. If this method * on each subsequent frame to continue the motion until it returns false. If this method
* returns false there is no further work to do to complete the movement. * returns false there is no further work to do to complete the movement.
* * <p>
* <p>This operation does not count as a capture event, though {@link #getCapturedView()} * <p>This operation does not count as a capture event, though {@link #getCapturedView()}
* will still report the sliding view while the slide is in progress.</p> * will still report the sliding view while the slide is in progress.</p>
* *
* @param child Child view to capture and animate * @param child Child view to capture and animate
* @param finalLeft Final left position of child * @param finalLeft Final left position of child
* @param finalTop Final top position of child * @param finalTop Final top position of child
* @return true if animation should continue through {@link #continueSettling(boolean)} calls * @return true if animation should continue through {@link #continueSettling(boolean)} calls
*/ */
public boolean smoothSlideViewTo(View child, int finalLeft, int finalTop) { public boolean smoothSlideViewTo(View child, int finalLeft, int finalTop) {
...@@ -486,7 +294,7 @@ public class ViewDragHelper { ...@@ -486,7 +294,7 @@ public class ViewDragHelper {
* returns false there is no further work to do to complete the movement. * returns false there is no further work to do to complete the movement.
* *
* @param finalLeft Settled left edge position for the captured view * @param finalLeft Settled left edge position for the captured view
* @param finalTop Settled top edge position for the captured view * @param finalTop Settled top edge position for the captured view
* @return true if animation should continue through {@link #continueSettling(boolean)} calls * @return true if animation should continue through {@link #continueSettling(boolean)} calls
*/ */
public boolean settleCapturedViewAt(int finalLeft, int finalTop) { public boolean settleCapturedViewAt(int finalLeft, int finalTop) {
...@@ -504,9 +312,9 @@ public class ViewDragHelper { ...@@ -504,9 +312,9 @@ public class ViewDragHelper {
* Settle the captured view at the given (left, top) position. * Settle the captured view at the given (left, top) position.
* *
* @param finalLeft Target left position for the captured view * @param finalLeft Target left position for the captured view
* @param finalTop Target top position for the captured view * @param finalTop Target top position for the captured view
* @param xvel Horizontal velocity * @param xvel Horizontal velocity
* @param yvel Vertical velocity * @param yvel Vertical velocity
* @return true if animation should continue through {@link #continueSettling(boolean)} calls * @return true if animation should continue through {@link #continueSettling(boolean)} calls
*/ */
private boolean forceSettleCapturedViewAt(int finalLeft, int finalTop, int xvel, int yvel) { private boolean forceSettleCapturedViewAt(int finalLeft, int finalTop, int xvel, int yvel) {
...@@ -577,7 +385,7 @@ public class ViewDragHelper { ...@@ -577,7 +385,7 @@ public class ViewDragHelper {
* If the value is below the minimum, it will be clamped to zero. * If the value is below the minimum, it will be clamped to zero.
* If the value is above the maximum, it will be clamped to the maximum. * If the value is above the maximum, it will be clamped to the maximum.
* *
* @param value Value to clamp * @param value Value to clamp
* @param absMin Absolute value of the minimum significant value to return * @param absMin Absolute value of the minimum significant value to return
* @param absMax Absolute value of the maximum value to return * @param absMax Absolute value of the maximum value to return
* @return The clamped value with the same sign as <code>value</code> * @return The clamped value with the same sign as <code>value</code>
...@@ -594,7 +402,7 @@ public class ViewDragHelper { ...@@ -594,7 +402,7 @@ public class ViewDragHelper {
* If the value is below the minimum, it will be clamped to zero. * If the value is below the minimum, it will be clamped to zero.
* If the value is above the maximum, it will be clamped to the maximum. * If the value is above the maximum, it will be clamped to the maximum.
* *
* @param value Value to clamp * @param value Value to clamp
* @param absMin Absolute value of the minimum significant value to return * @param absMin Absolute value of the minimum significant value to return
* @param absMax Absolute value of the maximum value to return * @param absMax Absolute value of the maximum value to return
* @return The clamped value with the same sign as <code>value</code> * @return The clamped value with the same sign as <code>value</code>
...@@ -758,7 +566,7 @@ public class ViewDragHelper { ...@@ -758,7 +566,7 @@ public class ViewDragHelper {
/** /**
* Check if the given pointer ID represents a pointer that is currently down (to the best * Check if the given pointer ID represents a pointer that is currently down (to the best
* of the ViewDragHelper's knowledge). * of the ViewDragHelper's knowledge).
* * <p>
* <p>The state used to report this information is populated by the methods * <p>The state used to report this information is populated by the methods
* {@link #shouldInterceptTouchEvent(android.view.MotionEvent)} or * {@link #shouldInterceptTouchEvent(android.view.MotionEvent)} or
* {@link #processTouchEvent(android.view.MotionEvent)}. If one of these methods has not * {@link #processTouchEvent(android.view.MotionEvent)}. If one of these methods has not
...@@ -886,7 +694,7 @@ public class ViewDragHelper { ...@@ -886,7 +694,7 @@ public class ViewDragHelper {
break; break;
} }
final View toCapture = findTopChildUnder((int)mInitialMotionX[pointerId], (int)mInitialMotionY[pointerId]); final View toCapture = findTopChildUnder((int) mInitialMotionX[pointerId], (int) mInitialMotionY[pointerId]);
if (toCapture != null && checkTouchSlop(toCapture, dx, dy) && if (toCapture != null && checkTouchSlop(toCapture, dx, dy) &&
tryCaptureViewForDrag(toCapture, pointerId)) { tryCaptureViewForDrag(toCapture, pointerId)) {
break; break;
...@@ -1094,7 +902,7 @@ public class ViewDragHelper { ...@@ -1094,7 +902,7 @@ public class ViewDragHelper {
final float absDelta = Math.abs(delta); final float absDelta = Math.abs(delta);
final float absODelta = Math.abs(odelta); final float absODelta = Math.abs(odelta);
if ((mInitialEdgesTouched[pointerId] & edge) != edge || (mTrackingEdges & edge) == 0 || if ((mInitialEdgesTouched[pointerId] & edge) != edge || (mTrackingEdges & edge) == 0 ||
(mEdgeDragsLocked[pointerId] & edge) == edge || (mEdgeDragsLocked[pointerId] & edge) == edge ||
(mEdgeDragsInProgress[pointerId] & edge) == edge || (mEdgeDragsInProgress[pointerId] & edge) == edge ||
(absDelta <= mTouchSlop && absODelta <= mTouchSlop)) { (absDelta <= mTouchSlop && absODelta <= mTouchSlop)) {
...@@ -1113,8 +921,8 @@ public class ViewDragHelper { ...@@ -1113,8 +921,8 @@ public class ViewDragHelper {
* along that axis will not count toward the slop check. * along that axis will not count toward the slop check.
* *
* @param child Child to check * @param child Child to check
* @param dx Motion since initial position along X axis * @param dx Motion since initial position along X axis
* @param dy Motion since initial position along Y axis * @param dy Motion since initial position along Y axis
* @return true if the touch slop has been crossed * @return true if the touch slop has been crossed
*/ */
private boolean checkTouchSlop(View child, float dx, float dy) { private boolean checkTouchSlop(View child, float dx, float dy) {
...@@ -1185,8 +993,8 @@ public class ViewDragHelper { ...@@ -1185,8 +993,8 @@ public class ViewDragHelper {
* parent view's coordinate system. * parent view's coordinate system.
* *
* @param view Child view of the parent to hit test * @param view Child view of the parent to hit test
* @param x X position to test in the parent's coordinate system * @param x X position to test in the parent's coordinate system
* @param y Y position to test in the parent's coordinate system * @param y Y position to test in the parent's coordinate system
* @return true if the supplied view is under the given point, false otherwise * @return true if the supplied view is under the given point, false otherwise
*/ */
public boolean isViewUnder(View view, int x, int y) { public boolean isViewUnder(View view, int x, int y) {
...@@ -1229,4 +1037,189 @@ public class ViewDragHelper { ...@@ -1229,4 +1037,189 @@ public class ViewDragHelper {
return result; return result;
} }
/**
* A Callback is used as a communication channel with the ViewDragHelper back to the
* parent view using it. <code>on*</code>methods are invoked on siginficant events and several
* accessor methods are expected to provide the ViewDragHelper with more information
* about the state of the parent view upon request. The callback also makes decisions
* governing the range and draggability of child views.
*/
public static abstract class Callback {
/**
* Called when the drag state changes. See the <code>STATE_*</code> constants
* for more information.
*
* @param state The new drag state
* @see #STATE_IDLE
* @see #STATE_DRAGGING
* @see #STATE_SETTLING
*/
public void onViewDragStateChanged(int state) {
}
/**
* Called when the captured view's position changes as the result of a drag or settle.
*
* @param changedView View whose position changed
* @param left New X coordinate of the left edge of the view
* @param top New Y coordinate of the top edge of the view
* @param dx Change in X position from the last call
* @param dy Change in Y position from the last call
*/
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
}
/**
* Called when a child view is captured for dragging or settling. The ID of the pointer
* currently dragging the captured view is supplied. If activePointerId is
* identified as {@link #INVALID_POINTER} the capture is programmatic instead of
* pointer-initiated.
*
* @param capturedChild Child view that was captured
* @param activePointerId Pointer id tracking the child capture
*/
public void onViewCaptured(View capturedChild, int activePointerId) {
}
/**
* Called when the child view is no longer being actively dragged.
* The fling velocity is also supplied, if relevant. The velocity values may
* be clamped to system minimums or maximums.
* <p>
* <p>Calling code may decide to fling or otherwise release the view to let it
* settle into place. It should do so using {@link #settleCapturedViewAt(int, int)}
* or {@link #flingCapturedView(int, int, int, int)}. If the Callback invokes
* one of these methods, the ViewDragHelper will enter {@link #STATE_SETTLING}
* and the view capture will not fully end until it comes to a complete stop.
* If neither of these methods is invoked before <code>onViewReleased</code> returns,
* the view will stop in place and the ViewDragHelper will return to
* {@link #STATE_IDLE}.</p>
*
* @param releasedChild The captured child view now being released
* @param xvel X velocity of the pointer as it left the screen in pixels per second.
* @param yvel Y velocity of the pointer as it left the screen in pixels per second.
*/
public void onViewReleased(View releasedChild, float xvel, float yvel) {
}
/**
* Called when one of the subscribed edges in the parent view has been touched
* by the user while no child view is currently captured.
*
* @param edgeFlags A combination of edge flags describing the edge(s) currently touched
* @param pointerId ID of the pointer touching the described edge(s)
* @see #EDGE_LEFT
* @see #EDGE_TOP
* @see #EDGE_RIGHT
* @see #EDGE_BOTTOM
*/
public void onEdgeTouched(int edgeFlags, int pointerId) {
}
/**
* Called when the given edge may become locked. This can happen if an edge drag
* was preliminarily rejected before beginning, but after {@link #onEdgeTouched(int, int)}
* was called. This method should return true to lock this edge or false to leave it
* unlocked. The default behavior is to leave edges unlocked.
*
* @param edgeFlags A combination of edge flags describing the edge(s) locked
* @return true to lock the edge, false to leave it unlocked
*/
public boolean onEdgeLock(int edgeFlags) {
return false;
}
/**
* Called when the user has started a deliberate drag away from one
* of the subscribed edges in the parent view while no child view is currently captured.
*
* @param edgeFlags A combination of edge flags describing the edge(s) dragged
* @param pointerId ID of the pointer touching the described edge(s)
* @see #EDGE_LEFT
* @see #EDGE_TOP
* @see #EDGE_RIGHT
* @see #EDGE_BOTTOM
*/
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
}
/**
* Called to determine the Z-order of child views.
*
* @param index the ordered position to query for
* @return index of the view that should be ordered at position <code>index</code>
*/
public int getOrderedChildIndex(int index) {
return index;
}
/**
* Return the magnitude of a draggable child view's horizontal range of motion in pixels.
* This method should return 0 for views that cannot move horizontally.
*
* @param child Child view to check
* @return range of horizontal motion in pixels
*/
public int getViewHorizontalDragRange(View child) {
return 0;
}
/**
* Return the magnitude of a draggable child view's vertical range of motion in pixels.
* This method should return 0 for views that cannot move vertically.
*
* @param child Child view to check
* @return range of vertical motion in pixels
*/
public int getViewVerticalDragRange(View child) {
return 0;
}
/**
* Called when the user's input indicates that they want to capture the given child view
* with the pointer indicated by pointerId. The callback should return true if the user
* is permitted to drag the given view with the indicated pointer.
* <p>
* <p>ViewDragHelper may call this method multiple times for the same view even if
* the view is already captured; this indicates that a new pointer is trying to take
* control of the view.</p>
* <p>
* <p>If this method returns true, a call to {@link #onViewCaptured(android.view.View, int)}
* will follow if the capture is successful.</p>
*
* @param child Child the user is attempting to capture
* @param pointerId ID of the pointer attempting the capture
* @return true if capture should be allowed, false otherwise
*/
public abstract boolean tryCaptureView(View child, int pointerId);
/**
* Restrict the motion of the dragged child view along the horizontal axis.
* The default implementation does not allow horizontal motion; the extending
* class must override this method and provide the desired clamping.
*
* @param child Child view being dragged
* @param left Attempted motion along the X axis
* @param dx Proposed change in position for left
* @return The new clamped position for left
*/
public int clampViewPositionHorizontal(View child, int left, int dx) {
return 0;
}
/**
* Restrict the motion of the dragged child view along the vertical axis.
* The default implementation does not allow vertical motion; the extending
* class must override this method and provide the desired clamping.
*
* @param child Child view being dragged
* @param top Attempted motion along the Y axis
* @param dy Proposed change in position for top
* @return The new clamped position for top
*/
public int clampViewPositionVertical(View child, int top, int dy) {
return 0;
}
}
} }
\ No newline at end of file
...@@ -23,9 +23,6 @@ import android.view.MotionEvent; ...@@ -23,9 +23,6 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.animation.BounceInterpolator; import android.view.animation.BounceInterpolator;
import app.insti.R.drawable;
import app.insti.fragment.MapFragment;
import com.mrane.campusmap.SettingsManager; import com.mrane.campusmap.SettingsManager;
import com.mrane.data.Building; import com.mrane.data.Building;
import com.mrane.data.Marker; import com.mrane.data.Marker;
...@@ -37,718 +34,719 @@ import java.util.Collection; ...@@ -37,718 +34,719 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import app.insti.R.drawable;
import app.insti.fragment.MapFragment;
public class CampusMapView extends SubsamplingScaleImageView { public class CampusMapView extends SubsamplingScaleImageView {
private MapFragment mainActivity; private static int RATIO_SHOW_PIN = 10;
private HashMap<String, Marker> data; private static int RATIO_SHOW_PIN_TEXT = 20;
private Collection<Marker> markerList; private static long DURATION_MARKER_ANIMATION = 500;
private ArrayList<Marker> addedMarkerList; private static long DELAY_MARKER_ANIMATION = 675;
private ArrayList<Marker> specialMarkerList; private static float MAX_SCALE = 1F;
private ArrayList<Marker> convoMarkerList; private MapFragment mainActivity;
private Marker resultMarker; private HashMap<String, Marker> data;
private Bitmap bluePointer; private Collection<Marker> markerList;
private Bitmap yellowPointer; private ArrayList<Marker> addedMarkerList;
private Bitmap greenPointer; private ArrayList<Marker> specialMarkerList;
private Bitmap grayPointer; private ArrayList<Marker> convoMarkerList;
private Bitmap blueMarker; private Marker resultMarker;
private Bitmap yellowMarker; private Bitmap bluePointer;
private Bitmap greenMarker; private Bitmap yellowPointer;
private Bitmap grayMarker; private Bitmap greenPointer;
private Bitmap blueLockedMarker; private Bitmap grayPointer;
private Bitmap blueConvoMarker; private Bitmap blueMarker;
private Bitmap yellowLockedMarker; private Bitmap yellowMarker;
private Bitmap greenLockedMarker; private Bitmap greenMarker;
private Bitmap grayLockedMarker; private Bitmap grayMarker;
private Bitmap userMarker; private Bitmap blueLockedMarker;
private float pointerWidth = 12; private Bitmap blueConvoMarker;
private float highlightedMarkerScale; private Bitmap yellowLockedMarker;
private Paint paint; private Bitmap greenLockedMarker;
private Paint textPaint; private Bitmap grayLockedMarker;
private Paint strokePaint; private Bitmap userMarker;
private Rect bounds = new Rect(); private float pointerWidth = 12;
private static int RATIO_SHOW_PIN = 10; private float highlightedMarkerScale;
private static int RATIO_SHOW_PIN_TEXT = 20; private Paint paint;
private static long DURATION_MARKER_ANIMATION = 500; private Paint textPaint;
private static long DELAY_MARKER_ANIMATION = 675; private Paint strokePaint;
private static float MAX_SCALE = 1F; private Rect bounds = new Rect();
private DisplayMetrics displayMetrics; private DisplayMetrics displayMetrics;
private float density; private float density;
private boolean isFirstLoad = true; private boolean isFirstLoad = true;
private SettingsManager settingsManager; private SettingsManager settingsManager;
public CampusMapView(Context context) { public CampusMapView(Context context) {
this(context, null); this(context, null);
} }
public CampusMapView(Context context, AttributeSet attr) { public CampusMapView(Context context, AttributeSet attr) {
super(context, attr); super(context, attr);
initialise(); initialise();
} }
private void initialise() { public static int getShowPinRatio() {
displayMetrics = getResources().getDisplayMetrics(); return RATIO_SHOW_PIN;
density = displayMetrics.density; }
highlightedMarkerScale = 1.0f;
initMarkers(); public static void setShowPinRatio(int ratio) {
RATIO_SHOW_PIN = ratio;
initPaints(); }
mainActivity = MapFragment.getMainActivity(); public static int getShowPinTextRatio() {
return RATIO_SHOW_PIN_TEXT;
setGestureDetector(); }
super.setMaxScale(density * MAX_SCALE);
} public static void setShowPinTextRatio(int ratio) {
RATIO_SHOW_PIN_TEXT = ratio;
@Override }
protected void onImageReady() {
if (isFirstLoad) { private void initialise() {
Runnable runnable = new Runnable() { displayMetrics = getResources().getDisplayMetrics();
public void run() { density = displayMetrics.density;
AnimationBuilder anim; highlightedMarkerScale = 1.0f;
anim = animateScaleAndCenter( initMarkers();
getTargetMinScale(), MapFragment.MAP_CENTER);
anim.withDuration(MapFragment.DURATION_INIT_MAP_ANIM) initPaints();
.start();
isFirstLoad = false; mainActivity = MapFragment.getMainActivity();
}
}; setGestureDetector();
mainActivity.getActivity().runOnUiThread(runnable); super.setMaxScale(density * MAX_SCALE);
} }
}
@Override
public void setSettingsManager(SettingsManager sm){ protected void onImageReady() {
settingsManager = sm; if (isFirstLoad) {
} Runnable runnable = new Runnable() {
public void run() {
public void setFirstLoad(boolean b) { AnimationBuilder anim;
isFirstLoad = b; anim = animateScaleAndCenter(
} getTargetMinScale(), MapFragment.MAP_CENTER);
anim.withDuration(MapFragment.DURATION_INIT_MAP_ANIM)
private void initMarkers() { .start();
float w = 0; isFirstLoad = false;
float h = 0; }
Options options = new BitmapFactory.Options(); };
options.inScaled = true; mainActivity.getActivity().runOnUiThread(runnable);
}
bluePointer = BitmapFactory.decodeResource(getResources(), }
drawable.marker_dot_blue, options);
blueMarker = BitmapFactory.decodeResource(getResources(), public void setSettingsManager(SettingsManager sm) {
drawable.marker_blue_s, options); settingsManager = sm;
blueLockedMarker = BitmapFactory.decodeResource(getResources(), }
drawable.marker_blue_h, options);
blueConvoMarker = BitmapFactory.decodeResource(getResources(), public void setFirstLoad(boolean b) {
drawable.marker_blue_h_convo, options); isFirstLoad = b;
}
yellowPointer = BitmapFactory.decodeResource(getResources(),
drawable.marker_dot_yellow, options); private void initMarkers() {
yellowMarker = BitmapFactory.decodeResource(getResources(), float w = 0;
drawable.marker_yellow_s, options); float h = 0;
yellowLockedMarker = BitmapFactory.decodeResource(getResources(), Options options = new BitmapFactory.Options();
drawable.marker_yellow_h, options); options.inScaled = true;
greenPointer = BitmapFactory.decodeResource(getResources(), bluePointer = BitmapFactory.decodeResource(getResources(),
drawable.marker_dot_green, options); drawable.marker_dot_blue, options);
greenMarker = BitmapFactory.decodeResource(getResources(), blueMarker = BitmapFactory.decodeResource(getResources(),
drawable.marker_green_s, options); drawable.marker_blue_s, options);
greenLockedMarker = BitmapFactory.decodeResource(getResources(), blueLockedMarker = BitmapFactory.decodeResource(getResources(),
drawable.marker_green_h, options); drawable.marker_blue_h, options);
blueConvoMarker = BitmapFactory.decodeResource(getResources(),
grayPointer = BitmapFactory.decodeResource(getResources(), drawable.marker_blue_h_convo, options);
drawable.marker_dot_gray, options);
grayMarker = BitmapFactory.decodeResource(getResources(), yellowPointer = BitmapFactory.decodeResource(getResources(),
drawable.marker_gray_s, options); drawable.marker_dot_yellow, options);
grayLockedMarker = BitmapFactory.decodeResource(getResources(), yellowMarker = BitmapFactory.decodeResource(getResources(),
drawable.marker_gray_h, options); drawable.marker_yellow_s, options);
w = pointerWidth*density; yellowLockedMarker = BitmapFactory.decodeResource(getResources(),
h = bluePointer.getScaledHeight(displayMetrics) * (w / bluePointer.getScaledWidth(displayMetrics)); drawable.marker_yellow_h, options);
bluePointer = Bitmap.createScaledBitmap(bluePointer, (int) w, (int) h, greenPointer = BitmapFactory.decodeResource(getResources(),
true); drawable.marker_dot_green, options);
bluePointer = Bitmap.createScaledBitmap(bluePointer, (int) w, (int) h, greenMarker = BitmapFactory.decodeResource(getResources(),
true); drawable.marker_green_s, options);
yellowPointer = Bitmap.createScaledBitmap(yellowPointer, (int) w, greenLockedMarker = BitmapFactory.decodeResource(getResources(),
(int) h, true); drawable.marker_green_h, options);
greenPointer = Bitmap.createScaledBitmap(greenPointer, (int) w,
(int) h, true); grayPointer = BitmapFactory.decodeResource(getResources(),
grayPointer = Bitmap.createScaledBitmap(grayPointer, (int) w, (int) h, drawable.marker_dot_gray, options);
true); grayMarker = BitmapFactory.decodeResource(getResources(),
w = 4f * w; drawable.marker_gray_s, options);
h = blueMarker.getScaledHeight(displayMetrics) * (w / blueMarker.getScaledWidth(displayMetrics)); grayLockedMarker = BitmapFactory.decodeResource(getResources(),
blueMarker = Bitmap.createScaledBitmap(blueMarker, (int) w, (int) h, drawable.marker_gray_h, options);
true); w = pointerWidth * density;
yellowMarker = Bitmap.createScaledBitmap(yellowMarker, (int) w, h = bluePointer.getScaledHeight(displayMetrics) * (w / bluePointer.getScaledWidth(displayMetrics));
(int) h, true);
greenMarker = Bitmap.createScaledBitmap(greenMarker, (int) w, (int) h, bluePointer = Bitmap.createScaledBitmap(bluePointer, (int) w, (int) h,
true); true);
grayMarker = Bitmap.createScaledBitmap(grayMarker, (int) w, (int) h, bluePointer = Bitmap.createScaledBitmap(bluePointer, (int) w, (int) h,
true); true);
blueLockedMarker = Bitmap.createScaledBitmap(blueLockedMarker, (int) w, yellowPointer = Bitmap.createScaledBitmap(yellowPointer, (int) w,
(int) h, true); (int) h, true);
blueConvoMarker = Bitmap.createScaledBitmap(blueConvoMarker, (int) w, greenPointer = Bitmap.createScaledBitmap(greenPointer, (int) w,
(int) h, true); (int) h, true);
yellowLockedMarker = Bitmap.createScaledBitmap(yellowLockedMarker, grayPointer = Bitmap.createScaledBitmap(grayPointer, (int) w, (int) h,
(int) w, (int) h, true); true);
greenLockedMarker = Bitmap.createScaledBitmap(greenLockedMarker, w = 4f * w;
(int) w, (int) h, true); h = blueMarker.getScaledHeight(displayMetrics) * (w / blueMarker.getScaledWidth(displayMetrics));
grayLockedMarker = Bitmap.createScaledBitmap(grayLockedMarker, (int) w, blueMarker = Bitmap.createScaledBitmap(blueMarker, (int) w, (int) h,
(int) h, true); true);
yellowMarker = Bitmap.createScaledBitmap(yellowMarker, (int) w,
(int) h, true);
greenMarker = Bitmap.createScaledBitmap(greenMarker, (int) w, (int) h,
true);
grayMarker = Bitmap.createScaledBitmap(grayMarker, (int) w, (int) h,
true);
blueLockedMarker = Bitmap.createScaledBitmap(blueLockedMarker, (int) w,
(int) h, true);
blueConvoMarker = Bitmap.createScaledBitmap(blueConvoMarker, (int) w,
(int) h, true);
yellowLockedMarker = Bitmap.createScaledBitmap(yellowLockedMarker,
(int) w, (int) h, true);
greenLockedMarker = Bitmap.createScaledBitmap(greenLockedMarker,
(int) w, (int) h, true);
grayLockedMarker = Bitmap.createScaledBitmap(grayLockedMarker, (int) w,
(int) h, true);
userMarker = BitmapFactory.decodeResource(getResources(), userMarker = BitmapFactory.decodeResource(getResources(),
drawable.marker_red_s, options); drawable.marker_red_s, options);
userMarker = Bitmap.createScaledBitmap(userMarker, (int) w, userMarker = Bitmap.createScaledBitmap(userMarker, (int) w,
(int) h, true); (int) h, true);
} }
private void initPaints() { private void initPaints() {
paint = new Paint(); paint = new Paint();
paint.setAntiAlias(true); paint.setAntiAlias(true);
textPaint = new Paint(); textPaint = new Paint();
textPaint.setAntiAlias(true); textPaint.setAntiAlias(true);
// textPaint.setColor(Color.rgb(254, 250, 217)); // textPaint.setColor(Color.rgb(254, 250, 217));
textPaint.setColor(Color.WHITE); textPaint.setColor(Color.WHITE);
textPaint.setShadowLayer(8.0f * density, -1 * density, 1 * density, textPaint.setShadowLayer(8.0f * density, -1 * density, 1 * density,
Color.BLACK); Color.BLACK);
textPaint.setTextSize(16 * density); textPaint.setTextSize(16 * density);
Typeface boldCn = Typeface.createFromAsset(getContext().getAssets(), Typeface boldCn = Typeface.createFromAsset(getContext().getAssets(),
MapFragment.FONT_SEMIBOLD); MapFragment.FONT_SEMIBOLD);
textPaint.setTypeface(boldCn); textPaint.setTypeface(boldCn);
strokePaint = new Paint(); strokePaint = new Paint();
strokePaint.setAntiAlias(true); strokePaint.setAntiAlias(true);
strokePaint.setColor(Color.BLACK); strokePaint.setColor(Color.BLACK);
strokePaint.setTypeface(Typeface.DEFAULT_BOLD); strokePaint.setTypeface(Typeface.DEFAULT_BOLD);
strokePaint.setTextSize(14 * density); strokePaint.setTextSize(14 * density);
strokePaint.setStyle(Style.STROKE); strokePaint.setStyle(Style.STROKE);
strokePaint.setStrokeJoin(Join.ROUND); strokePaint.setStrokeJoin(Join.ROUND);
strokePaint.setStrokeWidth(0.2f * density); strokePaint.setStrokeWidth(0.2f * density);
} }
public float getTargetMinScale() { public float getTargetMinScale() {
return Math.max(getWidth() / (float) getSWidth(), (getHeight()) return Math.max(getWidth() / (float) getSWidth(), (getHeight())
/ (float) getSHeight()); / (float) getSHeight());
} }
public void setData(HashMap<String, Marker> markerData) { public void setData(HashMap<String, Marker> markerData) {
data = markerData; data = markerData;
markerList = data.values(); markerList = data.values();
addedMarkerList = new ArrayList<Marker>(); addedMarkerList = new ArrayList<Marker>();
specialMarkerList = new ArrayList<Marker>(); specialMarkerList = new ArrayList<Marker>();
convoMarkerList = new ArrayList<Marker>(); convoMarkerList = new ArrayList<Marker>();
setSpecialMarkers(); setSpecialMarkers();
} }
private void setSpecialMarkers() { private void setSpecialMarkers() {
for (Marker m : markerList) { for (Marker m : markerList) {
if (m.isShowDefault()) { if (m.isShowDefault()) {
specialMarkerList.add(m); specialMarkerList.add(m);
} }
} }
} }
public static int getShowPinRatio() { public Marker getResultMarker() {
return RATIO_SHOW_PIN; return resultMarker;
} }
public static void setShowPinRatio(int ratio) { public void setResultMarker(Marker marker) {
RATIO_SHOW_PIN = ratio; resultMarker = marker;
} }
public static int getShowPinTextRatio() { @Deprecated
return RATIO_SHOW_PIN_TEXT; public Marker getHighlightedMarker() {
} return getResultMarker();
}
public static void setShowPinTextRatio(int ratio) {
RATIO_SHOW_PIN_TEXT = ratio; public boolean isResultMarker(Marker marker) {
} if (resultMarker == null)
return false;
public Marker getResultMarker() { return resultMarker == marker;
return resultMarker; }
}
public void showResultMarker() {
@Deprecated if (resultMarker != null) {
public Marker getHighlightedMarker() { boolean noDelay = false;
return getResultMarker(); if (isInView(getResultMarker().getPoint()))
} noDelay = true;
AnimationBuilder anim = animateScaleAndCenter(getShowTextScale(),
public void setResultMarker(Marker marker) { resultMarker.getPoint());
resultMarker = marker; anim.withDuration(750).start();
} setMarkerAnimation(noDelay, MapFragment.SOUND_ID_RESULT);
}
public boolean isResultMarker(Marker marker) { }
if (resultMarker == null)
return false; public void setAndShowResultMarker(Marker marker) {
return resultMarker == marker; setResultMarker(marker);
} showResultMarker();
}
public void showResultMarker() {
if (resultMarker != null) { public void addMarker(Marker m) {
boolean noDelay = false; if (!addedMarkerList.contains(m)) {
if (isInView(getResultMarker().getPoint())) addedMarkerList.add(m);
noDelay = true;
AnimationBuilder anim = animateScaleAndCenter(getShowTextScale(), }
resultMarker.getPoint()); }
anim.withDuration(750).start();
setMarkerAnimation(noDelay, MapFragment.SOUND_ID_RESULT); public void addMarker() {
} Marker m = getResultMarker();
} addMarker(m);
}
public void setAndShowResultMarker(Marker marker) {
setResultMarker(marker); public void addMarkers(Collection<? extends Marker> markers) {
showResultMarker(); for (Marker m : markers) {
} addMarker(m);
}
public void addMarker(Marker m) { }
if (!addedMarkerList.contains(m)) {
addedMarkerList.add(m); public void addMarkers(Marker[] markerArray) {
List<Marker> markerList = Arrays.asList(markerArray);
} addMarkers(markerList);
} }
public void addMarker() { public void removeAddedMarker(Marker m) {
Marker m = getResultMarker(); if (addedMarkerList.contains(m)) {
addMarker(m); addedMarkerList.remove(m);
} }
}
public void addMarkers(Collection<? extends Marker> markers) {
for (Marker m : markers) { public void removeAddedMarkers(Collection<? extends Marker> markers) {
addMarker(m); for (Marker m : markers) {
} removeAddedMarker(m);
} }
}
public void addMarkers(Marker[] markerArray) {
List<Marker> markerList = Arrays.asList(markerArray); public void removeAddedMarkers(Marker[] markerArray) {
addMarkers(markerList); List<Marker> markerList = Arrays.asList(markerArray);
} removeAddedMarkers(markerList);
}
public void removeAddedMarker(Marker m) {
if (addedMarkerList.contains(m)) { public void removeAddedMarkers() {
addedMarkerList.remove(m); addedMarkerList.clear();
} }
}
public boolean isAddedMarker(Marker m) {
public void removeAddedMarkers(Collection<? extends Marker> markers) { return addedMarkerList.contains(m);
for (Marker m : markers) { }
removeAddedMarker(m);
} public boolean isAddedMarker() {
} return isAddedMarker(getResultMarker());
}
public void removeAddedMarkers(Marker[] markerArray) {
List<Marker> markerList = Arrays.asList(markerArray); public void toggleMarker(Marker m) {
removeAddedMarkers(markerList); if (isAddedMarker(m)) {
} removeAddedMarker(m);
mainActivity.playAnimSound(MapFragment.SOUND_ID_REMOVE);
public void removeAddedMarkers() { } else {
addedMarkerList.clear(); addMarker(m);
} if (!isInView(m.getPoint())) {
AnimationBuilder anim = animateScaleAndCenter(
public boolean isAddedMarker(Marker m) { getShowTextScale(), m.getPoint());
return addedMarkerList.contains(m); anim.withDuration(750).start();
} setMarkerAnimation(false, MapFragment.SOUND_ID_ADD);
} else {
public boolean isAddedMarker() { setMarkerAnimation(true, MapFragment.SOUND_ID_ADD);
return isAddedMarker(getResultMarker()); }
} }
invalidate();
public void toggleMarker(Marker m) { }
if (isAddedMarker(m)) {
removeAddedMarker(m); public void toggleMarker() {
mainActivity.playAnimSound(MapFragment.SOUND_ID_REMOVE); toggleMarker(getResultMarker());
} else { }
addMarker(m);
if (!isInView(m.getPoint())) { @Override
AnimationBuilder anim = animateScaleAndCenter( protected void onDraw(Canvas canvas) {
getShowTextScale(), m.getPoint()); super.onDraw(canvas);
anim.withDuration(750).start();
setMarkerAnimation(false, MapFragment.SOUND_ID_ADD); // Don't draw pin before image is ready so it doesn't move around during
} else { // setup.
setMarkerAnimation(true, MapFragment.SOUND_ID_ADD); if (!isImageReady()) {
} return;
} }
invalidate();
} for (Marker marker : markerList) {
if (isInView(marker.getPoint())) {
public void toggleMarker() { if (isShowPinScale(marker)
toggleMarker(getResultMarker()); && !(isResultMarker(marker) || addedMarkerList
} .contains(marker))) {
if (shouldShowUp(marker))
@Override drawPionterAndText(canvas, marker);
protected void onDraw(Canvas canvas) { }
super.onDraw(canvas); }
}
// Don't draw pin before image is ready so it doesn't move around during for (Marker marker : addedMarkerList) {
// setup. if (isInView(marker.getPoint())) {
if (!isImageReady()) { if (!isResultMarker(marker)) {
return; drawMarkerBitmap(canvas, marker);
} drawMarkerText(canvas, marker);
}
for (Marker marker : markerList) { }
if (isInView(marker.getPoint())) { }
if (isShowPinScale(marker) Marker marker = getResultMarker();
&& !(isResultMarker(marker) || addedMarkerList if (marker != null) {
.contains(marker))) { if (isInView(marker.getPoint())) {
if (shouldShowUp(marker)) drawMarkerBitmap(canvas, marker);
drawPionterAndText(canvas, marker); drawMarkerText(canvas, marker);
} }
} }
}
for (Marker marker : addedMarkerList) { }
if (isInView(marker.getPoint())) {
if (!isResultMarker(marker)) { private boolean shouldShowUp(Marker marker) {
drawMarkerBitmap(canvas, marker); boolean result = true;
drawMarkerText(canvas, marker); if (marker.getGroupIndex() == Marker.RESIDENCES) {
} result = settingsManager.showResidences();
} }
} if (marker instanceof Building) {
Marker marker = getResultMarker(); String[] childKeys = ((Building) marker).children;
if (marker != null) { for (String childKey : childKeys) {
if (isInView(marker.getPoint())) { Marker child = data.get(childKey);
drawMarkerBitmap(canvas, marker); if (isAddedMarker(child) || isResultMarker(child)) {
drawMarkerText(canvas, marker); result = false;
} break;
} }
}
} }
if (marker instanceof Room)
private boolean shouldShowUp(Marker marker) { result = false;
boolean result = true; return result;
if(marker.getGroupIndex() == Marker.RESIDENCES){ }
result = settingsManager.showResidences();
} private void drawMarkerBitmap(Canvas canvas, Marker marker) {
if (marker instanceof Building) { Bitmap highlightedPin = getMarkerBitmap(marker);
String[] childKeys = ((Building) marker).children; PointF vPin = sourceToViewCoord(marker.getPoint());
for (String childKey : childKeys) { float vX = vPin.x - (highlightedPin.getWidth() / 2);
Marker child = data.get(childKey); float vY = vPin.y - highlightedPin.getHeight();
if (isAddedMarker(child) || isResultMarker(child)) { canvas.drawBitmap(highlightedPin, vX, vY, paint);
result = false; }
break;
} private void drawMarkerText(Canvas canvas, Marker marker) {
} String name;
} PointF vPin = sourceToViewCoord(marker.getPoint());
if (marker instanceof Room) if (marker.getShortName().equals("0") || marker.getShortName().isEmpty())
result = false; name = marker.getName();
return result; else
} name = marker.getShortName();
textPaint.getTextBounds(name, 0, name.length() - 1, bounds);
private void drawMarkerBitmap(Canvas canvas, Marker marker) { float tX = vPin.x - bounds.width() / 2;
Bitmap highlightedPin = getMarkerBitmap(marker); float tY = vPin.y + bounds.height();
PointF vPin = sourceToViewCoord(marker.getPoint()); canvas.drawText(name, tX, tY, textPaint);
float vX = vPin.x - (highlightedPin.getWidth() / 2); // canvas.drawText(names[0], tX, tY, strokePaint);
float vY = vPin.y - highlightedPin.getHeight(); }
canvas.drawBitmap(highlightedPin, vX, vY, paint);
} private void drawPionterAndText(Canvas canvas, Marker marker) {
Bitmap pin = getPointerBitmap(marker);
private void drawMarkerText(Canvas canvas, Marker marker) { PointF vPin = sourceToViewCoord(marker.getPoint());
String name; float vX = vPin.x - (pin.getWidth() / 2);
PointF vPin = sourceToViewCoord(marker.getPoint()); float vY = vPin.y - (pin.getHeight() / 2);
if (marker.getShortName().equals("0") || marker.getShortName().isEmpty()) canvas.drawBitmap(pin, vX, vY, paint);
name = marker.getName(); if (isShowPinTextScale(marker)) {
else String name;
name = marker.getShortName(); if (marker.getShortName().equals("0") || marker.getShortName().isEmpty())
textPaint.getTextBounds(name, 0, name.length() - 1, bounds); name = marker.getName();
float tX = vPin.x - bounds.width() / 2; else
float tY = vPin.y + bounds.height(); name = marker.getShortName();
canvas.drawText(name, tX, tY, textPaint); Paint temp = new Paint(textPaint);
// canvas.drawText(names[0], tX, tY, strokePaint); if (marker.getGroupIndex() == Marker.RESIDENCES) temp.setTextSize(12 * density);
} textPaint.getTextBounds(name, 0, name.length() - 1, bounds);
float tX = vPin.x + pin.getWidth();
private void drawPionterAndText(Canvas canvas, Marker marker) { float tY = vPin.y + bounds.height() / 2;
Bitmap pin = getPointerBitmap(marker); canvas.drawText(name, tX, tY, temp);
PointF vPin = sourceToViewCoord(marker.getPoint()); }
float vX = vPin.x - (pin.getWidth() / 2); }
float vY = vPin.y - (pin.getHeight() / 2);
canvas.drawBitmap(pin, vX, vY, paint); private boolean isInView(PointF point) {
if (isShowPinTextScale(marker)) { int displayWidth = displayMetrics.widthPixels;
String name; int displayHeight = displayMetrics.heightPixels;
if (marker.getShortName().equals("0") || marker.getShortName().isEmpty())
name = marker.getName(); int viewX = (int) sourceToViewCoord(point).x;
else int viewY = (int) sourceToViewCoord(point).y;
name = marker.getShortName();
Paint temp = new Paint(textPaint); if (viewX > -displayWidth / 3 && viewX < displayWidth && viewY > 0
if(marker.getGroupIndex() == Marker.RESIDENCES) temp.setTextSize(12*density); && viewY < displayHeight)
textPaint.getTextBounds(name, 0, name.length() - 1, bounds); return true;
float tX = vPin.x + pin.getWidth();
float tY = vPin.y + bounds.height() / 2; return false;
canvas.drawText(name, tX, tY, temp); }
}
} private Marker getNearestMarker(PointF touchPoint) {
Marker resultMarker = null;
private boolean isInView(PointF point) { float minDist = 100000000f;
int displayWidth = displayMetrics.widthPixels; for (Marker marker : markerList) {
int displayHeight = displayMetrics.heightPixels; PointF point = marker.getPoint();
float dist = (float) calculateDistance(point, touchPoint);
int viewX = (int) sourceToViewCoord(point).x;
int viewY = (int) sourceToViewCoord(point).y; if (dist < minDist && isMarkerVisible(marker)) {
minDist = dist;
if (viewX > -displayWidth / 3 && viewX < displayWidth && viewY > 0 resultMarker = marker;
&& viewY < displayHeight) }
return true; }
return resultMarker;
return false; }
}
private double calculateDistance(PointF point1, PointF point2) {
private Marker getNearestMarker(PointF touchPoint) { float xDiff = point1.x - point2.x;
Marker resultMarker = null; float yDiff = point1.y - point2.y;
float minDist = 100000000f;
for (Marker marker : markerList) { return Math.sqrt(xDiff * xDiff + yDiff * yDiff);
PointF point = marker.getPoint(); }
float dist = (float) calculateDistance(point, touchPoint);
private Bitmap getPointerBitmap(Marker marker) {
if (dist < minDist && isMarkerVisible(marker)) { int color = marker.getColor();
minDist = dist;
resultMarker = marker; if (color == Marker.COLOR_BLUE) {
} return bluePointer;
} } else if (color == Marker.COLOR_YELLOW) {
return resultMarker; return yellowPointer;
} } else if (color == Marker.COLOR_GREEN) {
return greenPointer;
private double calculateDistance(PointF point1, PointF point2) { } else if (color == Marker.COLOR_GRAY) {
float xDiff = point1.x - point2.x; return grayPointer;
float yDiff = point1.y - point2.y; }
return Math.sqrt(xDiff * xDiff + yDiff * yDiff); return bluePointer;
} }
private Bitmap getPointerBitmap(Marker marker) { private Bitmap getMarkerBitmap(Marker marker) {
int color = marker.getColor(); int color = marker.getColor();
if (color == Marker.COLOR_BLUE) { Bitmap markerBitmap = null;
return bluePointer;
} else if (color == Marker.COLOR_YELLOW) { if (color == Marker.COLOR_BLUE) {
return yellowPointer; markerBitmap = blueMarker;
} else if (color == Marker.COLOR_GREEN) { if (isAddedMarker(marker)) {
return greenPointer; markerBitmap = blueLockedMarker;
} else if (color == Marker.COLOR_GRAY) { if (convoMarkerList.contains(marker)) markerBitmap = blueConvoMarker;
return grayPointer; }
} } else if (color == Marker.COLOR_YELLOW) {
markerBitmap = yellowMarker;
return bluePointer; if (isAddedMarker(marker))
} markerBitmap = yellowLockedMarker;
} else if (color == Marker.COLOR_GREEN) {
private Bitmap getMarkerBitmap(Marker marker) { markerBitmap = greenMarker;
int color = marker.getColor(); if (isAddedMarker(marker))
markerBitmap = greenLockedMarker;
Bitmap markerBitmap = null; } else if (color == Marker.COLOR_GRAY) {
markerBitmap = grayMarker;
if (color == Marker.COLOR_BLUE) { if (isAddedMarker(marker))
markerBitmap = blueMarker; markerBitmap = grayLockedMarker;
if (isAddedMarker(marker)){ } else if (color == -10) {
markerBitmap = blueLockedMarker;
if(convoMarkerList.contains(marker)) markerBitmap = blueConvoMarker;
}
} else if (color == Marker.COLOR_YELLOW) {
markerBitmap = yellowMarker;
if (isAddedMarker(marker))
markerBitmap = yellowLockedMarker;
} else if (color == Marker.COLOR_GREEN) {
markerBitmap = greenMarker;
if (isAddedMarker(marker))
markerBitmap = greenLockedMarker;
} else if (color == Marker.COLOR_GRAY) {
markerBitmap = grayMarker;
if (isAddedMarker(marker))
markerBitmap = grayLockedMarker;
} else if (color == -10) {
if (isAddedMarker(marker)) if (isAddedMarker(marker))
markerBitmap = userMarker; markerBitmap = userMarker;
} }
if (highlightedMarkerScale != 1.0f && isResultMarker(marker)) { if (highlightedMarkerScale != 1.0f && isResultMarker(marker)) {
float w = markerBitmap.getWidth() * highlightedMarkerScale; float w = markerBitmap.getWidth() * highlightedMarkerScale;
float h = markerBitmap.getHeight() * highlightedMarkerScale; float h = markerBitmap.getHeight() * highlightedMarkerScale;
markerBitmap = Bitmap.createScaledBitmap(markerBitmap, (int) w, markerBitmap = Bitmap.createScaledBitmap(markerBitmap, (int) w,
(int) h, true); (int) h, true);
} }
if (isResultMarker(marker)) { if (isResultMarker(marker)) {
float w = markerBitmap.getWidth() * 1.2f; float w = markerBitmap.getWidth() * 1.2f;
float h = markerBitmap.getHeight() * 1.2f; float h = markerBitmap.getHeight() * 1.2f;
markerBitmap = Bitmap.createScaledBitmap(markerBitmap, (int) w, markerBitmap = Bitmap.createScaledBitmap(markerBitmap, (int) w,
(int) h, true); (int) h, true);
} }
return markerBitmap; return markerBitmap;
} }
private void setMarkerAnimation(boolean noDelay, int _sound_index) { private void setMarkerAnimation(boolean noDelay, int _sound_index) {
final int sound_index = _sound_index; final int sound_index = _sound_index;
long delay = 0; long delay = 0;
if (!noDelay) { if (!noDelay) {
delay = DELAY_MARKER_ANIMATION; delay = DELAY_MARKER_ANIMATION;
} }
if (android.os.Build.VERSION.SDK_INT >= 11) { if (android.os.Build.VERSION.SDK_INT >= 11) {
playAnim(delay); playAnim(delay);
} else { } else {
highlightedMarkerScale = 1.0f; highlightedMarkerScale = 1.0f;
} }
mainActivity.playAnimSoundDelayed(sound_index, delay); mainActivity.playAnimSoundDelayed(sound_index, delay);
if (isImageReady()) if (isImageReady())
invalidate(); invalidate();
} }
@SuppressLint("NewApi") @SuppressLint("NewApi")
private void playAnim(long delay) { private void playAnim(long delay) {
highlightedMarkerScale = 0.1f; highlightedMarkerScale = 0.1f;
ValueAnimator valAnim = new ValueAnimator(); ValueAnimator valAnim = new ValueAnimator();
valAnim.setFloatValues(0.1f, 1.0f); valAnim.setFloatValues(0.1f, 1.0f);
valAnim.setDuration(DURATION_MARKER_ANIMATION); valAnim.setDuration(DURATION_MARKER_ANIMATION);
valAnim.addUpdateListener(new AnimatorUpdateListener() { valAnim.addUpdateListener(new AnimatorUpdateListener() {
@Override @Override
public void onAnimationUpdate(ValueAnimator animation) { public void onAnimationUpdate(ValueAnimator animation) {
highlightedMarkerScale = (Float) animation.getAnimatedValue(); highlightedMarkerScale = (Float) animation.getAnimatedValue();
if (isImageReady()) if (isImageReady())
invalidate(); invalidate();
} }
}); });
TimeInterpolator i = new BounceInterpolator(); TimeInterpolator i = new BounceInterpolator();
valAnim.setInterpolator(i); valAnim.setInterpolator(i);
valAnim.setStartDelay(delay); valAnim.setStartDelay(delay);
valAnim.start(); valAnim.start();
} }
public Runnable getScaleAnim(final float scale){ public Runnable getScaleAnim(final float scale) {
Runnable anim = new Runnable() { Runnable anim = new Runnable() {
public void run() { public void run() {
AnimationBuilder animation = animateScale(scale); AnimationBuilder animation = animateScale(scale);
animation animation
.withDuration(200) .withDuration(200)
.withEasing( .withEasing(
SubsamplingScaleImageView.EASE_OUT_QUAD) SubsamplingScaleImageView.EASE_OUT_QUAD)
.start(); .start();
} }
}; };
return anim; return anim;
} }
@Override @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if(getTargetMinScale() > getScale()){ if (getTargetMinScale() > getScale()) {
setScaleAndCenter(getTargetMinScale(), getCenter()); setScaleAndCenter(getTargetMinScale(), getCenter());
} }
super.onSizeChanged(w, h, oldw, oldh); super.onSizeChanged(w, h, oldw, oldh);
} }
private void setGestureDetector() { private void setGestureDetector() {
final GestureDetector gestureDetector = new GestureDetector( final GestureDetector gestureDetector = new GestureDetector(
mainActivity.getContext(), new GestureDetector.SimpleOnGestureListener() { mainActivity.getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override @Override
public boolean onSingleTapConfirmed(MotionEvent e) { public boolean onSingleTapConfirmed(MotionEvent e) {
if (isImageReady()) { if (isImageReady()) {
PointF sCoord = viewToSourceCoord(e.getX(), PointF sCoord = viewToSourceCoord(e.getX(),
e.getY()); e.getY());
Marker marker = getNearestMarker(sCoord); Marker marker = getNearestMarker(sCoord);
if (isMarkerInTouchRegion(marker, sCoord)) { if (isMarkerInTouchRegion(marker, sCoord)) {
// mMainActivity.resultMarker(marker.name); // mMainActivity.resultMarker(marker.name);
mainActivity.editText.setText(marker.getName()); mainActivity.editText.setText(marker.getName());
mainActivity.displayMap(); mainActivity.displayMap();
} }
} else { } else {
} }
return true; return true;
} }
}); });
setOnTouchListener(new OnTouchListener() { setOnTouchListener(new OnTouchListener() {
@Override @Override
public boolean onTouch(View view, MotionEvent motionEvent) { public boolean onTouch(View view, MotionEvent motionEvent) {
final float targetMinScale = getTargetMinScale(); final float targetMinScale = getTargetMinScale();
int action = motionEvent.getAction(); int action = motionEvent.getAction();
if(action== MotionEvent.ACTION_DOWN){ if (action == MotionEvent.ACTION_DOWN) {
if(motionEvent.getX()<20*density){ if (motionEvent.getX() < 20 * density) {
getParent().requestDisallowInterceptTouchEvent(false); getParent().requestDisallowInterceptTouchEvent(false);
return true; return true;
} } else {
else{
// CampusMapView.this.setPanEnabled(true); // CampusMapView.this.setPanEnabled(true);
} }
} } else if (action == MotionEvent.ACTION_UP) {
else if(action == MotionEvent.ACTION_UP){ CampusMapView.this.setPanEnabled(true);
CampusMapView.this.setPanEnabled(true); }
} if (targetMinScale > getScale()) {
if (targetMinScale > getScale()) { callSuperOnTouch(motionEvent);
callSuperOnTouch(motionEvent);
if (action == MotionEvent.ACTION_UP) {
if (action == MotionEvent.ACTION_UP) {
Runnable anim = getScaleAnim(targetMinScale);
Runnable anim = getScaleAnim(targetMinScale); if (isImageReady()) anim.run();
if(isImageReady()) anim.run(); }
} return true;
return true; }
} return gestureDetector.onTouchEvent(motionEvent);
return gestureDetector.onTouchEvent(motionEvent); }
} });
});
}
}
private void callSuperOnTouch(MotionEvent me) {
private void callSuperOnTouch(MotionEvent me) { super.onTouchEvent(me);
super.onTouchEvent(me); }
}
private boolean isMarkerInTouchRegion(Marker marker, PointF o) {
private boolean isMarkerInTouchRegion(Marker marker, PointF o) { if (marker != null) {
if (marker != null) { PointF point = sourceToViewCoord(marker.getPoint());
PointF point = sourceToViewCoord(marker.getPoint()); PointF origin = sourceToViewCoord(o);
PointF origin = sourceToViewCoord(o); float dist = (float) calculateDistance(point, origin);
float dist = (float) calculateDistance(point, origin); if (dist < pointerWidth * density * 2 && isMarkerVisible(marker)) {
if (dist < pointerWidth * density * 2 && isMarkerVisible(marker)) { return true;
return true; }
} }
} return false;
return false; }
}
private boolean isMarkerVisible(Marker marker) {
private boolean isMarkerVisible(Marker marker) { if (marker == resultMarker)
if (marker == resultMarker) return true;
return true; if (addedMarkerList.contains(marker))
if (addedMarkerList.contains(marker)) return true;
return true; if (isShowPinScale(marker) && shouldShowUp(marker))
if (isShowPinScale(marker) && shouldShowUp(marker)) return true;
return true; return false;
return false; }
}
private boolean isShowPinScale(Marker m) {
private boolean isShowPinScale(Marker m) { if (specialMarkerList.contains(m))
if (specialMarkerList.contains(m)) return true;
return true; PointF left = viewToSourceCoord(0, 0);
PointF left = viewToSourceCoord(0, 0); PointF right = viewToSourceCoord(getWidth(), 0);
PointF right = viewToSourceCoord(getWidth(), 0); float xDpi = displayMetrics.xdpi;
float xDpi = displayMetrics.xdpi; if ((right.x - left.x) * xDpi / getWidth() < getSWidth()
if ((right.x - left.x) * xDpi / getWidth() < getSWidth() / RATIO_SHOW_PIN)
/ RATIO_SHOW_PIN) return true;
return true; return false;
return false; }
}
private boolean isShowPinTextScale(Marker m) {
private boolean isShowPinTextScale(Marker m) { if (specialMarkerList.contains(m))
if (specialMarkerList.contains(m)) return true;
return true; // PointF left = viewToSourceCoord(0, 0);
// PointF left = viewToSourceCoord(0, 0); // PointF right = viewToSourceCoord(getWidth(), 0);
// PointF right = viewToSourceCoord(getWidth(), 0); // float xDpi = displayMetrics.xdpi;
// float xDpi = displayMetrics.xdpi; // if((right.x-left.x)*xDpi/getWidth() <
// if((right.x-left.x)*xDpi/getWidth() < // getSWidth()*density/(RATIO_SHOW_PIN_TEXT*2)) return true;
// getSWidth()*density/(RATIO_SHOW_PIN_TEXT*2)) return true; if (getScale() >= (getShowTextScale()))
if (getScale() >= (getShowTextScale())) return true;
return true; return false;
return false; }
}
private float getShowTextScale() {
private float getShowTextScale() { float xDpi = displayMetrics.xdpi;
float xDpi = displayMetrics.xdpi; float scale = (RATIO_SHOW_PIN_TEXT * xDpi * 2 / density + 20)
float scale = (RATIO_SHOW_PIN_TEXT * xDpi * 2 / density + 20) / getSWidth();
/ getSWidth(); if (scale > getMaxScale()) {
if (scale > getMaxScale()) { scale = 0.7f * getMaxScale();
scale = 0.7f * getMaxScale(); }
} return scale;
return scale; }
}
@Override
@Override public boolean onTouchEvent(MotionEvent event) {
public boolean onTouchEvent(MotionEvent event) { MapFragment.getMainActivity().setFollowingUser(false);
MapFragment.getMainActivity().setFollowingUser(false); return super.onTouchEvent(event);
return super.onTouchEvent(event); }
}
} }
...@@ -26,11 +26,11 @@ import java.io.Serializable; ...@@ -26,11 +26,11 @@ import java.io.Serializable;
public class ImageViewState implements Serializable { public class ImageViewState implements Serializable {
/** /**
* *
*/ */
private static final long serialVersionUID = -4397017033346987595L; private static final long serialVersionUID = -4397017033346987595L;
private float scale; private float scale;
private float centerX; private float centerX;
......
...@@ -44,8 +44,6 @@ import android.view.GestureDetector; ...@@ -44,8 +44,6 @@ import android.view.GestureDetector;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import app.insti.R.styleable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -53,141 +51,139 @@ import java.util.LinkedHashMap; ...@@ -53,141 +51,139 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import app.insti.R.styleable;
/** /**
* Displays an image subsampled as necessary to avoid loading too much image data into memory. After a pinch to zoom in, * Displays an image subsampled as necessary to avoid loading too much image data into memory. After a pinch to zoom in,
* a set of image tiles subsampled at higher resolution are loaded and displayed over the base layer. During pinch and * a set of image tiles subsampled at higher resolution are loaded and displayed over the base layer. During pinch and
* zoom, tiles off screen or higher/lower resolution than required are discarded from memory. * zoom, tiles off screen or higher/lower resolution than required are discarded from memory.
* * <p>
* Tiles over 2048px are not used due to hardware rendering limitations. * Tiles over 2048px are not used due to hardware rendering limitations.
* * <p>
* This view will not work very well with images that are far larger in one dimension than the other because the tile grid * This view will not work very well with images that are far larger in one dimension than the other because the tile grid
* for each subsampling level has the same number of rows as columns, so each tile has the same width:height ratio as * for each subsampling level has the same number of rows as columns, so each tile has the same width:height ratio as
* the source image. This could result in image data totalling several times the screen area being loaded. * the source image. This could result in image data totalling several times the screen area being loaded.
* * <p>
* v prefixes - coordinates, translations and distances measured in screen (view) pixels * v prefixes - coordinates, translations and distances measured in screen (view) pixels
* s prefixes - coordinates, translations and distances measured in source image pixels (scaled) * s prefixes - coordinates, translations and distances measured in source image pixels (scaled)
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class SubsamplingScaleImageView extends View { public class SubsamplingScaleImageView extends View {
private static final String TAG = SubsamplingScaleImageView.class.getSimpleName(); /**
* Attempt to use EXIF information on the image to rotate it. Works for external files only.
/** Attempt to use EXIF information on the image to rotate it. Works for external files only. */ */
public static final int ORIENTATION_USE_EXIF = -1; public static final int ORIENTATION_USE_EXIF = -1;
/** Display the image file in its native orientation. */ /**
* Display the image file in its native orientation.
*/
public static final int ORIENTATION_0 = 0; public static final int ORIENTATION_0 = 0;
/** Rotate the image 90 degrees clockwise. */ /**
* Rotate the image 90 degrees clockwise.
*/
public static final int ORIENTATION_90 = 90; public static final int ORIENTATION_90 = 90;
/** Rotate the image 180 degrees. */ /**
* Rotate the image 180 degrees.
*/
public static final int ORIENTATION_180 = 180; public static final int ORIENTATION_180 = 180;
/** Rotate the image 270 degrees clockwise. */ /**
* Rotate the image 270 degrees clockwise.
*/
public static final int ORIENTATION_270 = 270; public static final int ORIENTATION_270 = 270;
/**
private static final List<Integer> VALID_ORIENTATIONS = Arrays.asList(ORIENTATION_0, ORIENTATION_90, ORIENTATION_180, ORIENTATION_270, ORIENTATION_USE_EXIF); * During zoom animation, keep the point of the image that was tapped in the same place, and scale the image around it.
*/
/** During zoom animation, keep the point of the image that was tapped in the same place, and scale the image around it. */
public static final int ZOOM_FOCUS_FIXED = 1; public static final int ZOOM_FOCUS_FIXED = 1;
/** During zoom animation, move the point of the image that was tapped to the center of the screen. */ /**
* During zoom animation, move the point of the image that was tapped to the center of the screen.
*/
public static final int ZOOM_FOCUS_CENTER = 2; public static final int ZOOM_FOCUS_CENTER = 2;
/** Zoom in to and center the tapped point immediately without animating. */ /**
* Zoom in to and center the tapped point immediately without animating.
*/
public static final int ZOOM_FOCUS_CENTER_IMMEDIATE = 3; public static final int ZOOM_FOCUS_CENTER_IMMEDIATE = 3;
/**
private static final List<Integer> VALID_ZOOM_STYLES = Arrays.asList(ZOOM_FOCUS_FIXED, ZOOM_FOCUS_CENTER, ZOOM_FOCUS_CENTER_IMMEDIATE); * Quadratic ease out. Not recommended for scale animation, but good for panning.
*/
/** Quadratic ease out. Not recommended for scale animation, but good for panning. */
public static final int EASE_OUT_QUAD = 1; public static final int EASE_OUT_QUAD = 1;
/** Quadratic ease in and out. */ /**
* Quadratic ease in and out.
*/
public static final int EASE_IN_OUT_QUAD = 2; public static final int EASE_IN_OUT_QUAD = 2;
/**
private static final List<Integer> VALID_EASING_STYLES = Arrays.asList(EASE_IN_OUT_QUAD, EASE_OUT_QUAD); * Don't allow the image to be panned off screen. As much of the image as possible is always displayed, centered in the view when it is smaller. This is the best option for galleries.
*/
/** Don't allow the image to be panned off screen. As much of the image as possible is always displayed, centered in the view when it is smaller. This is the best option for galleries. */
public static final int PAN_LIMIT_INSIDE = 1; public static final int PAN_LIMIT_INSIDE = 1;
/** Allows the image to be panned until it is just off screen, but no further. The edge of the image will stop when it is flush with the screen edge. */ /**
* Allows the image to be panned until it is just off screen, but no further. The edge of the image will stop when it is flush with the screen edge.
*/
public static final int PAN_LIMIT_OUTSIDE = 2; public static final int PAN_LIMIT_OUTSIDE = 2;
/** Allows the image to be panned until a corner reaches the center of the screen but no further. Useful when you want to pan any spot on the image to the exact center of the screen. */ /**
* Allows the image to be panned until a corner reaches the center of the screen but no further. Useful when you want to pan any spot on the image to the exact center of the screen.
*/
public static final int PAN_LIMIT_CUSTOM = 3; public static final int PAN_LIMIT_CUSTOM = 3;
private static final String TAG = SubsamplingScaleImageView.class.getSimpleName();
private static final List<Integer> VALID_ORIENTATIONS = Arrays.asList(ORIENTATION_0, ORIENTATION_90, ORIENTATION_180, ORIENTATION_270, ORIENTATION_USE_EXIF);
private static final List<Integer> VALID_ZOOM_STYLES = Arrays.asList(ZOOM_FOCUS_FIXED, ZOOM_FOCUS_CENTER, ZOOM_FOCUS_CENTER_IMMEDIATE);
private static final List<Integer> VALID_EASING_STYLES = Arrays.asList(EASE_IN_OUT_QUAD, EASE_OUT_QUAD);
private static final List<Integer> VALID_PAN_LIMITS = Arrays.asList(PAN_LIMIT_INSIDE, PAN_LIMIT_OUTSIDE, PAN_LIMIT_CUSTOM); private static final List<Integer> VALID_PAN_LIMITS = Arrays.asList(PAN_LIMIT_INSIDE, PAN_LIMIT_OUTSIDE, PAN_LIMIT_CUSTOM);
private static final int MESSAGE_LONG_CLICK = 1;
private final Object decoderLock = new Object();
// Overlay tile boundaries and other info // Overlay tile boundaries and other info
private boolean debug = false; private boolean debug = false;
// Image orientation setting // Image orientation setting
private int orientation = ORIENTATION_0; private int orientation = ORIENTATION_0;
// Max scale allowed (prevent infinite zoom) // Max scale allowed (prevent infinite zoom)
private float maxScale = 2F; private float maxScale = 2F;
// Density to reach before loading higher resolution tiles // Density to reach before loading higher resolution tiles
private int minimumTileDpi = -1; private int minimumTileDpi = -1;
// Pan limiting style // Pan limiting style
private int panLimit = PAN_LIMIT_INSIDE; private int panLimit = PAN_LIMIT_INSIDE;
// Gesture detection settings // Gesture detection settings
private boolean panEnabled = true; private boolean panEnabled = true;
private boolean zoomEnabled = true; private boolean zoomEnabled = true;
// Double tap zoom behaviour // Double tap zoom behaviour
private float doubleTapZoomScale = 1F; private float doubleTapZoomScale = 1F;
private int doubleTapZoomStyle = ZOOM_FOCUS_FIXED; private int doubleTapZoomStyle = ZOOM_FOCUS_FIXED;
// Current scale and scale at start of zoom // Current scale and scale at start of zoom
private float scale; private float scale;
private float scaleStart; private float scaleStart;
// Screen coordinate of top-left corner of source image // Screen coordinate of top-left corner of source image
private PointF vTranslate; private PointF vTranslate;
private PointF vTranslateStart; private PointF vTranslateStart;
// Source coordinate to center on, used when new position is set externally before view is ready // Source coordinate to center on, used when new position is set externally before view is ready
private Float pendingScale; private Float pendingScale;
private PointF sPendingCenter; private PointF sPendingCenter;
private PointF sRequestedCenter; private PointF sRequestedCenter;
// Source image dimensions and orientation - dimensions relate to the unrotated image // Source image dimensions and orientation - dimensions relate to the unrotated image
private int sWidth; private int sWidth;
private int sHeight; private int sHeight;
private int sOrientation; private int sOrientation;
// Is two-finger zooming in progress // Is two-finger zooming in progress
private boolean isZooming; private boolean isZooming;
// Is one-finger panning in progress // Is one-finger panning in progress
private boolean isPanning; private boolean isPanning;
// Max touches used in current gesture // Max touches used in current gesture
private int maxTouchCount; private int maxTouchCount;
// Fling detector // Fling detector
private GestureDetector detector; private GestureDetector detector;
// Tile decoder // Tile decoder
private BitmapRegionDecoder decoder; private BitmapRegionDecoder decoder;
private final Object decoderLock = new Object();
// Sample size used to display the whole image when fully zoomed out // Sample size used to display the whole image when fully zoomed out
private int fullImageSampleSize; private int fullImageSampleSize;
// Map of zoom level to tile grid // Map of zoom level to tile grid
private Map<Integer, List<Tile>> tileMap; private Map<Integer, List<Tile>> tileMap;
// Debug values // Debug values
private PointF vCenterStart; private PointF vCenterStart;
private float vDistStart; private float vDistStart;
// Scale and center animation tracking // Scale and center animation tracking
private Anim anim; private Anim anim;
// Whether a ready notification has been sent to subclasses // Whether a ready notification has been sent to subclasses
private boolean readySent = false; private boolean readySent = false;
// Long click listener // Long click listener
private OnLongClickListener onLongClickListener; private OnLongClickListener onLongClickListener;
// Long click handler // Long click handler
private Handler handler; private Handler handler;
private static final int MESSAGE_LONG_CLICK = 1;
// Paint objects created once and reused for efficiency // Paint objects created once and reused for efficiency
private Paint bitmapPaint; private Paint bitmapPaint;
private Paint debugPaint; private Paint debugPaint;
...@@ -212,8 +208,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -212,8 +208,8 @@ public class SubsamplingScaleImageView extends View {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (panEnabled && readySent && vTranslate != null && (Math.abs(e1.getX() - e2.getX()) > 50 || Math.abs(e1.getY() - e2.getY()) > 50) && (Math.abs(velocityX) > 500 || Math.abs(velocityY) > 500) && !isZooming) { if (panEnabled && readySent && vTranslate != null && (Math.abs(e1.getX() - e2.getX()) > 50 || Math.abs(e1.getY() - e2.getY()) > 50) && (Math.abs(velocityX) > 500 || Math.abs(velocityY) > 500) && !isZooming) {
PointF vTranslateEnd = new PointF(vTranslate.x + (velocityX * 0.25f), vTranslate.y + (velocityY * 0.25f)); PointF vTranslateEnd = new PointF(vTranslate.x + (velocityX * 0.25f), vTranslate.y + (velocityY * 0.25f));
float sCenterXEnd = ((getWidth()/2) - vTranslateEnd.x)/scale; float sCenterXEnd = ((getWidth() / 2) - vTranslateEnd.x) / scale;
float sCenterYEnd = ((getHeight()/2) - vTranslateEnd.y)/scale; float sCenterYEnd = ((getHeight() / 2) - vTranslateEnd.y) / scale;
new AnimationBuilder(new PointF(sCenterXEnd, sCenterYEnd)).withEasing(EASE_OUT_QUAD).withPanLimited(false).start(); new AnimationBuilder(new PointF(sCenterXEnd, sCenterYEnd)).withEasing(EASE_OUT_QUAD).withPanLimited(false).start();
return true; return true;
} }
...@@ -270,22 +266,9 @@ public class SubsamplingScaleImageView extends View { ...@@ -270,22 +266,9 @@ public class SubsamplingScaleImageView extends View {
this(context, null); this(context, null);
} }
/**
* Sets the image orientation. It's best to call this before setting the image file or asset, because it may waste
* loading of tiles. However, this can be freely called at any time.
*/
public final void setOrientation(int orientation) {
if (!VALID_ORIENTATIONS.contains(orientation)) {
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
this.orientation = orientation;
reset(false);
invalidate();
requestLayout();
}
/** /**
* Display an image from a file in internal or external storage. * Display an image from a file in internal or external storage.
*
* @param extFile URI of the file to display. * @param extFile URI of the file to display.
*/ */
public final void setImageFile(String extFile) { public final void setImageFile(String extFile) {
...@@ -299,8 +282,9 @@ public class SubsamplingScaleImageView extends View { ...@@ -299,8 +282,9 @@ public class SubsamplingScaleImageView extends View {
* Display an image from a file in internal or external storage, starting with a given orientation setting, scale * Display an image from a file in internal or external storage, starting with a given orientation setting, scale
* and center. This is the best method to use when you want scale and center to be restored after screen orientation * and center. This is the best method to use when you want scale and center to be restored after screen orientation
* change; it avoids any redundant loading of tiles in the wrong orientation. * change; it avoids any redundant loading of tiles in the wrong orientation.
*
* @param extFile URI of the file to display. * @param extFile URI of the file to display.
* @param state State to be restored. Nullable. * @param state State to be restored. Nullable.
*/ */
public final void setImageFile(String extFile, ImageViewState state) { public final void setImageFile(String extFile, ImageViewState state) {
reset(true); reset(true);
...@@ -312,6 +296,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -312,6 +296,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Display an image from a file in assets. * Display an image from a file in assets.
*
* @param assetName asset name. * @param assetName asset name.
*/ */
public final void setImageAsset(String assetName) { public final void setImageAsset(String assetName) {
...@@ -322,8 +307,9 @@ public class SubsamplingScaleImageView extends View { ...@@ -322,8 +307,9 @@ public class SubsamplingScaleImageView extends View {
* Display an image from a file in assets, starting with a given orientation setting, scale and center. This is the * Display an image from a file in assets, starting with a given orientation setting, scale and center. This is the
* best method to use when you want scale and center to be restored after screen orientation change; it avoids any * best method to use when you want scale and center to be restored after screen orientation change; it avoids any
* redundant loading of tiles in the wrong orientation. * redundant loading of tiles in the wrong orientation.
*
* @param assetName asset name. * @param assetName asset name.
* @param state State to be restored. Nullable. * @param state State to be restored. Nullable.
*/ */
public final void setImageAsset(String assetName, ImageViewState state) { public final void setImageAsset(String assetName, ImageViewState state) {
reset(true); reset(true);
...@@ -406,9 +392,9 @@ public class SubsamplingScaleImageView extends View { ...@@ -406,9 +392,9 @@ public class SubsamplingScaleImageView extends View {
width = sWidth(); width = sWidth();
height = sHeight(); height = sHeight();
} else if (resizeHeight) { } else if (resizeHeight) {
height = (int)((((double)sHeight()/(double)sWidth()) * width)); height = (int) ((((double) sHeight() / (double) sWidth()) * width));
} else if (resizeWidth) { } else if (resizeWidth) {
width = (int)((((double)sWidth()/(double)sHeight()) * height)); width = (int) ((((double) sWidth() / (double) sHeight()) * height));
} }
} }
width = Math.max(width, getSuggestedMinimumWidth()); width = Math.max(width, getSuggestedMinimumWidth());
...@@ -455,7 +441,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -455,7 +441,7 @@ public class SubsamplingScaleImageView extends View {
scaleStart = scale; scaleStart = scale;
vDistStart = distance; vDistStart = distance;
vTranslateStart = new PointF(vTranslate.x, vTranslate.y); vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
vCenterStart = new PointF((event.getX(0) + event.getX(1))/2, (event.getY(0) + event.getY(1))/2); vCenterStart = new PointF((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
} else { } else {
// Abort all gestures on second touch // Abort all gestures on second touch
maxTouchCount = 0; maxTouchCount = 0;
...@@ -477,7 +463,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -477,7 +463,7 @@ public class SubsamplingScaleImageView extends View {
if (touchCount >= 2) { if (touchCount >= 2) {
// Calculate new distance between touch points, to scale and pan relative to start values. // Calculate new distance between touch points, to scale and pan relative to start values.
vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1)); vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
vCenterEnd = new PointF((event.getX(0) + event.getX(1))/2, (event.getY(0) + event.getY(1))/2); vCenterEnd = new PointF((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
if (zoomEnabled && (distance(vCenterStart.x, vCenterEnd.x, vCenterStart.y, vCenterEnd.y) > 5 || Math.abs(vDistEnd - vDistStart) > 5 || isPanning)) { if (zoomEnabled && (distance(vCenterStart.x, vCenterEnd.x, vCenterStart.y, vCenterEnd.y) > 5 || Math.abs(vDistEnd - vDistStart) > 5 || isPanning)) {
isZooming = true; isZooming = true;
...@@ -497,18 +483,18 @@ public class SubsamplingScaleImageView extends View { ...@@ -497,18 +483,18 @@ public class SubsamplingScaleImageView extends View {
// at the center of the pinch now, to give simultaneous pan + zoom. // at the center of the pinch now, to give simultaneous pan + zoom.
float vLeftStart = vCenterStart.x - vTranslateStart.x; float vLeftStart = vCenterStart.x - vTranslateStart.x;
float vTopStart = vCenterStart.y - vTranslateStart.y; float vTopStart = vCenterStart.y - vTranslateStart.y;
float vLeftNow = vLeftStart * (scale/scaleStart); float vLeftNow = vLeftStart * (scale / scaleStart);
float vTopNow = vTopStart * (scale/scaleStart); float vTopNow = vTopStart * (scale / scaleStart);
vTranslate.x = vCenterEnd.x - vLeftNow; vTranslate.x = vCenterEnd.x - vLeftNow;
vTranslate.y = vCenterEnd.y - vTopNow; vTranslate.y = vCenterEnd.y - vTopNow;
} else if (sRequestedCenter != null) { } else if (sRequestedCenter != null) {
// With a center specified from code, zoom around that point. // With a center specified from code, zoom around that point.
vTranslate.x = (getWidth()/2) - (scale * sRequestedCenter.x); vTranslate.x = (getWidth() / 2) - (scale * sRequestedCenter.x);
vTranslate.y = (getHeight()/2) - (scale * sRequestedCenter.y); vTranslate.y = (getHeight() / 2) - (scale * sRequestedCenter.y);
} else { } else {
// With no requested center, scale around the image center. // With no requested center, scale around the image center.
vTranslate.x = (getWidth()/2) - (scale * (sWidth()/2)); vTranslate.x = (getWidth() / 2) - (scale * (sWidth() / 2));
vTranslate.y = (getHeight()/2) - (scale * (sHeight()/2)); vTranslate.y = (getHeight() / 2) - (scale * (sHeight() / 2));
} }
fitToBounds(true); fitToBounds(true);
...@@ -618,8 +604,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -618,8 +604,8 @@ public class SubsamplingScaleImageView extends View {
// If waiting to translate to new center position, set translate now // If waiting to translate to new center position, set translate now
if (sPendingCenter != null && pendingScale != null) { if (sPendingCenter != null && pendingScale != null) {
scale = pendingScale; scale = pendingScale;
vTranslate.x = (getWidth()/2) - (scale * sPendingCenter.x); vTranslate.x = (getWidth() / 2) - (scale * sPendingCenter.x);
vTranslate.y = (getHeight()/2) - (scale * sPendingCenter.y); vTranslate.y = (getHeight() / 2) - (scale * sPendingCenter.y);
sPendingCenter = null; sPendingCenter = null;
pendingScale = null; pendingScale = null;
fitToBounds(true); fitToBounds(true);
...@@ -711,7 +697,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -711,7 +697,7 @@ public class SubsamplingScaleImageView extends View {
canvas.drawCircle(vCenterStart.x, vCenterStart.y, 10, debugPaint); canvas.drawCircle(vCenterStart.x, vCenterStart.y, 10, debugPaint);
canvas.drawCircle(vCenterEndRequested.x, vCenterEndRequested.y, 20, debugPaint); canvas.drawCircle(vCenterEndRequested.x, vCenterEndRequested.y, 20, debugPaint);
canvas.drawCircle(vCenterEnd.x, vCenterEnd.y, 25, debugPaint); canvas.drawCircle(vCenterEnd.x, vCenterEnd.y, 25, debugPaint);
canvas.drawCircle(getWidth()/2, getHeight()/2, 30, debugPaint); canvas.drawCircle(getWidth() / 2, getHeight() / 2, 30, debugPaint);
} }
} }
} }
...@@ -741,16 +727,16 @@ public class SubsamplingScaleImageView extends View { ...@@ -741,16 +727,16 @@ public class SubsamplingScaleImageView extends View {
private synchronized void initialiseBaseLayer(Point maxTileDimensions) { private synchronized void initialiseBaseLayer(Point maxTileDimensions) {
fitToBounds(true); fitToBounds(true);
fullImageSampleSize = calculateInSampleSize(); fullImageSampleSize = calculateInSampleSize();
// Load double resolution - next level will be split into four tiles and at the center all four are required, // Load double resolution - next level will be split into four tiles and at the center all four are required,
// so don't bother with tiling until the next level 16 tiles are needed. // so don't bother with tiling until the next level 16 tiles are needed.
if (fullImageSampleSize > 1) { if (fullImageSampleSize > 1) {
fullImageSampleSize /= 2; fullImageSampleSize /= 2;
} }
initialiseTileMap(maxTileDimensions); initialiseTileMap(maxTileDimensions);
...@@ -765,6 +751,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -765,6 +751,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Loads the optimum tiles for display at the current scale and translate, so the screen can be filled with tiles * Loads the optimum tiles for display at the current scale and translate, so the screen can be filled with tiles
* that are at least as high resolution as the screen. Frees up bitmaps that are now off the screen. * that are at least as high resolution as the screen. Frees up bitmaps that are now off the screen.
*
* @param load Whether to load the new tiles needed. Use false while scrolling/panning for performance. * @param load Whether to load the new tiles needed. Use false while scrolling/panning for performance.
*/ */
private void refreshRequiredTiles(boolean load) { private void refreshRequiredTiles(boolean load) {
...@@ -812,12 +799,12 @@ public class SubsamplingScaleImageView extends View { ...@@ -812,12 +799,12 @@ public class SubsamplingScaleImageView extends View {
float adjustedScale = scale; float adjustedScale = scale;
if (minimumTileDpi > 0) { if (minimumTileDpi > 0) {
DisplayMetrics metrics = getResources().getDisplayMetrics(); DisplayMetrics metrics = getResources().getDisplayMetrics();
float averageDpi = (metrics.xdpi + metrics.ydpi)/2; float averageDpi = (metrics.xdpi + metrics.ydpi) / 2;
adjustedScale = (minimumTileDpi/averageDpi) * scale; adjustedScale = (minimumTileDpi / averageDpi) * scale;
} }
int reqWidth = (int)(sWidth() * adjustedScale); int reqWidth = (int) (sWidth() * adjustedScale);
int reqHeight = (int)(sHeight() * adjustedScale); int reqHeight = (int) (sHeight() * adjustedScale);
// Raw height and width of image // Raw height and width of image
int inSampleSize = 1; int inSampleSize = 1;
...@@ -850,7 +837,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -850,7 +837,8 @@ public class SubsamplingScaleImageView extends View {
* Adjusts hypothetical future scale and translate values to keep scale within the allowed range and the image on screen. Minimum scale * Adjusts hypothetical future scale and translate values to keep scale within the allowed range and the image on screen. Minimum scale
* is set so one dimension fills the view and the image is centered on the other dimension. Used to calculate what the target of an * is set so one dimension fills the view and the image is centered on the other dimension. Used to calculate what the target of an
* animation should be. * animation should be.
* @param center Whether the image should be centered in the dimension it's too small to fill. While animating this can be false to avoid changes in direction as bounds are reached. *
* @param center Whether the image should be centered in the dimension it's too small to fill. While animating this can be false to avoid changes in direction as bounds are reached.
* @param scaleAndTranslate The scale we want and the translation we're aiming for. The values are adjusted to be valid. * @param scaleAndTranslate The scale we want and the translation we're aiming for. The values are adjusted to be valid.
*/ */
private void fitToBounds(boolean center, ScaleAndTranslate scaleAndTranslate) { private void fitToBounds(boolean center, ScaleAndTranslate scaleAndTranslate) {
...@@ -865,7 +853,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -865,7 +853,7 @@ public class SubsamplingScaleImageView extends View {
if (panLimit == PAN_LIMIT_CUSTOM && isImageReady()) { if (panLimit == PAN_LIMIT_CUSTOM && isImageReady()) {
vTranslate.x = Math.max(vTranslate.x, getWidth() - scaleWidth); vTranslate.x = Math.max(vTranslate.x, getWidth() - scaleWidth);
vTranslate.y = Math.max(vTranslate.y, 9*getHeight()/10 - scaleHeight); vTranslate.y = Math.max(vTranslate.y, 9 * getHeight() / 10 - scaleHeight);
} else if (center) { } else if (center) {
vTranslate.x = Math.max(vTranslate.x, getWidth() - scaleWidth); vTranslate.x = Math.max(vTranslate.x, getWidth() - scaleWidth);
vTranslate.y = Math.max(vTranslate.y, getHeight() - scaleHeight); vTranslate.y = Math.max(vTranslate.y, getHeight() - scaleHeight);
...@@ -878,7 +866,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -878,7 +866,7 @@ public class SubsamplingScaleImageView extends View {
float maxTy; float maxTy;
if (panLimit == PAN_LIMIT_CUSTOM && isImageReady()) { if (panLimit == PAN_LIMIT_CUSTOM && isImageReady()) {
maxTx = Math.max(0, 0); maxTx = Math.max(0, 0);
maxTy = Math.max(0, getHeight()/10); maxTy = Math.max(0, getHeight() / 10);
} else if (center) { } else if (center) {
maxTx = Math.max(0, (getWidth() - scaleWidth) / 2); maxTx = Math.max(0, (getWidth() - scaleWidth) / 2);
maxTy = Math.max(0, (getHeight() - scaleHeight) / 2); maxTy = Math.max(0, (getHeight() - scaleHeight) / 2);
...@@ -896,6 +884,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -896,6 +884,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Adjusts current scale and translate values to keep scale within the allowed range and the image on screen. Minimum scale * Adjusts current scale and translate values to keep scale within the allowed range and the image on screen. Minimum scale
* is set so one dimension fills the view and the image is centered on the other dimension. * is set so one dimension fills the view and the image is centered on the other dimension.
*
* @param center Whether the image should be centered in the dimension it's too small to fill. While animating this can be false to avoid changes in direction as bounds are reached. * @param center Whether the image should be centered in the dimension it's too small to fill. While animating this can be false to avoid changes in direction as bounds are reached.
*/ */
private void fitToBounds(boolean center) { private void fitToBounds(boolean center) {
...@@ -916,19 +905,19 @@ public class SubsamplingScaleImageView extends View { ...@@ -916,19 +905,19 @@ public class SubsamplingScaleImageView extends View {
int xTiles = 1; int xTiles = 1;
int yTiles = 1; int yTiles = 1;
while (true) { while (true) {
int sTileWidth = sWidth()/xTiles; int sTileWidth = sWidth() / xTiles;
int sTileHeight = sHeight()/yTiles; int sTileHeight = sHeight() / yTiles;
int subTileWidth = sTileWidth/sampleSize; int subTileWidth = sTileWidth / sampleSize;
int subTileHeight = sTileHeight/sampleSize; int subTileHeight = sTileHeight / sampleSize;
while (subTileWidth > maxTileDimensions.x || (subTileWidth > getWidth() * 1.25 && sampleSize < fullImageSampleSize)) { while (subTileWidth > maxTileDimensions.x || (subTileWidth > getWidth() * 1.25 && sampleSize < fullImageSampleSize)) {
xTiles += 1; xTiles += 1;
sTileWidth = sWidth()/xTiles; sTileWidth = sWidth() / xTiles;
subTileWidth = sTileWidth/sampleSize; subTileWidth = sTileWidth / sampleSize;
} }
while (subTileHeight > maxTileDimensions.y || (subTileHeight > getHeight() * 1.25 && sampleSize < fullImageSampleSize)) { while (subTileHeight > maxTileDimensions.y || (subTileHeight > getHeight() * 1.25 && sampleSize < fullImageSampleSize)) {
yTiles += 1; yTiles += 1;
sTileHeight = sHeight()/yTiles; sTileHeight = sHeight() / yTiles;
subTileHeight = sTileHeight/sampleSize; subTileHeight = sTileHeight / sampleSize;
} }
List<Tile> tileGrid = new ArrayList<Tile>(xTiles * yTiles); List<Tile> tileGrid = new ArrayList<Tile>(xTiles * yTiles);
for (int x = 0; x < xTiles; x++) { for (int x = 0; x < xTiles; x++) {
...@@ -973,172 +962,6 @@ public class SubsamplingScaleImageView extends View { ...@@ -973,172 +962,6 @@ public class SubsamplingScaleImageView extends View {
invalidate(); invalidate();
} }
/**
* Async task used to get image details without blocking the UI thread.
*/
private static class BitmapInitTask extends AsyncTask<Void, Void, int[]> {
private final WeakReference<SubsamplingScaleImageView> viewRef;
private final WeakReference<Context> contextRef;
private final String source;
private final boolean sourceIsAsset;
private BitmapRegionDecoder decoder;
public BitmapInitTask(SubsamplingScaleImageView view, Context context, String source, boolean sourceIsAsset) {
this.viewRef = new WeakReference<SubsamplingScaleImageView>(view);
this.contextRef = new WeakReference<Context>(context);
this.source = source;
this.sourceIsAsset = sourceIsAsset;
}
@Override
protected int[] doInBackground(Void... params) {
try {
if (viewRef != null && contextRef != null) {
Context context = contextRef.get();
if (context != null) {
int exifOrientation = ORIENTATION_0;
if (sourceIsAsset) {
decoder = BitmapRegionDecoder.newInstance(context.getAssets().open(source, AssetManager.ACCESS_RANDOM), true);
} else {
decoder = BitmapRegionDecoder.newInstance(source, true);
try {
ExifInterface exifInterface = new ExifInterface(source);
int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
if (orientationAttr == ExifInterface.ORIENTATION_NORMAL) {
exifOrientation = ORIENTATION_0;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_90) {
exifOrientation = ORIENTATION_90;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_180) {
exifOrientation = ORIENTATION_180;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_270) {
exifOrientation = ORIENTATION_270;
} else {
Log.w(TAG, "Unsupported EXIF orientation: " + orientationAttr);
}
} catch (Exception e) {
Log.w(TAG, "Could not get EXIF orientation of image");
}
}
return new int[] { decoder.getWidth(), decoder.getHeight(), exifOrientation };
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to initialise bitmap decoder", e);
}
return null;
}
@Override
protected void onPostExecute(int[] xyo) {
if (viewRef != null && decoder != null) {
final SubsamplingScaleImageView subsamplingScaleImageView = viewRef.get();
if (subsamplingScaleImageView != null && decoder != null && xyo != null && xyo.length == 3) {
subsamplingScaleImageView.onImageInited(decoder, xyo[0], xyo[1], xyo[2]);
}
}
}
}
/**
* Async task used to load images without blocking the UI thread.
*/
private static class BitmapTileTask extends AsyncTask<Void, Void, Bitmap> {
private final WeakReference<SubsamplingScaleImageView> viewRef;
private final WeakReference<BitmapRegionDecoder> decoderRef;
private final WeakReference<Object> decoderLockRef;
private final WeakReference<Tile> tileRef;
public BitmapTileTask(SubsamplingScaleImageView view, BitmapRegionDecoder decoder, Object decoderLock, Tile tile) {
this.viewRef = new WeakReference<SubsamplingScaleImageView>(view);
this.decoderRef = new WeakReference<BitmapRegionDecoder>(decoder);
this.decoderLockRef = new WeakReference<Object>(decoderLock);
this.tileRef = new WeakReference<Tile>(tile);
tile.loading = true;
}
@Override
protected Bitmap doInBackground(Void... params) {
try {
if (decoderRef != null && tileRef != null && viewRef != null) {
final BitmapRegionDecoder decoder = decoderRef.get();
final Object decoderLock = decoderLockRef.get();
final Tile tile = tileRef.get();
final SubsamplingScaleImageView view = viewRef.get();
if (decoder != null && decoderLock != null && tile != null && view != null && !decoder.isRecycled()) {
synchronized (decoderLock) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = tile.sampleSize;
options.inPreferredConfig = Config.RGB_565;
options.inDither = true;
Bitmap bitmap = decoder.decodeRegion(view.fileSRect(tile.sRect), options);
int rotation = view.getRequiredRotation();
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return bitmap;
}
} else if (tile != null) {
tile.loading = false;
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to decode tile", e);
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (viewRef != null && tileRef != null && bitmap != null) {
final SubsamplingScaleImageView subsamplingScaleImageView = viewRef.get();
final Tile tile = tileRef.get();
if (subsamplingScaleImageView != null && tile != null) {
tile.bitmap = bitmap;
tile.loading = false;
subsamplingScaleImageView.onTileLoaded();
}
}
}
}
private static class Tile {
private Rect sRect;
private int sampleSize;
private Bitmap bitmap;
private boolean loading;
private boolean visible;
}
private static class Anim {
private float scaleStart; // Scale at start of anim
private float scaleEnd; // Scale at end of anim (target)
private PointF sCenterStart; // Source center point at start
private PointF sCenterEnd; // Source center point at end, adjusted for pan limits
private PointF sCenterEndRequested; // Source center point that was requested, without adjustment
private PointF vFocusStart; // View point that was double tapped
private PointF vFocusEnd; // Where the view focal point should be moved to during the anim
private long duration = 500; // How long the anim takes
private boolean interruptible = true; // Whether the anim can be interrupted by a touch
private int easing = EASE_IN_OUT_QUAD; // Easing style
private long time = System.currentTimeMillis(); // Start time
}
private static class ScaleAndTranslate {
private ScaleAndTranslate(float scale, PointF translate) {
this.scale = scale;
this.translate = translate;
}
private float scale;
private PointF translate;
}
/** /**
* Set scale, center and orientation from saved state. * Set scale, center and orientation from saved state.
*/ */
...@@ -1157,8 +980,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -1157,8 +980,8 @@ public class SubsamplingScaleImageView extends View {
private Point getMaxBitmapDimensions(Canvas canvas) { private Point getMaxBitmapDimensions(Canvas canvas) {
if (VERSION.SDK_INT >= 14) { if (VERSION.SDK_INT >= 14) {
try { try {
int maxWidth = (Integer)Canvas.class.getMethod("getMaximumBitmapWidth").invoke(canvas); int maxWidth = (Integer) Canvas.class.getMethod("getMaximumBitmapWidth").invoke(canvas);
int maxHeight = (Integer)Canvas.class.getMethod("getMaximumBitmapHeight").invoke(canvas); int maxHeight = (Integer) Canvas.class.getMethod("getMaximumBitmapHeight").invoke(canvas);
return new Point(maxWidth, maxHeight); return new Point(maxWidth, maxHeight);
} catch (Exception e) { } catch (Exception e) {
// Return default // Return default
...@@ -1224,7 +1047,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1224,7 +1047,7 @@ public class SubsamplingScaleImageView extends View {
private float distance(float x0, float x1, float y0, float y1) { private float distance(float x0, float x1, float y0, float y1) {
float x = x0 - x1; float x = x0 - x1;
float y = y0 - y1; float y = y0 - y1;
return (float)Math.sqrt(x * x + y * y); return (float) Math.sqrt(x * x + y * y);
} }
/** /**
...@@ -1241,8 +1064,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -1241,8 +1064,8 @@ public class SubsamplingScaleImageView extends View {
if (vTranslate == null) { if (vTranslate == null) {
return null; return null;
} }
float sx = (vx - vTranslate.x)/scale; float sx = (vx - vTranslate.x) / scale;
float sy = (vy - vTranslate.y)/scale; float sy = (vy - vTranslate.y) / scale;
return new PointF(sx, sy); return new PointF(sx, sy);
} }
...@@ -1301,7 +1124,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1301,7 +1124,7 @@ public class SubsamplingScaleImageView extends View {
* Float to int rect conversion. * Float to int rect conversion.
*/ */
private Rect convertRect(RectF rect) { private Rect convertRect(RectF rect) {
return new Rect((int)rect.left, (int)rect.top, (int)rect.right, (int)rect.bottom); return new Rect((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
} }
/** /**
...@@ -1310,7 +1133,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1310,7 +1133,7 @@ public class SubsamplingScaleImageView extends View {
* the image point as near to the screen center as permitted. * the image point as near to the screen center as permitted.
*/ */
private PointF vTranslateForSCenter(PointF sCenter, float scale) { private PointF vTranslateForSCenter(PointF sCenter, float scale) {
PointF vTranslate = new PointF((getWidth()/2) - (sCenter.x * scale), (getHeight()/2) - (sCenter.y * scale)); PointF vTranslate = new PointF((getWidth() / 2) - (sCenter.x * scale), (getHeight() / 2) - (sCenter.y * scale));
ScaleAndTranslate sat = new ScaleAndTranslate(scale, vTranslate); ScaleAndTranslate sat = new ScaleAndTranslate(scale, vTranslate);
fitToBounds(true, sat); fitToBounds(true, sat);
return vTranslate; return vTranslate;
...@@ -1322,9 +1145,9 @@ public class SubsamplingScaleImageView extends View { ...@@ -1322,9 +1145,9 @@ public class SubsamplingScaleImageView extends View {
*/ */
private PointF limitedSCenter(PointF sCenter, float scale) { private PointF limitedSCenter(PointF sCenter, float scale) {
PointF vTranslate = vTranslateForSCenter(sCenter, scale); PointF vTranslate = vTranslateForSCenter(sCenter, scale);
int mY = getHeight()/2; int mY = getHeight() / 2;
float sx = ((getWidth()/2) - vTranslate.x)/scale; float sx = ((getWidth() / 2) - vTranslate.x) / scale;
float sy = ((getHeight()/2) - vTranslate.y)/scale; float sy = ((getHeight() / 2) - vTranslate.y) / scale;
return new PointF(sx, sy); return new PointF(sx, sy);
} }
...@@ -1332,7 +1155,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1332,7 +1155,7 @@ public class SubsamplingScaleImageView extends View {
* Returns the minimum allowed scale. * Returns the minimum allowed scale.
*/ */
private float minScale() { private float minScale() {
return Math.min(getWidth() / (float) sWidth(), (getHeight())/ (float) sHeight()); return Math.min(getWidth() / (float) sWidth(), (getHeight()) / (float) sHeight());
} }
/** /**
...@@ -1346,10 +1169,11 @@ public class SubsamplingScaleImageView extends View { ...@@ -1346,10 +1169,11 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Apply a selected type of easing. * Apply a selected type of easing.
* @param type Easing type, from static fields *
* @param time Elapsed time * @param type Easing type, from static fields
* @param from Start value * @param time Elapsed time
* @param change Target value * @param from Start value
* @param change Target value
* @param duration Anm duration * @param duration Anm duration
* @return Current value * @return Current value
*/ */
...@@ -1366,32 +1190,34 @@ public class SubsamplingScaleImageView extends View { ...@@ -1366,32 +1190,34 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Quadratic easing for fling. With thanks to Robert Penner - http://gizma.com/easing/ * Quadratic easing for fling. With thanks to Robert Penner - http://gizma.com/easing/
* @param time Elapsed time *
* @param from Start value * @param time Elapsed time
* @param change Target value * @param from Start value
* @param change Target value
* @param duration Anm duration * @param duration Anm duration
* @return Current value * @return Current value
*/ */
private float easeOutQuad(long time, float from, float change, long duration) { private float easeOutQuad(long time, float from, float change, long duration) {
float progress = (float)time/(float)duration; float progress = (float) time / (float) duration;
return -change * progress*(progress-2) + from; return -change * progress * (progress - 2) + from;
} }
/** /**
* Quadratic easing for scale and center animations. With thanks to Robert Penner - http://gizma.com/easing/ * Quadratic easing for scale and center animations. With thanks to Robert Penner - http://gizma.com/easing/
* @param time Elapsed time *
* @param from Start value * @param time Elapsed time
* @param change Target value * @param from Start value
* @param change Target value
* @param duration Anm duration * @param duration Anm duration
* @return Current value * @return Current value
*/ */
private float easeInOutQuad(long time, float from, float change, long duration) { private float easeInOutQuad(long time, float from, float change, long duration) {
float timeF = time/(duration/2f); float timeF = time / (duration / 2f);
if (timeF < 1) { if (timeF < 1) {
return (change/2f * timeF * timeF) + from; return (change / 2f * timeF * timeF) + from;
} else { } else {
timeF--; timeF--;
return (-change/2f) * (timeF * (timeF - 2) - 1) + from; return (-change / 2f) * (timeF * (timeF - 2) - 1) + from;
} }
} }
...@@ -1409,6 +1235,13 @@ public class SubsamplingScaleImageView extends View { ...@@ -1409,6 +1235,13 @@ public class SubsamplingScaleImageView extends View {
} }
} }
/**
* Returns the maximum allowed scale.
*/
public float getMaxScale() {
return maxScale;
}
/** /**
* Set the maximum scale allowed. A value of 1 means 1:1 pixels at maximum scale. You may wish to set this according * Set the maximum scale allowed. A value of 1 means 1:1 pixels at maximum scale. You may wish to set this according
* to screen density - on a retina screen, 1:1 may still be too small. Consider using {@link #setMinimumDpi(int)}, * to screen density - on a retina screen, 1:1 may still be too small. Consider using {@link #setMinimumDpi(int)},
...@@ -1418,23 +1251,17 @@ public class SubsamplingScaleImageView extends View { ...@@ -1418,23 +1251,17 @@ public class SubsamplingScaleImageView extends View {
this.maxScale = maxScale; this.maxScale = maxScale;
} }
/**
* Returns the maximum allowed scale.
*/
public float getMaxScale() {
return maxScale;
}
/** /**
* This is a screen density aware alternative to {@link #setMaxScale(float)}; it allows you to express the maximum * This is a screen density aware alternative to {@link #setMaxScale(float)}; it allows you to express the maximum
* allowed scale in terms of the minimum pixel density. This avoids the problem of 1:1 scale still being * allowed scale in terms of the minimum pixel density. This avoids the problem of 1:1 scale still being
* too small on a high density screen. A sensible starting point is 160 - the default used by this view. * too small on a high density screen. A sensible starting point is 160 - the default used by this view.
*
* @param dpi Source image pixel density at maximum zoom. * @param dpi Source image pixel density at maximum zoom.
*/ */
public final void setMinimumDpi(int dpi) { public final void setMinimumDpi(int dpi) {
DisplayMetrics metrics = getResources().getDisplayMetrics(); DisplayMetrics metrics = getResources().getDisplayMetrics();
float averageDpi = (metrics.xdpi + metrics.ydpi)/2; float averageDpi = (metrics.xdpi + metrics.ydpi) / 2;
setMaxScale(averageDpi/dpi); setMaxScale(averageDpi / dpi);
} }
/** /**
...@@ -1449,12 +1276,13 @@ public class SubsamplingScaleImageView extends View { ...@@ -1449,12 +1276,13 @@ public class SubsamplingScaleImageView extends View {
* necessary, and may increase the likelihood of an OutOfMemoryError. This method sets a DPI at which higher * necessary, and may increase the likelihood of an OutOfMemoryError. This method sets a DPI at which higher
* resolution tiles should be loaded. Using a lower number will on average use less memory but result in a lower * resolution tiles should be loaded. Using a lower number will on average use less memory but result in a lower
* quality image. 160-240dpi will usually be enough. * quality image. 160-240dpi will usually be enough.
*
* @param minimumTileDpi Tile loading threshold. * @param minimumTileDpi Tile loading threshold.
*/ */
public void setMinimumTileDpi(int minimumTileDpi) { public void setMinimumTileDpi(int minimumTileDpi) {
DisplayMetrics metrics = getResources().getDisplayMetrics(); DisplayMetrics metrics = getResources().getDisplayMetrics();
float averageDpi = (metrics.xdpi + metrics.ydpi)/2; float averageDpi = (metrics.xdpi + metrics.ydpi) / 2;
this.minimumTileDpi = (int)Math.min(averageDpi, minimumTileDpi); this.minimumTileDpi = (int) Math.min(averageDpi, minimumTileDpi);
if (isImageReady()) { if (isImageReady()) {
reset(false); reset(false);
invalidate(); invalidate();
...@@ -1465,8 +1293,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -1465,8 +1293,8 @@ public class SubsamplingScaleImageView extends View {
* Returns the source point at the center of the view. * Returns the source point at the center of the view.
*/ */
public final PointF getCenter() { public final PointF getCenter() {
int mX = getWidth()/2; int mX = getWidth() / 2;
int mY = getHeight()/2; int mY = getHeight() / 2;
return viewToSourceCoord(mX, mY); return viewToSourceCoord(mX, mY);
} }
...@@ -1480,7 +1308,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -1480,7 +1308,8 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Externally change the scale and translation of the source image. This may be used with getCenter() and getScale() * Externally change the scale and translation of the source image. This may be used with getCenter() and getScale()
* to restore the scale and zoom after a screen rotate. * to restore the scale and zoom after a screen rotate.
* @param scale New scale to set. *
* @param scale New scale to set.
* @param sCenter New source image coordinate to center on the screen, subject to boundaries. * @param sCenter New source image coordinate to center on the screen, subject to boundaries.
*/ */
public final void setScaleAndCenter(float scale, PointF sCenter) { public final void setScaleAndCenter(float scale, PointF sCenter) {
...@@ -1490,7 +1319,6 @@ public class SubsamplingScaleImageView extends View { ...@@ -1490,7 +1319,6 @@ public class SubsamplingScaleImageView extends View {
this.sRequestedCenter = sCenter; this.sRequestedCenter = sCenter;
invalidate(); invalidate();
} }
/** /**
* Fully zoom out and return the image to the middle of the screen. This might be useful if you have a view pager * Fully zoom out and return the image to the middle of the screen. This might be useful if you have a view pager
...@@ -1500,7 +1328,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1500,7 +1328,7 @@ public class SubsamplingScaleImageView extends View {
this.anim = null; this.anim = null;
this.pendingScale = limitedScale(0); this.pendingScale = limitedScale(0);
if (isImageReady()) { if (isImageReady()) {
this.sPendingCenter = new PointF(sWidth()/2, sHeight()/2); this.sPendingCenter = new PointF(sWidth() / 2, sHeight() / 2);
} else { } else {
this.sPendingCenter = new PointF(0, 0); this.sPendingCenter = new PointF(0, 0);
} }
...@@ -1546,6 +1374,20 @@ public class SubsamplingScaleImageView extends View { ...@@ -1546,6 +1374,20 @@ public class SubsamplingScaleImageView extends View {
return orientation; return orientation;
} }
/**
* Sets the image orientation. It's best to call this before setting the image file or asset, because it may waste
* loading of tiles. However, this can be freely called at any time.
*/
public final void setOrientation(int orientation) {
if (!VALID_ORIENTATIONS.contains(orientation)) {
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
this.orientation = orientation;
reset(false);
invalidate();
requestLayout();
}
/** /**
* Returns the actual orientation of the image relative to the source file. This will be based on the source file's * Returns the actual orientation of the image relative to the source file. This will be based on the source file's
* EXIF orientation if you're using ORIENTATION_USE_EXIF. Values are 0, 90, 180, 270. * EXIF orientation if you're using ORIENTATION_USE_EXIF. Values are 0, 90, 180, 270.
...@@ -1592,8 +1434,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -1592,8 +1434,8 @@ public class SubsamplingScaleImageView extends View {
public final void setPanEnabled(boolean panEnabled) { public final void setPanEnabled(boolean panEnabled) {
this.panEnabled = panEnabled; this.panEnabled = panEnabled;
if (!panEnabled && vTranslate != null) { if (!panEnabled && vTranslate != null) {
vTranslate.x = (getWidth()/2) - (scale * (sWidth()/2)); vTranslate.x = (getWidth() / 2) - (scale * (sWidth() / 2));
vTranslate.y = (getHeight()/2) - (scale * (sHeight()/2)); vTranslate.y = (getHeight() / 2) - (scale * (sHeight() / 2));
if (isImageReady()) { if (isImageReady()) {
refreshRequiredTiles(true); refreshRequiredTiles(true);
invalidate(); invalidate();
...@@ -1605,6 +1447,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1605,6 +1447,7 @@ public class SubsamplingScaleImageView extends View {
* Set the scale the image will zoom in to when double tapped. This also the scale point where a double tap is interpreted * Set the scale the image will zoom in to when double tapped. This also the scale point where a double tap is interpreted
* as a zoom out gesture - if the scale is greater than 90% of this value, a double tap zooms out. Avoid using values * as a zoom out gesture - if the scale is greater than 90% of this value, a double tap zooms out. Avoid using values
* greater than the max zoom. * greater than the max zoom.
*
* @param doubleTapZoomScale New value for double tap gesture zoom scale. * @param doubleTapZoomScale New value for double tap gesture zoom scale.
*/ */
public final void setDoubleTapZoomScale(float doubleTapZoomScale) { public final void setDoubleTapZoomScale(float doubleTapZoomScale) {
...@@ -1615,16 +1458,18 @@ public class SubsamplingScaleImageView extends View { ...@@ -1615,16 +1458,18 @@ public class SubsamplingScaleImageView extends View {
* A density aware alternative to {@link #setDoubleTapZoomScale(float)}; this allows you to express the scale the * A density aware alternative to {@link #setDoubleTapZoomScale(float)}; this allows you to express the scale the
* image will zoom in to when double tapped in terms of the image pixel density. Values lower than the max scale will * image will zoom in to when double tapped in terms of the image pixel density. Values lower than the max scale will
* be ignored. A sensible starting point is 160 - the default used by this view. * be ignored. A sensible starting point is 160 - the default used by this view.
*
* @param dpi New value for double tap gesture zoom scale. * @param dpi New value for double tap gesture zoom scale.
*/ */
public final void setDoubleTapZoomDpi(int dpi) { public final void setDoubleTapZoomDpi(int dpi) {
DisplayMetrics metrics = getResources().getDisplayMetrics(); DisplayMetrics metrics = getResources().getDisplayMetrics();
float averageDpi = (metrics.xdpi + metrics.ydpi)/2; float averageDpi = (metrics.xdpi + metrics.ydpi) / 2;
setDoubleTapZoomScale(averageDpi/dpi); setDoubleTapZoomScale(averageDpi / dpi);
} }
/** /**
* Set the type of zoom animation to be used for double taps. See static fields. * Set the type of zoom animation to be used for double taps. See static fields.
*
* @param doubleTapZoomStyle New value for zoom style. * @param doubleTapZoomStyle New value for zoom style.
*/ */
public final void setDoubleTapZoomStyle(int doubleTapZoomStyle) { public final void setDoubleTapZoomStyle(int doubleTapZoomStyle) {
...@@ -1646,6 +1491,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1646,6 +1491,7 @@ public class SubsamplingScaleImageView extends View {
* the image in the center of the screen. If doing this would move the image beyond the edges of the screen, the * the image in the center of the screen. If doing this would move the image beyond the edges of the screen, the
* image is instead animated to move the center point as near to the center of the screen as is allowed - it's * image is instead animated to move the center point as near to the center of the screen as is allowed - it's
* guaranteed to be on screen. * guaranteed to be on screen.
*
* @param sCenter Target center point * @param sCenter Target center point
* @return {@link AnimationBuilder} instance. Call {@link com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. * @return {@link AnimationBuilder} instance. Call {@link com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim.
*/ */
...@@ -1659,6 +1505,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1659,6 +1505,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image * Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image
* beyond the panning limits, the image is automatically panned during the animation. * beyond the panning limits, the image is automatically panned during the animation.
*
* @param scale Target scale. * @param scale Target scale.
* @return {@link AnimationBuilder} instance. Call {@link com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. * @return {@link AnimationBuilder} instance. Call {@link com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim.
*/ */
...@@ -1672,6 +1519,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1672,6 +1519,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image * Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image
* beyond the panning limits, the image is automatically panned during the animation. * beyond the panning limits, the image is automatically panned during the animation.
*
* @param scale Target scale. * @param scale Target scale.
* @return {@link AnimationBuilder} instance. Call {@link com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. * @return {@link AnimationBuilder} instance. Call {@link com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim.
*/ */
...@@ -1682,6 +1530,172 @@ public class SubsamplingScaleImageView extends View { ...@@ -1682,6 +1530,172 @@ public class SubsamplingScaleImageView extends View {
return new AnimationBuilder(scale, sCenter); return new AnimationBuilder(scale, sCenter);
} }
/**
* Async task used to get image details without blocking the UI thread.
*/
private static class BitmapInitTask extends AsyncTask<Void, Void, int[]> {
private final WeakReference<SubsamplingScaleImageView> viewRef;
private final WeakReference<Context> contextRef;
private final String source;
private final boolean sourceIsAsset;
private BitmapRegionDecoder decoder;
public BitmapInitTask(SubsamplingScaleImageView view, Context context, String source, boolean sourceIsAsset) {
this.viewRef = new WeakReference<SubsamplingScaleImageView>(view);
this.contextRef = new WeakReference<Context>(context);
this.source = source;
this.sourceIsAsset = sourceIsAsset;
}
@Override
protected int[] doInBackground(Void... params) {
try {
if (viewRef != null && contextRef != null) {
Context context = contextRef.get();
if (context != null) {
int exifOrientation = ORIENTATION_0;
if (sourceIsAsset) {
decoder = BitmapRegionDecoder.newInstance(context.getAssets().open(source, AssetManager.ACCESS_RANDOM), true);
} else {
decoder = BitmapRegionDecoder.newInstance(source, true);
try {
ExifInterface exifInterface = new ExifInterface(source);
int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
if (orientationAttr == ExifInterface.ORIENTATION_NORMAL) {
exifOrientation = ORIENTATION_0;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_90) {
exifOrientation = ORIENTATION_90;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_180) {
exifOrientation = ORIENTATION_180;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_270) {
exifOrientation = ORIENTATION_270;
} else {
Log.w(TAG, "Unsupported EXIF orientation: " + orientationAttr);
}
} catch (Exception e) {
Log.w(TAG, "Could not get EXIF orientation of image");
}
}
return new int[]{decoder.getWidth(), decoder.getHeight(), exifOrientation};
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to initialise bitmap decoder", e);
}
return null;
}
@Override
protected void onPostExecute(int[] xyo) {
if (viewRef != null && decoder != null) {
final SubsamplingScaleImageView subsamplingScaleImageView = viewRef.get();
if (subsamplingScaleImageView != null && decoder != null && xyo != null && xyo.length == 3) {
subsamplingScaleImageView.onImageInited(decoder, xyo[0], xyo[1], xyo[2]);
}
}
}
}
/**
* Async task used to load images without blocking the UI thread.
*/
private static class BitmapTileTask extends AsyncTask<Void, Void, Bitmap> {
private final WeakReference<SubsamplingScaleImageView> viewRef;
private final WeakReference<BitmapRegionDecoder> decoderRef;
private final WeakReference<Object> decoderLockRef;
private final WeakReference<Tile> tileRef;
public BitmapTileTask(SubsamplingScaleImageView view, BitmapRegionDecoder decoder, Object decoderLock, Tile tile) {
this.viewRef = new WeakReference<SubsamplingScaleImageView>(view);
this.decoderRef = new WeakReference<BitmapRegionDecoder>(decoder);
this.decoderLockRef = new WeakReference<Object>(decoderLock);
this.tileRef = new WeakReference<Tile>(tile);
tile.loading = true;
}
@Override
protected Bitmap doInBackground(Void... params) {
try {
if (decoderRef != null && tileRef != null && viewRef != null) {
final BitmapRegionDecoder decoder = decoderRef.get();
final Object decoderLock = decoderLockRef.get();
final Tile tile = tileRef.get();
final SubsamplingScaleImageView view = viewRef.get();
if (decoder != null && decoderLock != null && tile != null && view != null && !decoder.isRecycled()) {
synchronized (decoderLock) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = tile.sampleSize;
options.inPreferredConfig = Config.RGB_565;
options.inDither = true;
Bitmap bitmap = decoder.decodeRegion(view.fileSRect(tile.sRect), options);
int rotation = view.getRequiredRotation();
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return bitmap;
}
} else if (tile != null) {
tile.loading = false;
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to decode tile", e);
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (viewRef != null && tileRef != null && bitmap != null) {
final SubsamplingScaleImageView subsamplingScaleImageView = viewRef.get();
final Tile tile = tileRef.get();
if (subsamplingScaleImageView != null && tile != null) {
tile.bitmap = bitmap;
tile.loading = false;
subsamplingScaleImageView.onTileLoaded();
}
}
}
}
private static class Tile {
private Rect sRect;
private int sampleSize;
private Bitmap bitmap;
private boolean loading;
private boolean visible;
}
private static class Anim {
private float scaleStart; // Scale at start of anim
private float scaleEnd; // Scale at end of anim (target)
private PointF sCenterStart; // Source center point at start
private PointF sCenterEnd; // Source center point at end, adjusted for pan limits
private PointF sCenterEndRequested; // Source center point that was requested, without adjustment
private PointF vFocusStart; // View point that was double tapped
private PointF vFocusEnd; // Where the view focal point should be moved to during the anim
private long duration = 500; // How long the anim takes
private boolean interruptible = true; // Whether the anim can be interrupted by a touch
private int easing = EASE_IN_OUT_QUAD; // Easing style
private long time = System.currentTimeMillis(); // Start time
}
private static class ScaleAndTranslate {
private float scale;
private PointF translate;
private ScaleAndTranslate(float scale, PointF translate) {
this.scale = scale;
this.translate = translate;
}
}
/** /**
* Builder class used to set additional options for a scale animation. Create an instance using {@link #animateScale(float)}, * Builder class used to set additional options for a scale animation. Create an instance using {@link #animateScale(float)},
* then set your options and call {@link #start()}. * then set your options and call {@link #start()}.
...@@ -1722,6 +1736,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1722,6 +1736,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Desired duration of the anim in milliseconds. Default is 500. * Desired duration of the anim in milliseconds. Default is 500.
*
* @param duration duration in milliseconds. * @param duration duration in milliseconds.
* @return this builder for method chaining. * @return this builder for method chaining.
*/ */
...@@ -1732,6 +1747,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1732,6 +1747,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Whether the animation can be interrupted with a touch. Default is true. * Whether the animation can be interrupted with a touch. Default is true.
*
* @param interruptible interruptible flag. * @param interruptible interruptible flag.
* @return this builder for method chaining. * @return this builder for method chaining.
*/ */
...@@ -1742,6 +1758,7 @@ public class SubsamplingScaleImageView extends View { ...@@ -1742,6 +1758,7 @@ public class SubsamplingScaleImageView extends View {
/** /**
* Set the easing style. See static fields. {@link #EASE_IN_OUT_QUAD} is recommended, and the default. * Set the easing style. See static fields. {@link #EASE_IN_OUT_QUAD} is recommended, and the default.
*
* @param easing easing style. * @param easing easing style.
* @return this builder for method chaining. * @return this builder for method chaining.
*/ */
...@@ -1779,8 +1796,8 @@ public class SubsamplingScaleImageView extends View { ...@@ -1779,8 +1796,8 @@ public class SubsamplingScaleImageView extends View {
anim.sCenterEnd = targetSCenter; anim.sCenterEnd = targetSCenter;
anim.vFocusStart = sourceToViewCoord(targetSCenter); anim.vFocusStart = sourceToViewCoord(targetSCenter);
anim.vFocusEnd = new PointF( anim.vFocusEnd = new PointF(
getWidth()/2, getWidth() / 2,
getHeight()/2 getHeight() / 2
); );
anim.duration = duration; anim.duration = duration;
anim.interruptible = interruptible; anim.interruptible = interruptible;
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient <gradient
android:startColor="#20000000" android:angle="90"
android:endColor="@android:color/transparent" android:endColor="@android:color/transparent"
android:angle="90" > android:startColor="#20000000"></gradient>
</gradient>
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient <gradient
android:startColor="#20000000" android:angle="270"
android:endColor="@android:color/transparent" android:endColor="@android:color/transparent"
android:angle="270" > android:startColor="#20000000"></gradient>
</gradient>
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack --> <!-- Drop Shadow Stack -->
<!-- Background --> <!-- Background -->
<item> <item>
<shape> <shape>
<solid android:color="#e5e5e5" /> <solid android:color="#e5e5e5" />
</shape> </shape>
</item> </item>
</layer-list> </layer-list>
\ No newline at end of file
...@@ -2,18 +2,18 @@ ...@@ -2,18 +2,18 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item> <item>
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="#30555555"/> <solid android:color="#30555555" />
<corners android:radius="2dp" /> <corners android:radius="2dp" />
</shape> </shape>
</item> </item>
<item <item
android:bottom="2dp"
android:left="0dp" android:left="0dp"
android:right="0dp" android:right="0dp"
android:top="0dp" android:top="0dp">
android:bottom="2dp">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="#FFFFFF"/> <solid android:color="#FFFFFF" />
<corners android:radius="2dp" /> <corners android:radius="2dp" />
</shape> </shape>
</item> </item>
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack --> <!-- Drop Shadow Stack -->
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#10999999" /> <solid android:color="#10999999" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#20999999" /> <solid android:color="#20999999" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#10999999" /> <solid android:color="#10999999" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
</shape> </shape>
</item> </item>
<!-- Background --> <!-- Background -->
<item> <item>
<shape> <shape>
<solid android:color="@android:color/transparent" /> <solid android:color="@android:color/transparent" />
</shape> </shape>
</item> </item>
</layer-list> </layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack --> <!-- Drop Shadow Stack -->
<!-- <item> <!-- <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
<corners android:radius="2dp" /> <corners android:radius="2dp" />
</shape> </shape>
</item> </item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#10999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="0dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#30999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item> <item>
<shape> <shape>
<padding android:top="0dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" /> <solid android:color="#10999999" />
<corners android:radius="2dp" /> <corners android:radius="2dp" />
</shape> </shape>
</item>--> </item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="0dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#30999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="0dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" />
<corners android:radius="2dp" />
</shape>
</item>-->
<!-- Background --> <!-- Background -->
<item> <item>
<shape> <shape>
<solid android:color="#F0FFFFFF" /> <solid android:color="#F0FFFFFF" />
<!-- <corners android:radius="2dp" />--> <!-- <corners android:radius="2dp" />-->
</shape> </shape>
</item> </item>
</layer-list> </layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack --> <!-- Drop Shadow Stack -->
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid android:color="#00999999" /> <solid android:color="#00999999" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
</shape> </shape>
...@@ -40,15 +60,15 @@ ...@@ -40,15 +60,15 @@
<!-- Background --> <!-- Background -->
<item> <item>
<shape> <shape>
<gradient <gradient
android:type="linear" android:angle="90"
android:centerX="6%" android:centerColor="#FFf6f6f6"
android:startColor="#FFe4e4e4" android:centerX="6%"
android:centerColor="#FFf6f6f6" android:endColor="#FFffffff"
android:endColor="#FFffffff" android:startColor="#FFe4e4e4"
android:angle="90"/> android:type="linear" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
</shape> </shape>
</item> </item>
</layer-list> </layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <shape xmlns:android="http://schemas.android.com/apk/res/android"
<gradient android:shape="rectangle">
android:type="linear" <gradient
android:centerX="20%" android:angle="270"
android:startColor="#66000000" android:centerColor="#22000000"
android:centerColor="#22000000" android:centerX="20%"
android:endColor="#00f6f6f6" android:endColor="#00f6f6f6"
android:angle="270"/> android:startColor="#66000000"
android:type="linear" />
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <shape xmlns:android="http://schemas.android.com/apk/res/android"
<gradient android:shape="rectangle">
android:type="linear" <gradient
android:centerX="2%" android:angle="90"
android:startColor="#FFe4e4e4" android:centerColor="#FFf6f6f6"
android:centerColor="#FFf6f6f6" android:centerX="2%"
android:endColor="#FFffffff" android:endColor="#FFffffff"
android:angle="90"/> android:startColor="#FFe4e4e4"
android:type="linear" />
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <shape xmlns:android="http://schemas.android.com/apk/res/android"
<gradient android:shape="rectangle">
android:type="linear" <gradient
android:centerX="60%" android:angle="270"
android:startColor="#00000000" android:centerColor="#19000000"
android:centerColor="#19000000" android:centerX="60%"
android:endColor="#FF000000" android:endColor="#FF000000"
android:angle="270"/> android:startColor="#00000000"
android:type="linear" />
</shape> </shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:tint="?attr/colorControlNormal"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal"> android:viewportWidth="24.0">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/> android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:tint="?attr/colorControlNormal"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal"> android:viewportWidth="24.0">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/> android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:tint="?attr/colorControlNormal"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal"> android:viewportWidth="24.0">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/> android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:tint="?attr/colorControlNormal"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal"> android:viewportWidth="24.0">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM13,14h-2v-2h2v2zM13,10h-2L11,6h2v4z"/> android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM13,14h-2v-2h2v2zM13,10h-2L11,6h2v4z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:tint="?attr/colorControlNormal"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal"> android:viewportWidth="24.0">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/> android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:tint="?attr/colorControlNormal"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal"> android:viewportWidth="24.0">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/> android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/> android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
</vector> </vector>
<vector android:height="24dp" android:viewportHeight="792" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="792" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="24dp"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:height="24dp"
android:pathData="m396.004,170.224l0,0a303.09,303.09 90,0 1,-0.007 428.627l0,0 0,0A303.09,303.09 90,0 1,396.004 170.224Z" android:strokeAlpha="0.4"/> android:viewportHeight="792"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:viewportWidth="792">
android:pathData="M726.43,533.13A302.83,302.83 0,0 1,396 598.85,303.38 303.38,0 0,1 726.43,533.13Z" android:strokeAlpha="0.4"/> <path
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:fillAlpha="0.4"
android:pathData="M297.36,532.94A302,302 0,0 1,396 598.85,303.48 303.48,0 0,1 65.57,533.13 304,304 0,0 1,297.36 532.94Z" android:strokeAlpha="0.4"/> android:fillColor="#ffffff"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:pathData="m396.004,170.224l0,0a303.09,303.09 90,0 1,-0.007 428.627l0,0 0,0A303.09,303.09 90,0 1,396.004 170.224Z"
android:pathData="m699.09,295.76l-0,0a303.09,303.09 0,0 1,-303.09 303.09l-0,0 -0,0A303.09,303.09 0,0 1,699.09 295.76Z" android:strokeAlpha="0.4"/> android:strokeAlpha="0.4" />
<path android:fillAlpha="0.4" android:fillColor="#ffffff" <path
android:pathData="M512.38,622A302.31,302.31 0,0 1,396 598.85,302.22 302.22,0 0,1 512.38,622Z" android:strokeAlpha="0.4"/> android:fillAlpha="0.4"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:fillColor="#ffffff"
android:pathData="M279.62,622A302.22,302.22 0,0 1,396 598.85,302.31 302.31,0 0,1 279.62,622Z" android:strokeAlpha="0.4"/> android:pathData="M726.43,533.13A302.83,302.83 0,0 1,396 598.85,303.38 303.38,0 0,1 726.43,533.13Z"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:strokeAlpha="0.4" />
android:pathData="m92.91,295.76v0A303.09,303.09 0,0 1,396 598.85v0,0A303.09,303.09 0,0 1,92.91 295.76Z" android:strokeAlpha="0.4"/> <path
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:fillAlpha="0.4"
android:pathData="m231.969,202.853l0,0a303.09,303.09 67.5,0 1,164.035 395.997l0,0 0,0A303.09,303.09 67.5,0 1,231.969 202.853Z" android:strokeAlpha="0.4"/> android:fillColor="#ffffff"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:pathData="M297.36,532.94A302,302 0,0 1,396 598.85,303.48 303.48,0 0,1 65.57,533.13 304,304 0,0 1,297.36 532.94Z"
android:pathData="m792,434.82a302.83,302.83 0,0 1,-396 164,302.83 302.83,0 0,1 396,-164z" android:strokeAlpha="0.4"/> android:strokeAlpha="0.4" />
<path android:fillAlpha="0.4" android:fillColor="#ffffff" <path
android:pathData="m279.62,575.7a301.94,301.94 0,0 1,116.38 23.15,302.06 302.06,0 0,1 -232,0 303.77,303.77 0,0 1,115.62 -23.15z" android:strokeAlpha="0.4"/> android:fillAlpha="0.4"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:fillColor="#ffffff"
android:pathData="m560.025,202.845l0,0a303.09,303.09 112.5,0 1,-164.022 396.002l0,0 0,0A303.09,303.09 112.5,0 1,560.025 202.845Z" android:strokeAlpha="0.4"/> android:pathData="m699.09,295.76l-0,0a303.09,303.09 0,0 1,-303.09 303.09l-0,0 -0,0A303.09,303.09 0,0 1,699.09 295.76Z"
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:strokeAlpha="0.4" />
android:pathData="m628,598.84a302.06,302.06 0,0 1,-232 0,302.18 302.18,0 0,1 232,0z" android:strokeAlpha="0.4"/> <path
<path android:fillAlpha="0.4" android:fillColor="#ffffff" android:fillAlpha="0.4"
android:pathData="M396,598.85A302.83,302.83 0,0 1,0 434.82a302.83,302.83 0,0 1,396 164z" android:strokeAlpha="0.4"/> android:fillColor="#ffffff"
android:pathData="M512.38,622A302.31,302.31 0,0 1,396 598.85,302.22 302.22,0 0,1 512.38,622Z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="M279.62,622A302.22,302.22 0,0 1,396 598.85,302.31 302.31,0 0,1 279.62,622Z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="m92.91,295.76v0A303.09,303.09 0,0 1,396 598.85v0,0A303.09,303.09 0,0 1,92.91 295.76Z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="m231.969,202.853l0,0a303.09,303.09 67.5,0 1,164.035 395.997l0,0 0,0A303.09,303.09 67.5,0 1,231.969 202.853Z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="m792,434.82a302.83,302.83 0,0 1,-396 164,302.83 302.83,0 0,1 396,-164z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="m279.62,575.7a301.94,301.94 0,0 1,116.38 23.15,302.06 302.06,0 0,1 -232,0 303.77,303.77 0,0 1,115.62 -23.15z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="m560.025,202.845l0,0a303.09,303.09 112.5,0 1,-164.022 396.002l0,0 0,0A303.09,303.09 112.5,0 1,560.025 202.845Z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="m628,598.84a302.06,302.06 0,0 1,-232 0,302.18 302.18,0 0,1 232,0z"
android:strokeAlpha="0.4" />
<path
android:fillAlpha="0.4"
android:fillColor="#ffffff"
android:pathData="M396,598.85A302.83,302.83 0,0 1,0 434.82a302.83,302.83 0,0 1,396 164z"
android:strokeAlpha="0.4" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:fillColor="#FFFFFFFF" android:fillColor="#FFFFFFFF"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/> android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/> android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
</vector> </vector>
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentTop="false" android:layout_alignParentTop="false"
android:layout_alignWithParentIfMissing="false"> android:layout_alignWithParentIfMissing="false"></WebView>
</WebView>
</LinearLayout> </LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:orientation="vertical">
<ProgressBar <ProgressBar
android:id="@+id/blog_load_item"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true"
android:id="@+id/blog_load_item"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_margin="@dimen/activity_vertical_margin"/> android:layout_margin="@dimen/activity_vertical_margin"
android:indeterminate="true" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:background="?android:attr/selectableItemBackground"
android:background="?android:attr/selectableItemBackground"> android:orientation="vertical">
<ImageView <ImageView
android:id="@+id/big_object_picture" android:id="@+id/big_object_picture"
...@@ -60,11 +60,11 @@ ...@@ -60,11 +60,11 @@
android:id="@+id/object_subtitle" android:id="@+id/object_subtitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Subtitle"
android:textSize="16sp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1"
android:scrollHorizontally="true" android:scrollHorizontally="true"
android:maxLines="1" /> android:text="Subtitle"
android:textSize="16sp" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
......
...@@ -278,20 +278,20 @@ ...@@ -278,20 +278,20 @@
android:id="@+id/mrunmayi" android:id="@+id/mrunmayi"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:gravity="center" android:gravity="center"
android:text="Mrunmayi Mungekar" android:text="Mrunmayi Mungekar"
android:textSize="13sp" android:textSize="13sp"
android:layout_marginEnd="15dp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/owais" android:id="@+id/owais"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="25dp"
android:gravity="center" android:gravity="center"
android:text="Owais Chunawala" android:text="Owais Chunawala"
android:textSize="13sp" android:textSize="13sp"
android:layout_marginEnd="25dp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
...@@ -306,7 +306,6 @@ ...@@ -306,7 +306,6 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
...@@ -349,18 +348,18 @@ ...@@ -349,18 +348,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="20dp" android:layout_marginEnd="20dp"
android:gravity="center" android:gravity="center"
android:textSize="13sp"
android:text="Yash Khemchandani" android:text="Yash Khemchandani"
android:textSize="13sp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/bavish" android:id="@+id/bavish"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center"
android:textSize="13sp"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:gravity="center"
android:text="Bavish Kulur" android:text="Bavish Kulur"
android:textSize="13sp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
...@@ -369,14 +368,13 @@ ...@@ -369,14 +368,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="40dp" android:layout_marginStart="40dp"
android:gravity="center" android:gravity="center"
android:textSize="13sp"
android:text="Mayuresh Bhattu" android:text="Mayuresh Bhattu"
android:textSize="13sp"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<de.hdodenhof.circleimageview.CircleImageView <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/maitreyaimg" android:id="@+id/maitreyaimg"
android:layout_width="75dp" android:layout_width="75dp"
...@@ -455,10 +453,10 @@ ...@@ -455,10 +453,10 @@
android:id="@+id/bijoy" android:id="@+id/bijoy"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:gravity="center" android:gravity="center"
android:textSize="13sp"
android:text="Bijoy Singh Kochar" android:text="Bijoy Singh Kochar"
android:layout_marginStart="30dp" android:textSize="13sp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
...@@ -467,8 +465,8 @@ ...@@ -467,8 +465,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="25dp" android:layout_marginStart="25dp"
android:gravity="center" android:gravity="center"
android:textSize="13sp"
android:text="Dheerendra Rathor" android:text="Dheerendra Rathor"
android:textSize="13sp"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
...@@ -550,9 +548,9 @@ ...@@ -550,9 +548,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:textStyle="bold"
android:gravity="center" android:gravity="center"
android:text="tty0" /> android:text="tty0"
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/join_us" android:id="@+id/join_us"
...@@ -570,42 +568,42 @@ ...@@ -570,42 +568,42 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginTop="10dp"
android:autoLink="web" android:autoLink="web"
android:linksClickable="true"
android:gravity="center" android:gravity="center"
android:linksClickable="true"
android:text="@string/django_api" android:text="@string/django_api"
android:textStyle="bold" android:textColorLink="@color/colorPrimaryDark"
android:textColorLink="@color/colorPrimaryDark"/> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/android" android:id="@+id/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginTop="5dp"
android:autoLink="web" android:autoLink="web"
android:linksClickable="true"
android:gravity="center" android:gravity="center"
android:linksClickable="true"
android:text="@string/android_app" android:text="@string/android_app"
android:textStyle="bold" android:textColorLink="@color/colorPrimaryDark"
android:textColorLink="@color/colorPrimaryDark"/> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/angular" android:id="@+id/angular"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="36dp" android:layout_marginBottom="36dp"
android:layout_marginTop="5dp"
android:autoLink="web" android:autoLink="web"
android:linksClickable="true"
android:gravity="center" android:gravity="center"
android:linksClickable="true"
android:text="@string/angular_pwa" android:text="@string/angular_pwa"
android:textStyle="bold" android:textColorLink="@color/colorPrimaryDark"
android:textColorLink="@color/colorPrimaryDark"/> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
......
...@@ -104,15 +104,15 @@ ...@@ -104,15 +104,15 @@
<Button <Button
android:id="@+id/follow_button" android:id="@+id/follow_button"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:textAllCaps="false"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="0dp" android:layout_margin="0dp"
android:layout_weight="1" android:layout_weight="1"
android:text="FOLLOW" android:clickable="true"
android:textColor="@color/secondaryTextColor"
android:foreground="?attr/selectableItemBackground" android:foreground="?attr/selectableItemBackground"
android:clickable="true" /> android:text="FOLLOW"
android:textAllCaps="false"
android:textColor="@color/secondaryTextColor" />
</LinearLayout> </LinearLayout>
<View <View
...@@ -219,7 +219,7 @@ ...@@ -219,7 +219,7 @@
android:layout_margin="16dp" android:layout_margin="16dp"
android:src="@drawable/ic_edit_black_24dp" android:src="@drawable/ic_edit_black_24dp"
android:tint="@android:color/black" android:tint="@android:color/black"
android:visibility="gone"/> android:visibility="gone" />
</RelativeLayout> </RelativeLayout>
...@@ -233,7 +233,7 @@ ...@@ -233,7 +233,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
<app.insti.TouchImageView <app.insti.TouchImageView
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -157,15 +157,15 @@ ...@@ -157,15 +157,15 @@
<Button <Button
android:id="@+id/going_button" android:id="@+id/going_button"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:textAllCaps="false"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="0dp" android:layout_margin="0dp"
android:layout_weight="1" android:layout_weight="1"
android:text="GOING" android:clickable="true"
android:textColor="@color/secondaryTextColor"
android:foreground="?attr/selectableItemBackground" android:foreground="?attr/selectableItemBackground"
android:clickable="true" /> android:text="GOING"
android:textAllCaps="false"
android:textColor="@color/secondaryTextColor" />
<View <View
android:layout_width="1dp" android:layout_width="1dp"
...@@ -177,15 +177,15 @@ ...@@ -177,15 +177,15 @@
<Button <Button
android:id="@+id/interested_button" android:id="@+id/interested_button"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:textAllCaps="false"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="0dp" android:layout_margin="0dp"
android:layout_weight="1" android:layout_weight="1"
android:text="INTERESTED" android:clickable="true"
android:textColor="@color/secondaryTextColor"
android:foreground="?attr/selectableItemBackground" android:foreground="?attr/selectableItemBackground"
android:clickable="true" /> android:text="INTERESTED"
android:textAllCaps="false"
android:textColor="@color/secondaryTextColor" />
</LinearLayout> </LinearLayout>
......
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
<EditText <EditText
android:id="@+id/explore_search" android:id="@+id/explore_search"
android:background="@color/colorPrimary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:hint="Search"
android:paddingBottom="15dp"
android:paddingLeft="18dp" android:paddingLeft="18dp"
android:paddingRight="6dp" android:paddingRight="6dp"
android:paddingTop="3dp" android:paddingTop="3dp"
android:paddingBottom="15dp"
android:hint="Search"
android:textColor="@color/primaryTextColor" android:textColor="@color/primaryTextColor"
android:textColorHint="@color/primaryTextColor"/> android:textColorHint="@color/primaryTextColor" />
<android.support.v4.widget.NestedScrollView <android.support.v4.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</FrameLayout> </FrameLayout>
\ No newline at end of file
...@@ -38,6 +38,6 @@ ...@@ -38,6 +38,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -6,22 +6,22 @@ ...@@ -6,22 +6,22 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"> android:focusableInTouchMode="true"
android:orientation="vertical">
<EditText <EditText
android:id="@+id/search" android:id="@+id/search"
android:background="@color/colorPrimary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:hint="Search"
android:paddingBottom="15dp"
android:paddingLeft="18dp" android:paddingLeft="18dp"
android:paddingRight="6dp" android:paddingRight="6dp"
android:paddingTop="3dp" android:paddingTop="3dp"
android:paddingBottom="15dp"
android:hint="Search"
android:textColor="@color/primaryTextColor" android:textColor="@color/primaryTextColor"
android:textColorHint="@color/primaryTextColor"/> android:textColorHint="@color/primaryTextColor" />
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/darker_gray" android:background="@android:color/darker_gray"
tools:context="com.mrane.campusmap.MainActivity"
tools:ignore="MergeRootFrame"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"> android:focusableInTouchMode="true"
tools:context="com.mrane.campusmap.MainActivity"
tools:ignore="MergeRootFrame">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"></LinearLayout> android:focusableInTouchMode="true"></LinearLayout>
<com.mrane.navigation.SlidingUpPanelLayout xmlns:sothree="http://schemas.android.com/apk/res-auto" <com.mrane.navigation.SlidingUpPanelLayout
android:id="@+id/sliding_layout" android:id="@+id/sliding_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
...@@ -76,16 +76,16 @@ ...@@ -76,16 +76,16 @@
</LinearLayout> </LinearLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/loadingPanel"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center" android:gravity="center">
android:id="@+id/loadingPanel">
<ProgressBar <ProgressBar
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
android:paddingLeft="16dp"
android:backgroundTint="@color/colorWhite" android:backgroundTint="@color/colorWhite"
android:paddingLeft="16dp"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
</FrameLayout> </FrameLayout>
...@@ -47,6 +47,6 @@ ...@@ -47,6 +47,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -39,6 +39,6 @@ ...@@ -39,6 +39,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</FrameLayout> </FrameLayout>
...@@ -27,6 +27,6 @@ ...@@ -27,6 +27,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="2dp" android:layout_marginBottom="2dp"
android:textSize="20sp"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:textColor="@color/secondaryTextColor"/> android:textColor="@color/secondaryTextColor"
android:textSize="20sp" />
<TextView <TextView
android:id="@+id/user_rollno_profile" android:id="@+id/user_rollno_profile"
...@@ -105,13 +105,13 @@ ...@@ -105,13 +105,13 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
<app.insti.TouchImageView <app.insti.TouchImageView
android:id="@+id/expanded_image_profile" android:id="@+id/expanded_image_profile"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="gone" android:contentDescription="Zoomed Image"
android:contentDescription="Zoomed Image" /> android:visibility="gone" />
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -48,10 +48,10 @@ ...@@ -48,10 +48,10 @@
style="@style/Widget.AppCompat.Button.Borderless" style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp"
android:drawablePadding="16dp" android:drawablePadding="16dp"
android:drawableStart="@drawable/baseline_account_circle_black_36" android:drawableStart="@drawable/baseline_account_circle_black_36"
android:gravity="center_vertical" android:gravity="center_vertical"
android:padding="16dp"
android:text="Update Profile" android:text="Update Profile"
android:textAllCaps="false" android:textAllCaps="false"
android:textSize="20sp" /> android:textSize="20sp" />
...@@ -61,10 +61,10 @@ ...@@ -61,10 +61,10 @@
style="@style/Widget.AppCompat.Button.Borderless" style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp"
android:drawablePadding="16dp" android:drawablePadding="16dp"
android:drawableStart="@drawable/baseline_feedback_black_36" android:drawableStart="@drawable/baseline_feedback_black_36"
android:gravity="center_vertical" android:gravity="center_vertical"
android:padding="16dp"
android:text="Feedback" android:text="Feedback"
android:textAllCaps="false" android:textAllCaps="false"
android:textSize="20sp" /> android:textSize="20sp" />
...@@ -74,10 +74,10 @@ ...@@ -74,10 +74,10 @@
style="@style/Widget.AppCompat.Button.Borderless" style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp"
android:drawablePadding="16dp" android:drawablePadding="16dp"
android:drawableStart="@drawable/baseline_info_black_36" android:drawableStart="@drawable/baseline_info_black_36"
android:gravity="center_vertical" android:gravity="center_vertical"
android:padding="16dp"
android:text="About" android:text="About"
android:textAllCaps="false" android:textAllCaps="false"
android:textSize="20sp" /> android:textSize="20sp" />
...@@ -87,10 +87,10 @@ ...@@ -87,10 +87,10 @@
style="@style/Widget.AppCompat.Button.Borderless" style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp"
android:drawablePadding="16dp" android:drawablePadding="16dp"
android:drawableStart="@drawable/baseline_exit_to_app_black_36" android:drawableStart="@drawable/baseline_exit_to_app_black_36"
android:gravity="center_vertical" android:gravity="center_vertical"
android:padding="16dp"
android:text="Logout" android:text="Logout"
android:textAllCaps="false" android:textAllCaps="false"
android:textSize="20sp" /> android:textSize="20sp" />
......
...@@ -27,6 +27,6 @@ ...@@ -27,6 +27,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:theme="@style/BlueAccent"/> android:theme="@style/BlueAccent" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/place_image" android:id="@+id/place_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:adjustViewBounds="true" /> android:adjustViewBounds="true" />
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/small_card_bg" android:background="@drawable/small_card_bg"
android:orientation="horizontal" > android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/place_color" android:id="@+id/place_color"
...@@ -24,16 +24,16 @@ ...@@ -24,16 +24,16 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="@dimen/hidden_card_height" android:minHeight="@dimen/hidden_card_height"
android:paddingBottom="8dp" > android:paddingBottom="8dp">
<ImageButton <ImageButton
android:id="@+id/add_marker_icon" android:id="@+id/add_marker_icon"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginRight="0dp" android:layout_marginRight="0dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_alignParentRight="true"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:contentDescription="Search" android:contentDescription="Search"
android:cropToPadding="true" android:cropToPadding="true"
...@@ -54,8 +54,7 @@ ...@@ -54,8 +54,7 @@
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:textSize="@dimen/place_name_text_size" > android:textSize="@dimen/place_name_text_size"></TextView>
</TextView>
<TextView <TextView
android:id="@+id/place_sub_head" android:id="@+id/place_sub_head"
...@@ -77,25 +76,24 @@ ...@@ -77,25 +76,24 @@
android:id="@+id/new_expand_container" android:id="@+id/new_expand_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:background="@color/list_item_gray_even" > android:background="@color/list_item_gray_even">
<com.mrane.navigation.EndDetectScrollView <com.mrane.navigation.EndDetectScrollView
android:id="@+id/new_expanded_place_card_scroll" android:id="@+id/new_expanded_place_card_scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_alignParentTop="true" > android:layout_alignParentTop="true">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" > android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:id="@+id/expanded_place_card" android:id="@+id/expanded_place_card"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#e5e5e5" android:background="#e5e5e5"
android:orientation="horizontal" > android:orientation="horizontal"></LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/other_details" android:id="@+id/other_details"
...@@ -103,8 +101,7 @@ ...@@ -103,8 +101,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:orientation="vertical" > android:orientation="vertical"></LinearLayout>
</LinearLayout>
</RelativeLayout> </RelativeLayout>
</com.mrane.navigation.EndDetectScrollView> </com.mrane.navigation.EndDetectScrollView>
...@@ -113,7 +110,7 @@ ...@@ -113,7 +110,7 @@
android:layout_width="12dp" android:layout_width="12dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" > android:layout_alignParentTop="true">
<View <View
android:id="@+id/place_group_color" android:id="@+id/place_group_color"
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
android:id="@+id/child_name" android:id="@+id/child_name"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp" android:fontFamily="sans-serif-light"
android:minHeight="56dp" android:minHeight="56dp"
android:textSize="18dp" android:padding="8dp"
android:fontFamily="sans-serif-light" /> android:textSize="18dp" />
...@@ -2,36 +2,40 @@ ...@@ -2,36 +2,40 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#e0e0e0" > android:background="#e0e0e0">
<LinearLayout
<LinearLayout
android:id="@+id/header_layout" android:id="@+id/header_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView
<ImageView
android:id="@+id/arrow_icon" android:id="@+id/arrow_icon"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:paddingTop="16dp" android:cropToPadding="true"
android:paddingBottom="16dp" android:paddingBottom="16dp"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:cropToPadding="true" android:paddingTop="16dp"
android:scaleType="centerInside" /> android:scaleType="centerInside" />
<TextView
<TextView
android:id="@+id/list_header" android:id="@+id/list_header"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical" android:layout_gravity="left|center_vertical"
android:paddingLeft="8dp" /> android:paddingLeft="8dp" />
</LinearLayout> </LinearLayout>
<ListView
android:id="@+id/child_list" <ListView
android:layout_width="match_parent" android:id="@+id/child_list"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_below="@id/header_layout" android:layout_height="wrap_content"
android:paddingLeft="48dp" android:layout_below="@id/header_layout"
android:background="#e5e5e5"></ListView> android:background="#e5e5e5"
android:paddingLeft="48dp"></ListView>
</RelativeLayout> </RelativeLayout>
...@@ -2,28 +2,31 @@ ...@@ -2,28 +2,31 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
android:orientation="vertical" android:background="#F5F5F5"
android:background="#F5F5F5" > android:orientation="vertical">
<ImageView
<ImageView
android:id="@+id/group_color" android:id="@+id/group_color"
android:layout_width="12dp" android:layout_width="12dp"
android:layout_height="56dp" android:layout_height="56dp"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:paddingLeft="0dp"
android:layout_marginLeft="0dp" android:layout_marginLeft="0dp"
android:cropToPadding="true"/> android:cropToPadding="true"
android:paddingLeft="0dp" />
<ImageView <ImageView
android:id="@+id/icon_expand" android:id="@+id/icon_expand"
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="56dp" android:layout_height="56dp"
android:layout_toRightOf="@id/group_color" android:layout_toRightOf="@id/group_color"
android:contentDescription="list item"
android:cropToPadding="true" android:cropToPadding="true"
android:paddingTop="16dp"
android:paddingBottom="16dp" android:paddingBottom="16dp"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:contentDescription="list item" android:paddingTop="16dp"
android:visibility="visible" /> android:visibility="visible" />
<TextView <TextView
android:id="@+id/lblListHeader" android:id="@+id/lblListHeader"
android:layout_width="fill_parent" android:layout_width="fill_parent"
...@@ -32,13 +35,15 @@ ...@@ -32,13 +35,15 @@
android:layout_toRightOf="@id/icon_expand" android:layout_toRightOf="@id/icon_expand"
android:padding="8dp" android:padding="8dp"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" /> android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" />
<View
android:layout_width="match_parent" <View
android:layout_height="1dp" android:layout_width="match_parent"
android:layout_alignParentBottom="true" /> android:layout_height="1dp"
<View android:layout_alignParentBottom="true" />
android:layout_width="match_parent"
android:layout_height="1dp" <View
android:layout_alignParentTop="true" /> android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentTop="true" />
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" > android:orientation="vertical">
<ExpandableListView <ExpandableListView
android:id="@+id/index_list" android:id="@+id/index_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:background="@android:color/transparent"
android:divider="@null" android:divider="@null"
android:groupIndicator="@null"
android:paddingLeft="0dp" android:paddingLeft="0dp"
android:paddingRight="0dp" android:paddingRight="0dp"
android:groupIndicator="@null"
android:background="@android:color/transparent"
android:transcriptMode="disabled" /> android:transcriptMode="disabled" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -8,9 +8,8 @@ ...@@ -8,9 +8,8 @@
android:id="@+id/suggestion_list" android:id="@+id/suggestion_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:background="@drawable/listview_background"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp" android:paddingRight="16dp"></ListView>
android:background="@drawable/listview_background" >
</ListView>
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -2,58 +2,65 @@ ...@@ -2,58 +2,65 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#F0E5E5E5"
android:minHeight="48dp" android:minHeight="48dp"
android:orientation="horizontal" android:orientation="horizontal">
android:background="#F0E5E5E5">
<RelativeLayout <RelativeLayout
android:layout_width="12dp" android:layout_width="12dp"
android:layout_height="fill_parent"> android:layout_height="fill_parent">
<View
android:id="@+id/item_group_color" <View
android:layout_width="12dp" android:id="@+id/item_group_color"
android:layout_height="fill_parent" android:layout_width="12dp"
android:layout_alignParentTop="true" android:layout_height="fill_parent"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:paddingLeft="0dp" android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"/> android:layout_marginLeft="0dp"
<View android:paddingLeft="0dp" />
android:layout_width="12dp"
android:layout_height="fill_parent" <View
android:layout_alignParentTop="true" android:layout_width="12dp"
android:layout_alignParentBottom="true" android:layout_height="fill_parent"
android:layout_alignParentLeft="true" android:layout_alignParentBottom="true"
android:paddingLeft="0dp" android:layout_alignParentLeft="true"
android:layout_marginLeft="0dp" /> android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
</RelativeLayout> android:paddingLeft="0dp" />
<RelativeLayout
android:layout_width="fill_parent" </RelativeLayout>
android:layout_height="wrap_content"
android:minHeight="48dp" <RelativeLayout
android:paddingRight="8dp"> android:layout_width="fill_parent"
<View android:layout_height="wrap_content"
android:layout_width="fill_parent" android:minHeight="48dp"
android:layout_height="1dp" android:paddingRight="8dp">
android:padding="8dp"
android:layout_marginLeft="40dp" <View
android:layout_alignParentBottom="true" android:layout_width="fill_parent"
android:layout_alignParentLeft="true" /> android:layout_height="1dp"
<View android:layout_alignParentBottom="true"
android:layout_width="fill_parent" android:layout_alignParentLeft="true"
android:layout_height="1dp" android:layout_marginLeft="40dp"
android:padding="8dp" android:padding="8dp" />
android:layout_marginLeft="40dp"
android:layout_alignParentTop="true" <View
android:layout_alignParentLeft="true" /> android:layout_width="fill_parent"
<TextView android:layout_height="1dp"
android:id="@+id/lblListItem" android:layout_alignParentLeft="true"
android:layout_width="fill_parent" android:layout_alignParentTop="true"
android:layout_height="wrap_content" android:layout_marginLeft="40dp"
android:layout_centerVertical="true" android:padding="8dp" />
android:layout_alignParentLeft="true"
android:padding="8dp" <TextView
android:fontFamily="sans-serif-light" android:id="@+id/lblListItem"
android:layout_marginLeft="48dp" /> android:layout_width="fill_parent"
</RelativeLayout> android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="48dp"
android:fontFamily="sans-serif-light"
android:padding="8dp" />
</RelativeLayout>
</LinearLayout> </LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="12dp" > android:paddingLeft="12dp">
<TextView
android:id="@+id/desc_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:paddingBottom="0dp"
android:textSize="20sp"
android:text="Description"/>
<TextView
android:id="@+id/desc_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/desc_header"
android:lineSpacingExtra="3dp"
android:padding="8dp"
android:textSize="18sp"
android:paddingTop="0dp"
android:textIsSelectable="true"/>
<View
android:layout_below="@id/desc_content"
android:layout_width="match_parent"
android:layout_height="96dp"/>
<View <TextView
android:layout_width="fill_parent" android:id="@+id/desc_header"
android:layout_height="0dp" android:layout_width="match_parent"
android:layout_alignParentBottom="true" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:padding="8dp"
android:background="@color/colorSecondary"/> android:paddingBottom="0dp"
<View android:text="Description"
android:layout_width="fill_parent" android:textSize="20sp" />
android:layout_height="0dp"
android:layout_alignParentTop="true" <TextView
android:layout_alignParentLeft="true" android:id="@+id/desc_content"
android:background="@color/colorSecondary"/> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/desc_header"
android:lineSpacingExtra="3dp"
android:padding="8dp"
android:paddingTop="0dp"
android:textIsSelectable="true"
android:textSize="18sp" />
<View
android:layout_width="match_parent"
android:layout_height="96dp"
android:layout_below="@id/desc_content" />
<View
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="@color/colorSecondary" />
<View
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@color/colorSecondary" />
</RelativeLayout> </RelativeLayout>
...@@ -3,14 +3,13 @@ ...@@ -3,14 +3,13 @@
android:id="@+id/row_container" android:id="@+id/row_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" > android:orientation="vertical">
<TextView <TextView
android:id="@+id/label" android:id="@+id/label"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp" android:fontFamily="sans-serif-light"
android:fontFamily="sans-serif-light" > android:padding="8dp"></TextView>
</TextView>
</LinearLayout> </LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<!--
Copyright 2014 David Morrissey Copyright 2014 David Morrissey
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
<string name="gps_network_not_enabled">Location is not enabled. Please turn on your location from the settings.</string> <string name="gps_network_not_enabled">Location is not enabled. Please turn on your location from the settings.</string>
<string name="open_location_settings">Open Location Settings</string> <string name="open_location_settings">Open Location Settings</string>
<string name="django_api"> <a href="https://github.com/wncc/IITBapp"> Django API</a></string> <string name="django_api"> <a href="https://github.com/wncc/IITBapp"> Django API</a></string>
<string name="android_app"> <a href= "https://github.com/wncc/InstiApp"> Android App</a></string> <string name="android_app"> <a href="https://github.com/wncc/InstiApp"> Android App</a></string>
<string name="angular_pwa"> <a href= "https://github.com/pulsejet/iitb-app-angular"> Angular PWA </a></string> <string name="angular_pwa"> <a href="https://github.com/pulsejet/iitb-app-angular"> Angular PWA </a></string>
<string-array name="hostels_array"> <string-array name="hostels_array">
<item>Hostel 1</item> <item>Hostel 1</item>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment