Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
apk
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
apk
Commits
4f929ceb
Commit
4f929ceb
authored
May 22, 2015
by
DrKLO
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Missing file
parent
2b81b7f0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
339 additions
and
0 deletions
+339
-0
RecyclerListView.java
...ain/java/org/telegram/ui/Components/RecyclerListView.java
+339
-0
No files found.
TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java
0 → 100644
View file @
4f929ceb
/*
* This is the source code of Telegram for Android v. 2.x
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2015.
*/
package
org
.
telegram
.
ui
.
Components
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.view.GestureDetector
;
import
android.view.HapticFeedbackConstants
;
import
android.view.MotionEvent
;
import
android.view.SoundEffectConstants
;
import
android.view.View
;
import
android.view.ViewConfiguration
;
import
org.telegram.android.AndroidUtilities
;
import
org.telegram.android.support.widget.RecyclerView
;
import
org.telegram.messenger.FileLog
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
public
class
RecyclerListView
extends
RecyclerView
{
private
OnItemClickListener
onItemClickListener
;
private
OnItemLongClickListener
onItemLongClickListener
;
private
RecyclerView
.
OnScrollListener
onScrollListener
;
private
OnInterceptTouchListener
onInterceptTouchListener
;
private
View
emptyView
;
private
Runnable
selectChildRunnable
;
private
GestureDetector
mGestureDetector
;
private
View
currentChildView
;
private
int
currentChildPosition
;
private
boolean
interceptedByChild
;
private
boolean
wasPressed
;
private
boolean
disallowInterceptTouchEvents
;
private
boolean
instantClick
;
private
static
int
[]
attributes
;
private
static
boolean
gotAttributes
;
public
interface
OnItemClickListener
{
void
onItemClick
(
View
view
,
int
position
);
}
public
interface
OnItemLongClickListener
{
void
onItemClick
(
View
view
,
int
position
);
}
public
interface
OnInterceptTouchListener
{
boolean
onInterceptTouchEvent
(
MotionEvent
event
);
}
private
class
RecyclerListViewItemClickListener
implements
RecyclerView
.
OnItemTouchListener
{
public
RecyclerListViewItemClickListener
(
Context
context
)
{
mGestureDetector
=
new
GestureDetector
(
context
,
new
GestureDetector
.
SimpleOnGestureListener
()
{
@Override
public
boolean
onSingleTapUp
(
MotionEvent
e
)
{
if
(
currentChildView
!=
null
&&
onItemClickListener
!=
null
)
{
currentChildView
.
setPressed
(
true
);
final
View
view
=
currentChildView
;
if
(
instantClick
)
{
view
.
playSoundEffect
(
SoundEffectConstants
.
CLICK
);
onItemClickListener
.
onItemClick
(
view
,
currentChildPosition
);
}
AndroidUtilities
.
runOnUIThread
(
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
view
!=
null
)
{
view
.
setPressed
(
false
);
if
(!
instantClick
)
{
view
.
playSoundEffect
(
SoundEffectConstants
.
CLICK
);
if
(
onItemClickListener
!=
null
)
{
onItemClickListener
.
onItemClick
(
view
,
currentChildPosition
);
}
}
}
}
},
ViewConfiguration
.
getPressedStateDuration
());
if
(
selectChildRunnable
!=
null
)
{
AndroidUtilities
.
cancelRunOnUIThread
(
selectChildRunnable
);
selectChildRunnable
=
null
;
currentChildView
=
null
;
interceptedByChild
=
false
;
}
}
return
true
;
}
@Override
public
void
onLongPress
(
MotionEvent
e
)
{
if
(
currentChildView
!=
null
&&
onItemLongClickListener
!=
null
)
{
currentChildView
.
performHapticFeedback
(
HapticFeedbackConstants
.
LONG_PRESS
);
onItemLongClickListener
.
onItemClick
(
currentChildView
,
currentChildPosition
);
}
}
});
}
@Override
public
boolean
onInterceptTouchEvent
(
RecyclerView
view
,
MotionEvent
e
)
{
int
action
=
e
.
getActionMasked
();
boolean
isScrollIdle
=
RecyclerListView
.
this
.
getScrollState
()
==
RecyclerListView
.
SCROLL_STATE_IDLE
;
if
((
action
==
MotionEvent
.
ACTION_DOWN
||
action
==
MotionEvent
.
ACTION_POINTER_DOWN
)
&&
currentChildView
==
null
&&
isScrollIdle
)
{
currentChildView
=
view
.
findChildViewUnder
(
e
.
getX
(),
e
.
getY
());
currentChildPosition
=
-
1
;
if
(
currentChildView
!=
null
)
{
currentChildPosition
=
view
.
getChildPosition
(
currentChildView
);
MotionEvent
childEvent
=
MotionEvent
.
obtain
(
0
,
0
,
e
.
getActionMasked
(),
e
.
getX
()
-
currentChildView
.
getLeft
(),
e
.
getY
()
-
currentChildView
.
getTop
(),
0
);
if
(
currentChildView
.
onTouchEvent
(
childEvent
))
{
interceptedByChild
=
true
;
}
childEvent
.
recycle
();
}
}
if
(
currentChildView
!=
null
&&
!
interceptedByChild
)
{
try
{
if
(
e
!=
null
)
{
mGestureDetector
.
onTouchEvent
(
e
);
}
}
catch
(
Exception
ev
)
{
FileLog
.
e
(
"tmessages"
,
ev
);
}
}
if
(
action
==
MotionEvent
.
ACTION_DOWN
||
action
==
MotionEvent
.
ACTION_POINTER_DOWN
)
{
if
(!
interceptedByChild
&&
currentChildView
!=
null
)
{
selectChildRunnable
=
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
selectChildRunnable
!=
null
&&
currentChildView
!=
null
)
{
currentChildView
.
setPressed
(
true
);
selectChildRunnable
=
null
;
}
}
};
AndroidUtilities
.
runOnUIThread
(
selectChildRunnable
,
ViewConfiguration
.
getTapTimeout
());
}
}
else
if
(
currentChildView
!=
null
&&
(
action
==
MotionEvent
.
ACTION_UP
||
action
==
MotionEvent
.
ACTION_POINTER_UP
||
action
==
MotionEvent
.
ACTION_CANCEL
||
!
isScrollIdle
))
{
if
(
selectChildRunnable
!=
null
)
{
AndroidUtilities
.
cancelRunOnUIThread
(
selectChildRunnable
);
selectChildRunnable
=
null
;
}
currentChildView
.
setPressed
(
false
);
currentChildView
=
null
;
interceptedByChild
=
false
;
}
return
false
;
}
@Override
public
void
onTouchEvent
(
RecyclerView
view
,
MotionEvent
e
)
{
}
}
private
AdapterDataObserver
observer
=
new
AdapterDataObserver
()
{
@Override
public
void
onChanged
()
{
checkIfEmpty
();
}
@Override
public
void
onItemRangeInserted
(
int
positionStart
,
int
itemCount
)
{
checkIfEmpty
();
}
@Override
public
void
onItemRangeRemoved
(
int
positionStart
,
int
itemCount
)
{
checkIfEmpty
();
}
};
public
int
[]
getResourceDeclareStyleableIntArray
(
String
packageName
,
String
name
)
{
try
{
Field
f
=
Class
.
forName
(
packageName
+
".R$styleable"
).
getField
(
name
);
if
(
f
!=
null
)
{
return
(
int
[])
f
.
get
(
null
);
}
}
catch
(
Throwable
t
)
{
//ignore
}
return
null
;
}
public
RecyclerListView
(
Context
context
)
{
super
(
context
);
try
{
if
(!
gotAttributes
)
{
attributes
=
getResourceDeclareStyleableIntArray
(
"com.android.internal"
,
"View"
);
gotAttributes
=
true
;
}
TypedArray
a
=
context
.
getTheme
().
obtainStyledAttributes
(
attributes
);
Method
initializeScrollbars
=
android
.
view
.
View
.
class
.
getDeclaredMethod
(
"initializeScrollbars"
,
TypedArray
.
class
);
initializeScrollbars
.
invoke
(
this
,
a
);
a
.
recycle
();
}
catch
(
Throwable
e
)
{
FileLog
.
e
(
"tmessages"
,
e
);
}
super
.
setOnScrollListener
(
new
OnScrollListener
()
{
@Override
public
void
onScrollStateChanged
(
RecyclerView
recyclerView
,
int
newState
)
{
if
(
newState
!=
SCROLL_STATE_IDLE
&&
currentChildView
!=
null
)
{
if
(
selectChildRunnable
!=
null
)
{
AndroidUtilities
.
cancelRunOnUIThread
(
selectChildRunnable
);
selectChildRunnable
=
null
;
}
MotionEvent
event
=
MotionEvent
.
obtain
(
0
,
0
,
MotionEvent
.
ACTION_CANCEL
,
0
,
0
,
0
);
try
{
mGestureDetector
.
onTouchEvent
(
event
);
}
catch
(
Exception
e
)
{
FileLog
.
e
(
"tmessages"
,
e
);
}
currentChildView
.
onTouchEvent
(
event
);
event
.
recycle
();
currentChildView
.
setPressed
(
false
);
currentChildView
=
null
;
interceptedByChild
=
false
;
}
if
(
onScrollListener
!=
null
)
{
onScrollListener
.
onScrollStateChanged
(
recyclerView
,
newState
);
}
}
@Override
public
void
onScrolled
(
RecyclerView
recyclerView
,
int
dx
,
int
dy
)
{
if
(
onScrollListener
!=
null
)
{
onScrollListener
.
onScrolled
(
recyclerView
,
dx
,
dy
);
}
}
});
addOnItemTouchListener
(
new
RecyclerListViewItemClickListener
(
context
));
}
@Override
public
void
setVerticalScrollBarEnabled
(
boolean
verticalScrollBarEnabled
)
{
if
(
attributes
!=
null
)
{
super
.
setVerticalScrollBarEnabled
(
verticalScrollBarEnabled
);
}
}
public
void
setOnItemClickListener
(
OnItemClickListener
listener
)
{
onItemClickListener
=
listener
;
}
public
void
setOnItemLongClickListener
(
OnItemLongClickListener
listener
)
{
onItemLongClickListener
=
listener
;
}
public
void
setEmptyView
(
View
view
)
{
if
(
emptyView
==
view
)
{
return
;
}
emptyView
=
view
;
checkIfEmpty
();
}
public
View
getEmptyView
()
{
return
emptyView
;
}
public
void
invalidateViews
()
{
int
count
=
getChildCount
();
for
(
int
a
=
0
;
a
<
count
;
a
++)
{
getChildAt
(
a
).
invalidate
();
}
}
@Override
public
boolean
onInterceptTouchEvent
(
MotionEvent
e
)
{
if
(
disallowInterceptTouchEvents
)
{
requestDisallowInterceptTouchEvent
(
true
);
}
return
onInterceptTouchListener
!=
null
&&
onInterceptTouchListener
.
onInterceptTouchEvent
(
e
)
||
super
.
onInterceptTouchEvent
(
e
);
}
private
void
checkIfEmpty
()
{
if
(
emptyView
==
null
||
getAdapter
()
==
null
)
{
return
;
}
boolean
emptyViewVisible
=
getAdapter
().
getItemCount
()
==
0
;
emptyView
.
setVisibility
(
emptyViewVisible
?
VISIBLE
:
INVISIBLE
);
setVisibility
(
emptyViewVisible
?
INVISIBLE
:
VISIBLE
);
}
@Override
public
void
setOnScrollListener
(
OnScrollListener
listener
)
{
onScrollListener
=
listener
;
}
public
void
setOnInterceptTouchListener
(
OnInterceptTouchListener
listener
)
{
onInterceptTouchListener
=
listener
;
}
public
void
setInstantClick
(
boolean
value
)
{
instantClick
=
value
;
}
public
void
setDisallowInterceptTouchEvents
(
boolean
value
)
{
disallowInterceptTouchEvents
=
value
;
}
@Override
public
void
setAdapter
(
Adapter
adapter
)
{
final
Adapter
oldAdapter
=
getAdapter
();
if
(
oldAdapter
!=
null
)
{
oldAdapter
.
unregisterAdapterDataObserver
(
observer
);
}
super
.
setAdapter
(
adapter
);
if
(
adapter
!=
null
)
{
adapter
.
registerAdapterDataObserver
(
observer
);
}
checkIfEmpty
();
}
@Override
public
void
stopScroll
()
{
try
{
super
.
stopScroll
();
}
catch
(
NullPointerException
exception
)
{
/**
* The mLayout has been disposed of before the
* RecyclerView and this stops the application
* from crashing.
*/
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment