展会信息港展会大全

android ExpandableListView的下拉刷新实现
来源:互联网   发布日期:2015-11-27 13:58:00   浏览:3300次  

导读:该控件的修改时根据PullToRefreshList的机制修改 下面是对ExpandableListView的扩展 package com.up91.gwy.view.componet; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import com.up91.gwy.R; import android.c...

该控件的修改时根据PullToRefreshList的机制修改

下面是对ExpandableListView的扩展

package com.up91.gwy.view.componet;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import com.up91.gwy.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.AbsListView;

import android.widget.ExpandableListView;

import android.widget.AbsListView.OnScrollListener;

import android.widget.ImageView;

import android.widget.ListAdapter;

import android.widget.ProgressBar;

import android.widget.RelativeLayout;

import android.widget.TextView;

public class PullToRefreshExpandableListView

extends ExpandableListView

implements

OnScrollListener {

private static final String TAG = "PullToRefreshExpandableListView";

private static final int TAP_TO_REFRESH = 1;

private static final int PULL_TO_REFRESH = 2;

private static final int RELEASE_TO_REFRESH = 3;

private static final int REFRESHING = 4;

private OnRefreshListener mOnRefreshListener;

private OnScrollListener mOnScrollListener;

private LayoutInflatermInflater;

private RelativeLayoutmRefreshView;

private TextView mRefreshViewText;

private ImageView mRefreshViewImage;

private ProgressBar mRefreshViewProgress;

private TextViewmRefreshViewLastUpdated;

private int mCurrentScrollState;

private int mRefreshState;

private RotateAnimation mFlipAnimation;

private RotateAnimation mReverseFlipAnimation;

private int mRefreshViewHeight;

private int mRefreshOriginalTopPadding;

private int mLastMotionY;

private boolean isInInitState;

public PullToRefreshExpandableListView(Context context) {

super(context);

init(context);

}

public PullToRefreshExpandableListView(Context context, AttributeSet attrs) {

super(context,attrs);

init(context);

}

public PullToRefreshExpandableListView(Context context,AttributeSet attrs, int defStyle) {

super(context,attrs,defStyle);

init(context);

}

private void init(Context context){

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) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

mRefreshView = (RelativeLayout) mInflater.inflate(R.layout.pull_to_refresh_header, this,false);

mRefreshViewText = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_text);

mRefreshViewImage = (ImageView) mRefreshView.findViewById(R.id.pull_to_refresh_image);

mRefreshViewProgress = (ProgressBar) mRefreshView.findViewById(R.id.pull_to_refresh_progress);

mRefreshViewLastUpdated = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_updated_at);

mRefreshViewImage.setMinimumHeight(50);

mRefreshView.setOnClickListener(new OnClickRefreshListener());

mRefreshOriginalTopPadding = mRefreshView.getPaddingTop();

mRefreshState = TAP_TO_REFRESH;

addHeaderView(mRefreshView);

super.setOnScrollListener(this);

measureView(mRefreshView);

mRefreshViewHeight = mRefreshView.getMeasuredHeight();

}

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);

}

private class OnClickRefreshListener implements OnClickListener{

@Override

public void onClick(View v) {

if(mRefreshState != REFRESHING){

prepareForRefresh();

onRefresh();

}

}

}

public interface OnRefreshListener{

public void onRefresh();

}

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

setSelection(1);

}

@Override

public void setAdapter(ListAdapter adapter) {

super.setAdapter(adapter);

setSelection(1);

}

@Override

public void setOnScrollListener(OnScrollListener l) {

mOnScrollListener = l;

}

public void setOnRefreshListener(OnRefreshListener onRefreshListener){

mOnRefreshListener = onRefreshListener;

}

public void setLastUpdated(CharSequence lastUpdated){

if(lastUpdated != null){

mRefreshViewLastUpdated.setVisibility(View.VISIBLE);

mRefreshViewLastUpdated.setText(lastUpdated);

}else{

mRefreshViewLastUpdated.setVisibility(View.GONE);

}

}

public boolean onTouchEvent(MotionEvent event) {

final int y = (int) event.getY();

switch (event.getAction()) {

case MotionEvent.ACTION_UP:

if (!isVerticalScrollBarEnabled()) {

setVerticalScrollBarEnabled(true);

}

if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {

if ((mRefreshView.getBottom() > mRefreshViewHeight

|| mRefreshView.getTop() >= 0)

&& mRefreshState == RELEASE_TO_REFRESH) {

// Initiate the refresh

mRefreshState = REFRESHING;

prepareForRefresh();

onRefresh();

} else if (mRefreshView.getBottom() < mRefreshViewHeight

|| mRefreshView.getTop() < 0) {

// Abort refresh and scroll down below the refresh view

resetHeader();

setSelection(1);

}

}

break;

case MotionEvent.ACTION_DOWN:

mLastMotionY = y;

break;

case MotionEvent.ACTION_MOVE:

applyHeaderPadding(event);

break;

}

return super.onTouchEvent(event);

}

private void applyHeaderPadding(MotionEvent ev) {

final int historySize = ev.getHistorySize();

// Workaround for getPointerCount() which is unavailable in 1.5

// (it's always 1 in 1.5)

int pointerCount = 1;

try {

Method method = MotionEvent.class.getMethod("getPointerCount");

pointerCount = (Integer)method.invoke(ev);

} catch (NoSuchMethodException e) {

pointerCount = 1;

} catch (IllegalArgumentException e) {

throw e;

} catch (IllegalAccessException e) {

System.err.println("unexpected " + e);

} catch (InvocationTargetException e) {

System.err.println("unexpected " + e);

}

for (int h = 0; h < historySize; h++) {

for (int p = 0; p < pointerCount; p++) {

if (mRefreshState == RELEASE_TO_REFRESH) {

if (isVerticalFadingEdgeEnabled()) {

setVerticalScrollBarEnabled(false);

}

int historicalY = 0;

try {

// For Android > 2.0

Method method = MotionEvent.class.getMethod(

"getHistoricalY", Integer.TYPE, Integer.TYPE);

historicalY = ((Float) method.invoke(ev, p, h)).intValue();

} catch (NoSuchMethodException e) {

// For Android < 2.0

historicalY = (int) (ev.getHistoricalY(h));

} catch (IllegalArgumentException e) {

throw e;

} catch (IllegalAccessException e) {

System.err.println("unexpected " + e);

} catch (InvocationTargetException e) {

System.err.println("unexpected " + e);

}

// Calculate the padding to apply, we divide by 1.7 to

// simulate a more resistant effect during pull.

int topPadding = (int) (((historicalY - mLastMotionY)

- mRefreshViewHeight) / 1.7);

mRefreshView.setPadding(

mRefreshView.getPaddingLeft(),

topPadding,

mRefreshView.getPaddingRight(),

mRefreshView.getPaddingBottom());

}

}

}

}

private void resetHeaderPadding() {

mRefreshView.setPadding(

mRefreshView.getPaddingLeft(),

mRefreshOriginalTopPadding,

mRefreshView.getPaddingRight(),

mRefreshView.getPaddingBottom());

}

private void resetHeader() {

if (mRefreshState != TAP_TO_REFRESH) {

mRefreshState = TAP_TO_REFRESH;

resetHeaderPadding();

// Set refresh view text to the pull label

mRefreshViewText.setText(R.string.pull_to_refresh_tap_label);

// Replace refresh drawable with arrow drawable

mRefreshViewImage.setImageResource(R.drawable.ic_pulltorefresh_arrow);

// Clear the full rotation animation

mRefreshViewImage.clearAnimation();

// Hide progress bar and arrow.

mRefreshViewImage.setVisibility(View.GONE);

mRefreshViewProgress.setVisibility(View.GONE);

}

}

public void onScroll(AbsListView view, int firstVisibleItem,

int visibleItemCount, int totalItemCount) {

// When the refresh view is completely visible, change the text to say

// "Release to refresh..." and flip the arrow drawable.

if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL

&& mRefreshState != REFRESHING) {

if (firstVisibleItem == 0) {

mRefreshViewImage.setVisibility(View.VISIBLE);

if((mRefreshView.getBottom() > mRefreshViewHeight + 20

|| mRefreshView.getTop() >= 0)

&& mRefreshState == PULL_TO_REFRESH){

mRefreshViewText.setText(R.string.pull_to_refresh_release_label);

mRefreshViewImage.clearAnimation();

mRefreshViewImage.startAnimation(mFlipAnimation);

mRefreshState = RELEASE_TO_REFRESH;

}else if(mRefreshState == RELEASE_TO_REFRESH

&&mRefreshView.getBottom() < mRefreshViewHeight + 20){

mRefreshViewImage.setVisibility(View.GONE);

resetHeader();

}else if(mRefreshView.getBottom() == mRefreshViewHeight

&& mRefreshState == TAP_TO_REFRESH){

//不作为

mRefreshViewImage.setVisibility(View.GONE);

resetHeader();

} else if(mRefreshView.getBottom() < mRefreshViewHeight + 20

&& mRefreshState == TAP_TO_REFRESH){

mRefreshViewText.setText(R.string.pull_to_refresh_pull_label);

mRefreshState = PULL_TO_REFRESH;

mRefreshViewImage.clearAnimation();

mRefreshViewImage.startAnimation(mReverseFlipAnimation);

}

} else {

mRefreshViewImage.setVisibility(View.GONE);

resetHeader();

}

} else if (mCurrentScrollState == SCROLL_STATE_FLING

&& firstVisibleItem == 0

&& mRefreshState != REFRESHING) {

setSelection(1);

}

if (mOnScrollListener != null) {

mOnScrollListener.onScroll(view, firstVisibleItem,

visibleItemCount, totalItemCount);

}

}

public void onScrollStateChanged(AbsListView view, int scrollState) {

mCurrentScrollState = scrollState;

if (mOnScrollListener != null) {

mOnScrollListener.onScrollStateChanged(view, scrollState);

}

}

public void prepareForRefresh() {

resetHeaderPadding();

mRefreshViewImage.setVisibility(View.GONE);

// We need this hack, otherwise it will keep the previous drawable.

mRefreshViewImage.setImageDrawable(null);

mRefreshViewProgress.setVisibility(View.VISIBLE);

// Set refresh view text to the refreshing label

mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label);

mRefreshState = REFRESHING;

}

public void onRefresh() {

if (mOnRefreshListener != null) {

mOnRefreshListener.onRefresh();

resetHeader();

}

}

public void onRefreshComplete(CharSequence lastUpdated) {

setLastUpdated(lastUpdated);

onRefreshComplete();

}

public void onRefreshComplete() {

resetHeader();

// If refresh view is visible when loading completes, scroll down to

// the next item.

if (mRefreshView.getBottom() > 0) {

invalidateViews();

setSelection(1);

}

}

}

使用时:

expLV.setOnRefreshListener(new OnRefreshListener(){

@Override

public void onRefresh() {

//远程取数据机制

});

摘自:timchen6824的专栏

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港