23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/dribSearch/src/main/java/org/liuyichen/dribsearch/DribSearchView.java:
--------------------------------------------------------------------------------
1 | package org.liuyichen.dribsearch;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.Path;
10 | import android.graphics.RectF;
11 | import android.os.Build;
12 | import android.os.Parcel;
13 | import android.os.Parcelable;
14 | import android.util.AttributeSet;
15 | import android.view.MotionEvent;
16 | import android.view.View;
17 |
18 | import com.nineoldandroids.animation.Animator;
19 | import com.nineoldandroids.animation.AnimatorSet;
20 | import com.nineoldandroids.animation.ObjectAnimator;
21 | import com.nineoldandroids.animation.PropertyValuesHolder;
22 | import com.nineoldandroids.animation.ValueAnimator;
23 | import com.nineoldandroids.util.Property;
24 |
25 | import static org.liuyichen.dribsearch.DribSearchView.State.LINE;
26 | import static org.liuyichen.dribsearch.DribSearchView.State.RUNNING;
27 | import static org.liuyichen.dribsearch.DribSearchView.State.SEARCH;
28 |
29 | /**
30 | * Copyright 2015 liuyichen
31 | * Licensed under the Apache License, Version 2.0 (the "License");
32 | * you may not use this file except in compliance with the License.
33 | * You may obtain a copy of the License at
34 | *
35 | * http://www.apache.org/licenses/LICENSE-2.0
36 | *
37 | * Unless required by applicable law or agreed to in writing, software
38 | * distributed under the License is distributed on an "AS IS" BASIS,
39 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40 | * See the License for the specific language governing permissions and
41 | * limitations under the License.
42 | */
43 | public class DribSearchView extends View implements ValueAnimator.AnimatorUpdateListener {
44 |
45 | private static final float DEFAULT_ALPHA = 0.8f;
46 | private static final int DEFAULT_COLOR = Color.WHITE;
47 |
48 | private static final float DEGREE_360 = 360f;
49 |
50 | private static final float DEFAULT_JOIN_ANGLE = 45;
51 |
52 | private static final double sin45 = Math.sin(2 * Math.PI / 360 * 45);
53 |
54 | private Paint mSearchPaint = new Paint();
55 | private Path mSearchPath = new Path();
56 |
57 | private int mBreadth = 2;
58 | private int mSearchColor = DEFAULT_COLOR;
59 |
60 | public DribSearchView(Context context) {
61 | this(context, null);
62 | }
63 |
64 | public DribSearchView(Context context, AttributeSet attrs) {
65 | this(context, attrs, 0);
66 | }
67 |
68 | public DribSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
69 | super(context, attrs, defStyleAttr);
70 |
71 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DribSearchView);
72 | mBreadth = a.getInteger(R.styleable.DribSearchView_breadth, 2);
73 | mSearchColor = a.getColor(R.styleable.DribSearchView_search_color, Color.WHITE);
74 | a.recycle();
75 | initView();
76 | }
77 |
78 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
79 | public DribSearchView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
80 | super(context, attrs, defStyleAttr, defStyleRes);
81 | initView();
82 |
83 | }
84 |
85 | void initView() {
86 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
87 | setLayerType(View.LAYER_TYPE_SOFTWARE, null);
88 | }
89 | // attrs to do
90 |
91 | mSearchPaint.setStyle(Paint.Style.STROKE);
92 | mSearchPaint.setStrokeWidth(mBreadth);
93 | mSearchPaint.setColor(mSearchColor);
94 | mSearchPaint.setAntiAlias(true);
95 | mSearchPaint.setAlpha((int)(255 * DEFAULT_ALPHA));
96 | mSearchPaint.setStrokeCap(Paint.Cap.ROUND);
97 | mSearchPaint.setStrokeJoin(Paint.Join.ROUND);
98 | }
99 |
100 | @Override
101 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
102 | super.onLayout(changed, left, top, right, bottom);
103 | resetLayout(left, top, right, bottom);
104 | }
105 |
106 | int drawLeft = 0;
107 | int drawTop = 0;
108 | int drawRight = 0;
109 | int drawBottom = 9;
110 |
111 | // float r = 0;
112 | float rx = 0;
113 | float ry = 0;
114 | RectF mRoundRect = new RectF();
115 | float defaultJoinx = 0;
116 | float defaultJoiny = 0;
117 |
118 | RectF mTouchRect = new RectF();
119 | protected void resetLayout(int left, int top, int right, int bottom) {
120 |
121 | drawLeft = left + getPaddingLeft() + 1;
122 | drawTop = top + getPaddingTop() + 1;
123 | drawRight = right - getPaddingRight() - 1;
124 | drawBottom = bottom - getPaddingBottom() - 1;
125 |
126 | int h = drawBottom - drawTop;
127 | float r = 0;
128 | mTouchRect.set(drawRight - h, drawTop, drawRight, drawBottom);
129 | // sin45 * 2R + R = height
130 | r = (float)(h / (sin45 * 2 + 1));
131 | rx = (float)(drawRight - 2 * r * sin45);
132 | ry = r + drawTop;
133 | mRoundRect.set(rx - r, ry - r, rx + r, ry + r);
134 | defaultJoinx = (float)(rx + sin45 * r);
135 | defaultJoiny = (float)(ry + sin45 * r);
136 |
137 | if (mState == SEARCH) {
138 | joinAngle = DEFAULT_JOIN_ANGLE;
139 | joinx = 0;
140 | joiny = 0;
141 | lineDelx = drawRight - drawLeft;
142 | } else if (mState == SEARCH) {
143 | joinAngle = DEGREE_360 + DEFAULT_JOIN_ANGLE;
144 | joinx = drawRight - defaultJoinx;
145 | joiny = drawBottom - defaultJoiny;
146 | lineDelx = 0;
147 | }
148 | mSearchTouchListener.setOther(mTmpOnTouchListener, mTouchRect);
149 | super.setOnTouchListener(mSearchTouchListener);
150 | }
151 |
152 | private float joinAngle = 0;
153 | private float joinx = 0;
154 | private float joiny = 0;
155 | private float lineDelx = 0;
156 |
157 | @Override
158 | protected void onDraw(Canvas canvas) {
159 | super.onDraw(canvas);
160 |
161 | mSearchPath.reset();
162 | mSearchPaint.setStrokeWidth(mBreadth);
163 | mSearchPath.addArc(mRoundRect, joinAngle, DEGREE_360 + DEFAULT_JOIN_ANGLE - joinAngle);
164 |
165 | mSearchPath.moveTo(defaultJoinx + joinx, defaultJoiny + joiny);
166 | mSearchPath.lineTo(drawRight, drawBottom);
167 |
168 | canvas.drawPath(mSearchPath, mSearchPaint);
169 |
170 | mSearchPaint.setStrokeWidth(2);
171 | mSearchPath.moveTo(drawRight, drawBottom);
172 | mSearchPath.lineTo(drawLeft + lineDelx, drawBottom);
173 |
174 | canvas.drawPath(mSearchPath, mSearchPaint);
175 | }
176 |
177 | public static enum State {
178 |
179 | RUNNING, SEARCH, LINE;
180 | }
181 |
182 | State mState = SEARCH;
183 |
184 | public void toggle() {
185 |
186 | switch (mState) {
187 | case RUNNING:
188 | break;
189 | case SEARCH:
190 | changeLine();
191 | break;
192 | case LINE:
193 | changeSearch();
194 | break;
195 | }
196 | }
197 |
198 | private class SearchTouchListener implements OnTouchListener {
199 |
200 | private OnTouchListener other;
201 | private RectF rect;
202 |
203 | private SearchTouchListener() {
204 | }
205 |
206 | public void setOther(OnTouchListener other,RectF rect ) {
207 | this.other = other;
208 | this.rect = rect;
209 | }
210 |
211 | @Override
212 | public boolean onTouch(View v, MotionEvent event) {
213 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
214 | float mx = event.getX();
215 | float my = event.getY();
216 | if (rect.contains(mx, my) && mClickSearchListener != null && mState == SEARCH) {
217 | mClickSearchListener.onClickSearch();
218 | }
219 | }
220 | if (other != null) {
221 | return other.onTouch(v, event);
222 | } else {
223 | return false;
224 | }
225 | }
226 | }
227 |
228 | private SearchTouchListener mSearchTouchListener = new SearchTouchListener();
229 |
230 | private OnTouchListener mTmpOnTouchListener = null;
231 | @Override
232 | public void setOnTouchListener(OnTouchListener l) {
233 | mTmpOnTouchListener = l;
234 | mSearchTouchListener.setOther(mTmpOnTouchListener, mTouchRect);
235 | super.setOnTouchListener(mSearchTouchListener);
236 | }
237 |
238 | public void changeLine() {
239 | if (mState == LINE) return;
240 | ObjectAnimator round = ObjectAnimator.ofFloat(this, joinAngleProperty, DEFAULT_JOIN_ANGLE, DEGREE_360 + DEFAULT_JOIN_ANGLE);
241 | round.setDuration(450);
242 | round.addUpdateListener(this);
243 |
244 | PropertyValuesHolder pvJx = PropertyValuesHolder.ofFloat(joinXProperty, 0f, drawRight - defaultJoinx);
245 | PropertyValuesHolder pvJy = PropertyValuesHolder.ofFloat(joinYProperty, 0f, drawBottom - defaultJoiny);
246 | ObjectAnimator bar = ObjectAnimator.ofPropertyValuesHolder(this, pvJx, pvJy);
247 | bar.setDuration(300);
248 | bar.addUpdateListener(this);
249 |
250 | ObjectAnimator line = ObjectAnimator.ofFloat(this, lineDelxProperty, drawRight - drawLeft, 0);
251 | line.setDuration(700);
252 | line.addUpdateListener(this);
253 |
254 | AnimatorSet animatorSet = new AnimatorSet();
255 | animatorSet.play(round).before(bar).with(line);
256 | animatorSet.addListener(new SimpleAnimatorListener() {
257 |
258 | @Override
259 | public void onAnimationEnd(Animator animator) {
260 | mState = LINE;
261 | mListener.onChange(mState);
262 | }
263 |
264 | @Override
265 | public void onAnimationStart(Animator animator) {
266 | mState = RUNNING;
267 | }
268 | });
269 | animatorSet.start();
270 | }
271 |
272 | public void changeSearch() {
273 | if (mState == SEARCH) return;
274 | ObjectAnimator round = ObjectAnimator.ofFloat(this, joinAngleProperty, DEGREE_360 + DEFAULT_JOIN_ANGLE, DEFAULT_JOIN_ANGLE);
275 | round.setDuration(450);
276 | round.addUpdateListener(this);
277 |
278 | PropertyValuesHolder pvJx = PropertyValuesHolder.ofFloat(joinXProperty, drawRight - defaultJoinx, 0f);
279 | PropertyValuesHolder pvJy = PropertyValuesHolder.ofFloat(joinYProperty, drawBottom - defaultJoiny, 0f);
280 | ObjectAnimator bar = ObjectAnimator.ofPropertyValuesHolder(this, pvJx, pvJy);
281 | bar.setDuration(300);
282 | bar.addUpdateListener(this);
283 |
284 | ObjectAnimator line = ObjectAnimator.ofFloat(this, lineDelxProperty, 0, drawRight - drawLeft);
285 | line.setDuration(700);
286 | line.addUpdateListener(this);
287 |
288 | AnimatorSet animatorSet = new AnimatorSet();
289 | animatorSet.play(bar).with(line);
290 | animatorSet.play(bar).before(round);
291 | animatorSet.addListener(new SimpleAnimatorListener() {
292 |
293 | @Override
294 | public void onAnimationEnd(Animator animator) {
295 | mState = SEARCH;
296 | mListener.onChange(mState);
297 | }
298 |
299 | @Override
300 | public void onAnimationStart(Animator animator) {
301 | mState = RUNNING;
302 | }
303 | });
304 | animatorSet.start();
305 | }
306 |
307 | private Property joinAngleProperty
308 | = new Property(Float.class, "joinAngle") {
309 | @Override
310 | public Float get(DribSearchView object) {
311 | return object.getJoinAngle();
312 | }
313 |
314 | @Override
315 | public void set(DribSearchView object, Float value) {
316 | object.setJoinAngle(value);
317 | }
318 | };
319 |
320 | private Property joinXProperty
321 | = new Property(Float.class, "joinx") {
322 | @Override
323 | public Float get(DribSearchView object) {
324 | return object.getJoinx();
325 | }
326 |
327 | @Override
328 | public void set(DribSearchView object, Float value) {
329 | object.setJoinx(value);
330 | }
331 | };
332 |
333 | private Property joinYProperty
334 | = new Property(Float.class, "joiny") {
335 | @Override
336 | public Float get(DribSearchView object) {
337 | return object.getJoiny();
338 | }
339 |
340 | @Override
341 | public void set(DribSearchView object, Float value) {
342 | object.setJoiny(value);
343 | }
344 | };
345 |
346 | private Property lineDelxProperty
347 | = new Property(Float.class, "lineDelx") {
348 | @Override
349 | public Float get(DribSearchView object) {
350 | return object.getLineDelx();
351 | }
352 |
353 | @Override
354 | public void set(DribSearchView object, Float value) {
355 | object.setLineDelx(value);
356 | }
357 | };
358 |
359 | private float getJoinAngle() {
360 | return joinAngle;
361 | }
362 |
363 | private void setJoinAngle(float joinAngle) {
364 | this.joinAngle = joinAngle;
365 | }
366 |
367 |
368 | private float getJoinx() {
369 | return joinx;
370 | }
371 |
372 | private void setJoinx(float joinx) {
373 | this.joinx = joinx;
374 | }
375 |
376 | private float getJoiny() {
377 | return joiny;
378 | }
379 |
380 | private void setJoiny(float joiny) {
381 | this.joiny = joiny;
382 | }
383 |
384 | private float getLineDelx() {
385 | return lineDelx;
386 | }
387 |
388 | private void setLineDelx(float lineDelx) {
389 | this.lineDelx = lineDelx;
390 | }
391 |
392 | @Override
393 | public void onAnimationUpdate(ValueAnimator valueAnimator) {
394 | invalidate();
395 | }
396 |
397 | private class SimpleAnimatorListener implements Animator.AnimatorListener {
398 |
399 | @Override
400 | public void onAnimationStart(Animator animator) {
401 |
402 | }
403 |
404 | @Override
405 | public void onAnimationEnd(Animator animator) {
406 |
407 | }
408 |
409 | @Override
410 | public void onAnimationCancel(Animator animator) {
411 |
412 | }
413 |
414 | @Override
415 | public void onAnimationRepeat(Animator animator) {
416 |
417 | }
418 | }
419 |
420 | public interface OnChangeListener {
421 |
422 | void onChange(State state);
423 | }
424 |
425 | private OnChangeListener mListener;
426 |
427 | public void setOnChangeListener(OnChangeListener listener) {
428 | mListener = listener;
429 | }
430 |
431 | public interface OnClickSearchListener {
432 | void onClickSearch();
433 | }
434 |
435 | private OnClickSearchListener mClickSearchListener;
436 |
437 | public void setOnClickSearchListener(OnClickSearchListener l) {
438 | mClickSearchListener = l;
439 | }
440 |
441 | @Override
442 | public Parcelable onSaveInstanceState() {
443 | Parcelable superState = super.onSaveInstanceState();
444 | SavedState savedState = new SavedState(superState);
445 | savedState.joinAngle = this.joinAngle;
446 | savedState.joinx = this.joinx;
447 | savedState.joiny = this.joiny;
448 | savedState.lineDelx = this.lineDelx;
449 | return savedState;
450 | }
451 |
452 | @Override
453 | public void onRestoreInstanceState(Parcelable state) {
454 | SavedState savedState = (SavedState) state;
455 | super.onRestoreInstanceState(savedState.getSuperState());
456 | this.joinAngle = savedState.joinAngle;
457 | this.joinx = savedState.joinx;
458 | this.joiny = savedState.joiny;
459 | this.lineDelx = savedState.lineDelx;
460 | invalidate();
461 | }
462 |
463 | private static class SavedState extends BaseSavedState {
464 |
465 | protected float joinAngle;
466 | protected float joinx;
467 | protected float joiny;
468 | protected float lineDelx;
469 |
470 | SavedState(Parcelable superState) {
471 | super(superState);
472 | }
473 |
474 | private SavedState(Parcel in) {
475 | super(in);
476 | }
477 |
478 | @Override
479 | public void writeToParcel(Parcel dest, int flags) {
480 | dest.writeFloat(this.joinAngle);
481 | dest.writeFloat(this.joinx);
482 | dest.writeFloat(this.joiny);
483 | dest.writeFloat(this.lineDelx);
484 | }
485 |
486 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
487 | public SavedState createFromParcel(Parcel source) {
488 | return new SavedState(source);
489 | }
490 |
491 | public SavedState[] newArray(int size) {
492 | return new SavedState[size];
493 | }
494 | };
495 | }
496 | }
497 |
--------------------------------------------------------------------------------