n>
		case PathMenu.LEFT_BOTTOM:// 左下
453
			params1.gravity = Gravity.LEFT | Gravity.BOTTOM;
454
			params.gravity = Gravity.LEFT | Gravity.BOTTOM;
455
			mPathMenuLayout.setArc(270, 360, position);
456
			break;
457
		case PathMenu.RIGHT_TOP:// 右上
458
			params1.gravity = Gravity.RIGHT | Gravity.TOP;
459
			params.gravity = Gravity.RIGHT | Gravity.TOP;
460
			mPathMenuLayout.setArc(90, 180, position);
461
			break;
462
		case PathMenu.RIGHT_CENTER:// 右中
463
			params1.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
464
			params.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
465
			mPathMenuLayout.setArc(90, 270, position);
466
			break;
467
		case PathMenu.RIGHT_BOTTOM:// 右下
468
			params1.gravity = Gravity.BOTTOM | Gravity.RIGHT;
469
			params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
470
			mPathMenuLayout.setArc(180, 270, position);
471
			break;
472
473
		case PathMenu.CENTER_TOP:// 上中
474
			params1.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
475
			params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
476
			mPathMenuLayout.setArc(0, 180, position);
477
			break;
478
		case PathMenu.CENTER_BOTTOM:// 下中
479
			params1.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
480
			params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
481
			mPathMenuLayout.setArc(180, 360, position);
482
			break;
483
		case PathMenu.CENTER:
484
			params1.gravity = Gravity.CENTER;
485
			params.gravity = Gravity.CENTER;
486
			mPathMenuLayout.setArc(0, 360, position);
487
			break;
488
		}
489
		controlLayout.setLayoutParams(params1);
490
		mPathMenuLayout.setLayoutParams(params);
491
492
	}
493
494
	int statusBarHeight = 0;
495
496
	public int getStatusBarHeight() {
497
		if (statusBarHeight <= 0) {
498
			int resourceId = getResources().getIdentifier("status_bar_height",
499
					"dimen", "android");
500
			if (resourceId > 0) {
501
				statusBarHeight = getResources().getDimensionPixelSize(
502
						resourceId);
503
			}
504
		}
505
		return statusBarHeight;
506
	}
507
508
	public void hidePathMenu() {
509
		try {
510
			setVisibility(View.GONE);
511
		} catch (final IllegalArgumentException e) {
512
			Log.e("PathMenu", "hidePathMenu error!");
513
		}
514
	}
515
}

+ 39 - 0
ipu-pathmenu/src/com/ai/ipu/ipu_pathmenu/PathMenuActivity.java

@ -0,0 +1,39 @@
1
package com.ai.ipu.ipu_pathmenu;
2
3
import android.app.Activity;
4
import android.content.Intent;
5
import android.os.Bundle;
6
import android.view.View;
7
import android.view.View.OnClickListener;
8
import android.widget.Button;
9
10
public class PathMenuActivity extends Activity {
11
12
	@Override
13
	protected void onCreate(Bundle savedInstanceState) {
14
		super.onCreate(savedInstanceState);
15
		setContentView(R.layout.activity_float);
16
		Button btnOpen = (Button) findViewById(R.id.btnOpenFloat);
17
		Button btnClose = (Button) findViewById(R.id.btnCloseFloat);
18
19
		btnOpen.setOnClickListener(mClickListener);
20
		btnClose.setOnClickListener(mClickListener);
21
22
	}
23
24
	OnClickListener mClickListener = new OnClickListener() {
25
26
		@Override
27
		public void onClick(View v) {
28
			if (v.getId() == R.id.btnOpenFloat) {
29
				Intent intent = new Intent(PathMenuActivity.this,
30
						PathMenuService.class);
31
				startService(intent);
32
			} else if (v.getId() == R.id.btnCloseFloat) {
33
				Intent intent = new Intent(PathMenuActivity.this,
34
						PathMenuService.class);
35
				stopService(intent);
36
			}
37
		}
38
	};
39
}

+ 495 - 0
ipu-pathmenu/src/com/ai/ipu/ipu_pathmenu/PathMenuLayout.java

@ -0,0 +1,495 @@
1
package com.ai.ipu.ipu_pathmenu;
2
3
import android.content.Context;
4
import android.content.res.TypedArray;
5
import android.graphics.Rect;
6
import android.util.AttributeSet;
7
import android.view.View;
8
import android.view.ViewGroup;
9
import android.view.animation.AccelerateInterpolator;
10
import android.view.animation.Animation;
11
import android.view.animation.Animation.AnimationListener;
12
import android.view.animation.AnimationSet;
13
import android.view.animation.Interpolator;
14
import android.view.animation.LinearInterpolator;
15
import android.view.animation.OvershootInterpolator;
16
import android.view.animation.RotateAnimation;
17
18
/**
19
 * 子菜单项布局
20
 * 
21
 * @author 何凌波
22
 *
23
 */
