美文网首页
android自定义下拉刷新使用ViewDraghelper处理

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

作者: Runtime123 | 来源:发表于2017-01-07 09:34 被阅读182次

    主要是使用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>

    欢迎大神指点

    相关文章

      网友评论

          本文标题:android自定义下拉刷新使用ViewDraghelper处理

          本文链接:https://www.haomeiwen.com/subject/uvxfbttx.html