自定义ViewGroup继承FrameLayout 实现下拉刷新功能

来源:互联网 发布:sql查询表列名 编辑:程序博客网 时间:2024/06/07 12:08

代码不多,注释也不多,因为比较简单

效果图




贴代码


activity_refresh_head.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="50dp"    android:orientation="vertical" >    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="50dp" >        <TextView            android:id="@+id/refresh_head_text"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:text="TextView" />                <LinearLayout            android:layout_width="match_parent"            android:layout_height="50dp"            android:orientation="horizontal" >                        <RelativeLayout            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="0.5" >                            <ImageView            android:id="@+id/refresh_head_img"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:src="@drawable/jiangou" />                          </RelativeLayout>                      <View            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="0.5" >                      </View>        </LinearLayout>    </RelativeLayout></LinearLayout>

activity_main.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" >    <com.test_myrefresh_list.views.MyRefreshListView     android:id="@+id/refreshview"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"><!--  <ListView    android:id="@+id/refreshListView"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@android:color/black" ></ListView>-->    </com.test_myrefresh_list.views.MyRefreshListView></LinearLayout>


activity_list_item.xml     (listView 的item布局)


<?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" >    <TextView        android:id="@+id/textView1"        android:layout_width="match_parent"        android:layout_height="40dp"        android:gravity="center"        android:text="TextView" /></LinearLayout>


MyRefreshListView.java       (自定义的ViewGroup布局)