24
public class PathMenuLayout extends ViewGroup {
25
	private int mChildSize; // 子菜单项大小相同
26
	private int mChildPadding = 5;
27
	private int mLayoutPadding = 10;
28
	public static final float DEFAULT_FROM_DEGREES = 270.0f;
29
	public static final float DEFAULT_TO_DEGREES = 360.0f;
30
	private float mFromDegrees = DEFAULT_FROM_DEGREES;
31
	private float mToDegrees = DEFAULT_TO_DEGREES;
32
	private static final int MIN_RADIUS = 100;
33
	private int mRadius;// 中心菜单圆点到子菜单中心的距离
34
	private boolean mExpanded = false;
35
	private int position = PathMenu.LEFT_TOP;
36
	private int centerX = 0;
37
	private int centerY = 0;
38
39
	public void computeCenterXY(int position) {
40
		switch (position) {
41
		case PathMenu.LEFT_TOP:// 左上
42
			centerX = getWidth() / 2 - getRadiusAndPadding();
43
			centerY = getHeight() / 2 - getRadiusAndPadding();
44
			break;
45
		case PathMenu.LEFT_CENTER:// 左中
46
			centerX = getWidth() / 2 - getRadiusAndPadding();
47
			centerY = getHeight() / 2;
48
			break;
49
		case PathMenu.LEFT_BOTTOM:// 左下
50
			centerX = getWidth() / 2 - getRadiusAndPadding();
51
			centerY = getHeight() / 2 + getRadiusAndPadding();
52
			break;
53
		case PathMenu.CENTER_TOP:// 上中
54
			centerX = getWidth() / 2;
55
			centerY = getHeight() / 2 - getRadiusAndPadding();
56
			break;
57
		case PathMenu.CENTER_BOTTOM:// 下中
58
			centerX = getWidth() / 2;
59
			centerY = getHeight() / 2 + getRadiusAndPadding();
60
			break;
61
		case PathMenu.RIGHT_TOP:// 右上
62
			centerX = getWidth() / 2 + getRadiusAndPadding();
63
			centerY = getHeight() / 2 - getRadiusAndPadding();
64
			break;
65
		case PathMenu.RIGHT_CENTER:// 右中
66
			centerX = getWidth() / 2 + getRadiusAndPadding();
67
			centerY = getHeight() / 2;
68
			break;
69
		case PathMenu.RIGHT_BOTTOM:// 右下
70
			centerX = getWidth() / 2 + getRadiusAndPadding();
71
			centerY = getHeight() / 2 + getRadiusAndPadding();
72
			break;
73
74
		case PathMenu.CENTER:
75
			centerX = getWidth() / 2;
76
			centerY = getHeight() / 2;
77
			break;
78
		}
79
	}
80
81
	private int getRadiusAndPadding() {
82
		return mRadius + (mChildPadding * 2);
83
	}
84
85
	public PathMenuLayout(Context context, AttributeSet attrs) {
86
		super(context, attrs);
87
		// 获取自定义属性,设定默认值
88
		if (attrs != null) {
89
			TypedArray a = getContext().obtainStyledAttributes(attrs,
90
					R.styleable.ArcLayout, 0, 0);
91
			mFromDegrees = a.getFloat(R.styleable.ArcLayout_fromDegrees,
92
					DEFAULT_FROM_DEGREES);
93
			mToDegrees = a.getFloat(R.styleable.ArcLayout_toDegrees,
94
					DEFAULT_TO_DEGREES);
95
			mChildSize = Math
96
					.max(a.getDimensionPixelSize(
97
							R.styleable.ArcLayout_childSize, 0), 0);
98
99
			a.recycle();
100
		}
101
	}
102
103
	/**
104
	 * 计算半径
105
	 * 
106
	 * @param arcDegrees
107
	 * @param childCount
108
	 * @param childSize
109
	 * @param childPadding
110
	 * @param minRadius
111
	 * @return
112
	 */
113
	private static int computeRadius(final float arcDegrees,
114
			final int childCount, final int childSize, final int childPadding,
115
			final int minRadius) {
116
		if (childCount < 2) {
117
			return minRadius;
118
		}
119
		final float perDegrees;
120
		if (arcDegrees < 360) {
121
			perDegrees = arcDegrees / (childCount - 1);
122
		} else {
123
			perDegrees = arcDegrees / (childCount);
124
		}
125
126
		final float perHalfDegrees = perDegrees / 2;
127
		final int perSize = childSize + childPadding;
128
129
		final int radius = (int) ((perSize / 2) / Math.sin(Math
130
				.toRadians(perHalfDegrees)));
131
132
		return Math.max(radius, minRadius);
133
	}
134
135
	/**
136
	 * 计算子菜单项的范围
137
	 * 
138
	 * @param centerX
139
	 * @param centerY
140
	 * @param radius
141
	 * @param degrees
142
	 * @param size
143
	 * @return
144
	 */
145
	private static Rect computeChildFrame(final int centerX, final int centerY,
146
			final int radius, final float degrees, final int size) {
147
		// 子菜单项中心点
148
		final double childCenterX = centerX + radius
149
				* Math.cos(Math.toRadians(degrees));
150
		final double childCenterY = centerY + radius
151
				* Math.sin(Math.toRadians(degrees));
152
		// 子菜单项的左上角,右上角,左下角,右下角
153
		return new Rect((int) (childCenterX - size / 2),
154
				(int) (childCenterY - size / 2),
155
				(int) (childCenterX + size / 2),
156
				(int) (childCenterY + size / 2));
157
	}
158
159
	/**
160
	 * 子菜单项大小
161
	 */
162
	@Override
163
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
164
		int radius = mRadius = computeRadius(
165
				Math.abs(mToDegrees - mFromDegrees), getChildCount(),
166
				mChildSize, mChildPadding, MIN_RADIUS);
167
168
		int size = radius * 2 + mChildSize + mChildPadding + mLayoutPadding * 2;
169
170
		setMeasuredDimension(size, size);
171
172
		final int count = getChildCount();
173
		for (int i = 0; i < count; i++) {
174
			getChildAt(i)
175
					.measure(
176
							MeasureSpec.makeMeasureSpec(mChildSize,
177
									MeasureSpec.EXACTLY),
178
							MeasureSpec.makeMeasureSpec(mChildSize,
179
									MeasureSpec.EXACTLY));
180
		}
181
	}
182
183
	/**
184
	 * 子菜单项位置
185
	 */
186
	@Override
187
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
188
		computeCenterXY(position);
189
		// 当子菜单要收缩时radius=0,在ViewGroup坐标中心
190
		final int radius = mExpanded ? mRadius : 0;
191
		final float perDegrees;// 菜单项之间的角度
192
		final int childCount = getChildCount();
193
		if (mToDegrees - mFromDegrees >= 360) {
194
			perDegrees = (mToDegrees - mFromDegrees) / (childCount);
195
		} else {
196
			perDegrees = (mToDegrees - mFromDegrees) / (childCount - 1);
197
		}
198
199
		float degrees = mFromDegrees;
200
		for (int i = 0; i < childCount; i++) {
201
			Rect frame = computeChildFrame(centerX, centerY, radius, degrees,
202
					mChildSize);
203
			degrees += perDegrees;
204
			getChildAt(i).layout(frame.left, frame.top, frame.right,
205
					frame.bottom);
206
		}
207
	}
208
209
	/**
210
	 * 计算动画开始时的偏移量
211
	 * 
212
	 * @param childCount
213
	 * @param expanded
214
	 * @param index
215
	 * @param delayPercent
216
	 * @param duration
217
	 * @param interpolator
218
	 * @return
219
	 */
220
	private static long computeStartOffset(final int childCount,
221
			final boolean expanded, final int index, final float delayPercent,
222
			final long duration, Interpolator interpolator) {
223
		final float delay = delayPercent * duration;
224
		final long viewDelay = (long) (getTransformedIndex(expanded,
225
				childCount, index) * delay);
226
		final float totalDelay = delay * childCount;
227
228
		float normalizedDelay = viewDelay / totalDelay;
229
		normalizedDelay = interpolator.getInterpolation(normalizedDelay);
230
231
		return (long) (normalizedDelay * totalDelay);
232
	}
233
234
	/**
235
	 * 变换时的子菜单项索引
236
	 * 
237
	 * @param expanded
238
	 * @param count
239
	 * @param index
240
	 * @return
241
	 */
242
	private static int getTransformedIndex(final boolean expanded,
243
			final int count, final int index) {
244
		if (expanded) {
245
			return count - 1 - index;
246
		}
247
248
		return index;
249
	}
250
251
	/**
252
	 * 展开动画
253
	 * 
254
	 * @param fromXDelta
255
	 * @param toXDelta
256
	 * @param fromYDelta
257
	 * @param toYDelta
258
	 * @param startOffset
259
	 * @param duration
260
	 * @param interpolator
261
	 * @return
262
	 */
263
	private static Animation createExpandAnimation(float fromXDelta,
264
			float toXDelta, float fromYDelta, float toYDelta, long startOffset,
265
			long duration, Interpolator interpolator) {
266
		Animation animation = new RotateAndTranslateAnimation(0, toXDelta, 0,
267
				toYDelta, 0, 720);
268
		animation.setStartOffset(startOffset);
269
		animation.setDuration(duration);
270
		animation.setInterpolator(interpolator);
271
		animation.setFillAfter(true);
272
273
		return animation;
274
	}
