开源RefreshListView下拉刷新效果
来源:互联网 发布:数码大师 mac版下载 编辑:程序博客网 时间:2024/06/16 22:52
1、AnimationDrawable
java.lang.Object ↳android.graphics.drawable.Drawable ↳android.graphics.drawable.DrawableContainer ↳android.graphics.drawable.AnimationDrawable文档概述:
An object used to create frame-by-frame animations, defined by a series of Drawable objects, which can be used as a View object's background.
An AnimationDrawable defined in XML consists of a single<animation-list>
element, and a series of nested <item>
tags. Each item defines a frame of the animation. See the example below.
<!-- Animation frames are wheel0.png -- wheel5.png files inside the res/drawable/ folder --> <animation-list android:id="@+id/selected" android:oneshot="false"> <item android:drawable="@drawable/wheel0" android:duration="50" /> <item android:drawable="@drawable/wheel1" android:duration="50" /> <item android:drawable="@drawable/wheel2" android:duration="50" /> <item android:drawable="@drawable/wheel3" android:duration="50" /> <item android:drawable="@drawable/wheel4" android:duration="50" /> <item android:drawable="@drawable/wheel5" android:duration="50" /> </animation-list>
Here is the code to load and play this animation.
// Load the ImageView that will host the animation and // set its background to our AnimationDrawable XML resource. ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image); img.setBackgroundResource(R.drawable.spin_animation); // Get the background, which has been compiled to an AnimationDrawable object. AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground(); // Start the animation (looped playback by default). frameAnimation.start();
https://github.com/FlyRecker/FlyMukeRefreshListView GitHub开源项目:仿慕课下拉刷新
RefreshListView.java
package com.example.openrefreshlistview;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.drawable.AnimationDrawable;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;/** * Created by recker on 16/5/13. */public class RefreshListView extends ListView implements AbsListView.OnScrollListener { private final int NONE = 0;//正常状态 private final int PULL = 1;//提示下拉刷新状态 private final int RELESE = 2;//提示释放状态 private final int REFLASHING = 3;//正在刷新状态 private final int RATIO = 3;//比值 private View headerView;//顶部刷新视图 private int headerViewHeight;//顶部布局文件的高度 private int firstVisibleItem;//当前第一个可见的item的位置 private boolean isEnd;//是否结束刷新 private boolean isRefreable;//是否可以刷新 private boolean isRemark;//标记,当前是在ListView是否是在第一个 private float startY; private float offsetY; private int state;//当前的状态 private TextView tip; private ImageView img; private AnimationDrawable drawableAnim; public RefreshListView(Context context) { super(context); init(context); } public RefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } @SuppressLint("NewApi")private void init(Context context) { headerView = LayoutInflater.from(context).inflate(R.layout.header_layout, null); /*void android.widget.ListView.addHeaderView(View v)Add a fixed view to appear at the top of the list.*/ addHeaderView(headerView); measureView(headerView); headerViewHeight = headerView.getMeasuredHeight(); topPadding(-headerViewHeight); //添加动画 tip = (TextView) headerView.findViewById(R.id.tip); img = (ImageView) headerView.findViewById(R.id.img); img.setBackgroundResource(R.drawable.c); drawableAnim = (AnimationDrawable) img.getBackground(); //关闭view的OverScroll setOverScrollMode(OVER_SCROLL_NEVER); setOnScrollListener(this); state = NONE; isEnd = true; isRefreable = false; } /** * 通知父布局,占用的宽,高 * @param view */ private void measureView(View view) { ViewGroup.LayoutParams p = view.getLayoutParams(); if (p == null) { p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } int width = ViewGroup.getChildMeasureSpec(0, 0, p.width); int height; int tempHeight = p.height; if (tempHeight > 0) { height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY); } else { height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } view.measure(width, height); } private void topPadding(int topPadding) { headerView.setPadding(headerView.getPaddingLeft(), topPadding, headerView.getPaddingRight(), headerView.getPaddingBottom()); headerView.invalidate(); } @Override public void onScrollStateChanged(AbsListView absListView, int scrollState) { } @Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.firstVisibleItem = firstVisibleItem; } @Override public boolean onTouchEvent(MotionEvent ev) { if (isEnd) {//如果现在时结束的状态,即刷新完毕了,可以再次刷新了,在refreshComplete中设置 if (isRefreable) {//如果现在是可刷新状态 在setOnRefreshListener中设置为true switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if (firstVisibleItem == 0 && !isRemark) { isRemark = true; startY = ev.getY(); } break; case MotionEvent.ACTION_MOVE: onMove(ev); break; case MotionEvent.ACTION_UP: if (state == RELESE) { state = REFLASHING; //加载最新数据 refreshViewByState(); onRefreshListener.onRefresh(); } else if (state == PULL) { state = NONE; refreshViewByState(); setSelection(0); } isRemark = false; break; } } } return super.onTouchEvent(ev); } /** * 判断移动过程操作 * @param ev */ private void onMove(MotionEvent ev) { //再次得到y坐标,用来和startY相减来计算offsetY位移值 float tempY = ev.getY(); //再起判断一下是否为listview顶部并且没有记录y坐标 if (firstVisibleItem == 0 && !isRemark) { isRemark = true; startY = tempY; } if (state != REFLASHING && isRemark) { //计算y的偏移量 offsetY = tempY - startY; //计算当前滑动的高度 float currentHeight = (-headerViewHeight+offsetY/3); //如果当前的状态是释放刷新,并且已经记录y坐标 if (state == RELESE && isRemark) { setSelection(0); //如果当前滑动的距离小于headerView的总高度 if (-headerViewHeight+offsetY/RATIO<0) { //状态改为下拉刷新 state = PULL; refreshViewByState(); } else if (offsetY <= 0) {//如果当前y的位移值小于0,即为headerView隐藏了 //状态改为正常状态 state = NONE; refreshViewByState(); } } //如果当前状态为下拉刷新并且已经记录y坐标 if (state == PULL && isRemark) { setSelection(0); //如果下拉距离大于等于headerView的总高度 if (-headerViewHeight+offsetY/RATIO>=0) { //状态改为释放刷新 state = RELESE; refreshViewByState(); } else if (offsetY <= 0) {//如果当前y的位移值小于0,即为headerView隐藏了 //状态改为正常状态 state = NONE; refreshViewByState(); } } //如果当前状态为正常并且已经记录y坐标 if (state == NONE && isRemark) { //如果位移值大于0 if (offsetY>=0) { //将状态改为释放刷新状态 state = PULL; refreshViewByState(); } } //如果为下拉刷新状态 if (state == PULL) { topPadding((int)(-headerViewHeight+offsetY/RATIO)); } //如果为释放刷新状态 if (state == RELESE) { topPadding((int)(-headerViewHeight+offsetY/RATIO)); } } } /** * 根据当前状态,改变界面显示 */ private void refreshViewByState() { switch (state) { case NONE: topPadding(-headerViewHeight); drawableAnim.stop(); break; case PULL: drawableAnim.stop(); tip.setText("下拉刷新"); break; case RELESE: drawableAnim.stop(); tip.setText("释放刷新"); break; case REFLASHING: drawableAnim.start(); tip.setText("正在刷新"); break; } } /** * 获取完数据 */ public void refreshComplete() { isEnd = true; state = NONE; refreshViewByState(); } private OnRefreshListener onRefreshListener; public void setOnRefreshListener(OnRefreshListener listener) { this.onRefreshListener = listener; isRefreable = true; } public interface OnRefreshListener { void onRefresh(); } private void debug(String str) { Log.d(RefreshListView.class.getSimpleName(), str); }}
header_layout.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="wrap_content" android:orientation="vertical" android:background="@android:color/white"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="center_horizontal" android:paddingBottom="20dp" android:paddingTop="12dp"> <ImageView android:id="@+id/img" android:layout_width="40dp" android:layout_height="40dp" android:background="@drawable/head_image_0" android:layout_marginRight="5dp"/> <TextView android:id="@+id/tip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:text="下拉刷新" android:textSize="12sp" android:layout_marginTop="5dp" android:layout_marginLeft="5dp" android:layout_gravity="center_vertical"/> </LinearLayout></LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.openrefreshlistview.RefreshListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none"/></RelativeLayout>
MainActivity.java
package com.example.openrefreshlistview;import android.os.Handler;//import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.widget.ArrayAdapter;import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class MainActivity extends ActionBarActivity implements RefreshListView.OnRefreshListener { private RefreshListView mListView; private List<String> mDatas; private ArrayAdapter<String> mAdapter; private final static int REFRESH_COMPLETE = 0; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case REFRESH_COMPLETE: mListView.refreshComplete(); mAdapter.notifyDataSetChanged(); break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (RefreshListView) findViewById(R.id.listview); String[] data = new String[]{"a","b","c","d", "e","f","g","h","i", "j","k","l","m","n","o","p","q","r","s"}; mDatas = new ArrayList<String>(Arrays.asList(data)); /*Open Declaration android.widget.ArrayAdapter.ArrayAdapter<String>(Context context, int textViewResourceId, List<String> objects)*/ mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,mDatas); mListView.setAdapter(mAdapter); mListView.setOnRefreshListener(this); } @Override public void onRefresh() { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); mDatas.add(0, "new data"); mHandler.sendEmptyMessage(REFRESH_COMPLETE); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); }}
0 0
- 开源RefreshListView下拉刷新效果
- RefreshListView listView的下拉刷新
- 上拉加载-下拉刷新控件 RefreshListView
- RefreshListView 下拉刷新和上拉加载
- 自定义控件之上拉刷新下拉加载RefreshListView
- 下拉刷新实现步骤分析及RefreshListView的使用步骤说明
- iOS 下拉刷新效果
- ListView下拉刷新效果
- 下拉刷新效果
- Inbox下拉刷新效果
- UIScrollView下拉刷新效果实现
- Android下拉刷新效果实现
- 下拉刷新头部视差效果
- 下拉刷新的视差效果
- Xamarin.ios 下拉刷新效果
- 下拉刷新各种效果集合
- 手机页面下拉刷新效果
- 250,下拉刷新,上拉刷新效果
- 被final修饰的变量不一定要赋初值
- php插件机制
- leetcode 231 Power of Two C++
- 0-1背包问题(递归解决)
- ISE12.1编译ModelSim10.1a库的版本识别问题及解决
- 开源RefreshListView下拉刷新效果
- 命令行 gif
- UVa11292
- web.xml <async-supported>标签报错解决方法
- 人力资源管理七大问题
- Atmega16-BSP和任务列表
- 负载均衡知识全概要
- Android4.0的Alertdialog对话框,设置点击其他位置不消失
- java 静态代码块与非静态代码块