97
     * tap.
98
     *
99
     * @param listener - Listener to be registered.
100
     */
101
    void setOnViewTapListener(PhotoViewAttacher.OnViewTapListener listener);
102
103
    /**
104
     * Controls how the image should be resized or moved to match the size of
105
     * the ImageView. Any scaling or panning will happen within the confines of
106
     * this {@link ImageView.ScaleType}.
107
     *
108
     * @param scaleType - The desired scaling mode.
109
     */
110
    void setScaleType(ImageView.ScaleType scaleType);
111
112
    /**
113
     * Allows you to enable/disable the zoom functionality on the ImageView.
114
     * When disable the ImageView reverts to using the FIT_CENTER matrix.
115
     *
116
     * @param zoomable - Whether the zoom functionality is enabled.
117
     */
118
    void setZoomable(boolean zoomable);
119
120
    /**
121
     * Zooms to the specified scale, around the focal point given.
122
     *
123
     * @param scale  - Scale to zoom to
124
     * @param focalX - X Focus Point
125
     * @param focalY - Y Focus Point
126
     */
127
    void zoomTo(float scale, float focalX, float focalY);
128
}

+ 0 - 165
app/src/main/java/com/electric/chargingpile/zoom/PhotoView.java

@ -1,165 +0,0 @@
1
package com.electric.chargingpile.zoom;
2
3
4
import android.content.Context;
5
import android.graphics.RectF;
6
import android.graphics.drawable.Drawable;
7
import android.net.Uri;
8
import android.util.AttributeSet;
9
import android.widget.ImageView;
10
11
import com.electric.chargingpile.zoom.PhotoViewAttacher.OnMatrixChangedListener;
12
import com.electric.chargingpile.zoom.PhotoViewAttacher.OnPhotoTapListener;
13
import com.electric.chargingpile.zoom.PhotoViewAttacher.OnViewTapListener;
14
15
public class PhotoView extends ImageView implements IPhotoView {
16
17
	private final PhotoViewAttacher mAttacher;
18
19
	private ScaleType mPendingScaleType;
20
21
	public PhotoView(Context context) {
22
		this(context, null);
23
	}
24
25
	public PhotoView(Context context, AttributeSet attr) {
26
		this(context, attr, 0);
27
	}
28
	
29
	public PhotoView(Context context, AttributeSet attr, int defStyle) {
30
		super(context, attr, defStyle);
31
		super.setScaleType(ScaleType.MATRIX);
32
		mAttacher = new PhotoViewAttacher(this);
33
34
		if (null != mPendingScaleType) {
35
			setScaleType(mPendingScaleType);
36
			mPendingScaleType = null;
37
		}
38
	}
39
40
	@Override
41
	public boolean canZoom() {
42
		return mAttacher.canZoom();
43
	}
44
45
	@Override
46
	public RectF getDisplayRect() {
47
		return mAttacher.getDisplayRect();
48
	}
49
50
	@Override
51
	public float getMinScale() {
52
		return mAttacher.getMinScale();
53
	}
54
55
	@Override
56
	public float getMidScale() {
57
		return mAttacher.getMidScale();
58
	}
59
60
	@Override
61
	public float getMaxScale() {
62
		return mAttacher.getMaxScale();
63
	}
64
65
	@Override
66
	public float getScale() {
67
		return mAttacher.getScale();
68
	}
69
70
	@Override
71
	public ScaleType getScaleType() {
72
		return mAttacher.getScaleType();
73
	}
74
75
    @Override
76
    public void setAllowParentInterceptOnEdge(boolean allow) {
77
        mAttacher.setAllowParentInterceptOnEdge(allow);
78
    }
79
80
    @Override
81
	public void setMinScale(float minScale) {
82
		mAttacher.setMinScale(minScale);
83
	}
84
85
	@Override
86
	public void setMidScale(float midScale) {
87
		mAttacher.setMidScale(midScale);
88
	}
89
90
	@Override
91
	public void setMaxScale(float maxScale) {
92
		mAttacher.setMaxScale(maxScale);
93
	}
94
95
	@Override
96
	// setImageBitmap calls through to this method
97
	public void setImageDrawable(Drawable drawable) {
98
		super.setImageDrawable(drawable);
99
		if (null != mAttacher) {
100
			mAttacher.update();
101
		}
102
	}
103
104
	@Override
105
	public void setImageResource(int resId) {
106
		super.setImageResource(resId);
107
		if (null != mAttacher) {
108
			mAttacher.update();
109
		}
110
	}
111
112
	@Override
113
	public void setImageURI(Uri uri) {
114
		super.setImageURI(uri);
115
		if (null != mAttacher) {
116
			mAttacher.update();
117
		}
118
	}
119
120
	@Override
121
	public void setOnMatrixChangeListener(OnMatrixChangedListener listener) {
122
		mAttacher.setOnMatrixChangeListener(listener);
123
	}
124
125
	@Override
126
	public void setOnLongClickListener(OnLongClickListener l) {
127
		mAttacher.setOnLongClickListener(l);
128
	}
129
130
	@Override
131
	public void setOnPhotoTapListener(OnPhotoTapListener listener) {
132
		mAttacher.setOnPhotoTapListener(listener);
133
	}
134
135
	@Override
136
	public void setOnViewTapListener(OnViewTapListener listener) {
137
		mAttacher.setOnViewTapListener(listener);
138
	}
139
140
	@Override
141
	public void setScaleType(ScaleType scaleType) {
142
		if (null != mAttacher) {
143
			mAttacher.setScaleType(scaleType);
144
		} else {
145
			mPendingScaleType = scaleType;
146
		}
147
	}
148
149
	@Override
150
	public void setZoomable(boolean zoomable) {
151
		mAttacher.setZoomable(zoomable);
152
	}
153
154
	@Override
155
	public void zoomTo(float scale, float focalX, float focalY) {
156
		mAttacher.zoomTo(scale, focalX, focalY);
157
	}
158
159
	@Override
160
	protected void onDetachedFromWindow() {
161
		mAttacher.cleanup();
162
		super.onDetachedFromWindow();
163
	}
164
165
}

+ 0 - 990
app/src/main/java/com/electric/chargingpile/zoom/PhotoViewAttacher.java

@ -1,990 +0,0 @@
1
package com.electric.chargingpile.zoom;
2
3
import android.annotation.SuppressLint;
4
import android.content.Context;
5
import android.graphics.Matrix;
6
import android.graphics.Matrix.ScaleToFit;
7
import android.graphics.RectF;
8
import android.graphics.drawable.Drawable;
9
import android.os.Build.VERSION;
10
import android.os.Build.VERSION_CODES;
11
import android.util.Log;
12
import android.view.GestureDetector;
13
import android.view.MotionEvent;
14
import android.view.View;
15
import android.view.View.OnLongClickListener;
16
import android.view.ViewTreeObserver;
17
import android.widget.ImageView;
18
import android.widget.ImageView.ScaleType;
19
import java.lang.ref.WeakReference;
20
21
public class PhotoViewAttacher implements IPhotoView, View.OnTouchListener,
22
		VersionedGestureDetector.OnGestureListener,
23
		GestureDetector.OnDoubleTapListener,
24
		ViewTreeObserver.OnGlobalLayoutListener {
25
26
	static final String LOG_TAG = "PhotoViewAttacher";
27
28
	// let debug flag be dynamic, but still Proguard can be used to remove from
29
	// release builds
30
	static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
31
32
	static final int EDGE_NONE = -1;
33
	static final int EDGE_LEFT = 0;
34
	static final int EDGE_RIGHT = 1;
35
	static final int EDGE_BOTH = 2;
36
37
	public static final float DEFAULT_MAX_SCALE = 3.0f;
38
	public static final float DEFAULT_MID_SCALE = 1.75f;
39
	public static final float DEFAULT_MIN_SCALE = 1.0f;
40
41
	private float mMinScale = DEFAULT_MIN_SCALE;
42
	private float mMidScale = DEFAULT_MID_SCALE;
43
	private float mMaxScale = DEFAULT_MAX_SCALE;
44
45
	private boolean mAllowParentInterceptOnEdge = true;
46
47
	private static void checkZoomLevels(float minZoom, float midZoom,
48
			float maxZoom) {
49
		if (minZoom >= midZoom) {
50
			throw new IllegalArgumentException(
51
					"MinZoom should be less than MidZoom");
52
		} else if (midZoom >= maxZoom) {
53
			throw new IllegalArgumentException(
54
					"MidZoom should be less than MaxZoom");
55
		}
56
	}
57
58
	/**
59
	 * @return true if the ImageView exists, and it's Drawable existss
60
	 */
61
	private static boolean hasDrawable(ImageView imageView) {
62
		return null != imageView && null != imageView.getDrawable();
63
	}
64
65
	/**
66
	 * @return true if the ScaleType is supported.
67
	 */
68
	private static boolean isSupportedScaleType(final ScaleType scaleType) {
69
		if (null == scaleType) {
70
			return false;
71
		}
72
73
		switch (scaleType) {
74
		case MATRIX:
75
			throw new IllegalArgumentException(scaleType.name()
76
					+ " is not supported in PhotoView");
77
78
		default:
79
			return true;
80
		}
81
	}
82
83
	/**
84
	 * Set's the ImageView's ScaleType to Matrix.
85
	 */
86
	private static void setImageViewScaleTypeMatrix(ImageView imageView) {
87
		if (null != imageView) {
88
			if (imageView instanceof PhotoView) {
89
				/**
90
				 * PhotoView sets it's own ScaleType to Matrix, then diverts all
91
				 * calls setScaleType to this.setScaleType. Basically we don't
92
				 * need to do anything here
93
				 */
94
			} else {
95
				imageView.setScaleType(ScaleType.MATRIX);
96
			}
97
		}
98
	}
99
100
	private WeakReference<ImageView> mImageView;
101
	private ViewTreeObserver mViewTreeObserver;
102
103
	// Gesture Detectors
104
	private GestureDetector mGestureDetector;
105
	private VersionedGestureDetector mScaleDragDetector;
106
107
	// These are set so we don't keep allocating them on the heap
108
	private final Matrix mBaseMatrix = new Matrix();
109
	private final Matrix mDrawMatrix = new Matrix();
110
	private final Matrix mSuppMatrix = new Matrix();
111
	private final RectF mDisplayRect = new RectF();
112
	private final float[] mMatrixValues = new float[9];
113
114
	// Listeners
115
	private OnMatrixChangedListener mMatrixChangeListener;
116
	private OnPhotoTapListener mPhotoTapListener;
117
	private OnViewTapListener mViewTapListener;
118
	private OnLongClickListener mLongClickListener;
119
120
	private int mIvTop, mIvRight, mIvBottom, mIvLeft;
121
	private FlingRunnable mCurrentFlingRunnable;
122
	private int mScrollEdge = EDGE_BOTH;
123
124
	private boolean mZoomEnabled;
125
	private ScaleType mScaleType = ScaleType.FIT_CENTER;
126
127
	public PhotoViewAttacher(ImageView imageView) {
128
		mImageView = new WeakReference<ImageView>(imageView);
129
130
		imageView.setOnTouchListener(this);
131
132
		mViewTreeObserver = imageView.getViewTreeObserver();
133
		mViewTreeObserver.addOnGlobalLayoutListener(this);
134
135
		// Make sure we using MATRIX Scale Type
136
		setImageViewScaleTypeMatrix(imageView);
137
138
		if (!imageView.isInEditMode()) {
139
			// Create Gesture Detectors...
140
			mScaleDragDetector = VersionedGestureDetector.newInstance(
141
					imageView.getContext(), this);
142
143
			mGestureDetector = new GestureDetector(imageView.getContext(),
144
					new GestureDetector.SimpleOnGestureListener() {
145
146
						// forward long click listener
147
						@Override
148
						public void onLongPress(MotionEvent e) {
149
							if (null != mLongClickListener) {
150
								mLongClickListener.onLongClick(mImageView.get());
151
							}
152
						}
153
					});
154
155
			mGestureDetector.setOnDoubleTapListener(this);
156
157
			// Finally, update the UI so that we're zoomable
158
			setZoomable(true);
159
		}
160
	}
161
162
	@Override
163
	public final boolean canZoom() {
164
		return mZoomEnabled;
165
	}
166
167
	/**
168
	 * Clean-up the resources attached to this object. This needs to be called
169
	 * when the ImageView is no longer used. A good example is from
170
	 * {@link View#onDetachedFromWindow()} or from
171
	 * {@link android.app.Activity#onDestroy()}. This is automatically called if
172
	 */
173
	@SuppressLint("NewApi")
174
	// @SuppressWarnings("deprecation")
175
	// public final void cleanup() {
176
	// if (null != mImageView) {
177
	// mImageView.get().getViewTreeObserver().removeGlobalOnLayoutListener(this);
178
	// }
179
	// mViewTreeObserver = null;
180
	//
181
	// // Clear listeners too
182
	// mMatrixChangeListener = null;
183
	// mPhotoTapListener = null;
184
	// mViewTapListener = null;
185
	//
186
	// // Finally, clear ImageView
187
	// mImageView = null;
188
	// }
189
	@SuppressWarnings("deprecation")
190
	public final void cleanup() {
191
		if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
192
			if (null != mImageView) {
193
				mImageView.get().getViewTreeObserver()
194
						.removeOnGlobalLayoutListener(this);
195
			}
196
197
			if (null != mViewTreeObserver && mViewTreeObserver.isAlive()) {
198
				mViewTreeObserver.removeOnGlobalLayoutListener(this);
199
200
				mViewTreeObserver = null;
201
202
				// Clear listeners too
203
				mMatrixChangeListener = null;
204
				mPhotoTapListener = null;
205
				mViewTapListener = null;
206
				// Finally, clear ImageView
207
				mImageView = null;
208
			}
209
210
		} else {
211
			if (null != mImageView) {
212
				mImageView.get().getViewTreeObserver()
213
						.removeGlobalOnLayoutListener(this);
214
			}
215
216
			if (null != mViewTreeObserver && mViewTreeObserver.isAlive()) {
217
				mViewTreeObserver.removeGlobalOnLayoutListener(this);
218
219
				mViewTreeObserver = null;
220
221
				// Clear listeners too
222
				mMatrixChangeListener = null;
223
				mPhotoTapListener = null;
224
				mViewTapListener = null;
225
				// Finally, clear ImageView
226
				mImageView = null;
227
			}
228
		}
229
	}
