編輯:關於android開發
如下是布局文件 主要是一個PullToRefreshView內包含一個Scrollview 在滑動面中放一個GridView 底部放個按鈕 當點擊時會返回手機頂部
其中的滑動PullToRefreshView是我從別人的代碼直接拿來的
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eee"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:paddingBottom="4dp"
android:paddingTop="5dp"
android:text="所有產品"
android:textSize="15sp" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="@android:color/white" />
<org.xml.demo.PullToRefreshView
android:id="@+id/pulltorefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ScrollView
android:id="@+id/sc_view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<org.xml.demo.MyGridView
android:id="@+id/product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:horizontalSpacing="5dp"
android:numColumns="2"
android:paddingBottom="10dp"
android:paddingLeft="7dp"
android:paddingRight="7dp"
android:paddingTop="5dp"
android:verticalSpacing="8dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:background="@android:color/white"
android:orientation="horizontal"
android:padding="5dp" >
<TextView
android:id="@+id/tv_backtop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableRight="@drawable/back_top"
android:gravity="center"
android:text="點擊 將返回頂部"
android:paddingRight="10dp"
android:textColor="@android:color/black"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</org.xml.demo.PullToRefreshView>
</LinearLayout>
主代碼是
package org.xml.demo;
import java.text.DateFormat;
import java.util.Date;
import org.xml.demo.PullToRefreshView.OnFooterRefreshListener;
import org.xml.demo.PullToRefreshView.OnHeaderRefreshListener;
import ogg.huanxin.huadong.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class MyProducte extends Activity implements OnHeaderRefreshListener, OnFooterRefreshListener {
// private GridView productGridView;
/** 定義產品 */
private MyGridView product_gridView;
/** 產品的適配器 */
private ProducteGridAdapter producteGridAdapter;
/** 下拉刷新 */
private PullToRefreshView pullToRefreshView;
/** 點擊返回到頂部 */
private TextView tv_backtop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//取消標題欄
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 定義布局變量
super.setContentView(R.layout.home_product);
pullToRefreshView = (PullToRefreshView) super
.findViewById(R.id.pulltorefresh);
//頭部刷新
pullToRefreshView.setOnHeaderRefreshListener(this);
//尾部刷新
pullToRefreshView.setOnFooterRefreshListener(this);
pullToRefreshView.setLastUpdated(new Date().toLocaleString());
// 取得控件
product_gridView = (MyGridView) super.findViewById(R.id.product);
tv_backtop = (TextView) super.findViewById(R.id.tv_backtop);
// 設置適配器
producteGridAdapter = new ProducteGridAdapter(this);
product_gridView.setAdapter(producteGridAdapter);
// product_gridView.setOnItemClickListener(new ItemClickListener());
product_gridView.setOnItemClickListener(new ItemClickListener());
// tv_backtop的監聽器
tv_backtop.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
product_gridView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
MyProducte.this.findViewById(R.id.sc_view_id).scrollTo(
0, 0);
}
});
}
});
}
private class ItemClickListener implements OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
}
}
@Override
public void onHeaderRefresh(PullToRefreshView view) {
// TODO Auto-generated method stub
pullToRefreshView.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Date date = new Date();
DateFormat ddf = DateFormat.getDateInstance();
String day = ddf.format(date);
DateFormat ddy = DateFormat.getTimeInstance();
String timeString = ddy.format(date);
DateFormat ddty = DateFormat.getDateTimeInstance();
String shjian = ddty.format(date);
System.out.println(day + "----" + timeString + "--------"
+ shjian);
// pullToRefreshView.onHeaderRefreshComplete("更新為"+new
// Date().toLocaleString());
pullToRefreshView.onHeaderRefreshComplete("更新為" + timeString);
}
}, 1000);
}
@Override
public void onFooterRefresh(PullToRefreshView view) {
// TODO Auto-generated method stub
pullToRefreshView.onFooterRefreshComplete();
}
}
其中的PullToRefreshView的代碼是也是別人的全代碼
package org.xml.demo;
import ogg.huanxin.huadong.R;
import android.content.Context;
import android.util.AttributeSet;
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.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
public class PullToRefreshView extends LinearLayout {
// private static final String TAG = "PullToRefreshView";
// refresh states
private static final int PULL_TO_REFRESH = 2;
private static final int RELEASE_TO_REFRESH = 3;
private static final int REFRESHING = 4;
// pull state
private static final int PULL_UP_STATE = 0;
private static final int PULL_DOWN_STATE = 1;
/**
* last y
*/
private int mLastMotionY;
/**
* lock
*/
// private boolean mLock;
/**
* header view
*/
private View mHeaderView;
/**
* footer view
*/
private View mFooterView;
/**
* list or grid
*/
private AdapterView<?> mAdapterView;
/**
* scrollview
*/
private ScrollView mScrollView;
/**
* header view height
*/
private int mHeaderViewHeight;
/**
* footer view height
*/
private int mFooterViewHeight;
/**
* header view image
*/
private ImageView mHeaderImageView;
/**
* footer view image
*/
private ImageView mFooterImageView;
/**
* header tip text
*/
private TextView mHeaderTextView;
/**
* footer tip text
*/
private TextView mFooterTextView;
/**
* header refresh time
*/
private TextView mHeaderUpdateTextView;
/**
* footer refresh time
*/
// private TextView mFooterUpdateTextView;
/**
* header progress bar
*/
private ProgressBar mHeaderProgressBar;
/**
* footer progress bar
*/
private ProgressBar mFooterProgressBar;
/**
* layout inflater
*/
private LayoutInflater mInflater;
/**
* header view current state
*/
private int mHeaderState;
/**
* footer view current state
*/
private int mFooterState;
/**
* pull state,pull up or pull down;PULL_UP_STATE or PULL_DOWN_STATE
*/
private int mPullState;
/**
* 變為向下的箭頭,改變箭頭方向
*/
private RotateAnimation mFlipAnimation;
/**
* 變為逆向的箭頭,旋轉
*/
private RotateAnimation mReverseFlipAnimation;
/**
* footer refresh listener
*/
private OnFooterRefreshListener mOnFooterRefreshListener;
/**
* footer refresh listener
*/
private OnHeaderRefreshListener mOnHeaderRefreshListener;
/**
* last update time
*/
// private String mLastUpdateTime;
public PullToRefreshView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PullToRefreshView(Context context) {
super(context);
init();
}
/**
* init
*
* @param context
*/
private void init() {
// 需要設置成vertical
setOrientation(LinearLayout.VERTICAL);
// Load all of the animations we need in code rather than through XML
mFlipAnimation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mFlipAnimation.setInterpolator(new LinearInterpolator());
mFlipAnimation.setDuration(250);
mFlipAnimation.setFillAfter(true);
mReverseFlipAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
mReverseFlipAnimation.setDuration(250);
mReverseFlipAnimation.setFillAfter(true);
mInflater = LayoutInflater.from(getContext());
// header view 在此添加,保證是第一個添加到linearlayout的最上端
addHeaderView();
}
private void addHeaderView() {
// header view
mHeaderView = mInflater.inflate(R.layout.refresh_header, this, false);
mHeaderImageView = (ImageView) mHeaderView
.findViewById(R.id.pull_to_refresh_image);
mHeaderTextView = (TextView) mHeaderView
.findViewById(R.id.pull_to_refresh_text);
mHeaderUpdateTextView = (TextView) mHeaderView
.findViewById(R.id.pull_to_refresh_updated_at);
mHeaderProgressBar = (ProgressBar) mHeaderView
.findViewById(R.id.pull_to_refresh_progress);
// header layout
measureView(mHeaderView);
mHeaderViewHeight = mHeaderView.getMeasuredHeight();
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
mHeaderViewHeight);
// 設置topMargin的值為負的header View高度,即將其隱藏在最上方
params.topMargin = -(mHeaderViewHeight);
// mHeaderView.setLayoutParams(params1);
addView(mHeaderView, params);
}
private void addFooterView() {
// footer view
mFooterView = mInflater.inflate(R.layout.refresh_footer, this, false);
mFooterImageView = (ImageView) mFooterView
.findViewById(R.id.pull_to_load_image);
mFooterTextView = (TextView) mFooterView
.findViewById(R.id.pull_to_load_text);
mFooterProgressBar = (ProgressBar) mFooterView
.findViewById(R.id.pull_to_load_progress);
// footer layout
measureView(mFooterView);
mFooterViewHeight = mFooterView.getMeasuredHeight();
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
mFooterViewHeight);
// int top = getHeight();
// params.topMargin
// =getHeight();//在這裡getHeight()==0,但在onInterceptTouchEvent()方法裡getHeight()已經有值了,不再是0;
// getHeight()什麼時候會賦值,稍候再研究一下
// 由於是線性布局可以直接添加,只要AdapterView的高度是MATCH_PARENT,那麼footer view就會被添加到最後,並隱藏
addView(mFooterView, params);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// footer view 在此添加保證添加到linearlayout中的最後
addFooterView();
initContentAdapterView();
}
/**
* init AdapterView like ListView,GridView and so on;or init ScrollView
*
*/
private void initContentAdapterView() {
int count = getChildCount();
if (count < 3) {
throw new IllegalArgumentException(
"This layout must contain 3 child views,and AdapterView or ScrollView must in the second position!");
}
View view = null;
for (int i = 0; i < count - 1; ++i) {
view = getChildAt(i);
if (view instanceof AdapterView<?>) {
mAdapterView = (AdapterView<?>) view;
}
if (view instanceof ScrollView) {
// finish later
mScrollView = (ScrollView) view;
}
}
if (mAdapterView == null && mScrollView == null) {
throw new IllegalArgumentException(
"must contain a AdapterView or ScrollView in this layout!");
}
}
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_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);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
int y = (int) e.getRawY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
// 首先攔截down事件,記錄y坐標
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
// deltaY > 0 是向下運動,< 0是向上運動
int deltaY = y - mLastMotionY;
if (isRefreshViewScroll(deltaY)) {
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
break;
}
return false;
}
/*
* 如果在onInterceptTouchEvent()方法中沒有攔截(即onInterceptTouchEvent()方法中 return
* false)則由PullToRefreshView 的子View來處理;否則由下面的方法來處理(即由PullToRefreshView自己來處理)
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// if (mLock) {
// return true;
// }
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// onInterceptTouchEvent已經記錄
// mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
int deltaY = y - mLastMotionY;
if (mPullState == PULL_DOWN_STATE) {// 執行下拉
headerPrepareToRefresh(deltaY);
// setHeaderPadding(-mHeaderViewHeight);
} else if (mPullState == PULL_UP_STATE) {// 執行上拉
footerPrepareToRefresh(deltaY);
}
mLastMotionY = y;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
int topMargin = getHeaderTopMargin();
if (mPullState == PULL_DOWN_STATE) {
if (topMargin >= 0) {
// 開始刷新
headerRefreshing();
} else {
// 還沒有執行刷新,重新隱藏
setHeaderTopMargin(-mHeaderViewHeight);
}
} else if (mPullState == PULL_UP_STATE) {
if (Math.abs(topMargin) >= mHeaderViewHeight
+ mFooterViewHeight) {
// 開始執行footer 刷新
footerRefreshing();
} else {
// 還沒有執行刷新,重新隱藏
setHeaderTopMargin(-mHeaderViewHeight);
}
}
break;
}
return super.onTouchEvent(event);
}
/**
* 是否應該到了父View,即PullToRefreshView滑動
*
* @param deltaY
* , deltaY > 0 是向下運動,< 0是向上運動
* @return
*/
private boolean isRefreshViewScroll(int deltaY) {
if (mHeaderState == REFRESHING || mFooterState == REFRESHING) {
return false;
}
// 對於ListView和GridView
if (mAdapterView != null) {
// 子view(ListView or GridView)滑動到最頂端
if (deltaY > 0) {
View child = mAdapterView.getChildAt(0);
if (child == null) {
// 如果mAdapterView中沒有數據,不攔截
return false;
}
if (mAdapterView.getFirstVisiblePosition() == 0
&& child.getTop() == 0) {
mPullState = PULL_DOWN_STATE;
return true;
}
int top = child.getTop();
int padding = mAdapterView.getPaddingTop();
if (mAdapterView.getFirstVisiblePosition() == 0
&& Math.abs(top - padding) <= 8) {// 這裡之前用3可以判斷,但現在不行,還沒找到原因
mPullState = PULL_DOWN_STATE;
return true;
}
} else if (deltaY < 0) {
View lastChild = mAdapterView.getChildAt(mAdapterView
.getChildCount() - 1);
if (lastChild == null) {
// 如果mAdapterView中沒有數據,不攔截
return false;
}
// 最後一個子view的Bottom小於父View的高度說明mAdapterView的數據沒有填滿父view,
// 等於父View的高度說明mAdapterView已經滑動到最後
if (lastChild.getBottom() <= getHeight()
&& mAdapterView.getLastVisiblePosition() == mAdapterView
.getCount() - 1) {
mPullState = PULL_UP_STATE;
return true;
}
}
}
// 對於ScrollView
if (mScrollView != null) {
// 子scroll view滑動到最頂端
View child = mScrollView.getChildAt(0);
if (deltaY > 0 && mScrollView.getScrollY() == 0) {
mPullState = PULL_DOWN_STATE;
return true;
} else if (deltaY < 0
&& child.getMeasuredHeight() <= getHeight()
+ mScrollView.getScrollY()) {
mPullState = PULL_UP_STATE;
return true;
}
}
return false;
}
/**
* header 准備刷新,手指移動過程,還沒有釋放
*
* @param deltaY
* ,手指滑動的距離
*/
private void headerPrepareToRefresh(int deltaY) {
int newTopMargin = changingHeaderViewTopMargin(deltaY);
// 當header view的topMargin>=0時,說明已經完全顯示出來了,修改header view 的提示狀態
if (newTopMargin >= 0 && mHeaderState != RELEASE_TO_REFRESH) {
mHeaderTextView.setText(R.string.app_name);
mHeaderUpdateTextView.setVisibility(View.VISIBLE);
mHeaderImageView.clearAnimation();
mHeaderImageView.startAnimation(mFlipAnimation);
mHeaderState = RELEASE_TO_REFRESH;
} else if (newTopMargin < 0 && newTopMargin > -mHeaderViewHeight) {// 拖動時沒有釋放
mHeaderImageView.clearAnimation();
mHeaderImageView.startAnimation(mFlipAnimation);
// mHeaderImageView.
mHeaderTextView.setText(R.string.app_name);
mHeaderState = PULL_TO_REFRESH;
}
}
/**
* footer 准備刷新,手指移動過程,還沒有釋放 移動footer view高度同樣和移動header view
* 高度是一樣,都是通過修改header view的topmargin的值來達到
*
* @param deltaY
* ,手指滑動的距離
*/
private void footerPrepareToRefresh(int deltaY) {
int newTopMargin = changingHeaderViewTopMargin(deltaY);
// 如果header view topMargin 的絕對值大於或等於header + footer 的高度
// 說明footer view 完全顯示出來了,修改footer view 的提示狀態
if (Math.abs(newTopMargin) >= (mHeaderViewHeight + mFooterViewHeight)
&& mFooterState != RELEASE_TO_REFRESH) {
mFooterTextView
.setText(R.string.app_name);
mFooterImageView.clearAnimation();
mFooterImageView.startAnimation(mFlipAnimation);
mFooterState = RELEASE_TO_REFRESH;
} else if (Math.abs(newTopMargin) < (mHeaderViewHeight + mFooterViewHeight)) {
mFooterImageView.clearAnimation();
mFooterImageView.startAnimation(mFlipAnimation);
mFooterTextView.setText(R.string.app_name);
mFooterState = PULL_TO_REFRESH;
}
}
/**
* 修改Header view top margin的值
*
* @param deltaY
*/
private int changingHeaderViewTopMargin(int deltaY) {
LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams();
float newTopMargin = params.topMargin + deltaY * 0.3f;
// 這裡對上拉做一下限制,因為當前上拉後然後不釋放手指直接下拉,會把下拉刷新給觸發了,感謝網友yufengzungzhe的指出
// 表示如果是在上拉後一段距離,然後直接下拉
if (deltaY > 0 && mPullState == PULL_UP_STATE
&& Math.abs(params.topMargin) <= mHeaderViewHeight) {
return params.topMargin;
}
// 同樣地,對下拉做一下限制,避免出現跟上拉操作時一樣的bug
if (deltaY < 0 && mPullState == PULL_DOWN_STATE
&& Math.abs(params.topMargin) >= mHeaderViewHeight) {
return params.topMargin;
}
params.topMargin = (int) newTopMargin;
mHeaderView.setLayoutParams(params);
invalidate();
return params.topMargin;
}
/**
* header refreshing
*
*/
private void headerRefreshing() {
mHeaderState = REFRESHING;
setHeaderTopMargin(0);
mHeaderImageView.setVisibility(View.GONE);
mHeaderImageView.clearAnimation();
mHeaderImageView.setImageDrawable(null);
mHeaderProgressBar.setVisibility(View.VISIBLE);
mHeaderTextView.setText(R.string.app_name);
if (mOnHeaderRefreshListener != null) {
mOnHeaderRefreshListener.onHeaderRefresh(this);
}
}
/**
* footer refreshing
*
*/
private void footerRefreshing() {
mFooterState = REFRESHING;
int top = mHeaderViewHeight + mFooterViewHeight;
setHeaderTopMargin(-top);
mFooterImageView.setVisibility(View.GONE);
mFooterImageView.clearAnimation();
mFooterImageView.setImageDrawable(null);
mFooterProgressBar.setVisibility(View.VISIBLE);
mFooterTextView
.setText(R.string.app_name);
if (mOnFooterRefreshListener != null) {
mOnFooterRefreshListener.onFooterRefresh(this);
}
}
/**
* 設置header view 的topMargin的值
*
* @param topMargin
* ,為0時,說明header view 剛好完全顯示出來; 為-mHeaderViewHeight時,說明完全隱藏了
*/
private void setHeaderTopMargin(int topMargin) {
LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams();
params.topMargin = topMargin;
mHeaderView.setLayoutParams(params);
invalidate();
}
/**
* header view 完成更新後恢復初始狀態
*
*/
public void onHeaderRefreshComplete() {
setHeaderTopMargin(-mHeaderViewHeight);
mHeaderImageView.setVisibility(View.VISIBLE);
mHeaderImageView.setImageResource(R.drawable.ic_pulltorefresh_arrow);
mHeaderTextView.setText(R.string.app_name);
mHeaderProgressBar.setVisibility(View.GONE);
// mHeaderUpdateTextView.setText("");
mHeaderState = PULL_TO_REFRESH;
}
/**
* Resets the list to a normal state after a refresh.
*
* @param lastUpdated
* Last updated at.
*/
public void onHeaderRefreshComplete(CharSequence lastUpdated) {
setLastUpdated(lastUpdated);
onHeaderRefreshComplete();
}
/**
* footer view 完成更新後恢復初始狀態
*/
public void onFooterRefreshComplete() {
setHeaderTopMargin(-mHeaderViewHeight);
mFooterImageView.setVisibility(View.VISIBLE);
mFooterImageView.setImageResource(R.drawable.ic_pulltorefresh_arrow_up);
mFooterTextView.setText(R.string.app_name);
mFooterProgressBar.setVisibility(View.GONE);
// mHeaderUpdateTextView.setText("");
mFooterState = PULL_TO_REFRESH;
}
/**
* Set a text to represent when the list was last updated.
*
* @param lastUpdated
* Last updated at.
*/
public void setLastUpdated(CharSequence lastUpdated) {
if (lastUpdated != null) {
mHeaderUpdateTextView.setVisibility(View.VISIBLE);
mHeaderUpdateTextView.setText(lastUpdated);
} else {
mHeaderUpdateTextView.setVisibility(View.GONE);
}
}
/**
* 獲取當前header view 的topMargin
*
*/
private int getHeaderTopMargin() {
LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams();
return params.topMargin;
}
// /**
// * lock
// *
// */
// private void lock() {
// mLock = true;
// }
//
// /**
// * unlock
// *
// */
// private void unlock() {
// mLock = false;
// }
/**
* set headerRefreshListener
*
* @param headerRefreshListener
*/
public void setOnHeaderRefreshListener(
OnHeaderRefreshListener headerRefreshListener) {
mOnHeaderRefreshListener = headerRefreshListener;
}
public void setOnFooterRefreshListener(
OnFooterRefreshListener footerRefreshListener) {
mOnFooterRefreshListener = footerRefreshListener;
}
/**
* Interface definition for a callback to be invoked when list/grid footer
* view should be refreshed.
*/
public interface OnFooterRefreshListener {
public void onFooterRefresh(PullToRefreshView view);
}
/**
* Interface definition for a callback to be invoked when list/grid header
* view should be refreshed.
*/
public interface OnHeaderRefreshListener {
public void onHeaderRefresh(PullToRefreshView view);
}}
Android上傳圖片之調用系統拍照和從相冊選擇圖片
Android上傳圖片之調用系統拍照和從相冊選擇圖片 Android上傳圖片之調用系統拍照和從相冊選擇圖片 前言: 萬丈高樓平底起,萬事起於微末。不知不覺距離上篇博文已近
RxAndroid使用方法介紹
RxAndroid使用方法介紹 熟悉RxAndroid的使用方法. 要點包含: (1) 鏈式表達式的使用方式. (2) Lambda的應用. (3) Rx處理網絡請求
淺談android:clipChildren屬性,
淺談android:clipChildren屬性,實現功能: 1、APP主界面底部模塊欄 2、ViewPager一屏多個界面顯示 3、........ 首先
Android學習----自適應國際化語言,android----
Android學習----自適應國際化語言,android---- 【前言】 自適應的知識與編程無關,關鍵在於配置文件的修改。自適應的內容包括: