整合大量开源库温习基础项目(四)伸缩实现OverscrollScale以及MaterialLoadingProgressBar

转载请注明出处:王亟亟的大牛之路

运行效果:(还是有点卡顿,大致看得到内容)

这一次的菜单的UI在上一篇文章中已经做了修改,上一篇的样子:

因为没想到要做些什么东西,所以大致的放了这几个栏目,这一片先把我们新加入的库来讲一下。

Gradle:

  compile 'com.dodola:listviewext:1.0'
  compile('com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE')

支持伸缩的ListView : https://github.com/dodola/OverscrollScale

自定义进度条View:https://github.com/lsjwzh/MaterialLoadingProgressBar

都是相当轻量级的两个自定义控件,使用也非常简单。



CircleProgressBar

我们来简单的分析一下这个自定义View

//继承于ImageView,也就是说没有了我们Dialog的一些父类的方法,什么都是自己画的
public class CircleProgressBar extends ImageView

常见的构造方法,内部都是一个private void init(Context context, AttributeSet attrs, int defStyleAttr)方法。

    public CircleProgressBar(Context context) {
        super(context);
        init(context, null, 0);

    }

    public CircleProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);

    }

    public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

初始化参数:

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.CircleProgressBar, defStyleAttr, 0);
        final float density = getContext().getResources().getDisplayMetrics().density;

        mBackGroundColor = a.getColor(
                R.styleable.CircleProgressBar_mlpb_background_color, DEFAULT_CIRCLE_BG_LIGHT);

        mProgressColor = a.getColor(
                R.styleable.CircleProgressBar_mlpb_progress_color, DEFAULT_CIRCLE_BG_LIGHT);
        mColors = new int[]{mProgressColor};

        mInnerRadius = a.getDimensionPixelOffset(
                R.styleable.CircleProgressBar_mlpb_inner_radius, -1);

        mProgressStokeWidth = a.getDimensionPixelOffset(
                R.styleable.CircleProgressBar_mlpb_progress_stoke_width, (int) (STROKE_WIDTH_LARGE * density));
        mArrowWidth = a.getDimensionPixelOffset(
                R.styleable.CircleProgressBar_mlpb_arrow_width, -1);
        mArrowHeight = a.getDimensionPixelOffset(
                R.styleable.CircleProgressBar_mlpb_arrow_height, -1);
        mTextSize = a.getDimensionPixelOffset(
                R.styleable.CircleProgressBar_mlpb_progress_text_size, (int) (DEFAULT_TEXT_SIZE * density));
        mTextColor = a.getColor(
                R.styleable.CircleProgressBar_mlpb_progress_text_color, Color.BLACK);

        mShowArrow = a.getBoolean(R.styleable.CircleProgressBar_mlpb_show_arrow, false);
        mCircleBackgroundEnabled = a.getBoolean(R.styleable.CircleProgressBar_mlpb_enable_circle_background, true);

        mProgress = a.getInt(R.styleable.CircleProgressBar_mlpb_progress, 0);
        mMax = a.getInt(R.styleable.CircleProgressBar_mlpb_max, 100);
        int textVisible = a.getInt(R.styleable.CircleProgressBar_mlpb_progress_text_visibility, 1);
        if (textVisible != 1) {
            mIfDrawText = true;
        }

        mTextPaint = new Paint();
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setColor(mTextColor);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setAntiAlias(true);
        a.recycle();
        mProgressDrawable = new MaterialProgressDrawable(getContext(), this);
        super.setImageDrawable(mProgressDrawable);
    }

以上都是从styleable XML中获取的一些参数(那如果没有这里设置就是我们代码中一系列的Set,如果都没设置那么就是默认值了)。

//版本判断
 private boolean elevationSupported() {
        return android.os.Build.VERSION.SDK_INT >= 21;
    }

在onMeasure方法中会调用elevationSupported(),对自定义View进行操作,顺便提一下自定义View的绘制。

onMeasure(),onLayout(),onDraw()这三个函数:1.View本身大小多少,这由onMeasure()决定;2.View在ViewGroup中的位置如何,这由onLayout()决定;3.绘制View,onDraw()定义了如何绘制这个View。