275
276
	/**
277
	 * 收缩动画
278
	 * 
279
	 * @param fromXDelta
280
	 * @param toXDelta
281
	 * @param fromYDelta
282
	 * @param toYDelta
283
	 * @param startOffset
284
	 * @param duration
285
	 * @param interpolator
286
	 * @return
287
	 */
288
	private static Animation createShrinkAnimation(float fromXDelta,
289
			float toXDelta, float fromYDelta, float toYDelta, long startOffset,
290
			long duration, Interpolator interpolator) {
291
		AnimationSet animationSet = new AnimationSet(false);
292
		animationSet.setFillAfter(true);
293
		// 收缩过程中,child 逆时针自旋转360度
294
		final long preDuration = duration / 2;
295
		Animation rotateAnimation = new RotateAnimation(0, 360,
296
				Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
297
				0.5f);
298
		rotateAnimation.setStartOffset(startOffset);
299
		rotateAnimation.setDuration(preDuration);
300
		rotateAnimation.setInterpolator(new LinearInterpolator());
301
		rotateAnimation.setFillAfter(true);
302
303
		animationSet.addAnimation(rotateAnimation);
304
		// 收缩过程中位移,并逆时针旋转360度
305
		Animation translateAnimation = new RotateAndTranslateAnimation(0,
306
				toXDelta, 0, toYDelta, 360, 720);
307
		translateAnimation.setStartOffset(startOffset + preDuration);
308
		translateAnimation.setDuration(duration - preDuration);
309
		translateAnimation.setInterpolator(interpolator);
310
		translateAnimation.setFillAfter(true);
311
312
		animationSet.addAnimation(translateAnimation);
313
314
		return animationSet;
315
	}
316
317
	/**
318
	 * 绑定子菜单项动画
319
	 * 
320
	 * @param child
321
	 * @param index
322
	 * @param duration
323
	 */
324
	private void bindChildAnimation(final View child, final int index,
325
			final long duration) {
326
		final boolean expanded = mExpanded;
327
		computeCenterXY(position);
328
		final int radius = expanded ? 0 : mRadius;
329
330
		final int childCount = getChildCount();
331
		final float perDegrees;
332
		if (mToDegrees - mFromDegrees >= 360) {
333
			perDegrees = (mToDegrees - mFromDegrees) / (childCount);
334
		} else {
335
			perDegrees = (mToDegrees - mFromDegrees) / (childCount - 1);
336
		}
337
		Rect frame = computeChildFrame(centerX, centerY, radius, mFromDegrees
338
				+ index * perDegrees, mChildSize);
339
340
		final int toXDelta = frame.left - child.getLeft();// 展开或收缩动画,child沿X轴位移距离
341
		final int toYDelta = frame.top - child.getTop();// 展开或收缩动画,child沿Y轴位移距离
342
343
		Interpolator interpolator = mExpanded ? new AccelerateInterpolator()
344
				: new OvershootInterpolator(1.5f);
345
		final long startOffset = computeStartOffset(childCount, mExpanded,
346
				index, 0.1f, duration, interpolator);
347
		// mExpanded为true,已经展开,收缩动画;为false,展开动画
348
		Animation animation = mExpanded ? createShrinkAnimation(0, toXDelta, 0,
349
				toYDelta, startOffset, duration, interpolator)
350
				: createExpandAnimation(0, toXDelta, 0, toYDelta, startOffset,
351
						duration, interpolator);
352
353
		final boolean isLast = getTransformedIndex(expanded, childCount, index) == childCount - 1;
354
		animation.setAnimationListener(new AnimationListener() {
355
356
			@Override
357
			public void onAnimationStart(Animation animation) {
358
359
			}
360
361
			@Override
362
			public void onAnimationRepeat(Animation animation) {
363
364
			}
365
366
			@Override
367
			public void onAnimationEnd(Animation animation) {
368
				if (isLast) {
369
					postDelayed(new Runnable() {
370
371
						@Override
372
						public void run() {
373
							onAllAnimationsEnd();
374
						}
375
					}, 0);
376
				}
377
			}
378
		});
379
380
		child.setAnimation(animation);
381
	}
382
383
	public boolean isExpanded() {
384
		return mExpanded;
385
	}
386
387
	/**
388
     * 设定弧度
389
     */
390
    public void setArc(float fromDegrees, float toDegrees, int position) {
391
        this.position = position;
392
        if (mFromDegrees == fromDegrees && mToDegrees == toDegrees) {
393
            return;
394
        }
395
396
        mFromDegrees = fromDegrees;
397
        mToDegrees = toDegrees;
398
        computeCenterXY(position);
399
        requestLayout();
400
    }
401
402
    /**
403
     * 设定弧度
404
     */
405
    public void setArc(float fromDegrees, float toDegrees) {
406
        if (mFromDegrees == fromDegrees && mToDegrees == toDegrees) {
407
            return;
408
        }
409
410
        mFromDegrees = fromDegrees;
411
        mToDegrees = toDegrees;
412
        computeCenterXY(position);
413
        requestLayout();
414
    }
415
416
417
	/**
418
	 * 设定子菜单项大小
419
	 * 
420
	 * @param size
421
	 */
422
	public void setChildSize(int size) {
423
		if (mChildSize == size || size < 0) {
424
			return;
425
		}
426
427
		mChildSize = size;
428
429
		requestLayout();
430
	}
431
432
	public int getChildSize() {
433
		return mChildSize;
434
	}
435
	
436
	public void setPosition(int position) {
437
        this.position = position;
438
        computeCenterXY(position);
439
        invalidate();
440
    }
441
	 /**
442
     * 切换中心按钮的展开缩小1
443
     * showAnimation一定要设置成true才有动画效果
444
     */
445
    public void switchState(final boolean showAnimation, int position) {
446
        this.position = position;
447
        if (showAnimation) {
448
            final int childCount = getChildCount();
449
            for (int i = 0; i < childCount; i++) {
450
                bindChildAnimation(getChildAt(i), i, 300);
451
            }
452
        }
453
454
        mExpanded = !mExpanded;
455
456
        if (!showAnimation) {
457
            requestLayout();
458
        }
459
460
        invalidate();
461
    }
462
	/**
463
	 * 切换中心按钮的展开缩小
464
	 * 
465
	 * @param showAnimation
466
	 */
467
	public void switchState(final boolean showAnimation) {
468
		if (showAnimation) {
469
			final int childCount = getChildCount();
470
			for (int i = 0; i < childCount; i++) {
471
				bindChildAnimation(getChildAt(i), i, 300);
472
			}
473
		}
474
475
		mExpanded = !mExpanded;
476
477
		if (!showAnimation) {
478
			requestLayout();
479
		}
480
481
		invalidate();
482
	}
483
484
	/**
485
	 * 结束所有动画
486
	 */
487
	private void onAllAnimationsEnd() {
488
		final int childCount = getChildCount();
489
		for (int i = 0; i < childCount; i++) {
490
			getChildAt(i).clearAnimation();
491
		}
492
493
		requestLayout();
494
	}
