listview下拉刷新上拉加载扩展(二)-仿美团外卖
经过前几篇的listview下拉刷新上拉加载讲解,相信你对其实现机制有了一个深刻的认识了吧,那么这篇文章我们来实现一个高级的listview下拉刷新上拉加载-仿新版美团外卖的袋鼠动画:
项目结构:
是不是灰常简单!!
headview的xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<com.baiyuliang.listviewrefreshdemo.RefreshAnimView
android:id="@+id/refreshAnimView"
android:layout_width="59dp"
android:layout_height="70dp"
android:layout_margin="10dp"/>
<ProgressBar
android:id="@+id/pb"
android:layout_width="59dp"
android:layout_height="70dp"
android:layout_margin="10dp"
android:indeterminateDrawable="@drawable/loading"
android:visibility="gone"/>
</LinearLayout>
自定义可缩放的View:
package com.baiyuliang.listviewrefreshdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class RefreshAnimView extends View{
private Bitmap daishu;
private int measuredWidth;
private int measuredHeight;
private float mCurrentProgress;
private int mCurrentAlpha;
private Paint mPaint;
private Bitmap scaleDaishu;
public RefreshAnimView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public RefreshAnimView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RefreshAnimView(Context context) {
super(context);
init();
}
private void init(){
//袋鼠bitmap
daishu = BitmapFactory.decodeResource(getResources(), R.mipmap.takeout_img_list_loading_pic1);
//mPaint.setAlpha来实现渐变效果
mPaint = new Paint();
//首先设置为完全透明
mPaint.setAlpha(0);
}
/**
* 测量方法
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
//测量宽度
private int measureWidth(int widthMeasureSpec){
int result = 0;
int size = MeasureSpec.getSize(widthMeasureSpec);
int mode = MeasureSpec.getMode(widthMeasureSpec);
if (MeasureSpec.EXACTLY == mode) {
result = size;
}else {
result = daishu.getWidth();
if (MeasureSpec.AT_MOST == mode) {
result = Math.min(result, size);
}
}
return result;
}
//测量高度
private int measureHeight(int heightMeasureSpec){
int result = 0;
int size = MeasureSpec.getSize(heightMeasureSpec);
int mode = MeasureSpec.getMode(heightMeasureSpec);
if (MeasureSpec.EXACTLY == mode) {
result = size;
}else {
result = daishu.getHeight();
if (MeasureSpec.AT_MOST == mode) {
result = Math.min(result, size);
}
}
return result;
}
//在这里面拿到测量后的宽和高,w就是测量后的宽,h是测量后的高
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
measuredWidth = w;
measuredHeight = h;
//根据测量后的宽高来对袋鼠做一个缩放
scaleDaishu = Bitmap.createScaledBitmap(daishu,measuredWidth,measuredHeight,true);
}
/**
* 绘制方法
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.scale(mCurrentProgress, mCurrentProgress, measuredWidth/2, measuredHeight);
mPaint.setAlpha(mCurrentAlpha);
canvas.drawBitmap(scaleDaishu, 0, 0, mPaint);
}
/**
* 根据进度对袋鼠进行缩放
* @param currentProgress
*/
public void setCurrentProgress(float currentProgress){
this.mCurrentProgress = currentProgress;
this.mCurrentAlpha = (int) (currentProgress*255);
}
}
在listview中的onTouch事件中将手指下拉滑动距离与headview的高度比传递给RefreshAnimView 重绘,以实现图片根据手指移动来缩放图片:
case MotionEvent.ACTION_MOVE:
offsetY = ev.getY() - startY;
/**
* 下拉刷新
*/
if (isRefreshable &&offsetY > 0 && loadstate == LOAD_DONE && isScrollFirst && refreshstate != REFRESHING) {
float headerViewShowHeight = offsetY / REFRESH_RATIO;
float scaleProgress=headerViewShowHeight/headerViewHeight;//图片放大缩小比例
if(scaleProgress>1){
scaleProgress=1;
}
......
if (refreshstate == PULL_TO_REFRESH || refreshstate == RELEASE_TO_REFRESH) {
headerView.setPadding(0, (int) (headerViewShowHeight - headerViewHeight), 0, 0);
refreshAnimView.setCurrentProgress(scaleProgress);//设置refreshAnimView的缩放进度
refreshAnimView.invalidate();//重绘
}
根据刷新状态实时更新headview:
private void changeHeaderByState(int state) {
switch (state) {
case REFRESH_DONE:
headerView.setPadding(0, -headerViewHeight, 0, 0);
refreshAnimView.setVisibility(View.VISIBLE);
pb.setVisibility(View.GONE);
break;
case RELEASE_TO_REFRESH:
break;
case PULL_TO_REFRESH:
break;
case REFRESHING:
headerView.setPadding(0, 0, 0, 0);
refreshAnimView.setVisibility(View.GONE);
pb.setVisibility(View.VISIBLE);
break;
default:
break;
}
}
PS:如何快速简单的实现一个帧动画?
利用ProgressBar的indeterminateDrawable属性,定义一个animation-list,也是灰常简单:
<ProgressBar
android:id="@+id/pb"
android:layout_width="59dp"
android:layout_height="70dp"
android:layout_margin="10dp"
android:indeterminateDrawable="@drawable/loading"
android:visibility="gone"/>
loadding.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:duration="50">
<clip
android:clipOrientation="horizontal"
android:drawable="@mipmap/takeout_img_list_loading_pic1"
android:gravity="left" />
</item>
<item android:duration="50">
<clip
android:clipOrientation="horizontal"
android:drawable="@mipmap/takeout_img_list_loading_pic2"
android:gravity="left" />
</item>
</animation-list>
好了,如果你还是那么懒,不想动手,demo给你:http://download.csdn.net/detail/baiyuliang2013/9344831
listview下拉刷新上拉加载扩展(二)-仿美团外卖的更多相关文章
- Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView
在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...
- SwipeRefreshLayout实现下拉刷新上滑加载
1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...
- 移动端下拉刷新上拉加载-mescroll.js插件
最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...
- ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多
ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多 package com.example.ListViewDragItem; import android.app.Ac ...
- ListView下拉刷新上拉加载更多实现
这篇文章将带大家了解listview下拉刷新和上拉加载更多的实现过程,先看效果(注:图片中listview中的阴影可以加上属性android:fadingEdge="none"去掉 ...
- listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖
本篇是基于上篇listview下拉刷新上拉加载扩展(二)-仿美团外卖改造而来,主要调整了headview的布局,并加了两个背景动画,看似高大上,其实很简单: as源码地址:http://downloa ...
- MaterialRefreshLayout+ListView 下拉刷新 上拉加载
效果图是这样的,有入侵式的,非入侵式的,带波浪效果的......就那几个属性,都给出来了,自己去试就行. 下拉刷新 上拉加载 关于下拉刷新-上拉加载的效果,有许许多多的实现方式,百度了一下竟然有几十种 ...
- react-native-page-listview使用方法(自定义FlatList/ListView下拉刷新,上拉加载更多,方便的实现分页)
react-native-page-listview 对ListView/FlatList的封装,可以很方便的分页加载网络数据,还支持自定义下拉刷新View和上拉加载更多的View.兼容高版本Flat ...
- 自定义ListView下拉刷新上拉加载更多
自定义ListView下拉刷新上拉加载更多 自定义RecyclerView下拉刷新上拉加载更多 Listview现在用的很少了,基本都是使用Recycleview,但是不得不说Listview具有划时 ...
随机推荐
- HTML中鼠标滚轮事件onmousewheel处理
滚轮事件是不同浏览器会有一点点区别,一个像Firefox使用DOMMouseScroll ,ff也可以使用addEventListener方法绑定DomMouseScroll事件,其他的浏览器滚轮事件 ...
- mysql 索引列为Null的走不走索引及null在统计时的问题
要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column)这仅仅是因为它为默认选项.除非真的要保存 NULL,否则就把 ...
- ERP中的序列管理
1.序列管理 序列管理主要实现系统用到序列生成规则的配置.主要包含序列配置.序列生产两个功能点. 2.术语说明 序列号:指序列中按步长递进的数字. 序列值:指按规则组合了 "拥有者.序列类型 ...
- python学习之路前端-JavaScript
JavaScript简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本 ...
- 使用FFMPEG在windows平台下推rtmp流
使用FFMPEG在windows平台下推rtmp流 工作中习惯在Linux下面使用FFmpeg模拟推rtmp流,无奈家中的电脑都是windows系统,需要利用家中的带宽来测试流媒体服务器的性能.所以研 ...
- MongoDB 排序
MongoDB sort()方法 在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 ...
- 巧用第三方快速开发Android App 热门第三方SDK及框架
巧用第三方快速开发Android App 热门第三方SDK及框架 历经大半年的时间,终于是把这门课程给录制出来了,也就在今天,正式在慕课网上上线了 项目地址:巧用第三方快速开发Android App ...
- 初识mybatis(二)
上篇博客我们介绍通过Java代码来创建mybatis的配置文件,港真,这种方式看起来有意思实际在开发中用的并不多,mybatis的配置还是以xml配置为主,本文我们就来看看如何通过xml文件来配置my ...
- Bootstrap3 栅格系统-列排序
通过使用 .col-md-push-* 和 .col-md-pull-* 类就可以很容易的改变列(column)的顺序. <div class="row"> <d ...
- DB 查询分析器7.01 新增的保存执行结果到多个文件功能
1 引言 中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员)推出的个人作品----万能数据库查询分析器,中文版本DB 查询分析器.英文版本< ...