android自定义下拉刷新使用ViewDraghelper处理

2017-01-07  本文已影响182人  Runtime123

主要是使用ViewDragHelper处理的滑动侦听

privateViewDragHelperdragHelper;

privateViewmContentView;

privateViewGroupmTopView;

privateListViewlistView;

privateRecyclerViewrecyclerView;

privateScrollViewscrollView;

privateImageViewiv_circel;

privateRelativeLayoutrl_content;

private intmWidth,mHeight;

private intmaxRange=0;//最大下拉的高度

private intrefreshHeight;//下拉出发刷新的高度

private inttext_bottom;//中间文字的底部

private intdownY;

private intchildViewTop;

private booleanisMoveChildView,isLayout;//是否包含可滑动的view true包含

private booleanisStop,isStartAnim;//是否停止刷新,是否开启动画

//下拉刷新的状态

private final intSTATE_DOWN=0;//下拉中

private final intSTATE_REFRESHING=1;//刷新中

private final intSTATE_REFRESH=2;//可刷新

private intcurrent_state=STATE_DOWN;

//属性值

private intrefresh_gravity=1;//1 top 2 center 3 bottom

privateOnRefreshListenerlistener;

private booleanisRefresh=true;//是否可以刷新

privateTextViewtv_text;

publicRefreshView(Context context) {

this(context, null);

}

publicRefreshView(Context context,AttributeSet attrs) {

this(context,attrs,0);

}

publicRefreshView(Context context,AttributeSet attrs, intdefStyleAttr) {

super(context,attrs,defStyleAttr);

init();

//获取自定义属性

TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.refreshView);

refresh_gravity= ta.getInt(R.styleable.refreshView_refresh_gravity,1);

ta.recycle();

}

public interfaceOnRefreshListener {

voidonRefresh();

}

public voidsetOnRefreshListener(OnRefreshListener listener) {

this.listener= listener;

}

public voidsetIsRefresh(booleanisRefresh) {

this.isRefresh= isRefresh;

}

private voidinit() {

dragHelper= ViewDragHelper.create(this, newMyCallBack());

}

@Override

protected voidonSizeChanged(intw, inth, intoldw, intoldh) {

super.onSizeChanged(w,h,oldw,oldh);

mWidth= w;

mHeight= h;

}

@Override

protected voidonFinishInflate() {

super.onFinishInflate();

//健壮性检查

if(getChildCount() >1) {

throw newRuntimeException("只能包含一个子view或viewgroup");

}

if(getChildCount() ==0) {

throw newRuntimeException("not childview,childview would not be null!");

}

isLayout=false;

//因为在onFinishInflate中添加一个viewgroup在0的位置

mContentView= getChildAt(0);//获取布局中的view

isMoveChildView= childType(mContentView);//查看是否有可滑动的view

//添加下拉刷新头布局

mTopView= (ViewGroup) View.inflate(getContext(),R.layout.layout_refresh, null);

addView(mTopView,0);

rl_content= (RelativeLayout)mTopView.findViewById(R.id.fl_header);

rl_content.measure(0,0);

refreshHeight=rl_content.getMeasuredHeight();

tv_text= (TextView)mTopView.findViewById(R.id.tv_text);

iv_circel= (ImageView)mTopView.findViewById(R.id.iv_circel);

iv_circel.setAlpha(0.0f);

//根据设置的属性设置头布局的位置

if(refresh_gravity==1) {

rl_content.setGravity(Gravity.TOP);

}else if(refresh_gravity==2) {

rl_content.setGravity(Gravity.CENTER);

}else{

rl_content.setGravity(Gravity.BOTTOM);

}

}

/**

*判断此view是否是可滑动的view,或此view中是否包含可滑动的view(listview,scrollview,recyclerview)

*

*@paramview

*@returntrue则表示包含可滑动的view

*/