230
231
	@Override
232
	public final RectF getDisplayRect() {
233
		checkMatrixBounds();
234
		return getDisplayRect(getDisplayMatrix());
235
	}
236
237
	public final ImageView getImageView() {
238
		ImageView imageView = null;
239
240
		if (null != mImageView) {
241
			imageView = mImageView.get();
242
		}
243
244
		// If we don't have an ImageView, call cleanup()
245
		if (null == imageView) {
246
			cleanup();
247
			throw new IllegalStateException(
248
					"ImageView no longer exists. You should not use this PhotoViewAttacher any more.");
249
		}
250
251
		return imageView;
252
	}
253
254
	@Override
255
	public float getMinScale() {
256
		return mMinScale;
257
	}
258
259
	@Override
260
	public float getMidScale() {
261
		return mMidScale;
262
	}
263
264
	@Override
265
	public float getMaxScale() {
266
		return mMaxScale;
267
	}
268
269
	@Override
270
	public final float getScale() {
271
		return getValue(mSuppMatrix, Matrix.MSCALE_X);
272
	}
273
274
	@Override
275
	public final ScaleType getScaleType() {
276
		return mScaleType;
277
	}
278
279
	@Override
280
	public final boolean onDoubleTap(MotionEvent ev) {
281
		try {
282
			float scale = getScale();
283
			float x = ev.getX();
284
			float y = ev.getY();
285
286
			if (scale < mMidScale) {
287
				zoomTo(mMidScale, x, y);
288
			} else if (scale >= mMidScale && scale < mMaxScale) {
289
				zoomTo(mMaxScale, x, y);
290
			} else {
291
				zoomTo(mMinScale, x, y);
292
			}
293
		} catch (ArrayIndexOutOfBoundsException e) {
294
			// Can sometimes happen when getX() and getY() is called
295
		}
296
297
		return true;
298
	}
299
300
	@Override
301
	public final boolean onDoubleTapEvent(MotionEvent e) {
302
		// Wait for the confirmed onDoubleTap() instead
303
		return false;
304
	}
305
306
	@Override
307
	public final void onDrag(float dx, float dy) {
308
		if (DEBUG) {
309
			Log.d(LOG_TAG, String.format("onDrag: dx: %.2f. dy: %.2f", dx, dy));
310
		}
311
312
		ImageView imageView = getImageView();
313
314
		if (null != imageView && hasDrawable(imageView)) {
315
			mSuppMatrix.postTranslate(dx, dy);
316
			checkAndDisplayMatrix();
317
318
			/**
319
			 * Here we decide whether to let the ImageView's parent to start
320
			 * taking over the touch event.
321
			 * 
322
			 * First we check whether this function is enabled. We never want
323
			 * the parent to take over if we're scaling. We then check the edge
324
			 * we're on, and the direction of the scroll (i.e. if we're pulling
325
			 * against the edge, aka 'overscrolling', let the parent take over).
326
			 */
327
			if (mAllowParentInterceptOnEdge && !mScaleDragDetector.isScaling()) {
328
				if (mScrollEdge == EDGE_BOTH
329
						|| (mScrollEdge == EDGE_LEFT && dx >= 1f)
330
						|| (mScrollEdge == EDGE_RIGHT && dx <= -1f)) {
331
					imageView.getParent().requestDisallowInterceptTouchEvent(
332
							false);
333
				}
334
			}
335
		}
336
	}
337
338
	@Override
339
	public final void onFling(float startX, float startY, float velocityX,
340
			float velocityY) {
341
		if (DEBUG) {
342
			Log.d(LOG_TAG, "onFling. sX: " + startX + " sY: " + startY
343
					+ " Vx: " + velocityX + " Vy: " + velocityY);
344
		}
345
346
		ImageView imageView = getImageView();
347
		if (hasDrawable(imageView)) {
348
			mCurrentFlingRunnable = new FlingRunnable(imageView.getContext());
349
			mCurrentFlingRunnable.fling(imageView.getWidth(),
350
					imageView.getHeight(), (int) velocityX, (int) velocityY);
351
			imageView.post(mCurrentFlingRunnable);
352
		}
353
	}
354
355
	@Override
356
	public final void onGlobalLayout() {
357
		ImageView imageView = getImageView();
358
359
		if (null != imageView && mZoomEnabled) {
360
			final int top = imageView.getTop();
361
			final int right = imageView.getRight();
362
			final int bottom = imageView.getBottom();
363
			final int left = imageView.getLeft();
364
365
			/**
366
			 * We need to check whether the ImageView's bounds have changed.
367
			 * This would be easier if we targeted API 11+ as we could just use
368
			 * View.OnLayoutChangeListener. Instead we have to replicate the
369
			 * work, keeping track of the ImageView's bounds and then checking
370
			 * if the values change.
371
			 */
372
			if (top != mIvTop || bottom != mIvBottom || left != mIvLeft
373
					|| right != mIvRight) {
374
				// Update our base matrix, as the bounds have changed
375
				updateBaseMatrix(imageView.getDrawable());
376
377
				// Update values as something has changed
378
				mIvTop = top;
379
				mIvRight = right;
380
				mIvBottom = bottom;
381
				mIvLeft = left;
382
			}
383
		}
384
	}
385
386
	@Override
387
	public final void onScale(float scaleFactor, float focusX, float focusY) {
388
		if (DEBUG) {
389
			Log.d(LOG_TAG, String.format(
390
					"onScale: scale: %.2f. fX: %.2f. fY: %.2f", scaleFactor,
391
					focusX, focusY));
392
		}
393
394
		if (hasDrawable(getImageView())
395
				&& (getScale() < mMaxScale || scaleFactor < 1f)) {
396
			mSuppMatrix.postScale(scaleFactor, scaleFactor, focusX, focusY);
397
			checkAndDisplayMatrix();
398
		}
399
	}
400
401
	@Override
402
	public final boolean onSingleTapConfirmed(MotionEvent e) {
403
		ImageView imageView = getImageView();
404
405
		if (null != imageView) {
406
			if (null != mPhotoTapListener) {
407
				final RectF displayRect = getDisplayRect();
408
409
				if (null != displayRect) {
410
					final float x = e.getX(), y = e.getY();
411
412
					// Check to see if the user tapped on the photo
413
					if (displayRect.contains(x, y)) {
414
415
						float xResult = (x - displayRect.left)
416
								/ displayRect.width();
417
						float yResult = (y - displayRect.top)
418
								/ displayRect.height();
419
420
						mPhotoTapListener.onPhotoTap(imageView, xResult,
421
								yResult);
422
						return true;
423
					}
424
				}
425
			}
426
			if (null != mViewTapListener) {
427
				mViewTapListener.onViewTap(imageView, e.getX(), e.getY());
428
			}
429
		}
430
431
		return false;
432
	}
433
434
	@Override
435
	public final boolean onTouch(View v, MotionEvent ev) {
436
		boolean handled = false;
437
438
		if (mZoomEnabled) {
439
			switch (ev.getAction()) {
440
			case MotionEvent.ACTION_DOWN:
441
				// First, disable the Parent from intercepting the touch
442
				// event
443
				v.getParent().requestDisallowInterceptTouchEvent(true);
444
445
				// If we're flinging, and the user presses down, cancel
446
				// fling
447
				cancelFling();
448
				break;
449
450
			case MotionEvent.ACTION_CANCEL:
451
			case MotionEvent.ACTION_UP:
452
				// If the user has zoomed less than min scale, zoom back
453
				// to min scale
454
				if (getScale() < mMinScale) {
455
					RectF rect = getDisplayRect();
456
					if (null != rect) {
457
						v.post(new AnimatedZoomRunnable(getScale(), mMinScale,
458
								rect.centerX(), rect.centerY()));
459
						handled = true;
460
					}
461
				}
462
				break;
463
			}
464
465
			// Check to see if the user double tapped
466
			if (null != mGestureDetector && mGestureDetector.onTouchEvent(ev)) {
467
				handled = true;
468
			}
469
470
			// Finally, try the Scale/Drag detector
471
			if (null != mScaleDragDetector
472
					&& mScaleDragDetector.onTouchEvent(ev)) {
473
				handled = true;
474
			}
475
		}
476
477
		return handled;
478
	}
479
480
	@Override
481
	public void setAllowParentInterceptOnEdge(boolean allow) {
482
		mAllowParentInterceptOnEdge = allow;
483
	}
484
485
	@Override
486
	public void setMinScale(float minScale) {
487
		checkZoomLevels(minScale, mMidScale, mMaxScale);
488
		mMinScale = minScale;
489
	}
490
491
	@Override
492
	public void setMidScale(float midScale) {
493
		checkZoomLevels(mMinScale, midScale, mMaxScale);
494
		mMidScale = midScale;
495
	}
496
497
	@Override
498
	public void setMaxScale(float maxScale) {
499
		checkZoomLevels(mMinScale, mMidScale, maxScale);
500
		mMaxScale = maxScale;
501
	}
502
503
	@Override
504
	public final void setOnLongClickListener(OnLongClickListener listener) {
505
		mLongClickListener = listener;
506
	}
507
508
	@Override
509
	public final void setOnMatrixChangeListener(OnMatrixChangedListener listener) {
510
		mMatrixChangeListener = listener;
511
	}
512
513
	@Override
514
	public final void setOnPhotoTapListener(OnPhotoTapListener listener) {
515
		mPhotoTapListener = listener;
516
	}
517
518
	@Override
519
	public final void setOnViewTapListener(OnViewTapListener listener) {
520
		mViewTapListener = listener;
521
	}
522
523
	@Override
524
	public final void setScaleType(ScaleType scaleType) {
525
		if (isSupportedScaleType(scaleType) && scaleType != mScaleType) {
526
			mScaleType = scaleType;
527
528
			// Finally update
529
			update();
530
		}
531
	}
532
533
	@Override
534
	public final void setZoomable(boolean zoomable) {
535
		mZoomEnabled = zoomable;
536
		update();
537
	}
538
539
	public final void update() {
540
		ImageView imageView = getImageView();
541
542
		if (null != imageView) {
543
			if (mZoomEnabled) {
544
				// Make sure we using MATRIX Scale Type
545
				setImageViewScaleTypeMatrix(imageView);
546
547
				// Update the base matrix using the current drawable
548
				updateBaseMatrix(imageView.getDrawable());
549
			} else {
550
				// Reset the Matrix...
551
				resetMatrix();
552
			}
553
		}
554
	}
555
556
	@Override
557
	public final void zoomTo(float scale, float focalX, float focalY) {
558
		ImageView imageView = getImageView();
559
560
		if (null != imageView) {
561
			imageView.post(new AnimatedZoomRunnable(getScale(), scale, focalX,
562
					focalY));
563
		}
564
	}
565
566
	protected Matrix getDisplayMatrix() {
567
		mDrawMatrix.set(mBaseMatrix);
568
		mDrawMatrix.postConcat(mSuppMatrix);
569
		return mDrawMatrix;
570
	}
571
572
	private void cancelFling() {
573
		if (null != mCurrentFlingRunnable) {
574
			mCurrentFlingRunnable.cancelFling();
575
			mCurrentFlingRunnable = null;
576
		}
577
	}
578
579
	/**
580
	 * Helper method that simply checks the Matrix, and then displays the result
581
	 */
582
	private void checkAndDisplayMatrix() {
583
		checkMatrixBounds();
584
		setImageViewMatrix(getDisplayMatrix());
585
	}
586
587
	private void checkImageViewScaleType() {
588
		ImageView imageView = getImageView();
589
590
		/**
591
		 * PhotoView's getScaleType() will just divert to this.getScaleType() so
592
		 * only call if we're not attached to a PhotoView.
593
		 */
594
		if (null != imageView && !(imageView instanceof PhotoView)) {
595
			if (imageView.getScaleType() != ScaleType.MATRIX) {
596
				throw new IllegalStateException(
597
						"The ImageView's ScaleType has been changed since attaching a PhotoViewAttacher");
598
			}
599
		}
600
	}
601
602
	private void checkMatrixBounds() {
603
		final ImageView imageView = getImageView();
604
		if (null == imageView) {
605
			return;
606
		}
607
608
		final RectF rect = getDisplayRect(getDisplayMatrix());
609
		if (null == rect) {
610
			return;
611
		}
612
613
		final float height = rect.height(), width = rect.width();
614
		float deltaX = 0, deltaY = 0;
615
616
		final int viewHeight = imageView.getHeight();
617
		if (height <= viewHeight) {
618
			switch (mScaleType) {
619
			case FIT_START:
620
				deltaY = -rect.top;
621
				break;
622
			case FIT_END:
623
				deltaY = viewHeight - height - rect.top;
624
				break;
625
			default:
626
				deltaY = (viewHeight - height) / 2 - rect.top;
627
				break;
628
			}
629
		} else if (rect.top > 0) {
630
			deltaY = -rect.top;
631
		} else if (rect.bottom < viewHeight) {
632
			deltaY = viewHeight - rect.bottom;
633
		}
634
635
		final int viewWidth = imageView.getWidth();
636
		if (width <= viewWidth) {
637
			switch (mScaleType) {
638
			case FIT_START:
639
				deltaX = -rect.left;
640
				break;
641
			case FIT_END:
642
				deltaX = viewWidth - width - rect.left;
643
				break;
644
			default:
645
				deltaX = (viewWidth - width) / 2 - rect.left;
646
				break;
647
			}
648
			mScrollEdge = EDGE_BOTH;
649
		} else if (rect.left > 0) {
650
			mScrollEdge = EDGE_LEFT;
651
			deltaX = -rect.left;
652
		} else if (rect.right < viewWidth) {
653
			deltaX = viewWidth - rect.right;
654
			mScrollEdge = EDGE_RIGHT;
655
		} else {
656
			mScrollEdge = EDGE_NONE;
657
		}
658
659
		// Finally actually translate the matrix
660
		mSuppMatrix.postTranslate(deltaX, deltaY);
661
	}
662
663
	/**
664
	 * Helper method that maps the supplied Matrix to the current Drawable
665
	 * 
666
	 * @param matrix
667
	 *            - Matrix to map Drawable against
668
	 * @return RectF - Displayed Rectangle
669
	 */
670
	private RectF getDisplayRect(Matrix matrix) {
671
		ImageView imageView = getImageView();
672
673
		if (null != imageView) {
674
			Drawable d = imageView.getDrawable();
675
			if (null != d) {
676
				mDisplayRect.set(0, 0, d.getIntrinsicWidth(),
677
						d.getIntrinsicHeight());
678
				matrix.mapRect(mDisplayRect);
679
				return mDisplayRect;
680
			}
681
		}
682
		return null;
683
	}
684
685
	/**
686
	 * Helper method that 'unpacks' a Matrix and returns the required value
687
	 * 
688
	 * @param matrix
689
	 *            - Matrix to unpack
690
	 * @param whichValue
691
	 *            - Which value from Matrix.M* to return
692
	 * @return float - returned value
693
	 */
694
	private float getValue(Matrix matrix, int whichValue) {
695
		matrix.getValues(mMatrixValues);
696
		return mMatrixValues[whichValue];
697
	}
698
699
	/**
700
	 * Resets the Matrix back to FIT_CENTER, and then displays it.s
701
	 */
702
	private void resetMatrix() {
703
		mSuppMatrix.reset();
704
		setImageViewMatrix(getDisplayMatrix());
705
		checkMatrixBounds();
706
	}
707
708
	private void setImageViewMatrix(Matrix matrix) {
709
		ImageView imageView = getImageView();
710
		if (null != imageView) {
711
712
			checkImageViewScaleType();
713
			imageView.setImageMatrix(matrix);
714
715
			// Call MatrixChangedListener if needed
716
			if (null != mMatrixChangeListener) {
717
				RectF displayRect = getDisplayRect(matrix);
718
				if (null != displayRect) {
719
					mMatrixChangeListener.onMatrixChanged(displayRect);
720
				}
721
			}
722
		}
723
	}
724
725
	/**
726
	 * Calculate Matrix for FIT_CENTER
727
	 * 
728
	 * @param d
729
	 *            - Drawable being displayed
730
	 */
731
	private void updateBaseMatrix(Drawable d) {
732
		ImageView imageView = getImageView();
733
		if (null == imageView || null == d) {
734
			return;
735
		}
736
737
		final float viewWidth = imageView.getWidth();
738
		final float viewHeight = imageView.getHeight();
739
		final int drawableWidth = d.getIntrinsicWidth();
740
		final int drawableHeight = d.getIntrinsicHeight();
741
742
		mBaseMatrix.reset();
743
744
		final float widthScale = viewWidth / drawableWidth;
745
		final float heightScale = viewHeight / drawableHeight;
746
747
		if (mScaleType == ScaleType.CENTER) {
748
			mBaseMatrix.postTranslate((viewWidth - drawableWidth) / 2F,
749
					(viewHeight - drawableHeight) / 2F);
750
751
		} else if (mScaleType == ScaleType.CENTER_CROP) {
752
			float scale = Math.max(widthScale, heightScale);
753
			mBaseMatrix.postScale(scale, scale);
754
			mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F,
755
					(viewHeight - drawableHeight * scale) / 2F);
756
757
		} else if (mScaleType == ScaleType.CENTER_INSIDE) {
758
			float scale = Math.min(1.0f, Math.min(widthScale, heightScale));
759
			mBaseMatrix.postScale(scale, scale);
760
			mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F,
761
					(viewHeight - drawableHeight * scale) / 2F);
762
763
		} else {
764
			RectF mTempSrc = new RectF(0, 0, drawableWidth, drawableHeight);
765
			RectF mTempDst = new RectF(0, 0, viewWidth, viewHeight);
766
767
			switch (mScaleType) {
768
			case FIT_CENTER:
769
				mBaseMatrix
770
						.setRectToRect(mTempSrc, mTempDst, ScaleToFit.CENTER);
771
				break;
772
773
			case FIT_START:
774
				mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.START);
775
				break;
776
777
			case FIT_END:
778
				mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.END);
779
				break;
780
781
			case FIT_XY:
782
				mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.FILL);
783
				break;
784
785
			default:
786
				break;
787
			}
788
		}
789
790
		resetMatrix();
791
	}
792
793
	/**
794
	 * Interface definition for a callback to be invoked when the internal
795
	 * Matrix has changed for this View.
796
	 * 
797
	 * @author Chris Banes
798
	 */
799
	public static interface OnMatrixChangedListener {
800
		/**
801
		 * Callback for when the Matrix displaying the Drawable has changed.
802
		 * This could be because the View's bounds have changed, or the user has
803
		 * zoomed.
804
		 * 
805
		 * @param rect
806
		 *            - Rectangle displaying the Drawable's new bounds.
807
		 */
808
		void onMatrixChanged(RectF rect);
809
	}