495
}

+ 94 - 0
ipu-pathmenu/src/com/ai/ipu/ipu_pathmenu/PathMenuService.java

@ -0,0 +1,94 @@
1
package com.ai.ipu.ipu_pathmenu;
2
3
4
import android.app.Service;
5
import android.content.Intent;
6
import android.os.IBinder;
7
import android.view.View;
8
import android.view.View.OnClickListener;
9
import android.widget.ImageView;
10
import android.widget.Toast;
11
12
public class PathMenuService extends Service {
13
	PathMenu pathMenu;
14
	private static int[] ITEM_DRAWABLES = {};
15
16
	@Override
17
	public IBinder onBind(Intent intent) {
18
		return null;
19
	}
20
21
	@Override
22
	public int onStartCommand(Intent intent, int flags, int startId) {
23
		ITEM_DRAWABLES = intent.getIntArrayExtra("icons");
24
		pathMenu = new PathMenu(getApplicationContext());
25
		initPathMenu(pathMenu, ITEM_DRAWABLES);// 初始化子菜单
26
		return super.onStartCommand(intent, flags, startId);
27
	}
28
29
	@Override
30
	public void onDestroy() {
31
		super.onDestroy();
32
		if (pathMenu != null) {
33
			pathMenu.hidePathMenu();
34
		}
35
	}
36
37
	/**
38
	 * 初始化子菜单图片、点击事件
39
	 * 
40
	 * @param menu
41
	 * @param itemDrawables
42
	 */
43
	private void initPathMenu(final PathMenu menu, final int[] itemDrawables) {
44
		final int itemCount = itemDrawables.length;
45
		for (int i = 0; i < itemCount; i++) {
46
			ImageView item = new ImageView(this);
47
			item.setImageResource(itemDrawables[i]);
48
			final int index = i;
49
			menu.addItem(item, new OnClickListener() {
50
51
				@Override
52
				public void onClick(View v) {
53
					switch (index) {
54
					case 0:
55
						Toast.makeText(PathMenuService.this, "关闭菜单",
56
								Toast.LENGTH_SHORT).show();
57
						stopSelf();// 关闭菜单
58
						break;
59
 
60
					case 1:
61
						Toast.makeText(PathMenuService.this, "第1个被点击",
62
								Toast.LENGTH_SHORT).show();
63
						break;
64
						
65
					case 2:
66
						Toast.makeText(PathMenuService.this, "第2个被点击",
67
								Toast.LENGTH_SHORT).show();
68
						break;
69
 
70
					case 3:
71
						Toast.makeText(PathMenuService.this, "第3个被点击",
72
								Toast.LENGTH_SHORT).show();
73
						break;
74
					case 4:
75
						Toast.makeText(PathMenuService.this, "第4个被点击",
76
								Toast.LENGTH_SHORT).show();
77
						break;
78
					case 5:
79
						Toast.makeText(PathMenuService.this, "第5个被点击",
80
								Toast.LENGTH_SHORT).show();
81
						break;
82
					case 6:
83
						Toast.makeText(PathMenuService.this, "第6个被点击",
84
								Toast.LENGTH_SHORT).show();
85
						break;
86
						
87
88
					}
89
				}
90
			});
91
		}
92
	}
93
	
94
}

+ 123 - 0
ipu-pathmenu/src/com/ai/ipu/ipu_pathmenu/RotateAndTranslateAnimation.java

@ -0,0 +1,123 @@
1
package com.ai.ipu.ipu_pathmenu;
2
3
import android.view.animation.Animation;
4
import android.view.animation.Transformation;
5
/**
6
 * 自定义动画类
7
 * 控制对象的位置,以对象的中心旋转
8
 * @author 何凌波
9
 *
10
 */
11
public class RotateAndTranslateAnimation extends Animation {
12
	private int mFromXType = ABSOLUTE;
13
14
	private int mToXType = ABSOLUTE;
15
16
	private int mFromYType = ABSOLUTE;
17
18
	private int mToYType = ABSOLUTE;
19
20
	private float mFromXValue = 0.0f;
21
22
	private float mToXValue = 0.0f;
23
24
	private float mFromYValue = 0.0f;
25
26
	private float mToYValue = 0.0f;
27
28
	private float mFromXDelta;
29
30
	private float mToXDelta;
31
32
	private float mFromYDelta;
33
34
	private float mToYDelta;
35
36
	private float mFromDegrees;
37
38
	private float mToDegrees;
39
40
	private int mPivotXType = ABSOLUTE;
41
42
	private int mPivotYType = ABSOLUTE;
43
44
	private float mPivotXValue = 0.0f;
45
46
	private float mPivotYValue = 0.0f;
47
48
	private float mPivotX;
49
50
	private float mPivotY;
51
52
	/**
53
	 * 位移动画的构造函数
54
	 * @param fromXDelta
55
	 *            动画开始时的X坐标
56
	 * @param toXDelta
57
	 *            动画结束时的X坐标
58
	 * @param fromYDelta
59
	 *            动画开始时的Y坐标
60
	 * @param toYDelta
61
	 *            动画结束时的Y坐标
62
	 * 
63
	 * @param fromDegrees
64
	 *            旋转开始时的角度
65
	 * @param toDegrees
66
	 *            旋转结束时的角度
67
	 */
68
	public RotateAndTranslateAnimation(float fromXDelta, float toXDelta,
69
			float fromYDelta, float toYDelta, float fromDegrees, float toDegrees) {
70
		mFromXValue = fromXDelta;
71
		mToXValue = toXDelta;
72
		mFromYValue = fromYDelta;
73
		mToYValue = toYDelta;
74
75
		mFromXType = ABSOLUTE;
76
		mToXType = ABSOLUTE;
77
		mFromYType = ABSOLUTE;
78
		mToYType = ABSOLUTE;
79
80
		mFromDegrees = fromDegrees;
81
		mToDegrees = toDegrees;
82
83
		mPivotXValue = 0.5f;
84
		mPivotXType = RELATIVE_TO_SELF;
85
		mPivotYValue = 0.5f;
86
		mPivotYType = RELATIVE_TO_SELF;
87
	}
88
89
	@Override
90
	protected void applyTransformation(float interpolatedTime, Transformation t) {
91
		final float degrees = mFromDegrees
92
				+ ((mToDegrees - mFromDegrees) * interpolatedTime);
93
		if (mPivotX == 0.0f && mPivotY == 0.0f) {
94
			t.getMatrix().setRotate(degrees);
95
		} else {
96
			t.getMatrix().setRotate(degrees, mPivotX, mPivotY);
97
		}
98
99
		float dx = mFromXDelta;
100
		float dy = mFromYDelta;
101
		if (mFromXDelta != mToXDelta) {
102
			dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
103
		}
104
		if (mFromYDelta != mToYDelta) {
105
			dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
106
		}
107
108
		t.getMatrix().postTranslate(dx, dy);
109
	}
110
111
	@Override
112
	public void initialize(int width, int height, int parentWidth,
113
			int parentHeight) {
114
		super.initialize(width, height, parentWidth, parentHeight);
115
		mFromXDelta = resolveSize(mFromXType, mFromXValue, width, parentWidth);
116
		mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
117
		mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
118
		mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);
119
120
		mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
121
		mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
122
	}
123
}

二进制
wade-mobile-common/libs/ipu-mobile-1.0.jar


二进制
wade-mobile-common/res/drawable/composer_button.png


二进制
wade-mobile-common/res/drawable/composer_camera.png


二进制
wade-mobile-common/res/drawable/composer_close.png


二进制
wade-mobile-common/res/drawable/composer_icn_plus.png


二进制
wade-mobile-common/res/drawable/composer_music.png


二进制
wade-mobile-common/res/drawable/composer_place.png


二进制
wade-mobile-common/res/drawable/composer_sleep.png


二进制
wade-mobile-common/res/drawable/composer_thought.png


二进制
wade-mobile-common/res/drawable/composer_with.png


+ 28 - 0
wade-mobile-common/res/layout/activity_float.xml

@ -0,0 +1,28 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:arc="http://schemas.android.com/apk/res-auto"
4
    android:layout_width="fill_parent"
5
    android:layout_height="fill_parent" >
6

7
    <LinearLayout
8
        android:layout_width="fill_parent"
9
        android:layout_height="wrap_content"
10
        android:orientation="vertical" >
11

12
        <Button
13
            android:id="@+id/btnOpenFloat"
14
            android:layout_width="wrap_content"
15
            android:layout_height="wrap_content"
16
            android:layout_weight="1"
17
            android:text="open float menu" />
18

19
        <Button
20
            android:id="@+id/btnCloseFloat"
21
            android:layout_width="wrap_content"
22
            android:layout_height="wrap_content"
23
            android:layout_weight="1"
24
            android:text="close float menu" />
25

26
    </LinearLayout>
27

28
</ScrollView>

+ 29 - 0
wade-mobile-common/res/layout/float_menu.xml

@ -0,0 +1,29 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
3

4
    <com.ai.ipu.ipu_pathmenu.PathMenuLayout
5
        xmlns:custom="http://schemas.android.com/apk/res-auto"
6
        android:id="@+id/item_layout"
7
        android:layout_width="wrap_content"
8
        android:layout_height="wrap_content"
9
        android:layout_centerInParent="true"
10
        custom:fromDegrees="270.0"
11
        custom:toDegrees="360.0" />
12

13
    <FrameLayout
14
        android:id="@+id/control_layout"
15
        android:layout_width="wrap_content"
16
        android:layout_height="wrap_content"
17
        android:layout_centerInParent="true"
18
        android:background="@drawable/composer_button" >
19

20
        <ImageView
21
            android:id="@+id/control_hint"
22
            android:layout_width="wrap_content"
23
            android:layout_height="wrap_content"
24
            android:layout_gravity="center"
25
            android:duplicateParentState="true"
26
            android:src="@drawable/composer_icn_plus" />
27
    </FrameLayout>
28

29
</merge>

+ 0 - 78
wade-mobile-func/src/com/wade/mobile/func/IpuWindowWebView.java

@ -1,78 +0,0 @@
1
package com.wade.mobile.func;
2
3
import java.util.Map;
4
5
import android.view.KeyEvent;
6
import android.webkit.WebView;
7
import android.widget.LinearLayout;
8
9
import com.ai.ipu.mobile.util.IpuMobileUtility;
10
import com.ailk.common.data.impl.DataMap;
11
import com.wade.mobile.frame.IWadeMobile;
12
import com.wade.mobile.frame.activity.WadeMobileActivity;
13
import com.wade.mobile.frame.client.WadeWebViewClient;
14
import com.wade.mobile.frame.config.ServerPageConfig;
15
import com.wade.mobile.frame.event.impl.TemplateWebViewEvent;
16
import com.wade.mobile.frame.template.TemplateWebView;
17
import com.wade.mobile.ui.anim.AnimationResource;
18
import com.wade.mobile.ui.view.FlipperLayout;
19
import com.wade.mobile.util.Messages;
20
21
/**
22
 * IpuWindowWebView用于替换CustomWindowActivity,保留openWindow和closeWindow的API使用
23
 */
24
public class IpuWindowWebView extends TemplateWebView {
25
	
26
	public IpuWindowWebView(IWadeMobile wademobile) {
27
		super(wademobile);
28
	}
29
	
30
	@Override
31
	protected void initialize() {
32
		setWebViewClient(new WadeWebViewClient(wademobile,
33
				new TemplateWebViewEvent(wademobile) {
34
					@Override
35
					public void loadingFinished(WebView view, String url) {
36
						wademobile.getFlipperLayout().showNextView();
37
					}
38
				}));
39
		clearCache(true);
40
		setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
41
		((WadeMobileActivity) wademobile).getWebviewSetting().setWebViewStyle(this);
42
	}
43
44
	public void openWindow(String pageAction, String data) throws Exception {
45
		/* 获取模板相对路径 */
46
		final String templatePath = ServerPageConfig.getTemplate(pageAction);
47
		if (templatePath == null || "".equals(templatePath)) {
48
			IpuMobileUtility.error(Messages.NO_TEMPLATE + ",Action:" + pageAction);
49
		}
50
		
51
		Map<?, ?> dataMap = null;
52
		if(data != null) {
53
			dataMap = new DataMap(data.replaceAll("\"null\"", "\"\"").replaceAll("null", "\"\""));
54
		}
55
		FlipperLayout flipperLayout = wademobile.getFlipperLayout();
56
		flipperLayout.setAnimation(AnimationResource.pushLeft[0],
57
				AnimationResource.pushLeft[1]);
58
		flipperLayout.setBackAnimation(AnimationResource.pushRight[0],
59
				AnimationResource.pushRight[1]);
60
		flipperLayout.addNextView(this);// 增加view
61
		flipperLayout.setPreCurrView(this);
62
		loadTemplate(templatePath, dataMap);
63
		
64
	}
65
66
	public void closeWindow(String resultData) {
67
		wademobile.getFlipperLayout().back();
68
	}
69
	
70
	@Override
71
	public boolean onKeyDown(int keyCode, KeyEvent event) {
72
		if (keyCode == KeyEvent.KEYCODE_BACK) {
73
			closeWindow(null);
74
			return true;
75
		}
76
		return super.onKeyDown(keyCode, event);
77
	}
78
}

+ 52 - 0
wade-mobile-func/src/com/wade/mobile/func/MobilePathMenu.java

@ -0,0 +1,52 @@
1
package com.wade.mobile.func;
2

3
import org.json.JSONArray;
4
import org.json.JSONObject;
5

6
import android.content.Intent;
7

8
import com.ai.ipu.ipu_pathmenu.PathMenu;
9
import com.ai.ipu.ipu_pathmenu.PathMenuService;
10
import com.wade.mobile.frame.IWadeMobile;
11
import com.wade.mobile.frame.plugin.Plugin;
12