package com.test_myrefresh_list.views;import android.content.Context;import android.os.AsyncTask;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import com.example.test_myrefresh_list.R;import com.nineoldandroids.view.ViewHelper;public class MyRefreshListView extends FrameLayout implements OnTouchListener{private View view_head;private ImageView head_img;private TextView head_text;//刷新的头部高度private int headView_height = -1;//刷新的头部当前拉伸高度private int now_trans_height;//主体listviewprivate ListView list;private BaseAdapter adapter;//保存当前的y坐标private float y;//保存按下时的y坐标private float down_y;//是否可以刷新private boolean canRefresh = false;//是否正在刷新private boolean isRefresh = false;//是否正在滑动刷新栏private boolean isSlide = false;private final int MODE_DISS = 0;private final int MODE_REFRESH = 1;private final String noRefreshText = "   下拉刷新...";private final String canRefreshText = "   释放可刷新...";private final String nowRefreshText = "   正在刷新...";//刷新时的回调事件private OnRefreshing refreshCallback;private Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {float du = (float) msg.obj;ViewHelper.setRotation(head_img, du);};};public MyRefreshListView(Context context) {super(context);init(context);// TODO Auto-generated constructor stub}public MyRefreshListView(Context context, AttributeSet attrs) {super(context, attrs);init(context);// TODO Auto-generated constructor stub}public MyRefreshListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);// TODO Auto-generated constructor stub}//初始化private void init(Context context){view_head = inflate(context, R.layout.activity_refresh_head, null);head_img = (ImageView) view_head.findViewById(R.id.refresh_head_img);head_text = (TextView) view_head.findViewById(R.id.refresh_head_text);head_img.setImageResource(R.drawable.jiangou);head_text.setText(noRefreshText);list = new ListView(context);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);list.setLayoutParams(params);list.setOnTouchListener(this);this.addView(view_head,0);this.addView(list,1);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);//设置头部高度,只需要设置一次就可以if(headView_height == -1){view_head.measure(widthMeasureSpec, 0);headView_height = view_head.getMeasuredHeight() ;now_trans_height = -headView_height;ViewHelper.setTranslationY(view_head, now_trans_height);}}//listView 设置OnTouch@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch(event.getAction()){case MotionEvent.ACTION_DOWN :{y = event.getRawY();down_y = event.getRawY();break;}case MotionEvent.ACTION_MOVE :{//如果是在滑动或者list中的第一项是第一个item,就表示可以滑动if(isSlide ||isListFrist() ){return move(event);}else{y = event.getRawY();}break;}case MotionEvent.ACTION_UP :{up();//只有touch的起点在落点附近正负10像素的位置内时,才有返回OnItemClick事件 float uy = event.getRawY();if(uy > down_y + 10 || uy < down_y - 10){return true;}break;}}return false;}private boolean move(MotionEvent event){float now_y = event.getRawY();float cha = now_y - y;//如果已经不在滑动且 手势为向上,则将此次事件返回给listif(!isSlide && cha < 0){return false;}now_trans_height += cha;//头部已经滑到最顶部,此时被隐藏,不可滑动if(now_trans_height < -headView_height){now_trans_height = -headView_height;isSlide = false;}else{isSlide = true;}this.y = now_y;//滑动ViewHelper.setTranslationY(view_head, now_trans_height);ViewHelper.setTranslationY(list, now_trans_height+headView_height);//头部是否已经滑动到可以刷新的阈值if(now_trans_height >= 0  && !canRefresh &&!isRefresh){canRefresh = true;ViewHelper.setRotation(head_img, 180f);head_text.setText(canRefreshText);}else if(now_trans_height < 0  && canRefresh &&!isRefresh){canRefresh = false;ViewHelper.setRotation(head_img, 0f);head_text.setText(noRefreshText);}return true;}private void up(){if(canRefresh){//刷新new MyTask().execute(MODE_REFRESH);}else{//隐藏new MyTask().execute(MODE_DISS);}canRefresh = false;}private boolean isListFrist(){int i = list.getFirstVisiblePosition();if(i == 0){View v = list.getChildAt(0);if(v.getTop() == 0){return true;}}return false;}//隐藏private void diss(){head_img.setImageResource(R.drawable.jiangou);head_text.setText(nowRefreshText);now_trans_height = -headView_height;ViewHelper.setRotation(head_img, 0);ViewHelper.setTranslationY(view_head, now_trans_height);ViewHelper.setTranslationY(list, 0);}//展示可刷新private void show_refresh(){isRefresh = true;head_text.setText(nowRefreshText);now_trans_height = 0;ViewHelper.setTranslationY(view_head, now_trans_height);ViewHelper.setTranslationY(list, headView_height);refreshCallback.callback();new Thread(refreshing).start();}//刷新时的回调事件public void setOnRefreshingCallback(OnRefreshing callback){this.refreshCallback = callback;}//刷新成功时调用此方法public void refreshOK(){isRefresh = false;new MyTask().execute(MODE_DISS);}//刷新时 调用此runnable来旋转图标Runnable refreshing = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfloat f = 180;while(isRefresh){Message message = new Message();message.obj = f;message.what = 0;handler.sendMessage(message);f += 9;try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}}}};private class MyTask extends AsyncTask<Integer, Integer, Integer>{@Overrideprotected Integer doInBackground(Integer... params) {// TODO Auto-generated method stubint mode = params[0];int cha = 0;if(mode == MODE_DISS){cha = (-headView_height - now_trans_height) / 50;}else{cha = (0 - now_trans_height) / 50;}int i = 0;while(i < 50){publishProgress(cha);try{Thread.sleep(2);}catch(Exception e){}i++;}return mode;}@Overrideprotected void onProgressUpdate(Integer... values) {// TODO Auto-generated method stubnow_trans_height += values[0];ViewHelper.setTranslationY(view_head, now_trans_height);ViewHelper.setTranslationY(list, now_trans_height +headView_height);}@Overrideprotected void onPostExecute(Integer result) {// TODO Auto-generated method stubint mode = result;if(mode == MODE_DISS){diss();}else{show_refresh();}}}//public void setAdapter(BaseAdapter adapter){this.adapter = adapter;list.setAdapter(adapter);}public void setOnItemClickLintener(OnItemClickListener listener){list.setOnItemClickListener(listener);}//定义刷新时调用的接口public interface OnRefreshing{public void callback();}}




MainActivity.java    (主界面)


package com.test_myrefresh_list.views;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.TextView;import com.example.test_myrefresh_list.R;import com.test_myrefresh_list.views.MyRefreshListView.OnRefreshing;public class MainActivity extends Activity implements OnItemClickListener{private MyRefreshListView refresh;private Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {refresh.refreshOK();};};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);refresh = (MyRefreshListView) findViewById(R.id.refreshview);refresh.setOnItemClickLintener(this);refresh.setAdapter(new MyAdapter(this));refresh.setOnRefreshingCallback(new OnRefreshing() {@Overridepublic void callback() {// TODO Auto-generated method stubnew Thread(){public void run(){try{Thread.sleep(3000);}catch(Exception e){}handler.sendEmptyMessage(0);}}.start();}});}class MyAdapter extends BaseAdapter{private LayoutInflater inflater;public MyAdapter(Context context){inflater = LayoutInflater.from(context);}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn 20;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubTextView t;if(convertView == null){convertView = inflater.inflate(R.layout.activity_list_item, null);t = (TextView) convertView.findViewById(R.id.textView1);convertView.setTag(t);}else{t = (TextView) convertView.getTag();}t.setText("this is "+position);return convertView;}}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {// TODO Auto-generated method stubLog.w("family_log", "in onitemclicklistener position  = "+position);}}


源码链接 : 

http://download.csdn.net/detail/wwwbjj1988/8968729

0 0
原创粉丝点击