Android简洁的下拉放大刷新

综合技术 简书 (源链)

序言

国庆放假过后眼看一年又要过完了,年初指望着已经有一年的经验本以为自己不是刚出校的学生以为翅膀已经硬了,打算辞职换新工作,一面试才发现自己就是个垃圾,什么oninterceptEvent,dispatchTouchEvent ,Aysnctask都不会。做了一年的项目也是用的Xutils2.6版本 还有一堆不常用不好的不主流不时尚的框架,技术也没任何长进。还好公司真的轻松(所以也学不到任何东西)可以趁闲下来的时间多学点东西。于是写了个简单但也有需求的控件练练手。

首先先看效果图吧

效果图.gif

1、具体使用

项目build.gradle

allprojects {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

app model build.gradle

compile 'com.github.xypmhxy:PullZoomLayout:1.1'

布局文件中

//图片缩放方式

        

    

2、实现思路

其思路很简单

1.首先在构造方法中动态添加下拉缩放的imageView和刷新的refreshProgress(控件中为实现跟随手指滑动旋转因此使用的为imageView)

2.获取到listview对象,然后监听listview的滑动事件,判断滑到顶部后继续向下滑动的时候将需要放大的ImageView高度增加然后利用ImageView的Scale方法完成缩放。

3.最后放开手指的时候用属性动画让imageView平滑回到最初状态,并且如果开启下拉刷新则回调其方法。

3、具体实现

1.动态添加两个ImageView(下拉放大的和刷新的progress),大致原理就是将这两个ImageView添加到RelativeLayout中然后将RelativeLayout 添加到自身中。代码如下

/*实例化头部布局包含pullZoomImage 和 refreshProgress*/
protected void init(Context context) {
        RelativeLayout head = new RelativeLayout(context);
        ViewGroup.LayoutParams headParams = new ViewGroup.LayoutParams(-1, -2);
        head.setLayoutParams(headParams);
        /*实例化pullZoomImage*/
      ·······
        pullZoomImage.setImageResource(imageRes);
        originalParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, imageHeight);
        pullZoomImage.setLayoutParams(originalParams);
        head.addView(pullZoomImage);
        /*实例化refreshProgress*/
        refreshProgress = new ImageView(context);
        refreshProgress.setVisibility(GONE);
        refreshProgress.setImageResource(R.drawable.refresh);
        RelativeLayout.LayoutParams refreshParams = new RelativeLayout.LayoutParams(dip2px(context, 35), dip2px(context, 35));
        refreshParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE);
        refreshProgress.setLayoutParams(refreshParams);
        head.addView(refreshProgress);
        /*将头部添加到此控件中*/
        addView(head, 0);
}

2.是获取listview对象,因为listview属于子控件所以不能在构造方法里直接获取,因为此时控件不一定加载完成所以需要等待子控件加载完成后获取因此在onFinishInflate方法中获取

@Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        /*获取listview*/
        if (getChildAt(1) instanceof ListView) {
            listView = (ListView) getChildAt(1);
            listView.setOnScrollListener(scrollListener);
            listView.setOnTouchListener(touchListener);
        }
    }

3.添加listview滑动监听判断是否滑动到顶部,可以开启下拉放大功能

/*listview滑动监听*/
    protected AbsListView.OnScrollListener scrollListener = new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            /*判断是否滑动到顶部*/
            int firstVisibleItem = listView.getFirstVisiblePosition();
            if (firstVisibleItem == 0 && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                View firstView = getChildAt(0);
                canZoom = firstView != null && firstView.getTop() == 0;
            } else
                canZoom = false;
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        }
    };

4.实现OnTouchListener根据事件调用放大和缩小动画,抬手时实现刷新等操作

/*listview touchListener监听*/
    protected OnTouchListener touchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {
            if (pullZoomImage == null) return false;
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    pressY = ev.getY();//获取按下的Y坐标
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (canZoom)//如果已经滑动到顶部并继续滑动则开始放大pullZoomImage
                        return zoomView(ev);
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    if (canZoom)
                        restroe();//还原pullZoomImage动画
                    if (needRefresh && refreshListener != null) {//达到刷新条件并且实现刷新监听
                        refreshListener.onRefresh();
                        rotationProgress();//刷新时progress旋转动画
                    } else
                        refreshProgress.setVisibility(GONE);
                    //重置变量
                    needRefresh = false;
                    canZoom = false;
                    break;

            }
            return false;
        }
    };

缩放imageview

/*放大pullZoomImage*/
    protected boolean zoomView(MotionEvent ev) {
        float offY = ev.getY() - pressY;
        if (offY <= 0="" ||="" offy="" = refrshSlop;
            if (needRefresh)
                refreshProgress.setVisibility(VISIBLE);
        }
        ViewGroup.LayoutParams params = pullZoomImage.getLayoutParams();
        float height = originalParams.height + offY / damp;//根据滑动距离增加pullZoomImage的高度
        params.height = (int) height;
        scaleImage(height);//放大图片
        rotationProgress(offY);//旋转refreshProgress
        if (params.height >= originalParams.height)
            pullZoomImage.setLayoutParams(params);//为pullZoomImage设置改变后的params
        return true;
    }
    /*缩放imageview*/
    protected void scaleImage(float height) {
//        if (pullZoomImage.getScaleType() == ImageView.ScaleType.CENTER_CROP)
//            return;
        float scale = (height - originalParams.height) / originalParams.height;//根据滑动的大小判断缩放比例
        pullZoomImage.setScaleX(1 + scale);
        pullZoomImage.setScaleY(1 + scale);
    }

抬手后通过属性动画还原pullZoomImage

/*放开后还原pullZoomImage*/
    protected void restroe() {
        ValueAnimator animator = ValueAnimator.ofFloat(pullZoomImage.getLayoutParams().height, originalParams.height);// 动画更新的监听
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator arg0) {
                float height = (float) arg0.getAnimatedValue();// 获取动画当前变化的值
                // 根据最新高度,更新布局高度
                ViewGroup.LayoutParams params = pullZoomImage.getLayoutParams();
                params.height = (int) height;
                scaleImage(height);
                pullZoomImage.setLayoutParams(params);
            }
        });
        animator.setDuration(200);// 动画时间
        animator.start();// 开启动画
    }

大致原理就是这样最后传送门开启 PullZoomLayout

您可能感兴趣的

Unity Android Activity控制 前言 开发游戏,在国内发行,接入各个渠道SDK是一件绕不开的事情。并且这件事非常复杂琐碎,原因如下: a、发行平台多,Android平台有30,40家主流发行平台 b、每家SDK的接入API五花八门 c、发布管理这么多的APP耗时耗力 d、各家的SDK经常更新,接口不兼容的事常有...
Why You Should Use Kotlin to Develop Expressive An... With around 85 percent of the market share and over 3.6 million apps, Google Play rules the mobile app realm. Every day, Android app developers are...
Equivalent to CSS class selectors for Android view... Do Android views have something equivalent to CSS class selectors? Something like R.id but usable for multiple views? I would like to hide some gro...
When to use FragmentManager ::... I've got an application that uses fragments and I was playing around with how to use the same fragment in an Activity with a dual pane and an Activity...
Set a Custom Saturation Level on your Google Pixel... Google’s latest flagship smartphones, the Google Pixel 2 and Pixel 2 XL , had a somewhat controversial launch week. Some early reviewers were complai...
简书责编内容来自:简书 (源链) | 更多关于

阅读提示:酷辣虫无法对本内容的真实性提供任何保证,请自行验证并承担相关的风险与后果!
本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » Android简洁的下拉放大刷新



专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录