13
public class MobilePathMenu extends Plugin {
14
	public MobilePathMenu(IWadeMobile wademobile) {
15
		super(wademobile);
16
	}
17

18
	/**
19
	 * js传参数,调用原生方法
20
	 * 
21
	 * @param menuIcons
22
	 * @throws Exception
23
	 */
24
	public void openPathMenu(JSONArray param) throws Exception {
25

26
		JSONObject jsonObject = param.getJSONObject(0);
27
		JSONObject map = jsonObject.getJSONObject("map");
28
		int[] menuIcons = new int[map.length()];
29
		menuIcons[0] = map.getInt("composer_close");
30
		menuIcons[1] = map.getInt("composer_music");
31
		menuIcons[2] = map.getInt("composer_place");
32
		menuIcons[3] = map.getInt("composer_sleep");
33
		menuIcons[4] = map.getInt("composer_thought");
34
		menuIcons[5] = map.getInt("composer_with");
35
		openPathMenu(menuIcons);
36
	}
37

38
	public void openPathMenu(int[] menuIcons) {
39
		Intent intent = new Intent(context, PathMenuService.class);
40
		intent.putExtra("icons", menuIcons);
41
		context.startService(intent);
42
	}
43

44
	public void closePathMenu(JSONArray param) throws Exception {
45
		closePathMenu();
46
	}
47

48
	public void closePathMenu() {
49
		Intent intent = new Intent(context, PathMenuService.class);
50
		context.stopService(intent);
51
	}
52
}

+ 13 - 39
wade-mobile-func/src/com/wade/mobile/func/MobileUI.java

@ -1,15 +1,5 @@
1 1
package com.wade.mobile.func;
2 2

3
import java.net.URLDecoder;
4
import java.text.ParseException;
5
import java.text.SimpleDateFormat;
6
import java.util.Calendar;
7
import java.util.Date;
8
import java.util.Map;
9
import java.util.Stack;
10

11
import org.json.JSONArray;
12

13 3
import android.app.AlertDialog;
14 4
import android.app.AlertDialog.Builder;
15 5
import android.app.DatePickerDialog;
@ -23,7 +13,6 @@ import android.webkit.WebView;
23 13
import android.widget.DatePicker;
24 14
import android.widget.LinearLayout;
25 15
import android.widget.TimePicker;
26

27 16
import com.ai.ipu.mobile.app.AppInfoUtil;
28 17
import com.ai.ipu.mobile.ui.HintUtil;
29 18
import com.ai.ipu.mobile.ui.UiTool;
@ -56,6 +45,15 @@ import com.wade.mobile.ui.layout.ConstantParams;
56 45
import com.wade.mobile.ui.view.FlipperLayout;
57 46
import com.wade.mobile.util.Constant;
58 47
import com.wade.mobile.util.Messages;
48
import org.json.JSONArray;
49

50
import java.net.URLDecoder;
51
import java.text.ParseException;
52
import java.text.SimpleDateFormat;
53
import java.util.Calendar;
54
import java.util.Date;
55
import java.util.Map;
56
import java.util.Stack;
59 57

