Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
jami-client-android
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Requirements
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
savoirfairelinux
jami-client-android
Commits
2c0e9745
Commit
2c0e9745
authored
Nov 26, 2013
by
Alexandre Lision
Browse files
Options
Downloads
Patches
Plain Diff
v3: delete old ContactDrawer component
parent
5702b37b
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/org/sflphone/views/CustomSlidingDrawer.java
+0
-1032
0 additions, 1032 deletions
src/org/sflphone/views/CustomSlidingDrawer.java
src/org/sflphone/views/SlidingUpPanelLayout.java
+0
-4
0 additions, 4 deletions
src/org/sflphone/views/SlidingUpPanelLayout.java
with
0 additions
and
1036 deletions
src/org/sflphone/views/CustomSlidingDrawer.java
deleted
100644 → 0
+
0
−
1032
View file @
5702b37b
/*
* Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
*
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
package
org.sflphone.views
;
import
java.lang.ref.WeakReference
;
import
org.sflphone.R
;
import
android.content.Context
;
import
android.content.res.Resources
;
import
android.content.res.TypedArray
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Rect
;
import
android.os.Handler
;
import
android.os.Message
;
import
android.os.SystemClock
;
import
android.util.AttributeSet
;
import
android.util.TypedValue
;
import
android.view.MotionEvent
;
import
android.view.SoundEffectConstants
;
import
android.view.VelocityTracker
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.view.accessibility.AccessibilityEvent
;
/**
* SlidingDrawer hides content out of the screen and allows the user to drag a handle to bring the content on screen. SlidingDrawer can be used
* vertically or horizontally.
*
* A special widget composed of two children views: the handle, that the users drags, and the content, attached to the handle and dragged with it.
*
* SlidingDrawer should be used as an overlay inside layouts. This means SlidingDrawer should only be used inside of a FrameLayout or a RelativeLayout
* for instance. The size of the SlidingDrawer defines how much space the content will occupy once slid out so SlidingDrawer should usually use
* match_parent for both its dimensions.
*
* Inside an XML layout, SlidingDrawer must define the id of the handle and of the content:
*
* <pre class="prettyprint">
* <SlidingDrawer
* android:id="@+id/drawer"
* android:layout_width="match_parent"
* android:layout_height="match_parent"
*
* android:handle="@+id/handle"
* android:content="@+id/content">
*
* <ImageView
* android:id="@id/handle"
* android:layout_width="88dip"
* android:layout_height="44dip" />
*
* <GridView
* android:id="@id/content"
* android:layout_width="match_parent"
* android:layout_height="match_parent" />
*
* </SlidingDrawer>
* </pre>
*
* @attr ref android.R.styleable#SlidingDrawer_content
* @attr ref android.R.styleable#SlidingDrawer_handle
* @attr ref android.R.styleable#SlidingDrawer_topOffset
* @attr ref android.R.styleable#SlidingDrawer_bottomOffset
* @attr ref android.R.styleable#SlidingDrawer_orientation
* @attr ref android.R.styleable#SlidingDrawer_allowSingleTap
* @attr ref android.R.styleable#SlidingDrawer_animateOnClick
*
*/
public
class
CustomSlidingDrawer
extends
ViewGroup
{
public
static
final
int
ORIENTATION_HORIZONTAL
=
0
;
public
static
final
int
ORIENTATION_VERTICAL
=
1
;
private
static
final
int
TAP_THRESHOLD
=
6
;
private
static
final
float
MAXIMUM_TAP_VELOCITY
=
100.0f
;
private
static
final
float
MAXIMUM_MINOR_VELOCITY
=
150.0f
;
private
static
final
float
MAXIMUM_MAJOR_VELOCITY
=
200.0f
;
private
static
final
float
MAXIMUM_ACCELERATION
=
2000.0f
;
private
static
final
int
VELOCITY_UNITS
=
1000
;
private
static
final
int
MSG_ANIMATE
=
1000
;
private
static
final
int
ANIMATION_FRAME_DURATION
=
1000
/
60
;
private
static
final
int
EXPANDED_FULL_OPEN
=
-
10001
;
private
static
final
int
COLLAPSED_FULL_CLOSED
=
-
10002
;
private
static
final
String
TAG
=
CustomSlidingDrawer
.
class
.
getSimpleName
();
private
final
int
mHandleId
;
private
final
int
mContentId
;
private
View
mHandle
;
private
View
mTrackHandle
;
private
View
mContent
;
private
final
Rect
mFrame
=
new
Rect
();
private
final
Rect
mInvalidate
=
new
Rect
();
private
boolean
mTracking
;
private
boolean
mLocked
;
private
VelocityTracker
mVelocityTracker
;
private
boolean
mVertical
;
private
boolean
mExpanded
;
private
int
mBottomOffset
;
private
int
mTopOffset
;
private
int
mHandleHeight
;
private
int
mHandleWidth
;
private
OnDrawerOpenListener
mOnDrawerOpenListener
;
private
OnDrawerCloseListener
mOnDrawerCloseListener
;
private
OnDrawerScrollListener
mOnDrawerScrollListener
;
private
SlidingHandler
mHandler
;
private
float
mAnimatedAcceleration
;
private
float
mAnimatedVelocity
;
private
float
mAnimationPosition
;
private
long
mAnimationLastTime
;
private
long
mCurrentAnimationTime
;
private
int
mTouchDelta
;
private
boolean
mAnimating
;
private
boolean
mAllowSingleTap
;
private
boolean
mAnimateOnClick
;
private
final
int
mTapThreshold
;
private
final
int
mMaximumTapVelocity
;
private
final
int
mMaximumMinorVelocity
;
private
final
int
mMaximumMajorVelocity
;
private
final
int
mMaximumAcceleration
;
private
final
int
mVelocityUnits
;
private
long
pressTime
;
/**
* Callback invoked when the drawer is opened.
*/
public
static
interface
OnDrawerOpenListener
{
/**
* Invoked when the drawer becomes fully open.
*/
public
void
onDrawerOpened
();
}
/**
* Callback invoked when the drawer is closed.
*/
public
static
interface
OnDrawerCloseListener
{
/**
* Invoked when the drawer becomes fully closed.
*/
public
void
onDrawerClosed
();
}
/**
* Callback invoked when the drawer is scrolled.
*/
public
static
interface
OnDrawerScrollListener
{
/**
* Invoked when the user starts dragging/flinging the drawer's handle.
*/
public
void
onScrollStarted
();
/**
* Invoked when the user stops dragging/flinging the drawer's handle.
*/
public
void
onScrollEnded
();
/**
* Invoked when the user stops dragging/flinging the drawer's handle.
*
* @param i
*/
public
void
onScroll
(
int
i
);
}
/**
* Creates a new SlidingDrawer from a specified set of attributes defined in XML.
*
* @param context
* The application's environment.
* @param attrs
* The attributes defined in XML.
*/
public
CustomSlidingDrawer
(
Context
context
,
AttributeSet
attrs
)
{
this
(
context
,
attrs
,
0
);
}
/**
* Creates a new SlidingDrawer from a specified set of attributes defined in XML.
*
* @param context
* The application's environment.
* @param attrs
* The attributes defined in XML.
* @param defStyle
* The style to apply to this widget.
*/
public
CustomSlidingDrawer
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
TypedArray
a
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
CustomSlidingDrawer
,
defStyle
,
0
);
mHandler
=
new
SlidingHandler
(
this
);
int
orientation
=
a
.
getInt
(
R
.
styleable
.
CustomSlidingDrawer_orientation
,
ORIENTATION_VERTICAL
);
mVertical
=
orientation
==
ORIENTATION_VERTICAL
;
mBottomOffset
=
(
int
)
a
.
getDimension
(
R
.
styleable
.
CustomSlidingDrawer_bottomOffset
,
0.0f
);
mTopOffset
=
(
int
)
a
.
getDimension
(
R
.
styleable
.
CustomSlidingDrawer_topOffset
,
0.0f
)
-
5
;
mAllowSingleTap
=
a
.
getBoolean
(
R
.
styleable
.
CustomSlidingDrawer_allowSingleTap
,
false
);
mAnimateOnClick
=
a
.
getBoolean
(
R
.
styleable
.
CustomSlidingDrawer_animateOnClick
,
false
);
int
handleId
=
a
.
getResourceId
(
R
.
styleable
.
CustomSlidingDrawer_handle
,
0
);
if
(
handleId
==
0
)
{
throw
new
IllegalArgumentException
(
"The handle attribute is required and must refer "
+
"to a valid child."
);
}
int
contentId
=
a
.
getResourceId
(
R
.
styleable
.
CustomSlidingDrawer_content
,
0
);
if
(
contentId
==
0
)
{
throw
new
IllegalArgumentException
(
"The content attribute is required and must refer "
+
"to a valid child."
);
}
if
(
handleId
==
contentId
)
{
throw
new
IllegalArgumentException
(
"The content and handle attributes must refer "
+
"to different children."
);
}
mHandleId
=
handleId
;
mContentId
=
contentId
;
final
float
density
=
getResources
().
getDisplayMetrics
().
density
>
2
?
2
:
getResources
().
getDisplayMetrics
().
density
;
mTapThreshold
=
(
int
)
(
TAP_THRESHOLD
*
density
+
0.5f
);
mMaximumTapVelocity
=
(
int
)
(
MAXIMUM_TAP_VELOCITY
*
density
+
0.5f
);
mMaximumMinorVelocity
=
(
int
)
(
MAXIMUM_MINOR_VELOCITY
*
density
+
0.5f
);
mMaximumMajorVelocity
=
(
int
)
(
MAXIMUM_MAJOR_VELOCITY
*
density
+
0.5f
);
mMaximumAcceleration
=
(
int
)
(
MAXIMUM_ACCELERATION
*
density
+
0.5f
);
mVelocityUnits
=
(
int
)
(
VELOCITY_UNITS
*
density
+
0.5f
);
a
.
recycle
();
setAlwaysDrawnWithCacheEnabled
(
false
);
}
@Override
protected
void
onFinishInflate
()
{
mHandle
=
findViewById
(
mHandleId
);
if
(
mHandle
==
null
)
{
throw
new
IllegalArgumentException
(
"The handle attribute is must refer to an"
+
" existing child."
);
}
mHandle
.
setOnClickListener
(
new
DrawerToggler
());
mContent
=
findViewById
(
mContentId
);
if
(
mContent
==
null
)
{
throw
new
IllegalArgumentException
(
"The content attribute is must refer to an"
+
" existing child."
);
}
mContent
.
setVisibility
(
View
.
GONE
);
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
int
widthSpecMode
=
MeasureSpec
.
getMode
(
widthMeasureSpec
);
int
widthSpecSize
=
MeasureSpec
.
getSize
(
widthMeasureSpec
);
int
heightSpecMode
=
MeasureSpec
.
getMode
(
heightMeasureSpec
);
int
heightSpecSize
=
MeasureSpec
.
getSize
(
heightMeasureSpec
);
if
(
widthSpecMode
==
MeasureSpec
.
UNSPECIFIED
||
heightSpecMode
==
MeasureSpec
.
UNSPECIFIED
)
{
throw
new
RuntimeException
(
"SlidingDrawer cannot have UNSPECIFIED dimensions"
);
}
final
View
handle
=
mHandle
;
measureChild
(
handle
,
widthMeasureSpec
,
heightMeasureSpec
);
if
(
mVertical
)
{
int
height
=
heightSpecSize
-
handle
.
getMeasuredHeight
()
-
mTopOffset
;
// Log.i("CustomSliding","heightSpecSize:"+heightSpecSize);
mContent
.
measure
(
MeasureSpec
.
makeMeasureSpec
(
widthSpecSize
,
MeasureSpec
.
EXACTLY
),
MeasureSpec
.
makeMeasureSpec
(
height
,
MeasureSpec
.
EXACTLY
));
}
else
{
int
width
=
widthSpecSize
-
handle
.
getMeasuredWidth
()
-
mTopOffset
;
mContent
.
measure
(
MeasureSpec
.
makeMeasureSpec
(
width
,
MeasureSpec
.
EXACTLY
),
MeasureSpec
.
makeMeasureSpec
(
heightSpecSize
,
MeasureSpec
.
EXACTLY
));
}
setMeasuredDimension
(
widthSpecSize
,
heightSpecSize
);
}
@Override
protected
void
dispatchDraw
(
Canvas
canvas
)
{
final
long
drawingTime
=
getDrawingTime
();
final
View
handle
=
mHandle
;
final
boolean
isVertical
=
mVertical
;
drawChild
(
canvas
,
handle
,
drawingTime
);
if
(
mTracking
||
mAnimating
)
{
final
Bitmap
cache
=
mContent
.
getDrawingCache
();
if
(
cache
!=
null
)
{
if
(
isVertical
)
{
canvas
.
drawBitmap
(
cache
,
0
,
handle
.
getBottom
(),
null
);
}
else
{
canvas
.
drawBitmap
(
cache
,
handle
.
getRight
(),
0
,
null
);
}
}
else
{
canvas
.
save
();
canvas
.
translate
(
isVertical
?
0
:
handle
.
getLeft
()
-
mTopOffset
,
isVertical
?
handle
.
getTop
()
-
mTopOffset
:
0
);
drawChild
(
canvas
,
mContent
,
drawingTime
);
canvas
.
restore
();
}
}
else
if
(
mExpanded
)
{
drawChild
(
canvas
,
mContent
,
drawingTime
);
}
}
@Override
protected
void
onLayout
(
boolean
changed
,
int
l
,
int
t
,
int
r
,
int
b
)
{
if
(
mTracking
)
{
return
;
}
final
int
width
=
r
-
l
;
final
int
height
=
b
-
t
;
// Log.i("Drawer","onLayout, height:"+height);
final
View
handle
=
mHandle
;
int
childWidth
=
handle
.
getMeasuredWidth
();
int
childHeight
=
handle
.
getMeasuredHeight
();
int
childLeft
;
int
childTop
;
final
View
content
=
mContent
;
if
(
mVertical
)
{
childLeft
=
(
width
-
childWidth
)
/
2
;
childTop
=
mExpanded
?
mTopOffset
:
height
-
childHeight
+
mBottomOffset
;
content
.
layout
(
0
,
mTopOffset
+
childHeight
,
content
.
getMeasuredWidth
(),
mTopOffset
+
childHeight
+
content
.
getMeasuredHeight
());
}
else
{
childLeft
=
mExpanded
?
mTopOffset
:
width
-
childWidth
+
mBottomOffset
;
childTop
=
(
height
-
childHeight
)
/
2
;
content
.
layout
(
mTopOffset
+
childWidth
,
0
,
mTopOffset
+
childWidth
+
content
.
getMeasuredWidth
(),
content
.
getMeasuredHeight
());
}
handle
.
layout
(
childLeft
,
childTop
,
childLeft
+
childWidth
,
childTop
+
childHeight
);
mHandleHeight
=
handle
.
getHeight
();
mHandleWidth
=
handle
.
getWidth
();
}
@Override
public
boolean
onInterceptTouchEvent
(
MotionEvent
event
)
{
// Log.i("SlidingDrawer", "onInterceptTouchEvent");
if
(
mLocked
)
{
// Log.i(TAG, "Locked");
return
false
;
}
final
int
action
=
event
.
getAction
();
float
x
=
event
.
getX
();
float
y
=
event
.
getY
();
final
Rect
frame
=
mFrame
;
final
View
handle
=
mHandle
;
// New code
View
trackHandle
=
mTrackHandle
;
// set the rect frame to the mTrackHandle view borders instead of the
// hole handle view
Resources
r
=
getResources
();
int
px
=
(
int
)
TypedValue
.
applyDimension
(
TypedValue
.
COMPLEX_UNIT_DIP
,
50
,
r
.
getDisplayMetrics
());
// getParent() => The right and left are valid, but we need to get the
// parent top and bottom to have absolute values (in screen)
frame
.
set
(
trackHandle
.
getLeft
(),
trackHandle
.
getTop
(),
trackHandle
.
getRight
()
-
px
,
trackHandle
.
getBottom
());
// handle.getHitRect(frame);
if
(!
mTracking
&&
!
frame
.
contains
((
int
)
x
,
(
int
)
y
))
{
return
false
;
}
if
(
action
==
MotionEvent
.
ACTION_DOWN
)
{
mTracking
=
true
;
// Log.i(TAG, "action down");
handle
.
setPressed
(
true
);
// Must be called before prepareTracking()
prepareContent
();
pressTime
=
System
.
currentTimeMillis
();
// Must be called after prepareContent()
if
(
mOnDrawerScrollListener
!=
null
)
{
mOnDrawerScrollListener
.
onScrollStarted
();
}
if
(
mVertical
)
{
final
int
top
=
mHandle
.
getTop
();
mTouchDelta
=
(
int
)
y
-
top
;
prepareTracking
(
top
);
}
else
{
final
int
left
=
mHandle
.
getLeft
();
mTouchDelta
=
(
int
)
x
-
left
;
prepareTracking
(
left
);
}
mVelocityTracker
.
addMovement
(
event
);
return
true
;
}
return
false
;
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
if
(
mLocked
)
{
return
true
;
}
if
(
mTracking
)
{
mVelocityTracker
.
addMovement
(
event
);
final
int
action
=
event
.
getAction
();
switch
(
action
)
{
case
MotionEvent
.
ACTION_MOVE
:
moveHandle
((
int
)
(
mVertical
?
event
.
getY
()
:
event
.
getX
())
-
mTouchDelta
);
break
;
case
MotionEvent
.
ACTION_UP
:
if
(
System
.
currentTimeMillis
()
-
pressTime
<=
100
)
{
animateToggle
();
break
;
}
case
MotionEvent
.
ACTION_CANCEL
:
{
final
VelocityTracker
velocityTracker
=
mVelocityTracker
;
velocityTracker
.
computeCurrentVelocity
(
mVelocityUnits
);
float
yVelocity
=
velocityTracker
.
getYVelocity
();
float
xVelocity
=
velocityTracker
.
getXVelocity
();
boolean
negative
;
final
boolean
vertical
=
mVertical
;
if
(
vertical
)
{
negative
=
yVelocity
<
0
;
if
(
xVelocity
<
0
)
{
xVelocity
=
-
xVelocity
;
}
if
(
xVelocity
>
mMaximumMinorVelocity
)
{
xVelocity
=
mMaximumMinorVelocity
;
}
}
else
{
negative
=
xVelocity
<
0
;
if
(
yVelocity
<
0
)
{
yVelocity
=
-
yVelocity
;
}
if
(
yVelocity
>
mMaximumMinorVelocity
)
{
yVelocity
=
mMaximumMinorVelocity
;
}
}
float
velocity
=
(
float
)
Math
.
hypot
(
xVelocity
,
yVelocity
);
if
(
negative
)
{
velocity
=
-
velocity
;
}
final
int
top
=
mHandle
.
getTop
();
final
int
left
=
mHandle
.
getLeft
();
if
(
Math
.
abs
(
velocity
)
<
mMaximumTapVelocity
)
{
if
(
vertical
?
(
mExpanded
&&
top
<
mTapThreshold
+
mTopOffset
)
||
(!
mExpanded
&&
top
>
mBottomOffset
+
getBottom
()
-
getTop
()
-
mHandleHeight
-
mTapThreshold
)
:
(
mExpanded
&&
left
<
mTapThreshold
+
mTopOffset
)
||
(!
mExpanded
&&
left
>
mBottomOffset
+
getRight
()
-
getLeft
()
-
mHandleWidth
-
mTapThreshold
))
{
if
(
mAllowSingleTap
)
{
playSoundEffect
(
SoundEffectConstants
.
CLICK
);
if
(
mExpanded
)
{
animateClose
(
vertical
?
top
:
left
);
}
else
{
animateOpen
(
vertical
?
top
:
left
);
}
}
else
{
performFling
(
vertical
?
top
:
left
,
velocity
,
false
);
}
}
else
{
performFling
(
vertical
?
top
:
left
,
velocity
,
false
);
}
}
else
{
performFling
(
vertical
?
top
:
left
,
velocity
,
false
);
}
}
break
;
}
}
return
mTracking
||
mAnimating
||
super
.
onTouchEvent
(
event
);
}
private
void
animateClose
(
int
position
)
{
prepareTracking
(
position
);
performFling
(
position
,
mMaximumAcceleration
,
true
);
}
private
void
animateOpen
(
int
position
)
{
prepareTracking
(
position
);
performFling
(
position
,
-
mMaximumAcceleration
,
true
);
}
private
void
performFling
(
int
position
,
float
velocity
,
boolean
always
)
{
mAnimationPosition
=
position
;
mAnimatedVelocity
=
velocity
;
if
(
mExpanded
)
{
if
(
always
||
(
velocity
>
mMaximumMajorVelocity
||
(
position
>
mTopOffset
+
(
mVertical
?
mHandleHeight
:
mHandleWidth
)
&&
velocity
>
-
mMaximumMajorVelocity
)))
{
// We are expanded, but they didn't move sufficiently to cause
// us to retract. Animate back to the expanded position.
mAnimatedAcceleration
=
mMaximumAcceleration
;
if
(
velocity
<
0
)
{
mAnimatedVelocity
=
0
;
}
}
else
{
// We are expanded and are now going to animate away.
mAnimatedAcceleration
=
-
mMaximumAcceleration
;
if
(
velocity
>
0
)
{
mAnimatedVelocity
=
0
;
}
}
}
else
{
if
(!
always
&&
(
velocity
>
mMaximumMajorVelocity
||
(
position
>
(
mVertical
?
getHeight
()
:
getWidth
())
/
2
&&
velocity
>
-
mMaximumMajorVelocity
)))
{
// We are collapsed, and they moved enough to allow us to
// expand.
mAnimatedAcceleration
=
mMaximumAcceleration
;
if
(
velocity
<
0
)
{
mAnimatedVelocity
=
0
;
}
}
else
{
// We are collapsed, but they didn't move sufficiently to cause
// us to retract. Animate back to the collapsed position.
mAnimatedAcceleration
=
-
mMaximumAcceleration
;
if
(
velocity
>
0
)
{
mAnimatedVelocity
=
0
;
}
}
}
long
now
=
SystemClock
.
uptimeMillis
();
mAnimationLastTime
=
now
;
mCurrentAnimationTime
=
now
+
ANIMATION_FRAME_DURATION
;
mAnimating
=
true
;
mHandler
.
removeMessages
(
MSG_ANIMATE
);
mHandler
.
sendMessageAtTime
(
mHandler
.
obtainMessage
(
MSG_ANIMATE
),
mCurrentAnimationTime
);
stopTracking
();
}
private
void
prepareTracking
(
int
position
)
{
mTracking
=
true
;
mVelocityTracker
=
VelocityTracker
.
obtain
();
boolean
opening
=
!
mExpanded
;
if
(
opening
)
{
mAnimatedAcceleration
=
mMaximumAcceleration
;
mAnimatedVelocity
=
mMaximumMajorVelocity
;
mAnimationPosition
=
mBottomOffset
+
(
mVertical
?
getHeight
()
-
mHandleHeight
:
getWidth
()
-
mHandleWidth
);
moveHandle
((
int
)
mAnimationPosition
);
mAnimating
=
true
;
mHandler
.
removeMessages
(
MSG_ANIMATE
);
long
now
=
SystemClock
.
uptimeMillis
();
mAnimationLastTime
=
now
;
mCurrentAnimationTime
=
now
+
ANIMATION_FRAME_DURATION
;
mAnimating
=
true
;
}
else
{
if
(
mAnimating
)
{
mAnimating
=
false
;
mHandler
.
removeMessages
(
MSG_ANIMATE
);
}
moveHandle
(
position
);
}
}
private
void
moveHandle
(
int
position
)
{
final
View
handle
=
mHandle
;
if
(
mVertical
)
{
if
(
position
==
EXPANDED_FULL_OPEN
)
{
handle
.
offsetTopAndBottom
(
mTopOffset
-
handle
.
getTop
());
invalidate
();
}
else
if
(
position
==
COLLAPSED_FULL_CLOSED
)
{
handle
.
offsetTopAndBottom
(
mBottomOffset
+
getBottom
()
-
getTop
()
-
mHandleHeight
-
handle
.
getTop
());
invalidate
();
}
else
{
final
int
top
=
handle
.
getTop
();
int
deltaY
=
position
-
top
;
if
(
position
<
mTopOffset
)
{
deltaY
=
mTopOffset
-
top
;
}
else
if
(
deltaY
>
mBottomOffset
+
getBottom
()
-
getTop
()
-
mHandleHeight
-
top
)
{
deltaY
=
mBottomOffset
+
getBottom
()
-
getTop
()
-
mHandleHeight
-
top
;
}
handle
.
offsetTopAndBottom
(
deltaY
);
final
Rect
frame
=
mFrame
;
final
Rect
region
=
mInvalidate
;
handle
.
getHitRect
(
frame
);
region
.
set
(
frame
);
region
.
union
(
frame
.
left
,
frame
.
top
-
deltaY
,
frame
.
right
,
frame
.
bottom
-
deltaY
);
region
.
union
(
0
,
frame
.
bottom
-
deltaY
,
getWidth
(),
frame
.
bottom
-
deltaY
+
mContent
.
getHeight
());
invalidate
(
region
);
if
(
mOnDrawerScrollListener
!=
null
)
{
mOnDrawerScrollListener
.
onScroll
(
handle
.
getTop
());
}
}
}
else
{
if
(
position
==
EXPANDED_FULL_OPEN
)
{
handle
.
offsetLeftAndRight
(
mTopOffset
-
handle
.
getLeft
());
invalidate
();
}
else
if
(
position
==
COLLAPSED_FULL_CLOSED
)
{
handle
.
offsetLeftAndRight
(
mBottomOffset
+
getRight
()
-
getLeft
()
-
mHandleWidth
-
handle
.
getLeft
());
invalidate
();
}
else
{
final
int
left
=
handle
.
getLeft
();
int
deltaX
=
position
-
left
;
if
(
position
<
mTopOffset
)
{
deltaX
=
mTopOffset
-
left
;
}
else
if
(
deltaX
>
mBottomOffset
+
getRight
()
-
getLeft
()
-
mHandleWidth
-
left
)
{
deltaX
=
mBottomOffset
+
getRight
()
-
getLeft
()
-
mHandleWidth
-
left
;
}
handle
.
offsetLeftAndRight
(
deltaX
);
final
Rect
frame
=
mFrame
;
final
Rect
region
=
mInvalidate
;
handle
.
getHitRect
(
frame
);
region
.
set
(
frame
);
region
.
union
(
frame
.
left
-
deltaX
,
frame
.
top
,
frame
.
right
-
deltaX
,
frame
.
bottom
);
region
.
union
(
frame
.
right
-
deltaX
,
0
,
frame
.
right
-
deltaX
+
mContent
.
getWidth
(),
getHeight
());
invalidate
(
region
);
}
}
}
private
void
prepareContent
()
{
if
(
mAnimating
)
{
return
;
}
// Something changed in the content, we need to honor the layout request
// before creating the cached bitmap
final
View
content
=
mContent
;
if
(
content
.
isLayoutRequested
())
{
if
(
mVertical
)
{
final
int
childHeight
=
mHandleHeight
;
int
height
=
getBottom
()
-
getTop
()
-
childHeight
-
mTopOffset
;
content
.
measure
(
MeasureSpec
.
makeMeasureSpec
(
getRight
()
-
getLeft
(),
MeasureSpec
.
EXACTLY
),
MeasureSpec
.
makeMeasureSpec
(
height
,
MeasureSpec
.
EXACTLY
));
content
.
layout
(
0
,
mTopOffset
+
childHeight
,
content
.
getMeasuredWidth
(),
mTopOffset
+
childHeight
+
content
.
getMeasuredHeight
());
}
else
{
final
int
childWidth
=
mHandle
.
getWidth
();
int
width
=
getRight
()
-
getLeft
()
-
childWidth
-
mTopOffset
;
content
.
measure
(
MeasureSpec
.
makeMeasureSpec
(
width
,
MeasureSpec
.
EXACTLY
),
MeasureSpec
.
makeMeasureSpec
(
getBottom
()
-
getTop
(),
MeasureSpec
.
EXACTLY
));
content
.
layout
(
childWidth
+
mTopOffset
,
0
,
mTopOffset
+
childWidth
+
content
.
getMeasuredWidth
(),
content
.
getMeasuredHeight
());
}
}
// Try only once... we should really loop but it's not a big deal
// if the draw was cancelled, it will only be temporary anyway
content
.
getViewTreeObserver
().
dispatchOnPreDraw
();
// if (!content.isHardwareAccelerated()) content.buildDrawingCache();
content
.
setVisibility
(
View
.
GONE
);
}
private
void
stopTracking
()
{
mHandle
.
setPressed
(
false
);
mTracking
=
false
;
if
(
mOnDrawerScrollListener
!=
null
)
{
mOnDrawerScrollListener
.
onScrollEnded
();
}
if
(
mVelocityTracker
!=
null
)
{
mVelocityTracker
.
recycle
();
mVelocityTracker
=
null
;
}
}
private
void
doAnimation
()
{
if
(
mAnimating
)
{
incrementAnimation
();
if
(
mAnimationPosition
>=
mBottomOffset
+
(
mVertical
?
getHeight
()
:
getWidth
())
-
1
)
{
mAnimating
=
false
;
closeDrawer
();
}
else
if
(
mAnimationPosition
<
mTopOffset
)
{
mAnimating
=
false
;
openDrawer
();
}
else
{
moveHandle
((
int
)
mAnimationPosition
);
mCurrentAnimationTime
+=
ANIMATION_FRAME_DURATION
;
mHandler
.
sendMessageAtTime
(
mHandler
.
obtainMessage
(
MSG_ANIMATE
),
mCurrentAnimationTime
);
}
}
}
private
void
incrementAnimation
()
{
long
now
=
SystemClock
.
uptimeMillis
();
float
t
=
(
now
-
mAnimationLastTime
)
/
1000.0f
;
// ms -> s
final
float
position
=
mAnimationPosition
;
final
float
v
=
mAnimatedVelocity
;
// px/s
final
float
a
=
mAnimatedAcceleration
;
// px/s/s
mAnimationPosition
=
position
+
(
v
*
t
)
+
(
0.5f
*
a
*
t
*
t
);
// px
mAnimatedVelocity
=
v
+
(
a
*
t
);
// px/s
mAnimationLastTime
=
now
;
// ms
}
/**
* Toggles the drawer open and close. Takes effect immediately.
*
* @see #open()
* @see #close()
* @see #animateClose()
* @see #animateOpen()
* @see #animateToggle()
*/
public
void
toggle
()
{
if
(!
mExpanded
)
{
openDrawer
();
}
else
{
closeDrawer
();
}
invalidate
();
requestLayout
();
}
/**
* Toggles the drawer open and close with an animation.
*
* @see #open()
* @see #close()
* @see #animateClose()
* @see #animateOpen()
* @see #toggle()
*/
public
void
animateToggle
()
{
if
(!
mExpanded
)
{
animateOpen
();
}
else
{
animateClose
();
}
}
/**
* Opens the drawer immediately.
*
* @see #toggle()
* @see #close()
* @see #animateOpen()
*/
public
void
open
()
{
openDrawer
();
invalidate
();
requestLayout
();
sendAccessibilityEvent
(
AccessibilityEvent
.
TYPE_WINDOW_STATE_CHANGED
);
}
/**
* Closes the drawer immediately.
*
* @see #toggle()
* @see #open()
* @see #animateClose()
*/
public
void
close
()
{
closeDrawer
();
invalidate
();
requestLayout
();
}
/**
* Closes the drawer with an animation.
*
* @see #close()
* @see #open()
* @see #animateOpen()
* @see #animateToggle()
* @see #toggle()
*/
public
void
animateClose
()
{
prepareContent
();
final
OnDrawerScrollListener
scrollListener
=
mOnDrawerScrollListener
;
if
(
scrollListener
!=
null
)
{
scrollListener
.
onScrollStarted
();
}
animateClose
(
mVertical
?
mHandle
.
getTop
()
:
mHandle
.
getLeft
());
if
(
scrollListener
!=
null
)
{
scrollListener
.
onScrollEnded
();
}
}
/**
* Opens the drawer with an animation.
*
* @see #close()
* @see #open()
* @see #animateClose()
* @see #animateToggle()
* @see #toggle()
*/
public
void
animateOpen
()
{
if
(
mExpanded
)
{
return
;
}
prepareContent
();
final
OnDrawerScrollListener
scrollListener
=
mOnDrawerScrollListener
;
if
(
scrollListener
!=
null
)
{
scrollListener
.
onScrollStarted
();
}
animateOpen
(
mVertical
?
mHandle
.
getTop
()
:
mHandle
.
getLeft
());
sendAccessibilityEvent
(
AccessibilityEvent
.
TYPE_WINDOW_STATE_CHANGED
);
if
(
scrollListener
!=
null
)
{
scrollListener
.
onScrollEnded
();
}
}
// @Override
// public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
// super.onInitializeAccessibilityEvent(event);
// event.setClassName(SlidingDrawer.class.getName());
// }
// @Override
// public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info)
// {
// super.onInitializeAccessibilityNodeInfo(info);
// info.setClassName(SlidingDrawer.class.getName());
// }
private
void
closeDrawer
()
{
moveHandle
(
COLLAPSED_FULL_CLOSED
);
mContent
.
setVisibility
(
View
.
GONE
);
mContent
.
destroyDrawingCache
();
if
(!
mExpanded
)
{
return
;
}
mExpanded
=
false
;
if
(
mOnDrawerCloseListener
!=
null
)
{
mOnDrawerCloseListener
.
onDrawerClosed
();
}
}
private
void
openDrawer
()
{
moveHandle
(
EXPANDED_FULL_OPEN
);
mContent
.
setVisibility
(
View
.
VISIBLE
);
if
(
mExpanded
)
{
return
;
}
mExpanded
=
true
;
if
(
mOnDrawerOpenListener
!=
null
)
{
mOnDrawerOpenListener
.
onDrawerOpened
();
}
}
/**
* Sets the listener that receives a notification when the drawer becomes open.
*
* @param onDrawerOpenListener
* The listener to be notified when the drawer is opened.
*/
public
void
setOnDrawerOpenListener
(
OnDrawerOpenListener
onDrawerOpenListener
)
{
mOnDrawerOpenListener
=
onDrawerOpenListener
;
}
/**
* Sets the listener that receives a notification when the drawer becomes close.
*
* @param onDrawerCloseListener
* The listener to be notified when the drawer is closed.
*/
public
void
setOnDrawerCloseListener
(
OnDrawerCloseListener
onDrawerCloseListener
)
{
mOnDrawerCloseListener
=
onDrawerCloseListener
;
}
/**
* Sets the listener that receives a notification when the drawer starts or ends a scroll. A fling is considered as a scroll. A fling will also
* trigger a drawer opened or drawer closed event.
*
* @param onDrawerScrollListener
* The listener to be notified when scrolling starts or stops.
*/
public
void
setOnDrawerScrollListener
(
OnDrawerScrollListener
onDrawerScrollListener
)
{
mOnDrawerScrollListener
=
onDrawerScrollListener
;
}
/**
* Returns the handle of the drawer.
*
* @return The View reprenseting the handle of the drawer, identified by the "handle" id in XML.
*/
public
View
getHandle
()
{
return
mHandle
;
}
/**
* Returns the content of the drawer.
*
* @return The View reprenseting the content of the drawer, identified by the "content" id in XML.
*/
public
View
getContent
()
{
return
mContent
;
}
/**
* Unlocks the SlidingDrawer so that touch events are processed.
*
* @see #lock()
*/
public
void
unlock
()
{
mLocked
=
false
;
}
/**
* Locks the SlidingDrawer so that touch events are ignores.
*
* @see #unlock()
*/
public
void
lock
()
{
mLocked
=
true
;
}
/**
* Indicates whether the drawer is currently fully opened.
*
* @return True if the drawer is opened, false otherwise.
*/
public
boolean
isOpened
()
{
return
mExpanded
;
}
/**
* Indicates whether the drawer is scrolling or flinging.
*
* @return True if the drawer is scroller or flinging, false otherwise.
*/
public
boolean
isMoving
()
{
return
mTracking
||
mAnimating
;
}
private
class
DrawerToggler
implements
OnClickListener
{
public
void
onClick
(
View
v
)
{
if
(
mLocked
)
{
return
;
}
// mAllowSingleTap isn't relevant here; you're *always*
// allowed to open/close the drawer by clicking with the
// trackball.
if
(
mAnimateOnClick
)
{
animateToggle
();
}
else
{
toggle
();
}
}
}
public
void
setmTrackHandle
(
View
mTrackHandle
)
{
this
.
mTrackHandle
=
mTrackHandle
;
}
private
static
class
SlidingHandler
extends
Handler
{
WeakReference
<
CustomSlidingDrawer
>
ref
;
public
SlidingHandler
(
CustomSlidingDrawer
r
)
{
ref
=
new
WeakReference
<
CustomSlidingDrawer
>(
r
);
}
public
void
handleMessage
(
Message
m
)
{
switch
(
m
.
what
)
{
case
MSG_ANIMATE:
if
(
ref
.
get
()
!=
null
)
ref
.
get
().
doAnimation
();
break
;
}
}
}
}
This diff is collapsed.
Click to expand it.
src/org/sflphone/views/SlidingUpPanelLayout.java
+
0
−
4
View file @
2c0e9745
...
@@ -555,13 +555,11 @@ public class SlidingUpPanelLayout extends ViewGroup {
...
@@ -555,13 +555,11 @@ public class SlidingUpPanelLayout extends ViewGroup {
final
int
action
=
MotionEventCompat
.
getActionMasked
(
ev
);
final
int
action
=
MotionEventCompat
.
getActionMasked
(
ev
);
if
(!
mCanSlide
||
!
mIsSlidingEnabled
||
(
mIsUnableToDrag
&&
action
!=
MotionEvent
.
ACTION_DOWN
))
{
if
(!
mCanSlide
||
!
mIsSlidingEnabled
||
(
mIsUnableToDrag
&&
action
!=
MotionEvent
.
ACTION_DOWN
))
{
Log
.
i
(
TAG
,
"onInterceptTouchEvent - !mCanSlide || !mIsSlidingEnabled || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN"
);
mDragHelper
.
cancel
();
mDragHelper
.
cancel
();
return
super
.
onInterceptTouchEvent
(
ev
);
return
super
.
onInterceptTouchEvent
(
ev
);
}
}
if
(
action
==
MotionEvent
.
ACTION_CANCEL
||
action
==
MotionEvent
.
ACTION_UP
)
{
if
(
action
==
MotionEvent
.
ACTION_CANCEL
||
action
==
MotionEvent
.
ACTION_UP
)
{
Log
.
i
(
TAG
,
"onInterceptTouchEvent - action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP"
);
mDragHelper
.
cancel
();
mDragHelper
.
cancel
();
return
false
;
return
false
;
}
}
...
@@ -578,7 +576,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
...
@@ -578,7 +576,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
mDragViewHit
=
isDragViewHit
((
int
)
x
,
(
int
)
y
);
mDragViewHit
=
isDragViewHit
((
int
)
x
,
(
int
)
y
);
if
(
mDragViewHit
&&
!
mIsUsingDragViewTouchEvents
)
{
if
(
mDragViewHit
&&
!
mIsUsingDragViewTouchEvents
)
{
Log
.
i
(
TAG
,
"interceptTap = true;"
);
interceptTap
=
true
;
interceptTap
=
true
;
}
}
break
;
break
;
...
@@ -604,7 +601,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
...
@@ -604,7 +601,6 @@ public class SlidingUpPanelLayout extends ViewGroup {
if
(
ady
>
dragSlop
&&
adx
>
ady
)
{
if
(
ady
>
dragSlop
&&
adx
>
ady
)
{
mDragHelper
.
cancel
();
mDragHelper
.
cancel
();
mIsUnableToDrag
=
true
;
mIsUnableToDrag
=
true
;
Log
.
i
(
TAG
,
"mIsUnableToDrag = true;"
);
return
false
;
return
false
;
}
}
break
;
break
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment