|
1 | 1 | package com.gc.materialdesign.views;
|
2 | 2 |
|
| 3 | +import com.gc.materialdesign.R; |
| 4 | +import com.gc.materialdesign.utils.Utils; |
| 5 | + |
3 | 6 | import android.content.Context;
|
4 | 7 | import android.graphics.Bitmap;
|
5 |
| -import android.graphics.Bitmap.Config; |
| 8 | +import android.graphics.Canvas; |
6 | 9 | import android.graphics.Color;
|
| 10 | +import android.graphics.Paint; |
| 11 | +import android.graphics.Rect; |
| 12 | +import android.graphics.Bitmap.Config; |
7 | 13 | import android.graphics.drawable.GradientDrawable;
|
8 | 14 | import android.graphics.drawable.LayerDrawable;
|
9 | 15 | import android.util.AttributeSet;
|
| 16 | +import android.view.MotionEvent; |
10 | 17 | import android.widget.TextView;
|
11 | 18 |
|
12 |
| -import com.gc.materialdesign.R; |
13 |
| -import com.gc.materialdesign.utils.Utils; |
| 19 | +public abstract class Button extends CustomView { |
14 | 20 |
|
15 |
| -public abstract class Button extends RippleView { |
| 21 | + final static String ANDROIDXML = "http://schemas.android.com/apk/res/android"; |
| 22 | + |
| 23 | + // Complete in child class |
| 24 | + int minWidth; |
| 25 | + int minHeight; |
| 26 | + int background; |
| 27 | + float rippleSpeed = 10f; |
| 28 | + int rippleSize = 3; |
| 29 | + Integer rippleColor; |
| 30 | + OnClickListener onClickListener; |
| 31 | + int backgroundColor = Color.parseColor("#1E88E5"); |
16 | 32 |
|
17 | 33 | public Button(Context context, AttributeSet attrs) {
|
18 | 34 | super(context, attrs);
|
19 |
| - onInitAttributes(attrs); |
| 35 | + setDefaultProperties(); |
| 36 | + setAttributes(attrs); |
| 37 | + beforeBackground = backgroundColor; |
| 38 | + if(rippleColor==null) |
| 39 | + rippleColor = makePressColor(); |
| 40 | + } |
| 41 | + |
| 42 | + protected void setDefaultProperties() { |
| 43 | + // Min size |
| 44 | + setMinimumHeight(Utils.dpToPx(minHeight, getResources())); |
| 45 | + setMinimumWidth(Utils.dpToPx(minWidth, getResources())); |
| 46 | + // Background shape |
| 47 | + setBackgroundResource(background); |
| 48 | + setBackgroundColor(backgroundColor); |
20 | 49 | }
|
21 | 50 |
|
| 51 | + |
| 52 | + // Set atributtes of XML to View |
| 53 | + abstract protected void setAttributes(AttributeSet attrs); |
| 54 | + |
| 55 | + // ### RIPPLE EFFECT ### |
| 56 | + |
| 57 | + float x = -1, y = -1; |
| 58 | + float radius = -1; |
| 59 | + |
22 | 60 | @Override
|
23 |
| - protected void onInitDefaultValues() { |
24 |
| - backgroundColor = Color.parseColor("#2196f3");// 默认的背景色,蓝色 |
25 |
| - ///beforeBackground = backgroundColor;// error |
| 61 | + public boolean onTouchEvent(MotionEvent event) { |
| 62 | + invalidate(); |
| 63 | + if (isEnabled()) { |
| 64 | + isLastTouch = true; |
| 65 | + if (event.getAction() == MotionEvent.ACTION_DOWN) { |
| 66 | + radius = getHeight() / rippleSize; |
| 67 | + x = event.getX(); |
| 68 | + y = event.getY(); |
| 69 | + } else if (event.getAction() == MotionEvent.ACTION_MOVE) { |
| 70 | + radius = getHeight() / rippleSize; |
| 71 | + x = event.getX(); |
| 72 | + y = event.getY(); |
| 73 | + if (!((event.getX() <= getWidth() && event.getX() >= 0) && (event |
| 74 | + .getY() <= getHeight() && event.getY() >= 0))) { |
| 75 | + isLastTouch = false; |
| 76 | + x = -1; |
| 77 | + y = -1; |
| 78 | + } |
| 79 | + } else if (event.getAction() == MotionEvent.ACTION_UP) { |
| 80 | + if ((event.getX() <= getWidth() && event.getX() >= 0) |
| 81 | + && (event.getY() <= getHeight() && event.getY() >= 0)) { |
| 82 | + radius++; |
| 83 | + } else { |
| 84 | + isLastTouch = false; |
| 85 | + x = -1; |
| 86 | + y = -1; |
| 87 | + } |
| 88 | + }else if (event.getAction() == MotionEvent.ACTION_CANCEL) { |
| 89 | + isLastTouch = false; |
| 90 | + x = -1; |
| 91 | + y = -1; |
| 92 | + } |
| 93 | + } |
| 94 | + return true; |
26 | 95 | }
|
27 |
| - |
28 |
| - protected void onInitAttributes(AttributeSet attrs) { |
29 |
| - setAttributes(attrs); |
| 96 | + |
| 97 | + @Override |
| 98 | + protected void onFocusChanged(boolean gainFocus, int direction, |
| 99 | + Rect previouslyFocusedRect) { |
| 100 | + if (!gainFocus) { |
| 101 | + x = -1; |
| 102 | + y = -1; |
| 103 | + } |
30 | 104 | }
|
31 |
| - |
32 |
| - // ### RIPPLE EFFECT ### |
33 |
| - |
34 |
| - /** |
35 |
| - * @return 涟漪的bitmap |
36 |
| - */ |
| 105 | + |
| 106 | + @Override |
| 107 | + public boolean onInterceptTouchEvent(MotionEvent ev) { |
| 108 | + // super.onInterceptTouchEvent(ev); |
| 109 | + return true; |
| 110 | + } |
| 111 | + |
37 | 112 | public Bitmap makeCircle() {
|
38 |
| - // 画涟漪时要考虑到按钮的边界区域,不要把按钮的阴影边界也填满了 |
39 | 113 | Bitmap output = Bitmap.createBitmap(
|
40 |
| - getWidth() - Utils.dpToPx(6, getResources()), |
41 |
| - getHeight() - Utils.dpToPx(7, getResources()), Config.ARGB_8888); |
42 |
| - return makeCircleFromBitmap(output); |
| 114 | + getWidth() - Utils.dpToPx(6, getResources()), getHeight() |
| 115 | + - Utils.dpToPx(7, getResources()), Config.ARGB_8888); |
| 116 | + Canvas canvas = new Canvas(output); |
| 117 | + canvas.drawARGB(0, 0, 0, 0); |
| 118 | + Paint paint = new Paint(); |
| 119 | + paint.setAntiAlias(true); |
| 120 | + paint.setColor(rippleColor); |
| 121 | + canvas.drawCircle(x, y, radius, paint); |
| 122 | + if (radius > getHeight() / rippleSize) |
| 123 | + radius += rippleSpeed; |
| 124 | + if (radius >= getWidth()) { |
| 125 | + x = -1; |
| 126 | + y = -1; |
| 127 | + radius = getHeight() / rippleSize; |
| 128 | + if (onClickListener != null) |
| 129 | + onClickListener.onClick(this); |
| 130 | + } |
| 131 | + return output; |
43 | 132 | }
|
44 |
| - |
45 |
| - // Set color of background |
| 133 | + |
| 134 | + /** |
| 135 | + * Make a dark color to ripple effect |
| 136 | + * |
| 137 | + * @return |
| 138 | + */ |
| 139 | + protected int makePressColor() { |
| 140 | + int r = (this.backgroundColor >> 16) & 0xFF; |
| 141 | + int g = (this.backgroundColor >> 8) & 0xFF; |
| 142 | + int b = (this.backgroundColor >> 0) & 0xFF; |
| 143 | + r = (r - 30 < 0) ? 0 : r - 30; |
| 144 | + g = (g - 30 < 0) ? 0 : g - 30; |
| 145 | + b = (b - 30 < 0) ? 0 : b - 30; |
| 146 | + return Color.rgb(r, g, b); |
| 147 | + } |
| 148 | + |
46 | 149 | @Override
|
| 150 | + public void setOnClickListener(OnClickListener l) { |
| 151 | + onClickListener = l; |
| 152 | + } |
| 153 | + |
| 154 | + // Set color of background |
47 | 155 | public void setBackgroundColor(int color) {
|
48 |
| - backgroundColor = color; |
49 |
| - if (isEnabled()) { |
| 156 | + this.backgroundColor = color; |
| 157 | + if (isEnabled()) |
50 | 158 | beforeBackground = backgroundColor;
|
51 |
| - } |
52 | 159 | try {
|
53 | 160 | LayerDrawable layer = (LayerDrawable) getBackground();
|
54 |
| - // 每个按钮的框架都是由drawable中的xml文件制定的,xml文件中都有一个item的id叫:shape_bacground |
55 |
| - GradientDrawable shape = (GradientDrawable) layer.findDrawableByLayerId(R.id.shape_bacground); |
56 |
| - /** |
57 |
| - * 给这个图片设置背景色,因为图片的主体是透明的所以可以直接显示背景色 |
58 |
| - * 效果就是一个透明但有阴影的框架下有了背景色,这样的方式可以方便的设置不同颜色的按钮,让按钮看起来还是浑然一体 |
59 |
| - */ |
| 161 | + GradientDrawable shape = (GradientDrawable) layer |
| 162 | + .findDrawableByLayerId(R.id.shape_bacground); |
60 | 163 | shape.setColor(backgroundColor);
|
61 |
| - /** |
62 |
| - * 当重新设定背景色后,要检查涟漪颜色。如果已经设定了涟漪颜色,那么就用之前的。如果没设定就重新生成 |
63 |
| - */ |
64 |
| - if (!settedRippleColor) { |
65 |
| - rippleColor = makePressColor(255); |
66 |
| - } |
| 164 | + rippleColor = makePressColor(); |
67 | 165 | } catch (Exception ex) {
|
68 | 166 | // Without bacground
|
69 | 167 | }
|
70 | 168 | }
|
71 | 169 |
|
72 | 170 | abstract public TextView getTextView();
|
73 |
| - |
| 171 | + |
| 172 | + public void setRippleSpeed(float rippleSpeed) { |
| 173 | + this.rippleSpeed = rippleSpeed; |
| 174 | + } |
| 175 | + |
| 176 | + public float getRippleSpeed() { |
| 177 | + return this.rippleSpeed; |
| 178 | + } |
74 | 179 | }
|
0 commit comments