ListView下拉刷新(慕课网教材源码)
2015-09-18 13:31
274 查看
MainActivity
ApkEntity.class
MyAdapter.class
ReFlashListView.class
activity_main.xml
header_layout.xml
item_layout.xml
package com.imooc.listviewfrashdemo1; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import com.example.listviewfrashdemo1.R; import com.imooc.listviewfrashdemo1.ReFlashListView.IReflashListener; public class MainActivity extends Activity implements IReflashListener{ ArrayList<ApkEntity> apk_list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setData(); showList(apk_list); } MyAdapter adapter; ReFlashListView listview; private void showList(ArrayList<ApkEntity> apk_list) { if (adapter == null) { listview = (ReFlashListView) findViewById(R.id.listview); listview.setInterface(this); adapter = new MyAdapter(this, apk_list); listview.setAdapter(adapter); } else { adapter.onDateChange(apk_list); } } private void setData() { apk_list = new ArrayList<ApkEntity>(); for (int i = 0; i < 10; i++) { ApkEntity entity = new ApkEntity(); entity.setName("Ĭ������"); entity.setDes("����һ�������Ӧ��"); entity.setInfo("50w�û�"); apk_list.add(entity); } } private void setReflashData() { for (int i = 0; i < 2; i++) { ApkEntity entity = new ApkEntity(); entity.setName("ˢ������"); entity.setDes("����һ�������Ӧ��"); entity.setInfo("50w�û�"); apk_list.add(0,entity); } } @Override public void onReflash() { // TODO Auto-generated method stub\ Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub //��ȡ�������� setReflashData(); //֪ͨ������ʾ showList(apk_list); //֪ͨlistview ˢ��������ϣ� listview.reflashComplete(); } }, 2000); } }
ApkEntity.class
package com.imooc.listviewfrashdemo1; public class ApkEntity { private String name; private String des; private String info; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDes() { return des; } public void setDes(String des) { this.des = des; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } }
MyAdapter.class
package com.imooc.listviewfrashdemo1; import java.util.ArrayList; import com.example.listviewfrashdemo1.R; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class MyAdapter extends BaseAdapter { ArrayList<ApkEntity> apk_list; LayoutInflater inflater; public MyAdapter(Context context, ArrayList<ApkEntity> apk_list) { this.apk_list = apk_list; this.inflater = LayoutInflater.from(context); } public void onDateChange(ArrayList<ApkEntity> apk_list) { this.apk_list = apk_list; this.notifyDataSetChanged(); } @Override public int getCount() { // TODO Auto-generated method stub return apk_list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return apk_list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ApkEntity entity = apk_list.get(position); ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = inflater.inflate(R.layout.item_layout, null); holder.name_tv = (TextView) convertView .findViewById(R.id.item3_apkname); holder.des_tv = (TextView) convertView .findViewById(R.id.item3_apkdes); holder.info_tv = (TextView) convertView .findViewById(R.id.item3_apkinfo); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } holder.name_tv.setText(entity.getName()); holder.des_tv.setText(entity.getDes()); holder.info_tv.setText(entity.getInfo()); return convertView; } class ViewHolder { TextView name_tv; TextView des_tv; TextView info_tv; } }
ReFlashListView.class
package com.imooc.listviewfrashdemo1; import com.example.listviewfrashdemo1.R; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; import android.view.animation.RotateAnimation; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; public class ReFlashListView extends ListView implements OnScrollListener { private View header; private int headerHeight;// 顶部布局文件的高度 private int firstVisibleItem;// 当前第一个可见的item的位置 private int scrollStste;// listview 当前滚动状态 private boolean isRemark;// 标记,当前是在ListView的最顶端按下 private int startY;// 按下时的Y值 private int state;// 当前状态 private final int NONE = 0;// 正常状态 private final int PULL = 1;// 提示下拉状态 private final int RELSE = 2;// 提示释放状态 private final int REFLASHING = 3;// 刷新状态 private IReflashListener reflashListener;// 刷新数据的接口 public ReFlashListView(Context context) { super(context); initView(context); } public ReFlashListView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public ReFlashListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } /** * 初始化界面,添加顶部布局文件到listview里面 * * @param context */ private void initView(Context context) { LayoutInflater inflater = LayoutInflater.from(context); header = inflater.inflate(R.layout.header_layout, null); measureView(header); headerHeight = header.getMeasuredHeight(); topPadding(-headerHeight); this.addHeaderView(header); this.setOnScrollListener(this); } /** * 通知父布局,占用多大地方 * * @param v */ private void measureView(View v) { ViewGroup.LayoutParams p = v.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); } v.measure(width, height); } /** * 设置header布局的上边距 * * @param topPadding */ private void topPadding(int topPadding) { header.setPadding(header.getPaddingLeft(), topPadding, header.getPaddingRight(), header.getPaddingBottom()); header.invalidate(); } @Override public void onScroll(AbsListView arg0, int firstVisibleItem, int arg2, int arg3) { this.firstVisibleItem = firstVisibleItem; } @Override public void onScrollStateChanged(AbsListView arg0, int scrollStste) { this.scrollStste = scrollStste; } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if (firstVisibleItem == 0) { isRemark = true; startY = (int) ev.getY(); } break; case MotionEvent.ACTION_MOVE: onMove(ev); break; case MotionEvent.ACTION_UP: if (state == RELSE) { state = REFLASHING; reflashViewByState(); // 加载最新数据 reflashListener.onReflash(); } else if (state == PULL) { state = NONE; isRemark = false; reflashViewByState(); } break; } return super.onTouchEvent(ev); } /** * 判断移动过程中的操作 * * @param ev */ private void onMove(MotionEvent ev) { if (!isRemark) { return; } int tempY = (int) ev.getY(); int space = tempY - startY; int topPadding = space - headerHeight; switch (state) { case NONE: // 下拉状态 if (space > 0) { state = PULL; reflashViewByState(); } break; case PULL: topPadding(topPadding); // 下拉达到一定程度,并且ListView当前是滚动状态 if (space > headerHeight + 30 && scrollStste == SCROLL_STATE_TOUCH_SCROLL) { state = RELSE; reflashViewByState(); } break; case RELSE: topPadding(topPadding); if (space < headerHeight + 30) { state = PULL; reflashViewByState(); } else if (space <= 0) { state = NONE; isRemark = false; reflashViewByState(); } break; } } /** * 根据当前状态改变界面显示 */ private void reflashViewByState() { TextView tip = (TextView) header.findViewById(R.id.tip); ImageView arrow = (ImageView) header.findViewById(R.id.arrow); ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress); RotateAnimation anim = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(500); anim.setFillAfter(true); RotateAnimation anim1 = new RotateAnimation(180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); anim1.setDuration(500); anim1.setFillAfter(true); switch (state) { case NONE: topPadding(-headerHeight); arrow.clearAnimation(); break; case PULL: arrow.setVisibility(View.VISIBLE); progress.setVisibility(View.GONE); tip.setText("下拉可以刷新"); arrow.clearAnimation(); arrow.setAnimation(anim1); break; case RELSE: arrow.setVisibility(View.VISIBLE); progress.setVisibility(View.GONE); tip.setText("松开可以刷新"); arrow.clearAnimation(); arrow.setAnimation(anim); break; case REFLASHING: arrow.clearAnimation(); topPadding(0);// 刷新的时候高度固定不变 arrow.setVisibility(View.GONE); progress.setVisibility(View.VISIBLE); tip.setText("正在刷新"); break; } } /** * 获取完数据 */ public void reflashComplete() { state = NONE; isRemark = false; reflashViewByState(); } public void setInterface(IReflashListener reflashListener) { this.reflashListener = reflashListener; } /** * 刷新数据接口 */ public interface IReflashListener { public void onReflash(); } }
activity_main.xml
<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" android:background="@color/white" tools:context=".MainActivity" > <com.imooc.listviewfrashdemo1.ReFlashListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/white" android:cacheColorHint="#00000000" android:dividerHeight="5dip" /> </RelativeLayout>
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" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="10dip" android:paddingTop="10dip" > <LinearLayout android:id="@+id/layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:orientation="vertical" > <TextView android:id="@+id/tip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉可以刷新!" /> <TextView android:id="@+id/lastupdate_time" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <ImageView android:id="@+id/arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/layout" android:layout_marginRight="20dip" android:src="@drawable/pull_to_refresh_arrow" /> <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/layout" android:layout_marginRight="20dip" android:visibility="gone" /> </RelativeLayout> </LinearLayout>
item_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="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="60dip" android:gravity="center_vertical" android:background="@drawable/app_item_bg" android:orientation="horizontal" > <ImageView android:id="@+id/item3_apkiv" android:layout_width="50dip" android:layout_height="50dip" android:background="@drawable/test_icon" android:layout_marginLeft="10dip" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginLeft="10dip" android:orientation="vertical" > <TextView android:id="@+id/item3_apkname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="应用程序名字" android:textColor="@color/black" android:textSize="18dip" /> <TextView android:id="@+id/item3_apkinfo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:text="应用程序信息" android:textSize="14dip" /> </LinearLayout> <Button android:layout_width="60dip" android:layout_height="30dip" android:background="@drawable/dlbtn_selector" android:id="@+id/item3_dlbtn" android:layout_marginRight="10dip" android:text="安装" /> </LinearLayout> <TextView android:id="@+id/item3_apkdes" android:layout_width="fill_parent" android:layout_height="30dip" android:layout_marginLeft="5dip" android:layout_marginRight="5dip" android:gravity="center_vertical" android:text="应用程序描述" android:textSize="14dip" /> </LinearLayout>
相关文章推荐
- ViewPager简单使用说明
- 通用型集成运放结构及特点
- XCode编译器里有鬼 – XCodeGhost样本分析
- 家用服务机器人将成为机器人的下一个入口
- 用gdb调试程序
- C#调用C++DLL的小总结5---和C++的DLL的联合调试
- RobotFramework+Selenium实现web自动化
- 学习Linux第五天
- ionic 更新插件
- xcode7.0-iOS9新特性之三:watch
- 30多年程序员生涯经验总结
- 论servlet和jsp 的区别
- HDU 4819 Mosaic D区段树
- ARC与MRC混编
- 设置QTableWidget的左上角CornerWidget的文字(二)
- Linux下配置多路径软件(openfiler模拟共享盘)
- discuz x2 个人资料项排序问题解决方法、添加自定义字段、修改栏目名称和介绍
- 卖家数据
- [Leetcode]Merge k Sorted Lists
- jsp引入struts标签,引入自己写的jquery需要注意的问题