60 58
public class MobileUI extends Plugin {
61 59
	private static SimpleProgressDialog progressDialog = null;
@ -791,23 +789,9 @@ public class MobileUI extends Plugin {
791 789
	public void openWindow(JSONArray param) throws Exception {
792 790
		final String pageAction = param.getString(0);
793 791
		final String data = param.getString(1);
794
		/*放弃使用CustomWindowActivity*/
795
		/*Intent intent = new Intent(context, CustomWindowActivity.class);
796
		intent.putExtra(CustomWindowActivity.KEY_PAGE_ACTION, pageAction);
797
		intent.putExtra(CustomWindowActivity.KEY_DATA, data);
798
		startActivityForResult(intent, REQUEST_CODE_CUSTOM_WINDOW);*/
799
		
800
		context.runOnUiThread(new Runnable() {
801
			@Override
802
			public void run() {
803
				IpuWindowWebView webView = new IpuWindowWebView(wademobile);
804
				try {
805
					webView.openWindow(pageAction, data);
806
				} catch (Exception e) {
807
					e.printStackTrace();
808
				}
809
			}
810
		});
792

793
        openTemplate(pageAction, isNull(data) ? null : new DataMap(data),
794
                true);
811 795
	}
812 796

813 797
	/**
@ -820,20 +804,10 @@ public class MobileUI extends Plugin {
820 804

821 805
			@Override
822 806
			public void run() {
823
				IpuWindowWebView webView = (IpuWindowWebView) wademobile.getFlipperLayout().getCurrView();
824
				webView.closeWindow(resultData);
807
                wademobile.getFlipperLayout().back();
825 808
				plugin.callback(resultData);
826 809
			}
827 810
		});
828
		/*放弃使用CustomWindowActivity*/
829
		/*int resultState = isNull(param.getString(1)) ? CustomWindowActivity.SUCCESS_CODE
830
				: param.getInt(1);
831
		if (context instanceof CustomWindowActivity) {
832
			((CustomWindowActivity) context).closeWindow(resultData,
833
					resultState);
834
		} else {
835
			HintUtil.alert(context, "无窗口可以关闭!");
836
		}*/
837 811
	}
838 812
	
839 813
	@Override

+ 273 - 0
wade-mobile-func/src/com/wade/mobile/func/MobileUIWithSAD.java

@ -0,0 +1,273 @@
1
package com.wade.mobile.func;
2
import org.json.JSONArray;
3
import org.json.JSONObject;
4
import android.graphics.Color;
5
import android.os.CountDownTimer;
6
import cn.pedant.SweetAlert.SweetAlertDialog;
7
import com.wade.mobile.frame.IWadeMobile;
8
import com.wade.mobile.frame.plugin.Plugin;
9
/**
10
 * 提示对话框,用到SweetAlertDialog开源库
11
 * 
12
 * @author 何凌波
13
 *
14
 */
15
public class MobileUIWithSAD extends Plugin {
16
	private int i = -1;
17
	public static final int NORMAL_TYPE = 0;// 文字提示框
18
	public static final int ERROR_TYPE = 1;// 错误提示框
19
	public static final int SUCCESS_TYPE = 2;// 成功提示框
20
	public static final int WARNING_TYPE = 3;// 确认提示框
21
	public static final int CUSTOM_IMAGE_TYPE = 4;// 自定义图片提示框
22
	public static final int PROGRESS_TYPE = 5;// 进度条提示框
23
	// 进度条加载时变换的颜色
24
	public static final int blue_btn_bg_color = Color.parseColor("#AEDEF4");
25
	public static final int material_deep_teal_50 = Color
26
			.parseColor("#ff009688");
27
	public static final int success_stroke_color = Color.parseColor("#F27474");
28
	public static final int material_deep_teal_20 = Color
29
			.parseColor("#ff80cbc4");
30
	public static final int material_blue_grey_80 = Color
31
			.parseColor("#ff37474f");
32
	public static final int warning_stroke_color = Color.parseColor("#F8BB86");
33
	public MobileUIWithSAD(IWadeMobile wademobile) {
34
		super(wademobile);
35
	}
36
	/**
37
	 * js传参数,调用原生方法
38
	 * 
39
	 * @param param
40
	 * @throws Exception
41
	 */
42
	public void alert(JSONArray param) throws Exception {
43
		JSONObject jsonObject = param.getJSONObject(0);
44
		JSONObject map = jsonObject.getJSONObject("map");
45
		String content = map.getString("content");
46
		String title = map.getString("title");
47
		Boolean cancelable = map.getBoolean("cancelable");
48
		int alertType = map.getInt("alertType");
49
		int imageID = map.getInt("imageID");
50
		alert(content, title, cancelable, alertType, imageID);
51
	}
52
	/**
53
	 * 普通类型的几种提示框
54
	 * 
55
	 * @param content
56
	 *            文本
57
	 * @param title
58
	 *            标题
59
	 * @param cancelable
60
	 *            是否可取消
61
	 * @param alertType
62
	 *            提示框类型
63
	 * @param imageID
64
	 *            图片资源ID
65
	 * @throws Exception
66
	 */
67
	public void alert(String content, String title, boolean cancelable,
68
			int alertType, int imageID) throws Exception {
69
		final SweetAlertDialog dialog = new SweetAlertDialog(context, alertType);
70
		if (title != null) {
71
			dialog.setTitleText(title);
72
		}
73
		if (!content.equals("")) {
74
			dialog.setContentText(content);
75
		}else
76
		{
77
			dialog.setContentText(null);
78
		}
79
		if (imageID != 0) {
80
			dialog.setCustomImage(imageID);
81
		} else {
82
			dialog.setCustomImage(null);
83
		}
84
		dialog.setCancelable(cancelable);
85
		dialog.show();
86
	}
87
	/**
88
	 * js传参数,调用原生方法
89
	 * 
90
	 * @param param
91
	 * @throws Exception
92
	 */
93
	public void confirm(JSONArray param) throws Exception {
94
		JSONObject jsonObject = param.getJSONObject(0);
95
		JSONObject map = jsonObject.getJSONObject("map");
96
		String content = map.getString("content");
97
		String title = map.getString("title");
98
		Boolean cancelable = map.getBoolean("cancelable");
99
		String cancelText = map.getString("cancelText");
100
		String confirmText = map.getString("confirmText");
101
		String cancelEvent = map.getString("cancelEvent");
102
		String confirmEvent = map.getString("confirmEvent");
103
		Boolean isCancel = map.getBoolean("isCancel");
104
		confirm(content, title, cancelable, cancelText, confirmText, isCancel,
105
				cancelEvent, confirmEvent);
106
	}
107
	/**
108
	 * 确认-取消提示框
109
	 * 
110
	 * @param content
111
	 *            文本
112
	 * @param title
113
	 *            标题
114
	 * @param cancelable
115
	 *            是否可取消
116
	 * @param cancelText
117
	 *            取消按钮文本
118
	 * @param confirmText
119
	 *            确认按钮文本
120
	 * @param isCancel
121
	 *            是否显示取消按钮
122
	 * @param cancelEvent
123
	 *            取消按钮点击事件
124
	 * @param confirmEvent
125
	 *            确认按钮点击事件
126
	 * @throws Exception
127
	 */
128
	public void confirm(String content, String title, boolean cancelable,
129
			String cancelText, String confirmText, boolean isCancel,
130
			final String cancelEvent, final String confirmEvent)
131
			throws Exception {
132
		final SweetAlertDialog dialog;
133
		if (cancelText != null && isCancel != false) {
134
			dialog = new SweetAlertDialog(context, WARNING_TYPE)
135
					.setTitleText(title)
136
					.setContentText(content)
137
					.setCancelText(cancelText)
138
					.setConfirmText(confirmText)
139
					.showCancelButton(isCancel)
140
					.setCancelClickListener(
141
							new SweetAlertDialog.OnSweetClickListener() {
142
								@Override
143
								public void onClick(SweetAlertDialog sdialog) {
144
									if (cancelEvent != null) {
145
										sdialog.dismiss();
146
										MobileUIWithSAD.this
147
												.executeJs("WadeMobile.customEvents."
148
														+ cancelEvent + "();");
149
									}
150
								}
151
							})
152
					.setConfirmClickListener(
153
							new SweetAlertDialog.OnSweetClickListener() {
154
								@Override
155
								public void onClick(SweetAlertDialog sdialog) {
156
									if (confirmEvent != null) {
157
										sdialog.dismiss();
158
										MobileUIWithSAD.this
159
												.executeJs("WadeMobile.customEvents."
160
														+ confirmEvent + "();");
161
									}
162
								}
163
							});
164
		} else {
165
			dialog = new SweetAlertDialog(context, WARNING_TYPE)
166
					.setTitleText(title)
167
					.setContentText(content)
168
					.setConfirmText(confirmText)
169
					.showCancelButton(isCancel)
170
					.setConfirmClickListener(
171
							new SweetAlertDialog.OnSweetClickListener() {
172
								@Override
173
								public void onClick(SweetAlertDialog sdialog) {
174
									if (confirmEvent != null) {
175
										sdialog.dismiss();
176
										MobileUIWithSAD.this
177
												.executeJs("WadeMobile.customEvents."
178
														+ confirmEvent + "();");
179
									}
180
								}
181
							});
182
		}
183
		dialog.setCancelable(cancelable);
184
		dialog.show();
185
	}
186
	/**
187
	 * js传参数,调用原生方法
188
	 * 
189
	 * @param param
190
	 * @throws Exception
191
	 */
192
	public void loading(JSONArray param) throws Exception {
193
		JSONObject jsonObject = param.getJSONObject(0);
194
		JSONObject map = jsonObject.getJSONObject("map");
195
		String title = map.getString("title");
196
		Boolean cancelable = map.getBoolean("cancelable");
197
		Long millisInFuture = map.getLong("millisInFuture");
198
		Long countDownInterval = map.getLong("countDownInterval");
199
		String nextEvent = map.getString("nextEvent");
200
		Boolean hasNext = map.getBoolean("hasNext");
201
		loading(title, cancelable, millisInFuture, countDownInterval, hasNext,
202
				nextEvent);
203
	}
204
	/**
205
	 * 进度条提示框
206
	 * 
207
	 * @param title
208
	 *            标题
209
	 * @param cancelable
210
	 *            是否可取消
211
	 * @param millisInFuture
212
	 *            倒计时总时间(毫秒)
213
	 * @param countDownInterval
214
	 *            间隔时间(毫秒)
215
	 * @param hasNext
216
	 *            是否继续弹出对话框
217
	 * @param nextEvent
218
	 *            对话框事件(JS定义弹出新对话框)
219
	 * @throws Exception
220
	 */
221
	public void loading(String title, boolean cancelable, long millisInFuture,
222
			long countDownInterval, final boolean hasNext,
223
			final String nextEvent) throws Exception {
224
		final SweetAlertDialog pDialog = new SweetAlertDialog(context,
225
				PROGRESS_TYPE).setTitleText(title);
226
		pDialog.setCancelable(cancelable);
227
		pDialog.show();
228
		new CountDownTimer(millisInFuture, countDownInterval) {
229
			public void onTick(long millisUntilFinished) {
230
				// you can change the progress bar color by ProgressHelper every
231
				// countDownInterval millis
232
				i++;
233
				switch (i) {
234
				case 0:
235
					pDialog.getProgressHelper().setBarColor(blue_btn_bg_color);
236
					break;
237
				case 1:
238
					pDialog.getProgressHelper().setBarColor(
239
							material_deep_teal_50);
240
					break;
241
				case 2:
242
					pDialog.getProgressHelper().setBarColor(
243
							success_stroke_color);
244
					break;
245
				case 3:
246
					pDialog.getProgressHelper().setBarColor(
247
							material_deep_teal_20);
248
					break;
249
				case 4:
250
					pDialog.getProgressHelper().setBarColor(
251
							material_blue_grey_80);
252
					break;
253
				case 5:
254
					pDialog.getProgressHelper().setBarColor(
255
							warning_stroke_color);
256
					break;
257
				case 6:
258
					pDialog.getProgressHelper().setBarColor(
259
							success_stroke_color);
260
					break;
261
				}
262
			}
263
			public void onFinish() {
264
				i = -1;
265
				pDialog.dismiss();
266
				if (hasNext && nextEvent != null) {
267
					MobileUIWithSAD.this.executeJs("WadeMobile.customEvents."
268
							+ nextEvent + "();");
269
				}
270
			}
271
		}.start();
272
	}
273
}

工程打包镜像输出版本@20211203:1)简化了ipu-assembly-parent中的pom,dockerfile-maven-plugin插件不使用contextDirectory或dockerfile标签。Dockerfile目前需要放置在根目录下。 · de7eae6749 - Nuosi Git Service
Selaa lähdekoodia

工程打包镜像输出版本@20211203:1)简化了ipu-assembly-parent中的pom,dockerfile-maven-plugin插件不使用contextDirectory或dockerfile标签。Dockerfile目前需要放置在根目录下。

huangbo 3 vuotta sitten
vanhempi
commit
de7eae6749

+ 3 - 2
ipu-rest-scaffold/Dockerfile

@ -3,7 +3,8 @@ RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
3 3
WORKDIR /ipu
4 4
ENV JVM_PARAM  " "
5 5
ARG JAR_FILE
6
ADD ${JAR_FILE}-bin.tar.gz ./
6 7
ARG JAR_NAME
7
ADD ${JAR_FILE}.jar ./${JAR_NAME}.jar
8
ENV DOCKER_JAR_NAME=$JAR_NAME
8 9
EXPOSE 8080
9
ENTRYPOINT java ${JVM_PARAM} -Dfile.encoding=utf-8 -Djava.security.egd=file:/dev/./urandom -jar ./${JAR_NAME}.jar $0 $@
10
ENTRYPOINT java ${JVM_PARAM} -Dfile.encoding=utf-8 -Djava.security.egd=file:/dev/./urandom -jar ./$DOCKER_JAR_NAME/$DOCKER_JAR_NAME.jar $0 $@

+ 0 - 9
ipu-rest-scaffold/docker/Dockerfile

@ -1,9 +0,0 @@
1
FROM openjdk:8-jdk-alpine
2
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
3
WORKDIR /ipu
4
ENV JVM_PARAM  " "
5
ARG JAR_FILE
6
ARG JAR_NAME
7
ADD ${JAR_FILE}.jar ./${JAR_NAME}.jar
8
EXPOSE 8080
9
ENTRYPOINT java ${JVM_PARAM} -Dfile.encoding=utf-8 -Djava.security.egd=file:/dev/./urandom -jar ./${JAR_NAME}.jar $0 $@

+ 2 - 4
ipu-rest-scaffold/pom.xml

@ -48,11 +48,9 @@
48 48
        <ipu-rest>3.3-SNAPSHOT</ipu-rest>
49 49
        <org.springframework.boot>2.3.1.RELEASE</org.springframework.boot>
50 50
51
        <!--<dockerfile-maven-plugin>1.4.0</dockerfile-maven-plugin>
52
        <docker-registry-server>192.168.128.77:5000</docker-registry-server>
51
        <!--<docker-registry-server>192.168.128.77:5000</docker-registry-server>
53 52
        <docker-registry-username>ipu</docker-registry-username>
54
        <docker-registry-password>ipuipu</docker-registry-password>
55
        <dockerDirectory>${project.basedir}</dockerDirectory>-->
53
        <docker-registry-password>ipuipu</docker-registry-password>-->
56 54
    </properties>
57 55
58 56
    <dependencyManagement>

MobileKeyboard.java依赖了ipu-plugin-extend中的代码,将MobileKeyboard.java移到ipu-plugin-extend中 · c80aff0be0 - Nuosi Git Service
瀏覽代碼

MobileKeyboard.java依赖了ipu-plugin-extend中的代码,将MobileKeyboard.java移到ipu-plugin-extend中

zhanglong7 5 年之前
父節點
當前提交
c80aff0be0
共有 1 個文件被更改,包括 0 次插入48 次删除
  1. 0 48
      ipu-plugin-basic/src/main/java/com/ai/ipu/mobile/plugin/MobileKeyboard.java

+ 0 - 48
ipu-plugin-basic/src/main/java/com/ai/ipu/mobile/plugin/MobileKeyboard.java

@ -1,48 +0,0 @@
1
package com.ai.ipu.mobile.plugin;
2

3
import org.json.JSONArray;
4

5
import android.content.Intent;
6
import android.os.Bundle;
7
import android.os.Handler;
8

9
import com.ai.ipu.basic.string.EscapeUnescape;
10
import com.ai.ipu.mobile.common.keyboard.KeyboardActivity;
11
import com.ai.ipu.mobile.common.keyboard.KeyboardConstants;
12
import com.ai.ipu.mobile.frame.IIpuMobile;
13
import com.ai.ipu.mobile.frame.plugin.Plugin;
14

15
public class MobileKeyboard extends Plugin {
16

17
	private static final int KEYBORAD = 1;
18
	String functionName = "";
19

20
	public MobileKeyboard(IIpuMobile ipumobile) {
21
		super(ipumobile);
22
	}
23

24
	public void openKeyboard(JSONArray param) throws Exception {
25
		functionName = param.getString(0);
26
		KeyboardConstants.handler = handler;
27

28
		Intent intent = new Intent(context, KeyboardActivity.class);
29
		startActivityForResult(intent, KEYBORAD);
30
	}
31

32
	final Handler handler = new Handler() {
33
		public void handleMessage(android.os.Message msg) {
34
			super.handleMessage(msg);
35
			if (msg.what == KeyboardConstants.KEYBOARD_BTN) { // 更新UI
36
				Bundle data = msg.getData();
37
				String character = data.getString("character");
38

39
				// 转义
40
				String callback = "(function(msg){" + functionName
41
						+ "(unescape(msg));})";
42
				String ret = callback + "('" + EscapeUnescape.escape(character)
43
						+ "')";
44
				ipumobile.getCurrentWebView().executeJs(ret);
45
			}
46
		}
47
	};
48
}