自定义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();}}
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
- 自定义ViewGroup继承FrameLayout 实现下拉刷新功能
- 继承ListView,自定义下拉刷新功能
- 自定义ListView实现下拉刷新功能
- 自定义viewgroup 继承 FrameLayout 仿QQ侧滑菜单
- 下拉刷新功能实现
- 自定义ExpandableListView下拉刷新功能简单实现(这里主要说自定义可下拉的功能)
- Android 自定义ListView 实现下拉刷新 上拉加载功能
- 自定义ListView实现下拉刷新上拉加载功能
- AndroidStaggeredGrid实现下拉刷新功能
- 实现listview下拉刷新功能
- 下拉刷新功能的实现。
- android 继承ViewGroup实现自定义布局
- 自定义view继承viewgroup,实现组合按钮。
- 自定义ListView实现下拉刷新
- 自定义ScrollView实现下拉刷新
- 自定义ListView实现下拉刷新
- 自定义继承ListView控件实现下拉刷新底部加载的实现
- Android从零开搞系列:自定义View(2)继承RecyclerView实现下拉刷新和加载更多
- IE6-8的响应式布局问题@media
- android的jni相关环境配置
- php 文件写入
- Java学习笔记-------使用DataOutputStream 、DataInputStream 组合实现C/S通信 :实例
- Java可变参数个数方法
- 自定义ViewGroup继承FrameLayout 实现下拉刷新功能
- 数据结构基础(13) --链式栈的设计与实现
- CSS3实现3D六面体
- MySQL-5.6.13免安装版配置方法
- C安全编码标准:开发安全、可靠、稳固系统的98条规则(原书第2版)——互动出版网
- jqgrid 日期格式化和反格式化
- 分享》:关于阅读开源项目的源码思路方法
- Google 镜像站搜集
- ThinkPHP 3 介绍及安装