private booleanchildType(View view) {

booleanconform =false;

conform = isTypeConform(view,conform);

if(!conform) {

if(viewinstanceofViewGroup) {

ViewGroup viewGroup = (ViewGroup) view;

intchildCount = viewGroup.getChildCount();

for(inti =0;i < childCount;i++) {

View childView = viewGroup.getChildAt(i);

if(childViewinstanceofViewGroup) {

booleantypeConform = isTypeConform(childView,conform);

if(typeConform) {

childViewTop= childView.getTop();//可滑动view的初始top值

returntypeConform;

}

childType(childView);

}

}

}

}

returnconform;

}

/**

*是否是可滑动的view

*/

private booleanisTypeConform(View view, booleantype) {

if(viewinstanceofListView) {

type =true;

listView= (ListView) view;

}else if(viewinstanceofRecyclerView) {

recyclerView= (RecyclerView) view;

type =true;

}else if(viewinstanceofScrollView) {

scrollView= (ScrollView) view;

type =true;

}

returntype;

}

@Override

protected voidonLayout(booleanchanged, intleft, inttop, intright, intbottom) {

if(!isLayout) {

if(iv_circel!=null&&isStartAnim) {

iv_circel.clearAnimation();

isStartAnim=false;

iv_circel.setAlpha(0.0f);

}

super.onLayout(changed,left,top,right,bottom);

}

maxRange=mHeight-refreshHeight;//最大下拉距离

text_bottom=refreshHeight-refreshHeight/2;

mTopView.layout(0,-(mHeight-refreshHeight),mWidth,refreshHeight);

isLayout=false;

//重新摆放刷新布局

if(refresh_gravity==1&&mContentView.getTop() >=refreshHeight) {

mTopView.setTranslationY(mContentView.getTop() -refreshHeight);

}

}

@Override

public booleanonInterceptTouchEvent(MotionEvent ev) {

if(ev.getAction() == MotionEvent.ACTION_DOWN) {

downY= (int) ev.getY();

}

returndragHelper.shouldInterceptTouchEvent(ev);

}

@Override

public booleanonTouchEvent(MotionEvent event) {

dragHelper.processTouchEvent(event);

return true;

}

private classMyCallBackextendsViewDragHelper.Callback {

/**

*返回可拖拽的范围

*/

@Override

public intgetViewVerticalDragRange(View child) {

//如果包含可滑动的view

if(isMoveChildView&&downY>childViewTop) {

if(listView!=null&&listView.getAdapter() !=null) {

View childView =listView.getChildAt(0);

if(listView.getAdapter().getCount() >0&& childView !=null&& childView.getTop() <0)

return super.getViewVerticalDragRange(child);

}else if(scrollView!=null&&scrollView.getScrollY() >0) {

return super.getViewVerticalDragRange(child);

}else if(recyclerView!=null&&recyclerView.getAdapter() !=null&&recyclerView.getChildAt(0).getTop() <0) {

return super.getViewVerticalDragRange(child);

}

}

returnmaxRange;

}

/**

*返回true表示可以拖拽

*/

@Override

public booleantryCaptureView(View child, intpointerId) {

//如果触摸的是刷新的头部view或者是设置为不可刷新则返回false

if(child ==mTopView|| !isRefresh) {

return false;

}

return true;

}

/**

*当被拖拽的view移动位置后,会调用此方法。可以用于处理View之间的联动

*/

@Override

public voidonViewPositionChanged(View changedView, intleft, inttop, intdx, intdy) {

super.onViewPositionChanged(changedView,left,top,dx,dy);

//处理上面view的移动

floatmoveTop = top;

if(moveTop >=text_bottom) {

floatalpha = (moveTop -text_bottom) /text_bottom;

if(alpha >1) {

alpha =1.0f;

}else if(alpha <0.0) {

alpha =0.0f;

}

iv_circel.setAlpha(alpha);

}else{

iv_circel.setAlpha(0.0f);

}

if(tv_text!=null) {

isLayout=true;

tv_text.setText("下拉刷新");

}

if(moveTop >=refreshHeight) {

if(iv_circel!=null&&isStartAnim) {

isStartAnim=false;

iv_circel.clearAnimation();

}

if(refresh_gravity==1) {

isLayout=true;

LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)rl_content.getLayoutParams();

params.height= (int) moveTop;

rl_content.setLayoutParams(params);

rl_content.requestLayout();

}else if(refresh_gravity==2||refresh_gravity==3) {

floattranslationY = moveTop -refreshHeight;

mTopView.setTranslationY(translationY);

}

}

}