在onLayout()里有一大堆对位置的计算的内容就不贴了,知道他干什么就行。

在我们的onDraw中绘制进度部分

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mIfDrawText) {
            String text = String.format("%s%%", mProgress);
            int x = getWidth() / 2 - text.length() * mTextSize / 4;
            int y = getHeight() / 2 + mTextSize / 4;
            canvas.drawText(text, x, y, mTextPaint);
        }
    }

然后就是一堆传参的方法了

public void setVisibility(int visibility) //设置是否可见

public void setCircleBackgroundEnabled(boolean enableCircleBackground)//设置是否存在图片背景(默认有)

public boolean circleBackgroundEnabled()//判断是否有背景

public boolean isShowProgressText()//判断是否显示进度文字

public void setShowProgressText(boolean mIfDrawText)//设置是否显示进度文字

public int getMax()//获取进度最大值

public void setMax(int max)//设置进度最大值

public int getProgress()//获取进度

public void setProgress(int progress)//设置进度



ListViewExt

我们再说一下ListViewExt

//没有出现什么惊叹的自定义控件正常的继承ListView(废话不然哪只这么点代码)
public class ListViewExt extends ListView
//构造方法里都调用了init方法,设置了监听事件,设置了边缘回弹以及边缘大小
 public ListViewExt(Context context) {
        super(context);
        this.init();
    }

    public ListViewExt(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.init();
    }

    public ListViewExt(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.init();
    }

    private void init() {
        this.setOverScrollMode(2);
        this.setFadingEdgeLength(0);
        this.setOnScrollListener(this.mScrollListenerWrapper);
    }

重要的逻辑与判断都在onTouchEvent方法中实现,包括判断是否到底,是否拉伸,是否在最上方等

具体如何做到拉伸,收缩的看同包内的ListViewEnhance .class这个类

   public boolean onTouchEvent(MotionEvent ev) {
        int y = (int)ev.getY();
        switch(ev.getActionMasked()) {
        case 0:
        case 5:
            ListViewEnhance.onTouchDown(this, ev);
            this.mDownMotionY = y - (this.mLastY - this.mDownMotionY);
            this.mLastY = y;
            break;
        case 1:
        case 6:
            this.mLastY = y;
            if(this.mIsTouching) {
                this.mIsTouching = false;
            }
            break;
        case 2:
            int offset = y - this.mDownMotionY;
            if(!this.mIsTouching) {
                ListViewEnhance.onTouchDown(this, ev);
            }

            this.mInertia = y - this.mDownMotionY;
            if(ListViewEnhance.needListScale(this, offset)) {
                this.mLastY = y;
                return true;
            }

            if(this.mScrollState == 1 && y != this.mLastY) {
                this.mLastY = y;
            }
            break;
        case 3:
            if(this.mIsTouching) {
                this.mIsTouching = false;
                ListViewEnhance.resetScale(this);
            }
        case 4:
        }

        return super.onTouchEvent(ev);
    }


具体使用实例,可以看源码,源码地址:https://github.com/ddwhan0123/SoyiGit

观众老爷欢迎点个赞,谢谢!

时间: 2024-09-19 08:18:16

整合大量开源库温习基础项目(四)伸缩实现OverscrollScale以及MaterialLoadingProgressBar的相关文章

整合大量开源库温习基础项目(二)顺便再提提单例模式

转载请注明出处:王亟亟的大牛之路 这一篇,属于开篇,把我们初期用到的一些资源做展示,之后会陆续添加,当然这是一个Git的public项目,更欢迎你的加入! 每个程序员都想,写点天花乱坠的东西,但是需求决定创造,往往我们不知道去做些什么,之前写了一些登录啊,注册啊,噼里啪啦一堆东西的小项目,然后做到核心部分,这个App要干什么?就茫然了...然后?..然后就闲置了...So....这一次从头再来...还是做一步想一步,让代码更合理,可读性更强,设计更合理(拒绝反人类),那么 GO GO GO GO

整合大量开源库温习基础项目(三)登陆注册主页面大致完成,分析下怎么处理用户信息

