Android Sina Weibo pull-down refresh (the latest message is displayed at the top)

Source: Internet
Author: User
Tags gety

The pull-down refresh function similar to Sina Weibo is used to view the latest news! Display the latest message at the top!
The Code is as follows:
Code of the PullToRefreshListView class Copy codeThe Code is as follows: package com. markupartist. android. widget;

Import java. util. Date;
Import com. markupartist. android. example. pulltorefresh. R;
Import android. content. Context;
Import android. util. AttributeSet;
Import android. util. Log;
Import android. view. LayoutInflater;
Import android. view. MotionEvent;
Import android. view. View;
Import android. view. ViewGroup;
Import android. view. animation. LinearInterpolator;
Import android. view. animation. RotateAnimation;
Import android. widget. AbsListView;
Import android. widget. AbsListView. OnScrollListener;
Import android. widget. BaseAdapter;
Import android. widget. ImageView;
Import android. widget. LinearLayout;
Import android. widget. ListView;
Import android. widget. ProgressBar;
Import android. widget. TextView;

Public class PullToRefreshListView extends ListView implements OnScrollListener {
Private static final String TAG = "listview ";
Private final static int RELEASE_To_REFRESH = 0;
Private final static int PULL_To_REFRESH = 1;
Private final static int REFRESHING = 2;
Private final static int DONE = 3;
Private final static int LOADING = 4;
// Percentage of the actual padding distance to the offset on the Interface
Private final static int RATIO = 3;
Private LayoutInflater inflater;
Private LinearLayout headView;
Private TextView tipsTextview;
Private TextView lastUpdatedTextView;
Private ImageView arrowImageView;
Private ProgressBar progressBar;

Private RotateAnimation animation;
Private RotateAnimation reverseAnimation;
// Ensure that the value of startY is recorded only once in a complete touch event
Private boolean isRecored;
Private int headContentWidth;
Private int headContentHeight;
Private int startY;
Private int firstItemIndex;
Private int state;
Private boolean isBack;
Private OnRefreshListener refreshListener;
Private boolean isRefreshable;
Public PullToRefreshListView (Context context ){
Super (context );
Init (context );
}
Public PullToRefreshListView (Context context, AttributeSet attrs ){
Super (context, attrs );
Init (context );
}
Private void init (Context context ){
SetCacheColorHint (context. getResources (). getColor (android. R. color. transparent ));
Inflater = LayoutInflater. from (context );
HeadView = (LinearLayout) inflater. inflate (R. layout. pull_to_refresh_header, null );
ArrowImageView = (ImageView) headView
. FindViewById (R. id. head_arrowImageView );
ArrowImageView. setMinimumWidth (70 );
ArrowImageView. setMinimumHeight (50 );
ProgressBar = (ProgressBar) headView
. FindViewById (R. id. head_progressBar );
TipsTextview = (TextView) headView. findViewById (R. id. head_tipsTextView );
LastUpdatedTextView = (TextView) headView
. FindViewById (R. id. head_lastUpdatedTextView );
MeasureView (headView );
HeadContentHeight = headView. getMeasuredHeight ();
HeadContentWidth = headView. getMeasuredWidth ();
HeadView. setPadding (0,-1 * headContentHeight, 0, 0 );
HeadView. invalidate ();
Log. v ("size", "width:" + headContentWidth + "height :"
+ HeadContentHeight );
AddHeaderView (headView, null, false );
SetOnScrollListener (this );
Animation = new RotateAnimation (0,-180,
RotateAnimation. RELATIVE_TO_SELF, 0.5f,
RotateAnimation. RELATIVE_TO_SELF, 0.5f );
Animation. setInterpolator (new LinearInterpolator ());
Animation. setDuration (250 );
Animation. setFillAfter (true );
ReverseAnimation = new RotateAnimation (-180, 0,
RotateAnimation. RELATIVE_TO_SELF, 0.5f,
RotateAnimation. RELATIVE_TO_SELF, 0.5f );
ReverseAnimation. setInterpolator (new LinearInterpolator ());
ReverseAnimation. setDuration (200 );
ReverseAnimation. setFillAfter (true );
State = DONE;
IsRefreshable = false;
}
Public void onScroll (AbsListView arg0, int firstVisiableItem, int arg2,
Int arg3 ){
FirstItemIndex = firstVisiableItem;
}
Public void onScrollStateChanged (AbsListView arg0, int arg1 ){
}
Public boolean onTouchEvent (MotionEvent event ){

FirstItemIndex = getFirstVisiblePosition ();
If (isRefreshable ){
Switch (event. getAction ()){
Case MotionEvent. ACTION_DOWN:
If (firstItemIndex = 0 &&! IsRecored ){
IsRecored = true;
StartY = (int) event. getY ();
Log. v (TAG, "record the current location when down '");
}
Break;
Case MotionEvent. ACTION_UP:
If (state! = REFRESHING & state! = LOADING ){
If (state = DONE ){
// Do nothing
}
If (state = PULL_To_REFRESH ){
State = DONE;
ChangeHeaderViewByState ();
Log. v (TAG, "Refresh from drop-down to done ");
}
If (state = RELEASE_To_REFRESH ){
State = REFRESHING;
ChangeHeaderViewByState ();
OnRefresh ();
Log. v (TAG, "from release refresh status to done status ");
}
}
IsRecored = false;
IsBack = false;
Break;
Case MotionEvent. ACTION_MOVE:
Int tempY = (int) event. getY ();
If (! IsRecored & firstItemIndex = 0 ){
Log. v (TAG, "record location when moving ");
IsRecored = true;
StartY = tempY;
}
If (state! = REFRESHING & isRecored & state! = LOADING ){
// Ensure that the current position is always in the head during the padding setting process. Otherwise, if the list exceeds the screen, the list will be rolled at the same time when it is being pushed.
// You can just refresh it.
If (state = RELEASE_To_REFRESH ){
SetSelection (0 );
// Pushed up to the extent that the screen is sufficient to cover up the head, but not to the full extent
If (tempY-startY)/RATIO & (TempY-startY)> 0 ){
State = PULL_To_REFRESH;
ChangeHeaderViewByState ();
Log. v (TAG, "changed from release refresh status to pull-down refresh status ");
}
// Pushed to the top
Else if (tempY-startY <= 0 ){
State = DONE;
ChangeHeaderViewByState ();
Log. v (TAG, "changed from release refresh status to done status ");
}
// Pull down, or you haven't pushed it to the top of the screen to hide the head.
Else {
// You only need to update the value of paddingTop without special operations.
}
}
// The DONE or PULL_To_REFRESH status is not displayed when the refresh is released.
If (state = PULL_To_REFRESH ){
SetSelection (0 );
// Drop-down to the RELEASE_TO_REFRESH status
If (tempY-startY)/RATIO> = headContentHeight ){
State = RELEASE_To_REFRESH;
IsBack = true;
ChangeHeaderViewByState ();
Log. v (TAG, "changed from done or pull-down refresh status to release refresh ");
}
// Pushed to the top
Else if (tempY-startY <= 0 ){
State = DONE;
ChangeHeaderViewByState ();
Log. v (TAG, "changed from DOne or pull-down refresh status to done status ");
}
}
// In the done status
If (state = DONE ){
If (tempY-startY> 0 ){
State = PULL_To_REFRESH;
ChangeHeaderViewByState ();
}
}
// Update the headView size.
If (state = PULL_To_REFRESH ){
HeadView. setPadding (0,-1 * headContentHeight
+ (TempY-startY)/RATIO, 0, 0 );
}
// Update the paddingTop of the headView
If (state = RELEASE_To_REFRESH ){
HeadView. setPadding (0, (tempY-startY)/RATIO
-HeadContentHeight, 0, 0 );
}
}
Break;
}
}
Return super. onTouchEvent (event );
}
// When the status changes, call this method to update the interface.
Private void changeHeaderViewByState (){
Switch (state ){
Case RELEASE_To_REFRESH:
ArrowImageView. setVisibility (View. VISIBLE );
ProgressBar. setVisibility (View. GONE );
TipsTextview. setVisibility (View. VISIBLE );
LastUpdatedTextView. setVisibility (View. VISIBLE );
ArrowImageView. clearAnimation ();
ArrowImageView. startAnimation (animation );
TipsTextview. setText ("Release refresh ");
Log. v (TAG, "Current Status, release refresh ");
Break;
Case PULL_To_REFRESH:
ProgressBar. setVisibility (View. GONE );
TipsTextview. setVisibility (View. VISIBLE );
LastUpdatedTextView. setVisibility (View. VISIBLE );
ArrowImageView. clearAnimation ();
ArrowImageView. setVisibility (View. VISIBLE );
// The status changes from RELEASE_To_REFRESH.
If (isBack ){
IsBack = false;
ArrowImageView. clearAnimation ();
ArrowImageView. startAnimation (reverseAnimation );
TipsTextview. setText ("pull-down refresh ");
} Else {
TipsTextview. setText ("pull-down refresh ");
}
Log. v (TAG, "Current Status, pull-down refresh ");
Break;
Case REFRESHING:
HeadView. setPadding (0, 0, 0, 0 );
ProgressBar. setVisibility (View. VISIBLE );
ArrowImageView. clearAnimation ();
ArrowImageView. setVisibility (View. GONE );
TipsTextview. setText ("refreshing ...");
LastUpdatedTextView. setVisibility (View. VISIBLE );
Log. v (TAG, "Current Status, refreshing ...");
Break;
Case DONE:
HeadView. setPadding (0,-1 * headContentHeight, 0, 0 );
ProgressBar. setVisibility (View. GONE );
ArrowImageView. clearAnimation ();
ArrowImageView. setImageResource (R. drawable. ic_pulltorefresh_arrow );
TipsTextview. setText ("pull-down refresh ");
LastUpdatedTextView. setVisibility (View. VISIBLE );
Log. v (TAG, "Current Status, done ");
Break;
}
}
Public void setOnRefreshListener (OnRefreshListener refreshListener ){
This. refreshListener = refreshListener;
IsRefreshable = true;
}
Public interface OnRefreshListener {
Public void onRefresh ();
}
Public void onRefreshComplete (){
State = DONE;
LastUpdatedTextView. setText ("last updated:" + new Date (). toLocaleString ());
ChangeHeaderViewByState ();
}
Private void onRefresh (){
If (refreshListener! = Null ){
RefreshListener. onRefresh ();
}
}
// This method is directly copied from a drop-down refresh demo on the network, where the width and height of the headView are estimated.
Private void measureView (View child ){
ViewGroup. LayoutParams p = child. getLayoutParams ();
If (p = null ){
P = new ViewGroup. LayoutParams (ViewGroup. LayoutParams. FILL_PARENT,
ViewGroup. LayoutParams. WRAP_CONTENT );
}
Int childWidthSpec = ViewGroup. getChildMeasureSpec (0, 0 + 0, p. width );
Int lpHeight = p. height;
Int childHeightSpec;
If (lpHeight> 0 ){
ChildHeightSpec = MeasureSpec. makeMeasureSpec (lpHeight,
MeasureSpec. EXACTLY );
} Else {
ChildHeightSpec = MeasureSpec. makeMeasureSpec (0,
MeasureSpec. UNSPECIFIED );
}
Child. measure (childWidthSpec, childHeightSpec );
}
Public void setAdapter (BaseAdapter adapter ){
LastUpdatedTextView. setText ("last updated:" + new Date (). toLocaleString ());
Super. setAdapter (adapter );
}
}