/**

*拖拽松开时调用

*/

@Override

public voidonViewReleased(View releasedChild, floatxvel, floatyvel) {

super.onViewReleased(releasedChild,xvel,yvel);

intmContentViewTop =mContentView.getTop();

if(mContentViewTop >refreshHeight) {

current_state=STATE_REFRESH;

refreshOpen();

}else{

close();

}

}

/**

*返回top值

*/

@Override

public intclampViewPositionVertical(View child, inttop, intdy) {

floatnewTop = top/** 0.93f*/;

if(newTop >=maxRange) {

newTop =maxRange;

}else if(top <0) {

newTop =0;

}

return(int) newTop;

}

}

/**

*开始刷新 并且滚动至相应的位置

*/

private voidrefreshOpen() {

inttop =refreshHeight;

if(dragHelper.smoothSlideViewTo(mContentView,0,top)) {

ViewCompat.postInvalidateOnAnimation(this);

}

}

/**

*关闭面板 此时下拉的高度没有达到刷新的高度,滚动至0的位置

*/

private voidclose() {

inttop =0;

if(dragHelper.smoothSlideViewTo(mContentView,0,top)) {

ViewCompat.postInvalidateOnAnimation(this);

}

isLayout=false;

current_state=STATE_DOWN;

iv_circel.clearAnimation();

}

@Override

public voidcomputeScroll() {

//        super.computeScroll();

if(dragHelper.continueSettling(true)) {

ViewCompat.postInvalidateOnAnimation(this);

}else if(mContentView.getTop() >=refreshHeight&¤t_state==STATE_REFRESH) {

startAnim();

current_state=STATE_REFRESHING;//改变状态

if(listener!=null) {

listener.onRefresh();

}

if(tv_text!=null) {

tv_text.setText("刷新中");

isLayout=true;

}

}

}

private longduration=500L;

private voidstartAnim() {

isStop=false;

duration=500L;

isStartAnim=true;

RotateAnimation anim =newRotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5F,Animation.RELATIVE_TO_SELF,0.5F);

anim.setDuration(duration);

anim.setRepeatCount(Animation.INFINITE);

anim.setInterpolator(newLinearInterpolator());

iv_circel.startAnimation(anim);

anim.setAnimationListener(newAnimation.AnimationListener() {

@Override

public voidonAnimationStart(Animation animation) {

}

@Override

public voidonAnimationEnd(Animation animation) {

current_state=STATE_DOWN;//清楚动画的同时并改变是否刷新的状态

if(tv_text!=null) {

isLayout=true;

tv_text.setText("刷新完毕");

}

postDelayed(newRunnable() {

@Override

public voidrun() {

close();//回滚至顶部

}

},300);

}

@Override

public voidonAnimationRepeat(Animation animation) {

if(!isStop) {

duration-=100;

if(duration<=230) {

duration=230;

}

}else{

duration+=100;

if(duration>=500) {

duration=500;

anim.setRepeatCount(1);

}

}

anim.setDuration(duration);

}

});

}

/**

*刷新完毕

*/

public voidrefreshFinish() {

isStop=true;

}

}

自定义属性

< declare-styleable name="refreshView">

<enum name="refresh_top" value="1"/>

<enum name="refresh_center" value="2"/>

<enum name="refresh_bottom" value="3"/>

<declare-styleable/>

头部布局

<LinearLayout 

android:id="@+id/ll_header"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@android:color/holo_green_light"

android:gravity="bottom"

android:orientation="vertical">

android:id="@+id/fl_header"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:gravity="bottom"

android:paddingBottom="20dp"

android:paddingTop="20dp">

<FramLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android:id="@+id/tv_text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:text="下拉刷新"

android:textColor="@android:color/black"

android:textSize="12sp"/>

android:id="@+id/iv_circel"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:scaleType="fitXY"

android:src="@mipmap/circle"/>

</Framlayout>

欢迎大神指点

上一篇下一篇

猜你喜欢

热点阅读