810
811
	/**
812
	 * Interface definition for a callback to be invoked when the Photo is
813
	 * tapped with a single tap.
814
	 * 
815
	 * @author Chris Banes
816
	 */
817
	public static interface OnPhotoTapListener {
818
819
		/**
820
		 * A callback to receive where the user taps on a photo. You will only
821
		 * receive a callback if the user taps on the actual photo, tapping on
822
		 * 'whitespace' will be ignored.
823
		 * 
824
		 * @param view
825
		 *            - View the user tapped.
826
		 * @param x
827
		 *            - where the user tapped from the of the Drawable, as
828
		 *            percentage of the Drawable width.
829
		 * @param y
830
		 *            - where the user tapped from the top of the Drawable, as
831
		 *            percentage of the Drawable height.
832
		 */
833
		void onPhotoTap(View view, float x, float y);
834
	}
835
836
	/**
837
	 * Interface definition for a callback to be invoked when the ImageView is
838
	 * tapped with a single tap.
839
	 * 
840
	 * @author Chris Banes
841
	 */
842
	public static interface OnViewTapListener {
843
844
		/**
845
		 * A callback to receive where the user taps on a ImageView. You will
846
		 * receive a callback if the user taps anywhere on the view, tapping on
847
		 * 'whitespace' will not be ignored.
848
		 * 
849
		 * @param view
850
		 *            - View the user tapped.
851
		 * @param x
852
		 *            - where the user tapped from the left of the View.
853
		 * @param y
854
		 *            - where the user tapped from the top of the View.
855
		 */
856
		void onViewTap(View view, float x, float y);
857
	}
858
859
	private class AnimatedZoomRunnable implements Runnable {
860
861
		// These are 'postScale' values, means they're compounded each iteration
862
		static final float ANIMATION_SCALE_PER_ITERATION_IN = 1.07f;
863
		static final float ANIMATION_SCALE_PER_ITERATION_OUT = 0.93f;
864
865
		private final float mFocalX, mFocalY;
866
		private final float mTargetZoom;
867
		private final float mDeltaScale;
868
869
		public AnimatedZoomRunnable(final float currentZoom,
870
				final float targetZoom, final float focalX, final float focalY) {
871
			mTargetZoom = targetZoom;
872
			mFocalX = focalX;
873
			mFocalY = focalY;
874
875
			if (currentZoom < targetZoom) {
876
				mDeltaScale = ANIMATION_SCALE_PER_ITERATION_IN;
877
			} else {
878
				mDeltaScale = ANIMATION_SCALE_PER_ITERATION_OUT;
879
			}
880
		}
881
882
		public void run() {
883
			ImageView imageView = getImageView();
884
885
			if (null != imageView) {
886
				mSuppMatrix.postScale(mDeltaScale, mDeltaScale, mFocalX,
887
						mFocalY);
888
				checkAndDisplayMatrix();
889
890
				final float currentScale = getScale();
891
892
				if ((mDeltaScale > 1f && currentScale < mTargetZoom)
893
						|| (mDeltaScale < 1f && mTargetZoom < currentScale)) {
894
					// We haven't hit our target scale yet, so post ourselves
895
					// again
896
					Compat.postOnAnimation(imageView, this);
897
898
				} else {
899
					// We've scaled past our target zoom, so calculate the
900
					// necessary scale so we're back at target zoom
901
					final float delta = mTargetZoom / currentScale;
902
					mSuppMatrix.postScale(delta, delta, mFocalX, mFocalY);
903
					checkAndDisplayMatrix();
904
				}
905
			}
906
		}
907
	}
908
909
	private class FlingRunnable implements Runnable {
910
911
		private final ScrollerProxy mScroller;
912
		private int mCurrentX, mCurrentY;
913
914
		public FlingRunnable(Context context) {
915
			mScroller = ScrollerProxy.getScroller(context);
916
		}
917
918
		public void cancelFling() {
919
			if (DEBUG) {
920
				Log.d(LOG_TAG, "Cancel Fling");
921
			}
922
			mScroller.forceFinished(true);
923
		}
924
925
		public void fling(int viewWidth, int viewHeight, int velocityX,
926
				int velocityY) {
927
			final RectF rect = getDisplayRect();
928
			if (null == rect) {
929
				return;
930
			}
931
932
			final int startX = Math.round(-rect.left);
933
			final int minX, maxX, minY, maxY;
934
935
			if (viewWidth < rect.width()) {
936
				minX = 0;
937
				maxX = Math.round(rect.width() - viewWidth);
938
			} else {
939
				minX = maxX = startX;
940
			}
941
942
			final int startY = Math.round(-rect.top);
943
			if (viewHeight < rect.height()) {
944
				minY = 0;
945
				maxY = Math.round(rect.height() - viewHeight);
946
			} else {
947
				minY = maxY = startY;
948
			}
949
950
			mCurrentX = startX;
951
			mCurrentY = startY;
952
953
			if (DEBUG) {
954
				Log.d(LOG_TAG, "fling. StartX:" + startX + " StartY:" + startY
955
						+ " MaxX:" + maxX + " MaxY:" + maxY);
956
			}
957
958
			// If we actually can move, fling the scroller
959
			if (startX != maxX || startY != maxY) {
960
				mScroller.fling(startX, startY, velocityX, velocityY, minX,
961
						maxX, minY, maxY, 0, 0);
962
			}
963
		}
964
965
		@Override
966
		public void run() {
967
			ImageView imageView = getImageView();
968
			if (null != imageView && mScroller.computeScrollOffset()) {
969
970
				final int newX = mScroller.getCurrX();
971
				final int newY = mScroller.getCurrY();
972
973
				if (DEBUG) {
974
					Log.d(LOG_TAG, "fling run(). CurrentX:" + mCurrentX
975
							+ " CurrentY:" + mCurrentY + " NewX:" + newX
976
							+ " NewY:" + newY);
977
				}
978
979
				mSuppMatrix.postTranslate(mCurrentX - newX, mCurrentY - newY);
980
				setImageViewMatrix(getDisplayMatrix());
981
982
				mCurrentX = newX;
983
				mCurrentY = newY;
984
985
				// Post On animation
986
				Compat.postOnAnimation(imageView, this);
987
			}
988
		}
989
	}
990
}

+ 0 - 13
app/src/main/java/com/electric/chargingpile/zoom/SDK16.java

@ -1,13 +0,0 @@
1
package com.electric.chargingpile.zoom;
2
3
import android.annotation.TargetApi;
4
import android.view.View;
5
6
@TargetApi(16)
7
public class SDK16 {
8
9
	public static void postOnAnimation(View view, Runnable r) {
10
		view.postOnAnimation(r);
11
	}
12
	
13
}

+ 0 - 101
app/src/main/java/com/electric/chargingpile/zoom/ScrollerProxy.java

@ -1,101 +0,0 @@
1
package com.electric.chargingpile.zoom;
2
3
import android.annotation.TargetApi;
4
import android.content.Context;
5
import android.os.Build.VERSION;
6
import android.os.Build.VERSION_CODES;
7
import android.widget.OverScroller;
8
import android.widget.Scroller;
9
10
public abstract class ScrollerProxy {
11
12
	public static ScrollerProxy getScroller(Context context) {
13
		if (VERSION.SDK_INT < VERSION_CODES.GINGERBREAD) {
14
			return new PreGingerScroller(context);
15
		} else {
16
			return new GingerScroller(context);
17
		}
18
	}
19
20
	public abstract boolean computeScrollOffset();
21
22
	public abstract void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY,
23
			int maxY, int overX, int overY);
24
25
	public abstract void forceFinished(boolean finished);
26
27
	public abstract int getCurrX();
28
29
	public abstract int getCurrY();
30
31
	@TargetApi(9)
32
	private static class GingerScroller extends ScrollerProxy {
33
34
		private OverScroller mScroller;
35
36
		public GingerScroller(Context context) {
37
			mScroller = new OverScroller(context);
38
		}
39
40
		@Override
41
		public boolean computeScrollOffset() {
42
			return mScroller.computeScrollOffset();
43
		}
44
45
		@Override
46
		public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY,
47
				int overX, int overY) {
48
			mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, overX, overY);
49
		}
50
51
		@Override
52
		public void forceFinished(boolean finished) {
53
			mScroller.forceFinished(finished);
54
		}
55
56
		@Override
57
		public int getCurrX() {
58
			return mScroller.getCurrX();
59
		}
60
61
		@Override
62
		public int getCurrY() {
63
			return mScroller.getCurrY();
64
		}
65
	}
66
67
	private static class PreGingerScroller extends ScrollerProxy {
68
69
		private Scroller mScroller;
70
71
		public PreGingerScroller(Context context) {
72
			mScroller = new Scroller(context);
73
		}
74
75
		@Override
76
		public boolean computeScrollOffset() {
77
			return mScroller.computeScrollOffset();
78
		}
79
80
		@Override
81
		public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY,
82
				int overX, int overY) {
83
			mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
84
		}
85
86
		@Override
87
		public void forceFinished(boolean finished) {
88
			mScroller.forceFinished(finished);
89
		}
90
91
		@Override
92
		public int getCurrX() {
93
			return mScroller.getCurrX();
94
		}
95
96
		@Override
97
		public int getCurrY() {
98
			return mScroller.getCurrY();
99
		}
100
	}
101
}

+ 0 - 253
app/src/main/java/com/electric/chargingpile/zoom/VersionedGestureDetector.java

@ -1,253 +0,0 @@
1
package com.electric.chargingpile.zoom;
2
3
import android.annotation.TargetApi;
4
import android.content.Context;
5
import android.os.Build;
6
import android.util.FloatMath;
7
import android.view.MotionEvent;
8
import android.view.ScaleGestureDetector;
9
import android.view.ScaleGestureDetector.OnScaleGestureListener;
10
import android.view.VelocityTracker;
11
import android.view.ViewConfiguration;
12
13
public abstract class VersionedGestureDetector {
14
	static final String LOG_TAG = "VersionedGestureDetector";
15
	OnGestureListener mListener;
16
17
	public static VersionedGestureDetector newInstance(Context context, OnGestureListener listener) {
18
		final int sdkVersion = Build.VERSION.SDK_INT;
19
		VersionedGestureDetector detector = null;
20
21
		if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
22
			detector = new CupcakeDetector(context);
23
		} else if (sdkVersion < Build.VERSION_CODES.FROYO) {
24
			detector = new EclairDetector(context);
25
		} else {
26
			detector = new FroyoDetector(context);
27
		}
28
29
		detector.mListener = listener;
30
31
		return detector;
32
	}
33
34
	public abstract boolean onTouchEvent(MotionEvent ev);
35
36
	public abstract boolean isScaling();
37
38
	public static interface OnGestureListener {
39
		public void onDrag(float dx, float dy);
40
41
		public void onFling(float startX, float startY, float velocityX, float velocityY);
42
43
		public void onScale(float scaleFactor, float focusX, float focusY);
44
	}
45
46
	private static class CupcakeDetector extends VersionedGestureDetector {
47
48
		float mLastTouchX;
49
		float mLastTouchY;
50
		final float mTouchSlop;
51
		final float mMinimumVelocity;
52
53
		public CupcakeDetector(Context context) {
54
			final ViewConfiguration configuration = ViewConfiguration.get(context);
55
			mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
56
			mTouchSlop = configuration.getScaledTouchSlop();
57
		}
58
59
		private VelocityTracker mVelocityTracker;
60
		private boolean mIsDragging;
61
62
		float getActiveX(MotionEvent ev) {
63
			return ev.getX();
64
		}
65
66
		float getActiveY(MotionEvent ev) {
67
			return ev.getY();
68
		}
69
70
		public boolean isScaling() {
71
			return false;
72
		}
73
74
		@Override
75
		public boolean onTouchEvent(MotionEvent ev) {
76
			switch (ev.getAction()) {
77
				case MotionEvent.ACTION_DOWN: {
78
					mVelocityTracker = VelocityTracker.obtain();
79
					mVelocityTracker.addMovement(ev);
80
81
					mLastTouchX = getActiveX(ev);
82
					mLastTouchY = getActiveY(ev);
83
					mIsDragging = false;
84
					break;
85
				}
86
87
				case MotionEvent.ACTION_MOVE: {
88
					final float x = getActiveX(ev);
89
					final float y = getActiveY(ev);
90
					final float dx = x - mLastTouchX, dy = y - mLastTouchY;
91
92
					if (!mIsDragging) {
93
						// Use Pythagoras to see if drag length is larger than
94
						// touch slop
95
						mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
96
					}
97
98
					if (mIsDragging) {
99
						mListener.onDrag(dx, dy);
100
						mLastTouchX = x;
101
						mLastTouchY = y;
102
103
						if (null != mVelocityTracker) {
104
							mVelocityTracker.addMovement(ev);
105
						}
106
					}
107
					break;
108
				}
109
110
				case MotionEvent.ACTION_CANCEL: {
111
					// Recycle Velocity Tracker
112
					if (null != mVelocityTracker) {
113
						mVelocityTracker.recycle();
114
						mVelocityTracker = null;
115
					}
116
					break;
117
				}
118
119
				case MotionEvent.ACTION_UP: {
120
					if (mIsDragging) {
121
						if (null != mVelocityTracker) {
122
							mLastTouchX = getActiveX(ev);
123
							mLastTouchY = getActiveY(ev);
124
125
							// Compute velocity within the last 1000ms
126
							mVelocityTracker.addMovement(ev);
127
							mVelocityTracker.computeCurrentVelocity(1000);
128
129
							final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker.getYVelocity();
130
131
							// If the velocity is greater than minVelocity, call
132
							// listener
133
							if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
134
								mListener.onFling(mLastTouchX, mLastTouchY, -vX, -vY);
135
							}
136
						}
137
					}
138
139
					// Recycle Velocity Tracker
140
					if (null != mVelocityTracker) {
141
						mVelocityTracker.recycle();
142
						mVelocityTracker = null;
143
					}
144
					break;
145
				}
146
			}
147
148
			return true;
149
		}
150
	}
151
152
	@TargetApi(5)
153
	private static class EclairDetector extends CupcakeDetector {
154
		private static final int INVALID_POINTER_ID = -1;
155
		private int mActivePointerId = INVALID_POINTER_ID;
156
		private int mActivePointerIndex = 0;
157
158
		public EclairDetector(Context context) {
159
			super(context);
160
		}
161
162
		@Override
163
		float getActiveX(MotionEvent ev) {
164
			try {
165
				return ev.getX(mActivePointerIndex);
166
			} catch (Exception e) {
167
				return ev.getX();
168
			}
169
		}
170
171
		@Override
172
		float getActiveY(MotionEvent ev) {
173
			try {
174
				return ev.getY(mActivePointerIndex);
175
			} catch (Exception e) {
176
				return ev.getY();
177
			}
178
		}
179
180
		@Override
181
		public boolean onTouchEvent(MotionEvent ev) {
182
			final int action = ev.getAction();
183
			switch (action & MotionEvent.ACTION_MASK) {
184
				case MotionEvent.ACTION_DOWN:
185
					mActivePointerId = ev.getPointerId(0);
186
					break;
187
				case MotionEvent.ACTION_CANCEL:
188
				case MotionEvent.ACTION_UP:
189
					mActivePointerId = INVALID_POINTER_ID;
190
					break;
191
				case MotionEvent.ACTION_POINTER_UP:
192
					final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
193
					final int pointerId = ev.getPointerId(pointerIndex);
194
					if (pointerId == mActivePointerId) {
195
						// This was our active pointer going up. Choose a new
196
						// active pointer and adjust accordingly.
197
						final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
198
						mActivePointerId = ev.getPointerId(newPointerIndex);
199
						mLastTouchX = ev.getX(newPointerIndex);
200
						mLastTouchY = ev.getY(newPointerIndex);
201
					}
202
					break;
203
			}
204
205
			mActivePointerIndex = ev.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId : 0);
206
			return super.onTouchEvent(ev);
207
		}
208
	}
209
210
	@TargetApi(8)
211
	private static class FroyoDetector extends EclairDetector {
212
213
		private final ScaleGestureDetector mDetector;
214
215
		// Needs to be an inner class so that we don't hit
216
		// VerifyError's on API 4.
217
		private final OnScaleGestureListener mScaleListener = new OnScaleGestureListener() {
218
219
			@Override
220
			public boolean onScale(ScaleGestureDetector detector) {
221
				mListener.onScale(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
222
				return true;
223
			}
224
225
			@Override
226
			public boolean onScaleBegin(ScaleGestureDetector detector) {
227
				return true;
228
			}
229
230
			@Override
231
			public void onScaleEnd(ScaleGestureDetector detector) {
232
				// NO-OP
233
			}
234
		};
235
236
		public FroyoDetector(Context context) {
237
			super(context);
238
			mDetector = new ScaleGestureDetector(context, mScaleListener);
239
		}
240
241
		@Override
242
		public boolean isScaling() {
243
			return mDetector.isInProgress();
244
		}
245
246
		@Override
247
		public boolean onTouchEvent(MotionEvent ev) {
248
			mDetector.onTouchEvent(ev);
249
			return super.onTouchEvent(ev);
250
		}
251
252
	}
253
}

+ 0 - 36
app/src/main/java/com/electric/chargingpile/zoom/ViewPagerFixed.java

@ -1,36 +0,0 @@
1
package com.electric.chargingpile.zoom;
2

3
import android.content.Context;
4
import android.util.AttributeSet;
5
import android.view.MotionEvent;
6

7
public class ViewPagerFixed extends android.support.v4.view.ViewPager {
8

9
    public ViewPagerFixed(Context context) {
10
        super(context);
11
    }
12

13
    public ViewPagerFixed(Context context, AttributeSet attrs) {
14
        super(context, attrs);
15
    }
16

17
    @Override
18
    public boolean onTouchEvent(MotionEvent ev) {
19
        try {
20
            return super.onTouchEvent(ev);
21
        } catch (IllegalArgumentException ex) {
22
            ex.printStackTrace();
23
        }
24
        return false;
25
    }
26

27
    @Override
28
    public boolean onInterceptTouchEvent(MotionEvent ev) {
29
        try {
30
            return super.onInterceptTouchEvent(ev);
31
        } catch (IllegalArgumentException ex) {
32
            ex.printStackTrace();
33
        }
34
        return false;
35
    }
36
}

完成接入特瓦特 · 07604be699 - Gogs: Go Git Service
Explorar el Código

完成接入特瓦特

hy %!s(int64=3) %!d(string=hace) años
padre
commit
07604be699

+ 2 - 1
app/src/main/AndroidManifest.xml

@ -3,7 +3,7 @@
3 3
    xmlns:tools="http://schemas.android.com/tools"
4 4
    package="com.electric.chargingpile"
5 5
    android:versionCode="103"
6
    android:versionName="3.5.17">
6
    android:versionName="3.5.18">
7 7
8 8
   <!-- <uses-permission android:name="android.permission.BLUETOOTH" />
9 9
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />-->
@ -74,6 +74,7 @@
74 74
    <!--适配Android R包可见性 结束-->
75 75
76 76
    <application
77
        android:extractNativeLibs="true"
77 78
        android:name=".application.MainApplication"
78 79
        android:allowBackup="true"
79 80
        android:icon="@drawable/icon626"

+ 233 - 5
app/src/main/java/com/electric/chargingpile/activity/ChargingPileActivity.java

@ -1,11 +1,14 @@
1 1
package com.electric.chargingpile.activity;
2 2
3
import android.Manifest;
3 4
import android.annotation.SuppressLint;
4 5
import android.content.Context;
5 6
import android.content.Intent;
7
import android.net.Uri;
6 8
import android.os.Bundle;
7 9
import android.text.Editable;
8 10
import android.text.TextWatcher;
11
import android.view.View;
9 12
import android.widget.EditText;
10 13
import android.widget.LinearLayout;
11 14
import android.widget.TextView;
@ -16,18 +19,37 @@ import androidx.appcompat.app.AppCompatActivity;
16 19
import androidx.recyclerview.widget.GridLayoutManager;
17 20
import androidx.recyclerview.widget.RecyclerView;
18 21
22
import com.blankj.utilcode.util.EmptyUtils;
23
import com.blankj.utilcode.util.LogUtils;
19 24
import com.electric.chargingpile.R;
20 25
import com.electric.chargingpile.adapter.LicensePlateHistoryAdapter;
26
import com.electric.chargingpile.application.MainApplication;
27
import com.electric.chargingpile.constant.UrlConstants;
21 28
import com.electric.chargingpile.manager.ProfileManager;
22 29
import com.electric.chargingpile.util.BarColorUtil;
30
import com.electric.chargingpile.util.JsonUtils;
31
import com.electric.chargingpile.util.LoadingDialog;
32
import com.electric.chargingpile.util.ToastUtil;
33
import com.electric.chargingpile.view.AlertDialogTwo;
23 34
import com.electric.chargingpile.view.ConfirmChargingDialog;
24 35
import com.google.zxing.client.android.constant.ChargingConstants;
25 36
import com.king.keyboard.KingKeyboard;
37
import com.tencent.bugly.crashreport.CrashReport;
38
import com.zhy.http.okhttp.OkHttpUtils;
39
import com.zhy.http.okhttp.callback.StringCallback;
40
41
import java.net.URLEncoder;
42
import java.util.List;
43
44
import okhttp3.Call;
45
import pub.devrel.easypermissions.AfterPermissionGranted;
46
import pub.devrel.easypermissions.AppSettingsDialog;
47
import pub.devrel.easypermissions.EasyPermissions;
26 48
27 49
/**
28 50
 *  特瓦特充电 详情页
29 51
 * */
30
public class ChargingPileActivity extends AppCompatActivity {
52
public class ChargingPileActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
31 53
32 54
    private KingKeyboard kingKeyboard;
33 55
    private int beforeCount = 0;
@ -40,7 +62,12 @@ public class ChargingPileActivity extends AppCompatActivity {
40 62
    private LinearLayout mKeyboardParent;
41 63
    private String pileId;
42 64
    private TextView tvCoding;
65
    private AlertDialogTwo alertDialog;
66
    private LoadingDialog loadingDialog;
43 67
68
    private static final int RC_TELL_PERM = 124;
69
    private static final int startInterface = 2;
70
    private static final String numType = "2";
44 71
45 72
    @Override
46 73
    protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
@ -60,8 +87,11 @@ public class ChargingPileActivity extends AppCompatActivity {
60 87
        rootView = findViewById(R.id.rootView);
61 88
        rvHistory = findViewById(R.id.rvHistory);
62 89
        tvCoding = findViewById(R.id.tvCoding);
63
90
        alertDialog = new AlertDialogTwo(this);
91
        loadingDialog = new LoadingDialog(this);
92
        loadingDialog.setCanceledOnTouchOutside(false);
64 93
        tvCoding.setText("充电桩编码:"+pileId);
94
65 95
    }
66 96
67 97
    private void initOnClick() {
@ -75,8 +105,9 @@ public class ChargingPileActivity extends AppCompatActivity {
75 105
        mAdapter.setList();
76 106
77 107
        mDialog.setOnClickListener(v->{
78
            //todo 进入充电流程
79
            ProfileManager.getInstance().setLicensePlateHistory(mDialog.getLicensePlate());
108
            String licensePlate = mDialog.getLicensePlate();
109
            startCharging(licensePlate);
110
            ProfileManager.getInstance().setLicensePlateHistory(licensePlate);
80 111
            mAdapter.setList();
81 112
        });
82 113
@ -86,6 +117,10 @@ public class ChargingPileActivity extends AppCompatActivity {
86 117
                Toast.makeText(this, "请输入车牌号", Toast.LENGTH_SHORT).show();
87 118
                return;
88 119
            }
120
            if (str.length() < 7){
121
                Toast.makeText(this, "请输入正确车牌号", Toast.LENGTH_SHORT).show();
122
                return;
123
            }
89 124
90 125
            mDialog.setLicensePlate(str);
91 126
            mDialog.show(getSupportFragmentManager());
@ -93,14 +128,17 @@ public class ChargingPileActivity extends AppCompatActivity {
93 128
        });
94 129
95 130
        rootView.setOnClickListener(v->{
96
            kingKeyboard.hide();
131
            if (kingKeyboard.isShow())
132
                kingKeyboard.hide();
97 133
        });
98 134
    }
99 135
100 136
    private void registerKingKeyboard(){
101 137
        kingKeyboard = new KingKeyboard(this,mKeyboardParent);
102 138
        //然后将EditText注册到KingKeyboard即可
139
        kingKeyboard.setBringToFront(true);
103 140
        kingKeyboard.register(editText, KingKeyboard.KeyboardType.LICENSE_PLATE_PROVINCE);
141
104 142
        editText.addTextChangedListener(new TextWatcher() {
105 143
            @Override
106 144
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@ -141,6 +179,196 @@ public class ChargingPileActivity extends AppCompatActivity {
141 179
        super.onDestroy();
142 180
        kingKeyboard.onDestroy();
143 181
    }
182
    private void startCharging(String result) {
183
        LogUtils.e(result);
184
        loadingDialog.show();
185
        OkHttpUtils.get().url(UrlConstants.START_CHARGING_URL)
186
                .addParams(com.electric.chargingpile.constant.ChargingConstants.FLAG, numType)
187
                .addParams(com.electric.chargingpile.constant.ChargingConstants.URL, URLEncoder.encode(pileId))
188
                .addParams(com.electric.chargingpile.constant.ChargingConstants.USERID, MainApplication.userId)
189
                .addParams(com.electric.chargingpile.constant.ChargingConstants.PWD, MainApplication.userPassword)
190
                .addParams(com.electric.chargingpile.constant.ChargingConstants.PLATE_NUM, result)
191
                .addParams("type", "1")
192
                .build().connTimeOut(30000).readTimeOut(30000).execute(new StringCallback() {
193
            @Override
194
            public void onError(Call call, Exception e) {
195
                ToastUtil.showToast(getApplicationContext(), "网络异常,请检查您的网络连接", Toast.LENGTH_SHORT);
196
                CrashReport.postCatchedException(e);
197
            }
198
199
            @Override
200
            public void onResponse(String response) {
201
                LogUtils.e(response);
202
                if (EmptyUtils.isNotEmpty(response)) {
203
                    dismissDialog();
204
                    handlingOperations(response, startInterface);
205
                }
206
207
            }
208
        });
209
    }
210
211
    private void handlingOperations(String response, int interfaceType) {
212
        String rtnCode = com.google.zxing.client.android.JsonUtils.getKeyResult(response, "rtnCode");
213
        String rtnMsg = com.google.zxing.client.android.JsonUtils.getKeyResult(response, "rtnMsg");
214
        switch (rtnCode) {
215
            case "01":
216
                if (interfaceType == startInterface) {
217
                    String data = JsonUtils.getKeyResult(response, "data");
218
                    String orderid = JsonUtils.getKeyResult(data, "orderId");
219
                    Intent intent = new Intent(getApplicationContext(), TLDLoadingActivity.class);
220
                    intent.putExtra(com.electric.chargingpile.constant.ChargingConstants.ORDERID, orderid);
221
                    startActivity(intent);
222
                    finish();
223
                }
224
                break;
225
            case "304":
226
                alertDialog.builder()
227
                        .setMsg(rtnMsg)
228
                        .setPositiveButton("去充值", new View.OnClickListener() {
229
                            @Override
230
                            public void onClick(View v) {
231
                                Intent intent = new Intent(getApplicationContext(), AccountRechargeActivity.class);
232
                                startActivity(intent);
233
                            }
234
                        })
235
//                        .setNegativeButton("开通免密支付", new View.OnClickListener() {
236
//                    @Override
237
//                    public void onClick(View v) {
238
//                        Intent intent = new Intent(getApplicationContext(),NonSecretSeettingActivity.class);
239
//                        Uri uri = Uri.parse("chongdianzhuang://");
240
//                        intent.setData(uri);
241
//                        startActivity(intent);
242
//                    }
243
//                })
244
                        .show();
245
                break;
246
            case "305":
247
                alertDialog.builder()
248
                        .setMsg(rtnMsg)
249
                        .setPositiveButton("联系客服", new View.OnClickListener() {
250
                            @Override
251
                            public void onClick(View v) {
252
                                tellTask();
253
                            }
254
                        }).setNegativeButton("取消", new View.OnClickListener() {
255
                    @Override
256
                    public void onClick(View v) {
257
                    }
258
                }).show();
259
                break;
260
            case "309":
261
                alertDialog.builder()
262
                        .setMsg(rtnMsg)
263
                        .setPositiveButton("联系客服", new View.OnClickListener() {
264
                            @Override
265
                            public void onClick(View v) {
266
                                tellTask();
267
                            }
268
                        }).setNegativeButton("取消", new View.OnClickListener() {
269
                    @Override
270
                    public void onClick(View v) {
271
                    }
272
                }).show();
273
                break;
274
            case "306":
275
                //跳转到充电详情界面
276
                String data306 = JsonUtils.getKeyResult(response, "data");
277
                String orderid = JsonUtils.getKeyResult(data306, "orderId");
278
                Intent intent306 = new Intent(getApplicationContext(), ChargingStatusActivity.class);
279
                intent306.putExtra(com.electric.chargingpile.constant.ChargingConstants.ORDERID, orderid);
280
                startActivity(intent306);
281
                finish();
282
                break;
283
            case "307":
284
                alertDialog.builder()
285
                        .setMsg(rtnMsg)
286
                        .setPositiveButton("去充值", new View.OnClickListener() {
287
                            @Override
288
                            public void onClick(View v) {
289
                                Intent intent = new Intent(getApplicationContext(), AccountRechargeActivity.class);
290
                                startActivity(intent);
291
                            }
292
                        }).show();
293
                break;
294
            case "311":
295
                alertDialog.builder()
296
                        .setMsg(rtnMsg)
297
                        .setPositiveButton("开通免密支付", new View.OnClickListener() {
298
                            @Override
299
                            public void onClick(View v) {
300
                                Intent intent = new Intent(getApplicationContext(), NonSecretSeettingActivity.class);
301
                                Uri uri = Uri.parse("chongdianzhuang://");
302
                                intent.setData(uri);
303
                                startActivity(intent);
304
                            }
305
                        }).show();
306
                break;
307
            case "1800":
308
                String data1800 = JsonUtils.getKeyResult(response, "data");
309
                String pileId = JsonUtils.getKeyResult(data1800, "pileId");
310
                Intent intent1800 = new Intent(getApplicationContext(), SelectPileActivity.class);
311
                intent1800.putExtra(com.electric.chargingpile.constant.ChargingConstants.ORDERID, pileId);
312
                startActivity(intent1800);
313
                break;
314
315
            case "1000":
316
                String data1000 = JsonUtils.getKeyResult(response, "data");
317
                String pileIds = JsonUtils.getKeyResult(data1000, "pileId");
318
                ChargingPileActivity.actionStart(this,pileIds);
319
                break;
320
            default:
321
                ToastUtil.showToast(getApplicationContext(), rtnMsg, Toast.LENGTH_SHORT);
322
                break;
323
        }
324
    }
325
326
    @AfterPermissionGranted(RC_TELL_PERM)
327
    public void tellTask() {
328
        if (hasTellPermission()) {
329
            // Have permission, do the thing!
330
//            Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show();
331
            String telNum = "4008810405";
332
            Intent intent = new Intent();
333
            intent.setAction("android.intent.action.CALL");
334
            intent.addCategory("android.intent.category.DEFAULT");
335
            intent.setData(Uri.parse("tel:" + telNum));
336
            ChargingPileActivity.this.startActivity(intent);
337
338
        } else {
339
            LogUtils.e("@@@@@@@");
340
            // Ask for one permission
341
            EasyPermissions.requestPermissions(
342
                    this,
343
                    "该功能需要开启拨号权限,是否前往开启?",
344
                    RC_TELL_PERM,
345
                    Manifest.permission.CALL_PHONE);
346
        }
347
    }
348
349
    private boolean hasTellPermission() {
350
        return EasyPermissions.hasPermissions(this, Manifest.permission.CALL_PHONE);
351
    }
352
353
    @Override
354
    public void onPermissionsGranted(int requestCode, List<String> perms) {
355
356
    }
357
358
    @Override
359
    public void onPermissionsDenied(int requestCode, List<String> perms) {
360
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
361
            new AppSettingsDialog.Builder(ChargingPileActivity.this).build().show();
362
        }
363
    }
364
365
    private void dismissDialog() {
366
        if (this != null && !isFinishing()) {
367
            if (loadingDialog.isShowing()) {
368
                loadingDialog.dismiss();
369
            }
370
        }
371
    }
144 372
145 373
146 374
    public static void actionStart(Context context,String pileId){

+ 47 - 5
app/src/main/java/com/electric/chargingpile/activity/ChargingStatusActivity.java

@ -51,6 +51,7 @@ import com.tencent.bugly.crashreport.CrashReport;
51 51
import com.umeng.analytics.MobclickAgent;
52 52
import com.zhy.http.okhttp.OkHttpUtils;
53 53
import com.zhy.http.okhttp.callback.StringCallback;
54
import com.zhy.http.okhttp.request.RequestCall;
54 55
55 56
import java.net.URLEncoder;
56 57
import java.text.SimpleDateFormat;
@ -70,7 +71,7 @@ import okhttp3.Call;
70 71
public class ChargingStatusActivity extends Activity implements View.OnClickListener {
71 72
    private static final String TAG = "ChargingStatusActivity";
72 73
    private ImageView iv_charging, iv_back, iv_activity;
73
    private TextView tv_charging, tv_stop, tv_activity;
74
    private TextView tv_charging, tv_stop;
74 75
    private TextView tv_chongdianliang, tv_zhuang_num, tv_jindu, tv_dianya, tv_dianliu, tv_time, tv_cost, tv_help;
75 76
    String result, stubGroupId;
76 77
    CircleProgressBar bar;
@ -116,6 +117,7 @@ public class ChargingStatusActivity extends Activity implements View.OnClickList
116 117
    private LinearLayout layoutCarCertificate;
117 118
    private ImageView imgA,imgV,imgProgrees;
118 119
    private TextView certifiedCarOwner;
120
    private TextView tv_overage;
119 121
120 122
121 123
    @Override
@ -138,6 +140,7 @@ public class ChargingStatusActivity extends Activity implements View.OnClickList
138 140
        // start timer task
139 141
        setTimerTask();
140 142
        msgStatus();
143
        getUserIntegral();
141 144
    }
142 145
143 146
@ -158,8 +161,6 @@ public class ChargingStatusActivity extends Activity implements View.OnClickList
158 161
                    String icon = JsonUtils.getKeyResult(response, "icon");
159 162
                    String url = JsonUtils.getKeyResult(response, "url");
160 163
                    if (status.equals("1")) {
161
//                        tv_activity.setVisibility(View.VISIBLE);
162
//                        tv_activity.setText(message);
163 164
                        Picasso.with(MainApplication.context)
164 165
                                .load(icon)
165 166
                                .into(iv_activity);
@ -205,8 +206,6 @@ public class ChargingStatusActivity extends Activity implements View.OnClickList
205 206
        iv_activity = (ImageView) findViewById(R.id.iv_activity);
206 207
        iv_back.setOnClickListener(this);
207 208
        iv_activity.setOnClickListener(this);
208
        tv_activity = (TextView) findViewById(R.id.tv_activity);
209
        tv_activity.setOnClickListener(this);
210 209
211 210
        tv_help = findViewById(R.id.tv_help);
212 211
        tv_help.setOnClickListener(this);
@ -226,6 +225,7 @@ public class ChargingStatusActivity extends Activity implements View.OnClickList
226 225
        tv_dianya = (TextView) findViewById(R.id.tv_dianya);
227 226
        tv_dianliu = (TextView) findViewById(R.id.tv_dianliu);
228 227
        tv_time = (TextView) findViewById(R.id.tv_time);
228
        tv_overage = (TextView) findViewById(R.id.tv_overage);
229 229
        layoutCarCertificate = findViewById(R.id.layoutCarCertificate);
230 230
231 231
        imgA = findViewById(R.id.imgA);
@ -649,6 +649,48 @@ public class ChargingStatusActivity extends Activity implements View.OnClickList
649 649
        }
650 650
    }
651 651
652
    private void getUserIntegral() {
653
        String replace = null;
654
        try {
655
            long appTime1 = System.currentTimeMillis() / 1000;
656
            long updatetime = appTime1 - MainMapActivity.cha - 3;
657
            String token = String.valueOf(updatetime);
658
            String encode_token = DES3.encode(token);
659
            replace = URLEncoder.encode(encode_token);
660
        } catch (Exception e) {
661
            e.printStackTrace();
662
        }
663
        String url = MainApplication.url + "/zhannew/basic/web/index.php/member/get-score?id=" + MainApplication.userId +
664
                "&phone=" + MainApplication.userPhone + "&password=" + URLEncoder.encode(MainApplication.userPassword) + "&token=" + replace;
665
        RequestCall call = OkHttpUtils.get().url(url).build();
666
        call.execute(new StringCallback() {
667
            @Override
668
            public void onError(Call call, Exception e) {
669
670
            }
671
672
            @Override
673
            public void onResponse(String response) {
674
//                Log.e(TAG, "onResponse:getUserIntegral= "+response );
675
                String rtnCode = JsonUtils.getKeyResult(response, "rtnCode");
676
                if (null != rtnCode && rtnCode.equals("01")) {
677
                    String rtnMsg = JsonUtils.getKeyResult(response, "rtnMsg");
678
                    String money = JsonUtils.getKeyResult(rtnMsg, "money");
679
                    if (null != money && !money.equals("")) {
680
                        tv_overage.setText(money);
681
                    }
682
                } else {
683
                    ProfileManager.getInstance().setUsername(getApplicationContext(), "");
684
                    MainApplication.userPhone = "";
685
                    Toast.makeText(getApplicationContext(), "登录已失效,请重新登录", Toast.LENGTH_SHORT).show();
686
                    startActivity(new Intent(getApplicationContext(), LoginActivity.class));
687
                }
688
            }
689
        });
690
691
    }
692
693
652 694
    private void chargingChangeStatus(String third_id) {
653 695
        String url = MainApplication.url + "/zhannew/basic/web/index.php/kazuma/offline";
654 696
        OkHttpUtils.get().url(url)

+ 11 - 5
app/src/main/java/com/electric/chargingpile/activity/ConfirmOrderActivity.java

@ -59,6 +59,8 @@ public class ConfirmOrderActivity extends AppCompatActivity implements View.OnCl
59 59
    private LoadingDialog mDialog;
60 60
    private int try_count=0;
61 61
    private int delayedSettlementCount=0;
62
    private RelativeLayout rl_number_plate;
63
    private TextView tv_num_plate;
62 64
63 65
    @Override
64 66
    protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
@ -172,6 +174,8 @@ public class ConfirmOrderActivity extends AppCompatActivity implements View.OnCl
172 174
        rl_end_info=findViewById(R.id.rl_end_info);
173 175
174 176
        tv_gocomment = findViewById(R.id.tv_gocomment);
177
        rl_number_plate = findViewById(R.id.rl_number_plate);
178
        tv_num_plate = findViewById(R.id.tv_num_plate);
175 179
176 180
        iv_back.setOnClickListener(this);
177 181
        layoutRed.setOnClickListener(this);
@ -193,12 +197,14 @@ public class ConfirmOrderActivity extends AppCompatActivity implements View.OnCl
193 197
            tv_charging_time.setText(mChargingBean.getTimeCharge());
194 198
            tv_charging_liang.setText(mChargingBean.getPower()+"度");
195 199
196
           /* if (TextUtils.isEmpty(mChargingBean.getEndInfo())) {
197
                rl_end_info.setVisibility(View.GONE);
200
            String plate_number = mChargingBean.getPlate_number();
201
202
            if (plate_number == null || plate_number.equals("")){
203
                rl_number_plate.setVisibility(View.GONE);
198 204
            }else{
199
                tv_tishi.setText(mChargingBean.getEndInfo());
200
                rl_end_info.setVisibility(View.VISIBLE);
201
            }*/
205
                rl_number_plate.setVisibility(View.VISIBLE);
206
                tv_num_plate.setText(plate_number);
207
            }
202 208
        }
203 209
    }
204 210

+ 3 - 3
app/src/main/java/com/electric/chargingpile/activity/MainMapActivity.java

@ -498,7 +498,8 @@ public class MainMapActivity extends Activity implements LocationSource, AMapLoc
498 498
                                if (key.length - 1 > 2) {
499 499
                                    permissionTask();
500 500
                                } else {
501
                                    dialogup();
501
//                                    dialogup();
502
                                    permissionTask();
502 503
                                }
503 504
                            }
504 505
@ -3430,6 +3431,7 @@ public class MainMapActivity extends Activity implements LocationSource, AMapLoc
3430 3431
    private void dialogup_other() {
3431 3432
        int code = Integer.parseInt(now_versionCode);
3432 3433
        if (code - getVersionCode(getApplication()) > 0) {
3434
//           if(true){
3433 3435
            alterDialog = new AlertDialogUpdate(MainMapActivity.this);
3434 3436
3435 3437
            alterDialog.builder()
@ -3457,8 +3459,6 @@ public class MainMapActivity extends Activity implements LocationSource, AMapLoc
3457 3459
        }
3458 3460
    }
3459 3461
    private void downLoadFile() {
3460
        String url = "http://cdz.evcharge.cc/app/app.apk";
3461
3462 3462
        showProgressWindow();
3463 3463
        ToastUtil.showToast(getApplicationContext(), "正在下载中", Toast.LENGTH_SHORT);
3464 3464
        OkHttpUtils.get().url("http://cdz.evcharge.cc/app/app.apk").build()

+ 18 - 7
app/src/main/java/com/electric/chargingpile/activity/OderDetailsActivity.java

@ -67,6 +67,9 @@ public class OderDetailsActivity extends Activity implements View.OnClickListene
67 67
    private LinearLayout red_paper_bag_bottom;
68 68
    private RelativeLayout rl_end_info;
69 69
    private String name;
70
    private TextView tv_num_plate;
71
    private RelativeLayout rl_number_plate;
72
    private String plate_number;
70 73
71 74
    @Override
72 75
    protected void onCreate(Bundle savedInstanceState) {
@ -89,6 +92,10 @@ public class OderDetailsActivity extends Activity implements View.OnClickListene
89 92
        tv_pinglun = (TextView) findViewById(R.id.tv_pinglun);
90 93
        tv_gocomment = (TextView) findViewById(R.id.tv_gocomment);
91 94
        red_paper_bag_bottom = findViewById(R.id.red_paper_bag_bottom);
95
96
        rl_number_plate = findViewById(R.id.rl_number_plate);
97
        tv_num_plate = findViewById(R.id.tv_num_plate);
98
92 99
        iv = (ImageView) findViewById(R.id.iv);
93 100
94 101
        tv_gocomment.setOnClickListener(this);
@ -120,21 +127,23 @@ public class OderDetailsActivity extends Activity implements View.OnClickListene
120 127
121 128
        tv_tishi = (TextView) findViewById(R.id.tv_tishi);
122 129
        rl_end_info = (RelativeLayout) findViewById(R.id.rl_end_info);
123
//        if (ChargingStatusActivity.no == 0){
124
//            tv_tishi.setVisibility(View.GONE);
125
//        }else{
130
126 131
        if (end_info.equals("")) {
127 132
            rl_end_info.setVisibility(View.GONE);
128 133
        } else {
129 134
            rl_end_info.setVisibility(View.VISIBLE);
130 135
            tv_tishi.setText(end_info);
131 136
        }
132
//            tv_tishi.setVisibility(View.VISIBLE);
133
//            tv_tishi.setText(end_info);
134
//        }
137
138
        if (plate_number == null || plate_number.equals("")){
139
            rl_number_plate.setVisibility(View.GONE);
140
        }else{
141
            rl_number_plate.setVisibility(View.VISIBLE);
142
            tv_num_plate.setText(plate_number);
143
        }
144
135 145
136 146
        if (EmptyUtils.isNotEmpty(activeUrl)) {
137
//            ToastUtil.showToast(getApplicationContext(),activeUrl,Toast.LENGTH_LONG);
138 147
            new Handler().postDelayed(new Runnable() {
139 148
                @Override
140 149
                public void run() {
@ -165,6 +174,8 @@ public class OderDetailsActivity extends Activity implements View.OnClickListene
165 174
        zhan_idc = chargingBean.getZhanID();
166 175
        order_id = chargingBean.getOrderId();
167 176
        out_order_id = chargingBean.getOutOrderId();
177
        plate_number = chargingBean.getPlate_number();
178
168 179
//        settlement = getIntent().getStringExtra("settlement");
169 180
        name = chargingBean.getZhanname();
170 181
        serviceCharge = chargingBean.getServiceMoney();

+ 3 - 1
app/src/main/java/com/electric/chargingpile/application/MainApplication.java

@ -52,7 +52,6 @@ import org.jetbrains.annotations.NotNull;
52 52

53 53
import java.io.BufferedReader;
54 54
import java.io.BufferedWriter;
55
import java.io.File;
56 55
import java.io.IOException;
57 56
import java.io.InputStreamReader;
58 57
import java.io.OutputStreamWriter;
@ -187,6 +186,9 @@ public class MainApplication extends MultiDexApplication implements CameraXConfi
187 186
        initImageLoader(getApplicationContext());
188 187

189 188
        try {
189
            if (BuildConfig.DEBUG){
190
                OkHttpUtils.getInstance().debug("hyc",true);
191
            }
190 192
            OkHttpUtils.getInstance().setCertificates(getAssets().open("ca.crt"));
191 193
            OkHttpUtils.getInstance().setCertificates();
192 194
        } catch (IOException e) {

+ 1 - 0
app/src/main/java/com/electric/chargingpile/constant/ChargingConstants.java

@ -6,5 +6,6 @@ public interface ChargingConstants {
6 6
    String URL = "url";
7 7
    String FLAG = "flag";
8 8
    String ORDERID = "orderid";
9
    String PLATE_NUM = "plate_num";
9 10
    String TYPE = "type";
10 11
}

+ 9 - 0
app/src/main/java/com/electric/chargingpile/data/ChargingBean.java

@ -44,6 +44,15 @@ public class ChargingBean implements Serializable {
44 44
    private String serviceMoney;
45 45
    private String totalMoney;
46 46
    private String redMoney;
47
    private String plate_number;
48
49
    public String getPlate_number() {
50
        return plate_number;
51
    }
52
53
    public void setPlate_number(String plate_number) {
54
        this.plate_number = plate_number;
55
    }
47 56
48 57
    public String getOrderId() {
49 58
        return orderId;

+ 1 - 2
app/src/main/java/com/electric/chargingpile/manager/ProfileManager.java

@ -742,11 +742,10 @@ public class ProfileManager {
742 742

743 743
    public void setLicensePlateHistory(String str) {
744 744
        ArrayList<String> list = getLicensePlateHistory();
745
        list.remove(str); //除重
745 746
        if (list.size() >= 6){
746 747
            list.remove(list.size() -1 );
747 748
        }
748

749
        list.remove(str);
750 749
        list.add(0,str);
751 750
        PreferenceManager.getInstance(MainApplication.context).putString(KEY_LICENSE_PLATE_HISTORY, new Gson().toJson(list));
752 751
    }

+ 1 - 0
app/src/main/java/com/electric/chargingpile/view/UpdateDialog.java

@ -2,6 +2,7 @@ package com.electric.chargingpile.view;
2 2
3 3
import android.app.Dialog;
4 4
import android.content.Context;
5
import android.util.Log;
5 6
import android.view.Display;
6 7
import android.view.LayoutInflater;
7 8
import android.view.View;

+ 1 - 1
app/src/main/res/layout/activity_charging_pile.xml

@ -159,7 +159,7 @@
159 159
    </androidx.constraintlayout.widget.ConstraintLayout>
160 160
161 161
    <View
162
        android:layout_width="1dp"
162
        android:layout_width="match_parent"
163 163
        android:layout_height="0dp"
164 164
        android:layout_weight="1" />
165 165

+ 34 - 24
app/src/main/res/layout/activity_charging_status.xml

@ -231,16 +231,6 @@
231 231
                    app:wlv_waveColor="#3fffffff"
232 232
                    app:wlv_wave_background_Color="#00ffffff" />
233 233
234
235
                <!--<com.loonggg.circleprogressbarlibrary.view.CircleProgressBar-->
236
                <!--android:id="@+id/pb"-->
237
                <!--android:layout_width="143dp"-->
238
                <!--android:layout_height="143dp"-->
239
                <!--android:visibility="gone"-->
240
                <!--android:layout_centerInParent="true"-->
241
                <!--loonggg:bgProgressBarColor="#efefef"-->
242
                <!--loonggg:circleStrokeWidth="5dp" />-->
243
244 234
                <LinearLayout
245 235
                    android:layout_width="wrap_content"
246 236
                    android:layout_height="wrap_content"
@ -347,10 +337,43 @@
347 337
348 338
                </RelativeLayout>
349 339
340
                <View
341
                    android:layout_width="0.5dp"
342
                    android:layout_height="match_parent"
343
                    android:background="@color/ui_6d" />
344
345
                <RelativeLayout
346
                    android:layout_width="0dp"
347
                    android:layout_height="match_parent"
348
                    android:layout_weight="1">
349
350
                    <TextView
351
                        android:layout_width="wrap_content"
352
                        android:layout_height="wrap_content"
353
                        android:layout_alignParentTop="true"
354
                        android:layout_centerHorizontal="true"
355
                        android:text="账户余额"
356
                        android:textColor="@color/ui_68"
357
                        android:textSize="12sp" />
358
359
                    <TextView
360
                        android:id="@+id/tv_overage"
361
                        android:layout_width="wrap_content"
362
                        android:layout_height="wrap_content"
363
                        android:layout_alignParentBottom="true"
364
                        android:layout_centerHorizontal="true"
365
                        android:layout_centerVertical="true"
366
                        android:text="--"
367
                        android:textColor="@color/ui_62"
368
                        android:textSize="21sp" />
369
370
                </RelativeLayout>
371
350 372
            </LinearLayout>
351 373
352 374
353 375
            <RelativeLayout
376
                android:paddingBottom="30dp"
354 377
                android:layout_width="match_parent"
355 378
                android:layout_height="match_parent">
356 379
                <LinearLayout
@ -385,6 +408,7 @@
385 408
386 409
                </LinearLayout>
387 410
                <ImageView
411
                    tools:src="@drawable/ic_charging_pile"
388 412
                    tools:visibility="visible"
389 413
                    android:id="@+id/iv_activity"
390 414
                    android:layout_width="wrap_content"
@ -396,20 +420,6 @@
396 420
                    android:visibility="gone" />
397 421
398 422
                <TextView
399
                    tools:visibility="visible"
400
                    android:id="@+id/tv_activity"
401
                    android:layout_width="wrap_content"
402
                    android:layout_height="wrap_content"
403
                    android:layout_below="@+id/tv_stop"
404
                    android:layout_centerHorizontal="true"
405
                    android:paddingTop="20dp"
406
                    android:paddingBottom="15dp"
407
                    android:text=""
408
                    android:textColor="#ffa900"
409
                    android:textSize="14sp"
410
                    android:visibility="visible" />
411
412
                <TextView
413 423
                    android:layout_centerHorizontal="true"
414 424
                    android:textStyle="bold"
415 425
                    android:id="@+id/tv_stop"

+ 28 - 0
app/src/main/res/layout/activity_oder_details.xml

@ -273,6 +273,34 @@
273 273
                android:textSize="14sp" />
274 274
275 275
        </RelativeLayout>
276
        <RelativeLayout
277
            tools:visibility="visible"
278
            android:visibility="gone"
279
            android:id="@+id/rl_number_plate"
280
            android:layout_width="match_parent"
281
            android:layout_height="wrap_content"
282
            android:layout_marginTop="13dp">
283
284
            <TextView
285
                android:layout_width="wrap_content"
286
                android:layout_height="wrap_content"
287
                android:layout_alignParentLeft="true"
288
                android:layout_marginLeft="15dp"
289
                android:text="充电车辆"
290
                android:textColor="@color/ui_68"
291
                android:textSize="14sp" />
292
293
            <TextView
294
                android:id="@+id/tv_num_plate"
295
                android:layout_width="wrap_content"
296
                android:layout_height="wrap_content"
297
                android:layout_alignParentRight="true"
298
                android:layout_marginRight="15dp"
299
                tools:text="--"
300
                android:textColor="@color/ui_68"
301
                android:textSize="14sp" />
302
303
        </RelativeLayout>
276 304
277 305
278 306
    </LinearLayout>

+ 29 - 0
app/src/main/res/layout/activity_submit_orders.xml

@ -282,6 +282,35 @@
282 282
                android:textSize="14sp" />
283 283
284 284
        </RelativeLayout>
285
286
        <RelativeLayout
287
            tools:visibility="visible"
288
            android:visibility="gone"
289
            android:id="@+id/rl_number_plate"
290
            android:layout_width="match_parent"
291
            android:layout_height="wrap_content"
292
            android:layout_marginTop="13dp">
293
294
            <TextView
295
                android:layout_width="wrap_content"
296
                android:layout_height="wrap_content"
297
                android:layout_alignParentLeft="true"
298
                android:layout_marginLeft="15dp"
299
                android:text="充电车辆"
300
                android:textColor="@color/ui_68"
301
                android:textSize="14sp" />
302
303
            <TextView
304
                android:id="@+id/tv_num_plate"
305
                android:layout_width="wrap_content"
306
                android:layout_height="wrap_content"
307
                android:layout_alignParentRight="true"
308
                android:layout_marginRight="15dp"
309
                tools:text="--"
310
                android:textColor="@color/ui_68"
311
                android:textSize="14sp" />
312
313
        </RelativeLayout>
285 314
    </LinearLayout>
286 315
287 316
    <TextView

+ 2 - 2
app/src/main/res/layout/layout_update_dialog.xml

@ -21,9 +21,9 @@
21 21
    <com.qmuiteam.qmui.widget.QMUIProgressBar
22 22
        android:id="@+id/qMUIProgressBar"
23 23
        android:layout_width="match_parent"
24
        android:layout_height="16dp"
24
        android:layout_height="12dp"
25 25
        android:textColor="@color/lvse"
26
        android:textSize="16sp"
26
        android:textSize="12sp"
27 27
        android:layout_marginBottom="20dp"
28 28
        android:layout_marginLeft="16dp"
29 29
        android:layout_marginRight="16dp"