GridView基于pulltorefresh实现下拉刷新 上拉加载更多功能
【摘要】
原理和listview一样 ,都是重写android原生控件
Activity
package com.example.refreshgridview; import java.util.ArrayList;import java.util.List; import android.app.Activity;import a...
原理和listview一样 ,都是重写android原生控件
Activity
-
package com.example.refreshgridview;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import android.app.Activity;
-
import android.os.Bundle;
-
import android.widget.GridView;
-
import android.widget.Toast;
-
-
import com.example.refreshgridview.PullToRefreshBase.OnRefreshListener;
-
-
public class MainActivity extends Activity {
-
private PullToRefreshGridView mPullRefreshGridView;
-
private GridView mGridView;
-
private GridViewAdapter adapter;
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
mPullRefreshGridView = (PullToRefreshGridView) findViewById(R.id.video_gridView);
-
mPullRefreshGridView.init(PullToRefreshGridView.MODE_BOTH);
-
mGridView = mPullRefreshGridView.getRefreshableView();
-
mPullRefreshGridView.setOnRefreshListener(refreshListener);
-
List<String> list = new ArrayList<String>();
-
for (int i = 0; i < 40; i++) {
-
list.add(i+"");
-
}
-
adapter = new GridViewAdapter(MainActivity.this,list);
-
mGridView.setAdapter(adapter);
-
}
-
private OnRefreshListener refreshListener = new OnRefreshListener() {
-
@Override
-
public void onRefresh(int mode) {
-
if (PullToRefreshGridView.MODE_PULL_DOWN_TO_REFRESH == mPullRefreshGridView.getCurrentMode()) {
-
Toast.makeText(MainActivity.this, "下拉刷新", Toast.LENGTH_SHORT).show();
-
mPullRefreshGridView.onRefreshComplete();
-
} else if (mode == PullToRefreshGridView.MODE_PULL_UP_TO_REFRESH) {
-
// 加载更多
-
Toast.makeText(MainActivity.this, "上拉加载更多", Toast.LENGTH_SHORT).show();
-
mPullRefreshGridView.onRefreshComplete();
-
}
-
}
-
};
-
}
adapter
-
package com.example.refreshgridview;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import android.content.Context;
-
import android.content.Intent;
-
import android.text.TextUtils;
-
import android.view.LayoutInflater;
-
import android.view.View;
-
import android.view.ViewGroup;
-
import android.widget.BaseAdapter;
-
import android.widget.TextView;
-
-
public class GridViewAdapter extends BaseAdapter {
-
-
private List<String> mList = new ArrayList<String>();
-
-
private Context mContext;
-
-
public GridViewAdapter(Context context,List<String> list) {
-
super();
-
this.mContext = context;
-
this.mList = list;
-
}
-
-
@Override
-
public int getCount() {
-
return mList.size();
-
}
-
-
@Override
-
public String getItem(int position) {
-
return mList.get(position);
-
}
-
-
@Override
-
public long getItemId(int position) {
-
return position;
-
}
-
-
@Override
-
public View getView(int position, View convertView, ViewGroup parent) {
-
ChildHolderOne holder;
-
if (convertView == null) {
-
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_grid_live_show, parent, false);
-
holder = new ChildHolderOne();
-
holder.tvTitle = (TextView)convertView.findViewById(R.id.title_tv);
-
convertView.setTag(holder);
-
} else {
-
holder = (ChildHolderOne) convertView.getTag();
-
}
-
return convertView;
-
}
-
-
class ChildHolderOne {
-
TextView tvTitle;
-
}
-
-
}
PullToRefreshGridView
-
package com.example.refreshgridview;
-
-
-
import android.content.Context;
-
import android.util.AttributeSet;
-
import android.view.ContextMenu.ContextMenuInfo;
-
import android.view.View;
-
import android.widget.GridView;
-
-
-
public class PullToRefreshGridView extends PullToRefreshAdapterViewBase<GridView> {
-
-
class InternalGridView extends GridView implements EmptyViewMethodAccessor {
-
-
public InternalGridView(Context context, AttributeSet attrs) {
-
super(context, attrs);
-
}
-
-
@Override
-
public void setEmptyView(View emptyView) {
-
PullToRefreshGridView.this.setEmptyView(emptyView);
-
}
-
-
@Override
-
public void setEmptyViewInternal(View emptyView) {
-
super.setEmptyView(emptyView);
-
}
-
-
@Override
-
public ContextMenuInfo getContextMenuInfo() {
-
return super.getContextMenuInfo();
-
}
-
-
}
-
-
public PullToRefreshGridView(Context context) {
-
super(context);
-
}
-
-
public PullToRefreshGridView(Context context, int mode) {
-
super(context, mode);
-
}
-
-
public PullToRefreshGridView(Context context, AttributeSet attrs) {
-
super(context, attrs);
-
}
-
-
@Override
-
protected final GridView createRefreshableView(Context context, AttributeSet attrs) {
-
GridView gv = new InternalGridView(context, attrs);
-
// Use Generated ID (from res/values/ids.xml)
-
gv.setId(R.id.gridview);
-
return gv;
-
}
-
-
@Override
-
public ContextMenuInfo getContextMenuInfo() {
-
return ((InternalGridView) getRefreshableView()).getContextMenuInfo();
-
}
-
}
PullToRefreshBase
-
package com.example.refreshgridview;
-
-
-
import android.content.Context;
-
import android.os.Handler;
-
import android.util.AttributeSet;
-
import android.view.MotionEvent;
-
import android.view.View;
-
import android.view.ViewConfiguration;
-
import android.view.ViewGroup;
-
import android.view.animation.AccelerateDecelerateInterpolator;
-
import android.view.animation.Interpolator;
-
import android.widget.LinearLayout;
-
import android.widget.TextView;
-
-
/**
-
*
-
* @author zlw
-
*/
-
public abstract class PullToRefreshBase<T extends View> extends LinearLayout {
-
-
final class SmoothScrollRunnable implements Runnable {
-
-
static final int ANIMATION_DURATION_MS = 190;
-
static final int ANIMATION_FPS = 1000 / 60;
-
-
private final Interpolator interpolator;
-
private final int scrollToY;
-
private final int scrollFromY;
-
private final Handler handler;
-
private boolean continueRunning = true;
-
private long startTime = -1;
-
private int currentY = -1;
-
-
public SmoothScrollRunnable(Handler handler, int fromY, int toY) {
-
this.handler = handler;
-
this.scrollFromY = fromY;
-
this.scrollToY = toY;
-
this.interpolator = new AccelerateDecelerateInterpolator();
-
}
-
-
@Override
-
public void run() {
-
-
/**
-
* Only set startTime if this is the first time we're starting, else
-
* actually calculate the Y delta
-
*/
-
if (startTime == -1) {
-
startTime = System.currentTimeMillis();
-
} else {
-
-
/**
-
* We do do all calculations in long to reduce software float
-
* calculations. We use 1000 as it gives us good accuracy and
-
* small rounding errors
-
*/
-
long normalizedTime = (1000 * (System.currentTimeMillis() - startTime))
-
/ ANIMATION_DURATION_MS;
-
normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0);
-
-
final int deltaY = Math
-
.round((scrollFromY - scrollToY)
-
* interpolator
-
.getInterpolation(normalizedTime / 1000f));
-
this.currentY = scrollFromY - deltaY;
-
setHeaderScroll(currentY);
-
}
-
-
// If we're not at the target Y, keep going...
-
if (continueRunning && scrollToY != currentY) {
-
handler.postDelayed(this, ANIMATION_FPS);
-
}
-
}
-
-
public void stop() {
-
this.continueRunning = false;
-
this.handler.removeCallbacks(this);
-
}
-
};
-
-
// ===========================================================
-
// Constants
-
// ===========================================================
-
-
static final float FRICTION = 2.0f;
-
-
static final int PULL_TO_REFRESH = 0x0;
-
static final int RELEASE_TO_REFRESH = 0x1;
-
static final int REFRESHING = 0x2;
-
static final int MANUAL_REFRESHING = 0x3;
-
-
public static final int MODE_PULL_DOWN_TO_REFRESH = 0x1;
-
public static final int MODE_PULL_UP_TO_REFRESH = 0x2;
-
public static final int MODE_BOTH = 0x3;
-
-
// ===========================================================
-
// Fields
-
// ===========================================================
-
-
private int touchSlop;
-
-
private float initialMotionY;
-
private float lastMotionX;
-
private float lastMotionY;
-
private boolean isBeingDragged = false;
-
-
private int state = PULL_TO_REFRESH;
-
private int mode = MODE_PULL_UP_TO_REFRESH;
-
private int currentMode;
-
-
private boolean disableScrollingWhileRefreshing = true;
-
-
T refreshableView;
-
private boolean isPullToRefreshEnabled = true;
-
-
private LoadingLayout headerLayout;
-
private LoadingLayout footerLayout;
-
private int headerHeight;
-
-
private final Handler handler = new Handler();
-
-
private OnRefreshListener onRefreshListener;
-
-
private SmoothScrollRunnable currentSmoothScrollRunnable;
-
-
// ===========================================================
-
// Constructors
-
// ===========================================================
-
-
public PullToRefreshBase(Context context) {
-
super(context);
-
init(context, null);
-
}
-
-
public PullToRefreshBase(Context context, int mode) {
-
super(context);
-
this.mode = mode;
-
init(context, null);
-
}
-
-
public PullToRefreshBase(Context context, AttributeSet attrs) {
-
super(context, attrs);
-
init(context, attrs);
-
}
-
-
// ===========================================================
-
// Getter & Setter
-
// ===========================================================
-
-
/**
-
* Deprecated. Use {@link #getRefreshableView()} from now on.
-
*
-
* @deprecated
-
* @return The Refreshable View which is currently wrapped
-
*/
-
public final T getAdapterView() {
-
return refreshableView;
-
}
-
-
/**
-
* Get the Wrapped Refreshable View. Anything returned here has already been
-
* added to the content view.
-
*
-
* @return The View which is currently wrapped
-
*/
-
public final T getRefreshableView() {
-
return refreshableView;
-
}
-
-
/**
-
* Whether Pull-to-Refresh is enabled
-
*
-
* @return enabled
-
*/
-
public final boolean isPullToRefreshEnabled() {
-
return isPullToRefreshEnabled;
-
}
-
-
/**
-
* Returns whether the widget has disabled scrolling on the Refreshable View
-
* while refreshing.
-
*
-
* @return true if the widget has disabled scrolling while refreshing
-
*/
-
public final boolean isDisableScrollingWhileRefreshing() {
-
return disableScrollingWhileRefreshing;
-
}
-
-
/**
-
* Returns whether the Widget is currently in the Refreshing state
-
*
-
* @return true if the Widget is currently refreshing
-
*/
-
public final boolean isRefreshing() {
-
return state == REFRESHING || state == MANUAL_REFRESHING;
-
}
-
-
/**
-
* By default the Widget disabled scrolling on the Refreshable View while
-
* refreshing. This method can change this behaviour.
-
*
-
* @param disableScrollingWhileRefreshing
-
* - true if you want to disable scrolling while refreshing
-
*/
-
public final void setDisableScrollingWhileRefreshing(
-
boolean disableScrollingWhileRefreshing) {
-
this.disableScrollingWhileRefreshing = disableScrollingWhileRefreshing;
-
}
-
-
/**
-
* Mark the current Refresh as complete. Will Reset the UI and hide the
-
* Refreshing View
-
*/
-
public final void onRefreshComplete() {
-
if (state != PULL_TO_REFRESH) {
-
resetHeader();
-
if (onShowLayoutListener != null) {
-
onShowLayoutListener.onDismiss();
-
}
-
}
-
}
-
-
/**
-
* Set OnRefreshListener for the Widget
-
*
-
* @param listener
-
* - Listener to be used when the Widget is set to Refresh
-
*/
-
public final void setOnRefreshListener(OnRefreshListener listener) {
-
onRefreshListener = listener;
-
}
-
-
/**
-
* auto load headerLayout to refresh
-
*
-
* @param listener
-
*/
-
public final void setFirstAutoPullUpToRefresh(OnRefreshListener listener) {
-
setRefreshingInternal(true, MODE_PULL_DOWN_TO_REFRESH);
-
listener.onRefresh(MODE_PULL_DOWN_TO_REFRESH);
-
}
-
-
/**
-
* set refreshLable , default use null
-
*
-
* @param pullLabel
-
* @param releaseLabel
-
* @param refreshingLabel
-
*/
-
public void setRefreshLabel(String pullLabel, String releaseLabel,
-
String refreshingLabel) {
-
if (pullLabel != null) {
-
setPullLabel(pullLabel);
-
}
-
if (releaseLabel != null) {
-
setReleaseLabel(releaseLabel);
-
}
-
if (refreshingLabel != null) {
-
setRefreshingLabel(refreshingLabel);
-
}
-
}
-
-
/**
-
* A mutator to enable/disable Pull-to-Refresh for the current View
-
*
-
* @param enable
-
* Whether Pull-To-Refresh should be used
-
*/
-
public final void setPullToRefreshEnabled(boolean enable) {
-
this.isPullToRefreshEnabled = enable;
-
}
-
-
/**
-
* Set Text to show when the Widget is being pulled, and will refresh when
-
* released
-
*
-
* @param releaseLabel
-
* - String to display
-
*/
-
private void setReleaseLabel(String releaseLabel) {
-
if (null != headerLayout) {
-
headerLayout.setReleaseLabel(releaseLabel);
-
}
-
if (null != footerLayout) {
-
footerLayout.setReleaseLabel(releaseLabel);
-
}
-
}
-
-
/**
-
* Set Text to show when the Widget is being Pulled
-
*
-
* @param pullLabel
-
* - String to display
-
*/
-
private void setPullLabel(String pullLabel) {
-
if (null != headerLayout) {
-
headerLayout.setPullLabel(pullLabel);
-
}
-
if (null != footerLayout) {
-
footerLayout.setPullLabel(pullLabel);
-
}
-
}
-
-
/**
-
* Set Text to show when the Widget is refreshing
-
*
-
* @param refreshingLabel
-
* - String to display
-
*/
-
private void setRefreshingLabel(String refreshingLabel) {
-
if (null != headerLayout) {
-
headerLayout.setRefreshingLabel(refreshingLabel);
-
}
-
if (null != footerLayout) {
-
footerLayout.setRefreshingLabel(refreshingLabel);
-
}
-
}
-
-
public final void setRefreshing() {
-
this.setRefreshing(true);
-
}
-
-
/**
-
* Sets the Widget to be in the refresh state. The UI will be updated to
-
* show the 'Refreshing' view.
-
*
-
* @param doScroll
-
* - true if you want to force a scroll to the Refreshing view.
-
*/
-
public final void setRefreshing(boolean doScroll) {
-
if (!isRefreshing()) {
-
setRefreshingInternal(doScroll);
-
state = MANUAL_REFRESHING;
-
}
-
}
-
-
public final boolean hasPullFromTop() {
-
return currentMode != MODE_PULL_UP_TO_REFRESH;
-
}
-
-
// ===========================================================
-
// Methods for/from SuperClass/Interfaces
-
// ===========================================================
-
-
@Override
-
public final boolean onTouchEvent(MotionEvent event) {
-
if (!isPullToRefreshEnabled) {
-
return false;
-
}
-
-
if (isRefreshing() && disableScrollingWhileRefreshing) {
-
return true;
-
}
-
-
if (event.getAction() == MotionEvent.ACTION_DOWN
-
&& event.getEdgeFlags() != 0) {
-
return false;
-
}
-
-
switch (event.getAction()) {
-
-
case MotionEvent.ACTION_MOVE: {
-
if (isBeingDragged) {
-
if (Math.abs(event.getY() - downLocation) > 5
-
&& onShowLayoutListener != null) {
-
onShowLayoutListener.onShow();
-
}
-
lastMotionY = event.getY();
-
this.pullEvent();
-
return true;
-
}
-
break;
-
}
-
-
case MotionEvent.ACTION_DOWN: {
-
-
if (isReadyForPull()) {
-
downLocation = event.getY();
-
lastMotionY = initialMotionY = event.getY();
-
return true;
-
}
-
break;
-
}
-
-
case MotionEvent.ACTION_CANCEL:
-
case MotionEvent.ACTION_UP: {
-
if (isBeingDragged) {
-
isBeingDragged = false;
-
-
if (state == RELEASE_TO_REFRESH && null != onRefreshListener) {
-
setRefreshingInternal(true);
-
onRefreshListener.onRefresh(currentMode);
-
} else {
-
smoothScrollTo(0);
-
if (onShowLayoutListener != null) {
-
onShowLayoutListener.onDismiss();
-
}
-
}
-
return true;
-
}
-
break;
-
}
-
}
-
-
return false;
-
}
-
-
// remeber to down location
-
private float downLocation = 0;
-
-
@Override
-
public final boolean onInterceptTouchEvent(MotionEvent event) {
-
-
if (!isPullToRefreshEnabled) {
-
return false;
-
}
-
-
if (isRefreshing() && disableScrollingWhileRefreshing) {
-
return true;
-
}
-
-
final int action = event.getAction();
-
-
if (action == MotionEvent.ACTION_CANCEL
-
|| action == MotionEvent.ACTION_UP) {
-
isBeingDragged = false;
-
return false;
-
}
-
-
if (action != MotionEvent.ACTION_DOWN && isBeingDragged) {
-
return true;
-
}
-
-
switch (action) {
-
case MotionEvent.ACTION_MOVE: {
-
if (isReadyForPull()) {
-
-
final float y = event.getY();
-
final float dy = y - lastMotionY;
-
final float yDiff = Math.abs(dy);
-
final float xDiff = Math.abs(event.getX() - lastMotionX);
-
-
if (yDiff > touchSlop && yDiff > xDiff) {
-
if ((mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH)
-
&& dy >= 0.0001f && isReadyForPullDown()) {
-
lastMotionY = y;
-
isBeingDragged = true;
-
if (mode == MODE_BOTH) {
-
currentMode = MODE_PULL_DOWN_TO_REFRESH;
-
}
-
} else if ((mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH)
-
&& dy <= 0.0001f && isReadyForPullUp()) {
-
lastMotionY = y;
-
isBeingDragged = true;
-
if (mode == MODE_BOTH) {
-
currentMode = MODE_PULL_UP_TO_REFRESH;
-
}
-
}
-
}
-
}
-
break;
-
}
-
case MotionEvent.ACTION_DOWN: {
-
if (isReadyForPull()) {
-
-
lastMotionY = initialMotionY = event.getY();
-
lastMotionX = event.getX();
-
isBeingDragged = false;
-
}
-
break;
-
}
-
case MotionEvent.ACTION_UP:
-
break;
-
}
-
setRefreshLabel(currentMode);
-
return isBeingDragged;
-
}
-
-
protected void addRefreshableView(Context context, T refreshableView) {
-
addView(refreshableView, new LinearLayout.LayoutParams(
-
LayoutParams.FILL_PARENT, 0, 1.0f));
-
}
-
-
/**
-
* This is implemented by derived classes to return the created View. If you
-
* need to use a custom View (such as a custom ListView), override this
-
* method and return an instance of your custom class.
-
*
-
* Be sure to set the ID of the view in this method, especially if you're
-
* using a ListActivity or ListFragment.
-
*
-
* @param context
-
* @param attrs
-
* AttributeSet from wrapped class. Means that anything you
-
* include in the XML layout declaration will be routed to the
-
* created View
-
* @return New instance of the Refreshable View
-
*/
-
protected abstract T createRefreshableView(Context context,
-
AttributeSet attrs);
-
-
public final int getCurrentMode() {
-
return currentMode;
-
}
-
-
protected final LoadingLayout getFooterLayout() {
-
return footerLayout;
-
}
-
-
protected final LoadingLayout getHeaderLayout() {
-
return headerLayout;
-
}
-
-
protected final int getHeaderHeight() {
-
return headerHeight;
-
}
-
-
protected final int getMode() {
-
return mode;
-
}
-
-
/**
-
* Implemented by derived class to return whether the View is in a state
-
* where the user can Pull to Refresh by scrolling down.
-
*
-
* @return true if the View is currently the correct state (for example, top
-
* of a ListView)
-
*/
-
protected abstract boolean isReadyForPullDown();
-
-
/**
-
* Implemented by derived class to return whether the View is in a state
-
* where the user can Pull to Refresh by scrolling up.
-
*
-
* @return true if the View is currently in the correct state (for example,
-
* bottom of a ListView)
-
*/
-
protected abstract boolean isReadyForPullUp();
-
-
// ===========================================================
-
// Methods
-
// ===========================================================
-
-
protected void resetHeader() {
-
state = PULL_TO_REFRESH;
-
isBeingDragged = false;
-
-
if (null != headerLayout) {
-
headerLayout.reset();
-
}
-
if (null != footerLayout) {
-
footerLayout.reset();
-
}
-
-
smoothScrollTo(0);
-
}
-
-
/**
-
* unless special requirements to call the method ,default call the method
-
* {@link #setRefreshingInternal(boolean doScroll)}
-
*
-
* @param doScroll
-
* @param mode
-
*/
-
protected void setRefreshingInternal(boolean doScroll, int mode) {
-
state = REFRESHING;
-
setRefreshLabel(mode);
-
if (null != headerLayout) {
-
headerLayout.refreshing();
-
}
-
if (doScroll) {
-
smoothScrollTo(mode == MODE_PULL_DOWN_TO_REFRESH ? -headerHeight
-
: headerHeight);
-
}
-
}
-
-
/**
-
* set last refresh time
-
*
-
* @param time
-
*/
-
public void setRefreshTime(String time) {
-
TextView mHeaderTimeView = (TextView) headerLayout
-
.findViewById(R.id.xlistview_header_time);
-
mHeaderTimeView.setText(time);
-
}
-
-
public void setRefreshTime(long time){
-
TextView mHeaderTimeView = (TextView) headerLayout
-
.findViewById(R.id.xlistview_header_time);
-
mHeaderTimeView.setText(TimeUtil.getChatTime(time));
-
}
-
-
protected void setRefreshingInternal(boolean doScroll) {
-
state = REFRESHING;
-
setRefreshLabel(currentMode);
-
if (null != footerLayout) {
-
footerLayout.refreshing();
-
}
-
if (null != headerLayout) {
-
headerLayout.refreshing();
-
}
-
if (doScroll) {
-
smoothScrollTo(currentMode == MODE_PULL_DOWN_TO_REFRESH ? -headerHeight
-
: headerHeight);
-
}
-
}
-
-
private void setRefreshLabel(int mode) {
-
if (mode == MODE_PULL_DOWN_TO_REFRESH) {
-
setRefreshLabel("涓嬫媺鍒锋柊", "閲婃斁绔嬪嵆鍒锋柊", "姝e湪鍒锋柊");
-
}
-
if (mode == MODE_PULL_UP_TO_REFRESH) {
-
setRefreshLabel("涓婃媺鑾峰彇鏇村", "鏉惧紑鏄剧ず鏇村", "姝e湪鍔犺浇");
-
}
-
}
-
-
protected final void setHeaderScroll(int y) {
-
scrollTo(0, y);
-
}
-
-
protected final void smoothScrollTo(int y) {
-
if (null != currentSmoothScrollRunnable) {
-
currentSmoothScrollRunnable.stop();
-
}
-
-
if (this.getScrollY() != y) {
-
this.currentSmoothScrollRunnable = new SmoothScrollRunnable(
-
handler, getScrollY(), y);
-
handler.post(currentSmoothScrollRunnable);
-
}
-
}
-
-
public void init(int mode) {
-
// Loading View Strings
-
String pullLabel = context
-
.getString(R.string.pull_to_refresh_pull_label);
-
String refreshingLabel = context
-
.getString(R.string.pull_to_refresh_refreshing_label);
-
String releaseLabel = context
-
.getString(R.string.pull_to_refresh_release_label);
-
-
// Add Loading Views
-
if (mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH) {
-
headerLayout = new LoadingLayout(context,MODE_PULL_DOWN_TO_REFRESH, releaseLabel, pullLabel,refreshingLabel);
-
addView(headerLayout, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
-
measureView(headerLayout);
-
headerHeight = headerLayout.getMeasuredHeight();
-
}
-
if (mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH) {
-
footerLayout = new LoadingLayout(context, MODE_PULL_UP_TO_REFRESH,releaseLabel, pullLabel, refreshingLabel);
-
addView(footerLayout, new LinearLayout.LayoutParams(
-
ViewGroup.LayoutParams.FILL_PARENT,
-
ViewGroup.LayoutParams.WRAP_CONTENT));
-
measureView(footerLayout);
-
headerHeight = footerLayout.getMeasuredHeight();
-
}
-
-
// Styleables from XML
-
if (null != headerLayout) {
-
// headerLayout.setTextColor(Color.BLACK);
-
}
-
if (null != footerLayout) {
-
// footerLayout.setTextColor(Color.BLACK);
-
}
-
// Hide Loading Views
-
switch (mode) {
-
case MODE_BOTH:
-
setPadding(0, -headerHeight, 0, -headerHeight);
-
break;
-
case MODE_PULL_UP_TO_REFRESH:
-
setPadding(0, 0, 0, -headerHeight);
-
break;
-
case MODE_PULL_DOWN_TO_REFRESH:
-
default:
-
setPadding(0, -headerHeight, 0, 0);
-
break;
-
}
-
-
// If we're not using MODE_BOTH, then just set currentMode to current
-
// mode
-
if (mode != MODE_BOTH) {
-
currentMode = mode;
-
}
-
this.mode = mode;
-
}
-
-
private void init(Context context, AttributeSet attrs) {
-
this.context = context;
-
setOrientation(LinearLayout.VERTICAL);
-
-
touchSlop = ViewConfiguration.getTouchSlop();
-
-
// Refreshable View
-
// By passing the attrs, we can add ListView/GridView params via XML
-
refreshableView = this.createRefreshableView(context, attrs);
-
this.addRefreshableView(context, refreshableView);
-
-
}
-
-
private Context context;
-
-
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);
-
}
-
-
/**
-
* Actions a Pull Event
-
*
-
* @return true if the Event has been handled, false if there has been no
-
* change
-
*/
-
private boolean pullEvent() {
-
-
final int newHeight;
-
final int oldHeight = this.getScrollY();
-
-
switch (currentMode) {
-
case MODE_PULL_UP_TO_REFRESH:
-
newHeight = Math.round(Math.max(initialMotionY - lastMotionY, 0)
-
/ FRICTION);
-
// newHeight = Math.round((initialMotionY - lastMotionY) /
-
// FRICTION);
-
break;
-
case MODE_PULL_DOWN_TO_REFRESH:
-
default:
-
newHeight = Math.round(Math.min(initialMotionY - lastMotionY, 0)
-
/ FRICTION);
-
// newHeight = Math.round((initialMotionY - lastMotionY) /
-
// FRICTION);
-
break;
-
}
-
-
setHeaderScroll(newHeight);
-
-
if (newHeight != 0) {
-
if (state == PULL_TO_REFRESH && headerHeight < Math.abs(newHeight)) {
-
state = RELEASE_TO_REFRESH;
-
-
switch (currentMode) {
-
case MODE_PULL_UP_TO_REFRESH:
-
footerLayout.releaseToRefresh();
-
break;
-
case MODE_PULL_DOWN_TO_REFRESH:
-
headerLayout.releaseToRefresh();
-
break;
-
}
-
-
return true;
-
-
} else if (state == RELEASE_TO_REFRESH
-
&& headerHeight >= Math.abs(newHeight)) {
-
state = PULL_TO_REFRESH;
-
-
switch (currentMode) {
-
case MODE_PULL_UP_TO_REFRESH:
-
footerLayout.pullToRefresh();
-
break;
-
case MODE_PULL_DOWN_TO_REFRESH:
-
headerLayout.pullToRefresh();
-
break;
-
}
-
-
return true;
-
}
-
}
-
-
return oldHeight != newHeight;
-
}
-
-
private boolean isReadyForPull() {
-
switch (mode) {
-
case MODE_PULL_DOWN_TO_REFRESH:
-
return isReadyForPullDown();
-
case MODE_PULL_UP_TO_REFRESH:
-
return isReadyForPullUp();
-
case MODE_BOTH:
-
return isReadyForPullUp() || isReadyForPullDown();
-
}
-
return false;
-
}
-
-
// ===========================================================
-
// Inner and Anonymous Classes
-
// ===========================================================
-
-
public static interface OnRefreshListener {
-
-
public void onRefresh(int mode);
-
}
-
-
private OnShowLayoutListener onShowLayoutListener;
-
-
public void setOnShowLayoutListener(OnShowLayoutListener listener) {
-
this.onShowLayoutListener = listener;
-
}
-
-
public static interface OnShowLayoutListener {
-
/**
-
* 鏄惁姝e湪鏄剧ず搴曢儴甯冨眬
-
*/
-
public void onShow();
-
-
/**
-
* 鏄惁娑堝け
-
*/
-
public void onDismiss();
-
-
}
-
-
public static interface OnLastItemVisibleListener {
-
-
public void onLastItemVisible();
-
}
-
-
@Override
-
public void setLongClickable(boolean longClickable) {
-
getRefreshableView().setLongClickable(longClickable);
-
}
-
}
主要代码都在上面贴出来了,当然还是一定要有demo
这个源码里面 我把 PullToRefreshExpandableListView 和 PullToRefreshListView 也都放进来了,一样的逻辑。希望对大家有用。
如果还有其它问题 希望大家加入我的qq群 Android开发经验交流群 454430053 互相讨论交流。
文章来源: wukong.blog.csdn.net,作者:再见孙悟空_,版权归原作者所有,如需转载,请联系作者。
原文链接:wukong.blog.csdn.net/article/details/53159142
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)