編輯:關於android開發
整理了下以前寫的小項目,ListView的下拉刷新,雖然小但還是想紀念下。。適合新手看,大神略過。。。
效果圖:
package com.example.listviewrefreshdemo; /** * @author 超超boy */ 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; } }
MainActivity:
package com.example.listviewrefreshdemo; import java.util.ArrayList; import com.example.listviewrefreshdemo.RefreshListView.IReflashListener; import android.app.Activity; import android.os.Bundle; import android.os.Handler; /** * @author 超超boy */ 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; RefreshListView listview; private void showList(ArrayList<ApkEntity> apk_list) { if (adapter == null) { listview = (RefreshListView) findViewById(R.id.listview); listview.setIReflashListener(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(i,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); } /** * 回掉方法 */ /*public void onReflash() { //獲取最新數據 setReflashData(); //通知界面顯示 showList(apk_list); //通知listview刷新數據完畢 listview.reflashComplete(); }*/ }
RefreshListView:
package com.example.listviewrefreshdemo; import java.text.SimpleDateFormat; import java.util.Date; import android.R.anim; import android.R.interpolator; import android.content.Context; 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.view.animation.RotateAnimation; import android.widget.AbsListView; import android.widget.ImageView; import android.widget.ListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ProgressBar; import android.widget.TextView; /** * @author 超超boy */ public class RefreshListView extends ListView implements OnScrollListener{ LayoutInflater inflater; View header; int headerHeight; //頂部布局文件的高度 int firstVisibleItem; //當前第一個可見的item的位置 int scrollState; //listview當前滾動狀態 boolean isRemark; //標記,當前是在listview的最頂部摁下的 int startY; //摁下時的Y值 int state; //當前的狀態 final int NONE = 0;// 正常狀態; final int PULL = 1;// 提示下拉狀態; final int RELESE = 2;// 提示釋放狀態; final int REFLASHING = 3;// 刷新狀態; IReflashListener reflashListener; public RefreshListView(Context context) { super(context); initView(context); } public RefreshListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } public RefreshListView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } /** * 初始化界面,添加頂部布局文件到ListView * @param context */ private void initView(Context context){ inflater = LayoutInflater.from(context); header =inflater.inflate(R.layout.header, null); measureView(header); headerHeight = header.getMeasuredHeight(); Log.i("tag", "headerHeight="+headerHeight); topPadding(-headerHeight); //負的高度,把它能沒啦 this.addHeaderView(header); this.setOnScrollListener(this); } /** * 通知父布局,占用的寬高。 * @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); } //spec:header的左右邊距,padding內邊距,childDimension字布局的寬度 int width = ViewGroup.getChildMeasureSpec(0, 0, p.width); int height; int tempHeight = p.height; if(tempHeight > 0){ //高度不是空,需要填充這個布局 //EXACTLY(完全),父元素決定自元素的確切大小,子元素將被限定在給定的邊界裡而忽略它本身大小; height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY); }else{ //UNSPECIFIED(未指定),父元素不對子元素施加任何束縛,子元素可以得到任意想要的大小; height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } view.measure(width, height); } /** * 設置header布局的上邊距 * @param topPadding */ private void topPadding(int topPadding){ //header的上邊距 header.setPadding(header.getPaddingLeft(), topPadding, header.getPaddingRight(), header.getPaddingBottom()); header.invalidate(); } /** * 取得當前的滾動狀態 */ public void onScrollStateChanged(AbsListView view, int scrollState) { this.scrollState = scrollState; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.firstVisibleItem = firstVisibleItem; //當前第一個可見的item的位置 } /** * 觸摸事件 */ public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: //下拉 if (firstVisibleItem == 0) { //在界面最頂端 isRemark = true; //標記,當前是在listview的最頂部摁下的 startY = (int) ev.getY(); } break; case MotionEvent.ACTION_MOVE: onMove(ev); break; case MotionEvent.ACTION_UP: //抬起 if (state == RELESE) { //釋放 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 sapce = tempY-startY; //移動的距離 int topPadding = sapce - headerHeight; //移動過程中不斷設置topPadding switch (state) { case NONE: // 正常狀態; if(sapce>0){ state = PULL; // 提示下拉狀態 reflashViewByState(); } break; case PULL: // 提示下拉狀態; topPadding(topPadding); //不斷設置上邊距 if(sapce > headerHeight+30 && scrollState == SCROLL_STATE_TOUCH_SCROLL){ state = RELESE; // 提示釋放狀態; reflashViewByState(); } break; case RELESE: // 提示釋放狀態; topPadding(topPadding); if(sapce<headerHeight+30){ state = PULL; reflashViewByState(); }else if(sapce <= 0){ state = NONE; isRemark = false; reflashViewByState(); } break; default: break; } } /** * 根據當前的狀態,改變頁面顯示 */ private void reflashViewByState(){ TextView tip = (TextView) header.findViewById(R.id.tip); ImageView arrow = (ImageView) header.findViewById(R.id.arrow); ProgressBar bar = (ProgressBar) header.findViewById(R.id.progress); RotateAnimation animation = new RotateAnimation(0, 180 ,RotateAnimation.RELATIVE_TO_SELF,0.5f, RotateAnimation.RELATIVE_TO_SELF,0.5f); animation.setDuration(500); animation.setFillAfter(true); RotateAnimation animation2 = new RotateAnimation(180, 0 ,RotateAnimation.RELATIVE_TO_SELF,0.5f, RotateAnimation.RELATIVE_TO_SELF,0.5f); animation2.setDuration(500); animation2.setFillAfter(true); switch (state) { case NONE: arrow.clearAnimation(); topPadding(-headerHeight); break; case PULL: //下拉 arrow.setVisibility(View.VISIBLE); bar.setVisibility(View.GONE); tip.setText("下拉可以刷新"); arrow.clearAnimation(); arrow.setAnimation(animation2); break; case RELESE: //釋放 arrow.setVisibility(View.VISIBLE); bar.setVisibility(View.GONE); tip.setText("松開可以刷新"); arrow.clearAnimation(); arrow.setAnimation(animation); break; case REFLASHING: //刷新 topPadding(50); arrow.setVisibility(View.GONE); bar.setVisibility(View.VISIBLE); tip.setText("正在刷新"); arrow.clearAnimation(); break; default: break; } } /** * 獲取完數據 */ public void reflashComplete(){ state = NONE; isRemark = false; //不在頂部 reflashViewByState(); TextView lastupdatetime = (TextView) header.findViewById(R.id.lastUpdate_time); SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); Date date = new Date(System.currentTimeMillis()); String time = format.format(date); lastupdatetime.setText(time); } /** * 回調接口 * @author user * */ public interface IReflashListener{ public void onReflash(); } public void setIReflashListener(IReflashListener listener){ this.reflashListener = listener; } }
適配器:
package com.example.listviewrefreshdemo; import java.util.ArrayList; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; /** * @author 超超boy */ 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; } }
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" tools:context="com.example.listviewrefreshdemo.MainActivity" > <com.example.listviewrefreshdemo.RefreshListView 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.xml和item_layout.xml,就不粘貼了,想看的可以去下我的源代碼,下邊有下載鏈接。。
ok。。代碼很簡單。。。
Demo源代碼下載:http://download.csdn.net/detail/jycboy/9588195
附一篇很好的博文:Android 下拉刷新框架實現:http://blog.csdn.net/leehong2005/article/details/12567757
轉發請注明出處:http://www.cnblogs.com/jycboy/p/5712620.html
RxJava 和 RxAndroid 二,rxjavarxandroid前言:對Rx不了解的朋友可以先看我的第一篇博文 RxJava 和 RxAndroid&n
Gradle混淆+打包Jar包基礎,gradle混淆打包jar本文為原創文章,轉載請注明出處。 文章最後會附帶源碼下載地址,有需要的朋友可下載。 通常我們編
獲取手機通訊錄放入PinnedSectionListView中,按名字首字母排序,並且實現撥打電話功能。,釘釘撥打非通訊錄 1 package com.lixu.ton
Android SurfaceView的生命周期,androidsurfaceview本文利用SurfaceView來實現視頻的播放 本文地址:http://www.cn