Skip to content

Commit 3eff5f7

Browse files
committed
Fixed bugs in top gravity support. Added second shadow version. Added paralax support.
1 parent 0445497 commit 3eff5f7

File tree

8 files changed

+388
-16
lines changed

8 files changed

+388
-16
lines changed

demo/res/layout/activity_demo.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
android:gravity="bottom"
1313
sothree:panelHeight="68dp"
1414
sothree:shadowHeight="4dp"
15+
sothree:paralaxOffset="100dp"
1516
sothree:dragView="@+id/name">
1617

1718
<LinearLayout

demo/res/values/styles.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
Theme customizations available in newer API levels can go in
1010
res/values-vXX/styles.xml, while customizations related to
1111
backward-compatibility can go here.
12-
-->
13-
<item name="android:windowActionBarOverlay">true</item>
12+
-->
1413
</style>
1514

1615
<!-- Application theme. -->

demo/src/com/sothree/slidinguppanel/demo/DemoActivity.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ protected void onCreate(Bundle savedInstanceState) {
2929
setContentView(R.layout.activity_demo);
3030

3131
SlidingUpPanelLayout layout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
32-
layout.setAnchorPoint(0.3f);
3332
layout.setPanelSlideListener(new PanelSlideListener() {
3433
@Override
3534
public void onPanelSlide(View panel, float slideOffset) {

library/res/drawable/below_shadow.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android">
3+
<gradient
4+
android:startColor="#20000000"
5+
android:endColor="@android:color/transparent"
6+
android:angle="270" >
7+
</gradient>
8+
</shape>

library/res/values/attrs.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<declare-styleable name="SlidingUpPanelLayout">
55
<attr name="panelHeight" format="dimension" />
66
<attr name="shadowHeight" format="dimension" />
7+
<attr name="paralaxOffset" format="dimension" />
78
<attr name="fadeColor" format="color" />
89
<attr name="flingVelocity" format="integer" />
910
<attr name="dragView" format="reference" />
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
package com.nineoldandroids.view.animation;
2+
3+
import android.graphics.Camera;
4+
import android.graphics.Matrix;
5+
import android.graphics.RectF;
6+
import android.os.Build;
7+
import android.view.View;
8+
import android.view.animation.Animation;
9+
import android.view.animation.Transformation;
10+
11+
import java.lang.ref.WeakReference;
12+
import java.util.WeakHashMap;
13+
14+
/**
15+
* A proxy class to allow for modifying post-3.0 view properties on all pre-3.0
16+
* platforms. <strong>DO NOT</strong> wrap your views with this class if you
17+
* are using {@code ObjectAnimator} as it will handle that itself.
18+
* Source:
19+
* http://grepcode.com/file/repo1.maven.org/maven2/com.nineoldandroids/library/2.4.0/com/nineoldandroids/view/animation/AnimatorProxy.java
20+
*/
21+
public final class AnimatorProxy extends Animation {
22+
/** Whether or not the current running platform needs to be proxied. */
23+
public static final boolean NEEDS_PROXY = Integer.valueOf(Build.VERSION.SDK).intValue() < Build.VERSION_CODES.HONEYCOMB;
24+
25+
private static final WeakHashMap<View, AnimatorProxy> PROXIES =
26+
new WeakHashMap<View, AnimatorProxy>();
27+
28+
/**
29+
* Create a proxy to allow for modifying post-3.0 view properties on all
30+
* pre-3.0 platforms. <strong>DO NOT</strong> wrap your views if you are
31+
* using {@code ObjectAnimator} as it will handle that itself.
32+
*
33+
* @param view View to wrap.
34+
* @return Proxy to post-3.0 properties.
35+
*/
36+
public static AnimatorProxy wrap(View view) {
37+
AnimatorProxy proxy = PROXIES.get(view);
38+
// This checks if the proxy already exists and whether it still is the animation of the given view
39+
if (proxy == null || proxy != view.getAnimation()) {
40+
proxy = new AnimatorProxy(view);
41+
PROXIES.put(view, proxy);
42+
}
43+
return proxy;
44+
}
45+
46+
private final WeakReference<View> mView;
47+
private final Camera mCamera = new Camera();
48+
private boolean mHasPivot;
49+
50+
private float mAlpha = 1;
51+
private float mPivotX;
52+
private float mPivotY;
53+
private float mRotationX;
54+
private float mRotationY;
55+
private float mRotationZ;
56+
private float mScaleX = 1;
57+
private float mScaleY = 1;
58+
private float mTranslationX;
59+
private float mTranslationY;
60+
61+
private final RectF mBefore = new RectF();
62+
private final RectF mAfter = new RectF();
63+
private final Matrix mTempMatrix = new Matrix();
64+
65+
private AnimatorProxy(View view) {
66+
setDuration(0); //perform transformation immediately
67+
setFillAfter(true); //persist transformation beyond duration
68+
view.setAnimation(this);
69+
mView = new WeakReference<View>(view);
70+
}
71+
72+
public float getAlpha() {
73+
return mAlpha;
74+
}
75+
public void setAlpha(float alpha) {
76+
if (mAlpha != alpha) {
77+
mAlpha = alpha;
78+
View view = mView.get();
79+
if (view != null) {
80+
view.invalidate();
81+
}
82+
}
83+
}
84+
public float getPivotX() {
85+
return mPivotX;
86+
}
87+
public void setPivotX(float pivotX) {
88+
if (!mHasPivot || mPivotX != pivotX) {
89+
prepareForUpdate();
90+
mHasPivot = true;
91+
mPivotX = pivotX;
92+
invalidateAfterUpdate();
93+
}
94+
}
95+
public float getPivotY() {
96+
return mPivotY;
97+
}
98+
public void setPivotY(float pivotY) {
99+
if (!mHasPivot || mPivotY != pivotY) {
100+
prepareForUpdate();
101+
mHasPivot = true;
102+
mPivotY = pivotY;
103+
invalidateAfterUpdate();
104+
}
105+
}
106+
public float getRotation() {
107+
return mRotationZ;
108+
}
109+
public void setRotation(float rotation) {
110+
if (mRotationZ != rotation) {
111+
prepareForUpdate();
112+
mRotationZ = rotation;
113+
invalidateAfterUpdate();
114+
}
115+
}
116+
public float getRotationX() {
117+
return mRotationX;
118+
}
119+
public void setRotationX(float rotationX) {
120+
if (mRotationX != rotationX) {
121+
prepareForUpdate();
122+
mRotationX = rotationX;
123+
invalidateAfterUpdate();
124+
}
125+
}
126+
public float getRotationY() {
127+
return mRotationY;
128+
}
129+
130+
public void setRotationY(float rotationY) {
131+
if (mRotationY != rotationY) {
132+
prepareForUpdate();
133+
mRotationY = rotationY;
134+
invalidateAfterUpdate();
135+
}
136+
}
137+
public float getScaleX() {
138+
return mScaleX;
139+
}
140+
public void setScaleX(float scaleX) {
141+
if (mScaleX != scaleX) {
142+
prepareForUpdate();
143+
mScaleX = scaleX;
144+
invalidateAfterUpdate();
145+
}
146+
}
147+
public float getScaleY() {
148+
return mScaleY;
149+
}
150+
public void setScaleY(float scaleY) {
151+
if (mScaleY != scaleY) {
152+
prepareForUpdate();
153+
mScaleY = scaleY;
154+
invalidateAfterUpdate();
155+
}
156+
}
157+
public int getScrollX() {
158+
View view = mView.get();
159+
if (view == null) {
160+
return 0;
161+
}
162+
return view.getScrollX();
163+
}
164+
public void setScrollX(int value) {
165+
View view = mView.get();
166+
if (view != null) {
167+
view.scrollTo(value, view.getScrollY());
168+
}
169+
}
170+
public int getScrollY() {
171+
View view = mView.get();
172+
if (view == null) {
173+
return 0;
174+
}
175+
return view.getScrollY();
176+
}
177+
public void setScrollY(int value) {
178+
View view = mView.get();
179+
if (view != null) {
180+
view.scrollTo(view.getScrollX(), value);
181+
}
182+
}
183+
184+
public float getTranslationX() {
185+
return mTranslationX;
186+
}
187+
public void setTranslationX(float translationX) {
188+
if (mTranslationX != translationX) {
189+
prepareForUpdate();
190+
mTranslationX = translationX;
191+
invalidateAfterUpdate();
192+
}
193+
}
194+
public float getTranslationY() {
195+
return mTranslationY;
196+
}
197+
public void setTranslationY(float translationY) {
198+
if (mTranslationY != translationY) {
199+
prepareForUpdate();
200+
mTranslationY = translationY;
201+
invalidateAfterUpdate();
202+
}
203+
}
204+
public float getX() {
205+
View view = mView.get();
206+
if (view == null) {
207+
return 0;
208+
}
209+
return view.getLeft() + mTranslationX;
210+
}
211+
public void setX(float x) {
212+
View view = mView.get();
213+
if (view != null) {
214+
setTranslationX(x - view.getLeft());
215+
}
216+
}
217+
public float getY() {
218+
View view = mView.get();
219+
if (view == null) {
220+
return 0;
221+
}
222+
return view.getTop() + mTranslationY;
223+
}
224+
public void setY(float y) {
225+
View view = mView.get();
226+
if (view != null) {
227+
setTranslationY(y - view.getTop());
228+
}
229+
}
230+
231+
private void prepareForUpdate() {
232+
View view = mView.get();
233+
if (view != null) {
234+
computeRect(mBefore, view);
235+
}
236+
}
237+
private void invalidateAfterUpdate() {
238+
View view = mView.get();
239+
if (view == null || view.getParent() == null) {
240+
return;
241+
}
242+
243+
final RectF after = mAfter;
244+
computeRect(after, view);
245+
after.union(mBefore);
246+
247+
((View)view.getParent()).invalidate(
248+
(int) Math.floor(after.left),
249+
(int) Math.floor(after.top),
250+
(int) Math.ceil(after.right),
251+
(int) Math.ceil(after.bottom));
252+
}
253+
254+
private void computeRect(final RectF r, View view) {
255+
// compute current rectangle according to matrix transformation
256+
final float w = view.getWidth();
257+
final float h = view.getHeight();
258+
259+
// use a rectangle at 0,0 to make sure we don't run into issues with scaling
260+
r.set(0, 0, w, h);
261+
262+
final Matrix m = mTempMatrix;
263+
m.reset();
264+
transformMatrix(m, view);
265+
mTempMatrix.mapRect(r);
266+
267+
r.offset(view.getLeft(), view.getTop());
268+
269+
// Straighten coords if rotations flipped them
270+
if (r.right < r.left) {
271+
final float f = r.right;
272+
r.right = r.left;
273+
r.left = f;
274+
}
275+
if (r.bottom < r.top) {
276+
final float f = r.top;
277+
r.top = r.bottom;
278+
r.bottom = f;
279+
}
280+
}
281+
282+
private void transformMatrix(Matrix m, View view) {
283+
final float w = view.getWidth();
284+
final float h = view.getHeight();
285+
final boolean hasPivot = mHasPivot;
286+
final float pX = hasPivot ? mPivotX : w / 2f;
287+
final float pY = hasPivot ? mPivotY : h / 2f;
288+
289+
final float rX = mRotationX;
290+
final float rY = mRotationY;
291+
final float rZ = mRotationZ;
292+
if ((rX != 0) || (rY != 0) || (rZ != 0)) {
293+
final Camera camera = mCamera;
294+
camera.save();
295+
camera.rotateX(rX);
296+
camera.rotateY(rY);
297+
camera.rotateZ(-rZ);
298+
camera.getMatrix(m);
299+
camera.restore();
300+
m.preTranslate(-pX, -pY);
301+
m.postTranslate(pX, pY);
302+
}
303+
304+
final float sX = mScaleX;
305+
final float sY = mScaleY;
306+
if ((sX != 1.0f) || (sY != 1.0f)) {
307+
m.postScale(sX, sY);
308+
final float sPX = -(pX / w) * ((sX * w) - w);
309+
final float sPY = -(pY / h) * ((sY * h) - h);
310+
m.postTranslate(sPX, sPY);
311+
}
312+
313+
m.postTranslate(mTranslationX, mTranslationY);
314+
}
315+
316+
@Override
317+
protected void applyTransformation(float interpolatedTime, Transformation t) {
318+
View view = mView.get();
319+
if (view != null) {
320+
t.setAlpha(mAlpha);
321+
transformMatrix(t.getMatrix(), view);
322+
}
323+
}
324+
}

0 commit comments

Comments
 (0)