转载请注明出处:王亟亟的大牛之路 说内容之前运行效果图,毕竟这样是最直观的(不知道为什么白色截图下来就成黄的了) 样例Apk地址:https://github.com/ddwhan0123/SoyiGit/blob/master/Soyi/Soyi.apk 上一篇文章写到了项目中引用到的一些第三方框架,这一篇我们来具体敲我们的业务和实现. -那一个App常规的有什么? 引导页面,注册,登录,主页面,具体内部业务,设置等等等.我们一步一步做.,这一篇主要说的是登陆注册以及主页面的架构部分的代码和内

整合大量开源库项目(八)可以加载Gif动画的GifImageView

转载请注明出处王亟亟的大牛之路 上周大多数时间都是根据兴起,想到什么做什么写了几个自定义控件,把Soyi丢在那没怎么动,今天就把写的东西整合进来,顺便把SOyi"个人研发的结构理一下". 先上一下今天整合之后的效果,以及新加进来的几个库: 按照惯例,贴一下Gradle的配置: dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'c

整合大量开源库项目(五)跳动的TextView JumpingBeans,良好体验的滚动栏ConvenientBanner

转载请注明出处:王亟亟的大牛之路 时间过得很快,这一系列已经写了第五篇了(感觉还要写好久),今天又引入了2个很好用的库JumpingBeans,ConvenientBanner.首先,先看一下效果. 1.这2个控件做了什么? JumpingBeans是加载页面时那个蓝色跳动的动画效果. JumpingBeans:https://github.com/frakbot/JumpingBeans ConvenientBanner是滚动的那个广告栏. ConvenientBanner:https://g

整合大量开源库项目(六)ListView动画,Activity"抽象化",顺便提一提”抽象类“And"接口"

转载请注明出处:王亟亟的大牛之路 昨天发了一个自己写的简单的诸如EditText一个自定义控件,不过貌似反响不太好,这里再推一推,希望大家给予意见和支持:http://blog.csdn.net/ddwhan0123/article/details/50235151 OK,言归正传,上一次添加了一个"个人开发:界面,希望把之后自己写的一些东西都加入里面,作为一个"大型Lib"使用,所以就简单的把内容和界面搭了一下,也大致区分了下栏目,这种展示性的还是以ListView为佳,上

Android Studio项目中导入开源库的方法_Android

前两天,谷歌发布了Android Studio 1.0的正式版,也有更多的人开始迁移到Android Studio进行开发.然而,网上很多的开源库,控件等还是以前的基于Eclipse进行开发,很多人不知道怎么导入到自己的基于Android Studio项目中来,微博上也有人私信我,让我来写写,正好今天回来的比较早,就写写吧.主要介绍一下常见的一些导包的场景. 前言 复制代码 代码如下: --project   //项目目录   |   build.gradle  //项目的gradle配置文件

Android Studio项目中导入开源库的方法

前两天,谷歌发布了Android Studio 1.0的正式版,也有更多的人开始迁移到Android Studio进行开发.然而,网上很多的开源库,控件等还是以前的基于Eclipse进行开发,很多人不知道怎么导入到自己的基于Android Studio项目中来,微博上也有人私信我,让我来写写,正好今天回来的比较早,就写写吧.主要介绍一下常见的一些导包的场景. 前言 复制代码 代码如下: --project   //项目目录   |   build.gradle  //项目的gradle配置文件

C++开源库,欢迎补充。

C++在"商业应用"方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成 Web应 用.当Java横行天下之后,MS又突然发力,搞出C#语言,有大片的曾经的C++程序员,以为C++要就此沉沦,未料,这三年来,C++的生命力突然被 严重地增强了.主力原因就是开源的软件.基础软件(比如并发原生支持,比如Android必定要推出原生的SDK).各种跨平台应用的出现.   开源C++库必须具有以下特点:必须是成熟的产品.跨平台的产

C++开源库详细介绍

C++在"商业应用"方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又突然发力,搞出C#语言,有大片的曾经的C++程序员,以为C++要就此沉沦,未料,这三年来,C++的生命力突然被 严重地增强了.主力原因就是开源的软件.基础软件(比如并发原生支持,比如Android必定要推出原生的SDK).各种跨平台应用的出现. 开源C++库必须具有以下特点:必须是成熟的产品.跨平台的产品.相