Activity call code Copy codeThe Code is as follows: package com. markupartist. android. example. pulltorefresh;
Import java. util. Arrays;
Import java. util. Collections list;
Import android. app. ListActivity;
Import android. OS. AsyncTask;
Import android. OS. Bundle;
Import android. widget. ArrayAdapter;
Import com. markupartist. android. widget. PullToRefreshListView;
Import com. markupartist. android. widget. PullToRefreshListView. OnRefreshListener;
Public class PullToRefreshActivity extends ListActivity {
Private parameter list <String> mListItems;
/** Called when the activity is first created .*/
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. pull_to_refresh );
// Set a listener to be invoked when the list shocould be refreshed.
(PullToRefreshListView) getListView (). setOnRefreshListener (new OnRefreshListener (){
@ Override
Public void onRefresh (){
// Do work to refresh the list here.
New getdatatask(cmd.exe cute ();
}
});
MListItems = new listlist <String> ();
MListItems. addAll (Arrays. asList (mStrings ));
ArrayAdapter <String> adapter = new ArrayAdapter <String> (this,
Android. R. layout. simple_list_item_1, mListItems );
SetListAdapter (adapter );
}
Private class GetDataTask extends AsyncTask <Void, Void, String []> {
@ Override
Protected String [] doInBackground (Void... params ){
// Simulates a background job.
Try {
Thread. sleep (2000 );
} Catch (InterruptedException e ){

}
Return mStrings;
}
@ Override
Protected void onPostExecute (String [] result ){
MListItems. addFirst ("Added after refresh ...");
// Call onRefreshComplete when the list has been refreshed.
(PullToRefreshListView) getListView (). onRefreshComplete ();
Super. onPostExecute (result );
}
}
Private String [] mStrings = {
// "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam ",
// "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis ",
"Afustm'l Pitu", "Airag", "Airedale", "Aisy cendh ",
"Allgauer Emmentaler "};
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.