一般的下拉刷新都只实现了刷新ListView,本demo实现了刷新普通Activity
RefreshScrollActivity.java:
package com.nono.refreshDemo; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.Toast; /** * * @author Nono * */ public class RefreshScrollActivity extends Activity implements RefreshableView.RefreshListener { /** Called when the activity is first created. */ private RefreshableView mRefreshableView; private Context mContext; Handler handler = new Handler() { public void handleMessage(Message message) { super.handleMessage(message); mRefreshableView.finishRefresh(); Toast.makeText(mContext, R.string.toast_text, Toast.LENGTH_SHORT).show(); }; }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mContext = this; init(); } private void init() { // TODO Auto-generated method stub initView(); } private void initView() { // TODO Auto-generated method stub mRefreshableView = (RefreshableView) findViewById(R.id.refresh_root); initData(); } private void initData() { mRefreshableView.setRefreshListener(this); } //实现刷新RefreshListener 中方法 public void onRefresh(RefreshableView view) { //伪处理 handler.sendEmptyMessageDelayed(1, 2000); } }
RefreshableView.java:
package com.nono.refreshDemo; import java.util.Calendar; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.ScrollView; import android.widget.Scroller; import android.widget.TextView; /** * 刷新控制view * * @author Nono * */ public class RefreshableView extends LinearLayout { private static final String TAG = "LILITH"; private Scroller scroller; private View refreshView; private ImageView refreshIndicatorView; private int refreshTargetTop = -60; private ProgressBar bar; private TextView downTextView; private TextView timeTextView; private LinearLayout reFreshTimeLayout;//显示上次刷新时间的layout private RefreshListener refreshListener; private String downTextString; private String releaseTextString; // private Long refreshTime = null; private int lastX; private int lastY; // 拉动标记 private boolean isDragging = false; // 是否可刷新标记 private boolean isRefreshEnabled = true; // 在刷新中标记 private boolean isRefreshing = false; Calendar LastRefreshTime; private Context mContext; public RefreshableView(Context context) { super(context); mContext = context; } public RefreshableView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); } private void init() { // TODO Auto-generated method stub //滑动对象, LastRefreshTime=Calendar.getInstance(); scroller = new Scroller(mContext); //刷新视图顶端的的view refreshView = LayoutInflater.from(mContext).inflate(R.layout.refresh_top_item, null); //指示器view refreshIndicatorView = (ImageView) refreshView.findViewById(R.id.indicator); //刷新bar bar = (ProgressBar) refreshView.findViewById(R.id.progress); //下拉显示text downTextView = (TextView) refreshView.findViewById(R.id.refresh_hint); //下来显示时间 timeTextView = (TextView) refreshView.findViewById(R.id.refresh_time); reFreshTimeLayout=(LinearLayout)refreshView.findViewById(R.id.refresh_time_layout); LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, -refreshTargetTop); lp.topMargin = refreshTargetTop; lp.gravity = Gravity.CENTER; addView(refreshView, lp); downTextString = mContext.getResources().getString(R.string.refresh_down_text); releaseTextString = mContext.getResources().getString(R.string.refresh_release_text); } /** * 设置上次刷新时间 * @param time */ private void setLastRefreshTimeText() { // TODO Auto-generated method stub reFreshTimeLayout.setVisibility(View.VISIBLE); Calendar NowTime=Calendar.getInstance(); long l=NowTime.getTimeInMillis()-LastRefreshTime.getTimeInMillis(); int days=new Long(l/(1000*60*60*24)).intValue(); int hour=new Long(l/(1000*60*60)).intValue(); int min=new Long(l/(1000*60)).intValue(); if(days!=0) { timeTextView.setText(days+"天"); } else if(hour!=0) { timeTextView.setText(hour+"小时"); } else if(min!=0) { timeTextView.setText(min+"分钟"); } //timeTextView.setText(time); } @Override public boolean onTouchEvent(MotionEvent event) { int y= (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //记录下y坐标 lastY = y; break; case MotionEvent.ACTION_MOVE: Log.i(TAG, "ACTION_MOVE"); //y移动坐标 int m = y - lastY; if(((m < 6) && (m > -1)) || (!isDragging )){ setLastRefreshTimeText(); doMovement(m); } //记录下此刻y坐标 this.lastY = y; break; case MotionEvent.ACTION_UP: Log.i(TAG, "ACTION_UP"); fling(); break; } return true; } /** * up事件处理 */ private void fling() { // TODO Auto-generated method stub LinearLayout.LayoutParams lp = (LayoutParams) refreshView.getLayoutParams(); Log.i(TAG, "fling()" + lp.topMargin); if(lp.topMargin > 0){//拉到了触发可刷新事件 refresh(); }else{ returnInitState(); } } private void returnInitState() { // TODO Auto-generated method stub LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)this.refreshView.getLayoutParams(); int i = lp.topMargin; scroller.startScroll(0, i, 0, refreshTargetTop); invalidate(); } private void refresh() { // TODO Auto-generated method stub LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)this.refreshView.getLayoutParams(); int i = lp.topMargin; reFreshTimeLayout.setVisibility(View.GONE); refreshIndicatorView.setVisibility(View.GONE); bar.setVisibility(View.VISIBLE); timeTextView.setVisibility(View.GONE); downTextView.setVisibility(View.GONE); scroller.startScroll(0, i, 0, 0-i); invalidate(); if(refreshListener !=null){ refreshListener.onRefresh(this); isRefreshing = true; } } /** * */ @Override public void computeScroll() { // TODO Auto-generated method stub if(scroller.computeScrollOffset()){ int i = this.scroller.getCurrY(); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)this.refreshView.getLayoutParams(); int k = Math.max(i, refreshTargetTop); lp.topMargin = k; this.refreshView.setLayoutParams(lp); this.refreshView.invalidate(); invalidate(); } } /** * 下拉move事件处理 * @param moveY */ private void doMovement(int moveY) { // TODO Auto-generated method stub LinearLayout.LayoutParams lp = (LayoutParams) refreshView.getLayoutParams(); if(moveY>0){ //获取view的上边距 float f1 =lp.topMargin; float f2 = moveY * 0.3F; int i = (int)(f1+f2); //修改上边距 lp.topMargin = i; //修改后刷新 refreshView.setLayoutParams(lp); refreshView.invalidate(); invalidate(); } else { float f1 =lp.topMargin; int i=(int)(f1+moveY*0.9F); Log.i("aa", String.valueOf(i)); if(i>=refreshTargetTop) { lp.topMargin = i; //修改后刷新 refreshView.setLayoutParams(lp); refreshView.invalidate(); invalidate(); } else { } } timeTextView.setVisibility(View.VISIBLE); // if(refreshTime!= null){ // setRefreshTime(refreshTime); // } downTextView.setVisibility(View.VISIBLE); refreshIndicatorView.setVisibility(View.VISIBLE); bar.setVisibility(View.GONE); if(lp.topMargin > 0){ downTextView.setText(R.string.refresh_release_text); refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_up); }else{ downTextView.setText(R.string.refresh_down_text); refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_down); } } public void setRefreshEnabled(boolean b) { this.isRefreshEnabled = b; } public void setRefreshListener(RefreshListener listener) { this.refreshListener = listener; } /** * 结束刷新事件 */ public void finishRefresh(){ Log.i(TAG, "执行了=====finishRefresh"); LinearLayout.LayoutParams lp= (LinearLayout.LayoutParams)this.refreshView.getLayoutParams(); int i = lp.topMargin; refreshIndicatorView.setVisibility(View.VISIBLE); timeTextView.setVisibility(View.VISIBLE); scroller.startScroll(0, i, 0, refreshTargetTop); invalidate(); isRefreshing = false; LastRefreshTime=Calendar.getInstance(); } /*该方法一般和ontouchEvent 一起用 * (non-Javadoc) * @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent) */ @Override public boolean onInterceptTouchEvent(MotionEvent e) { // TODO Auto-generated method stub int action = e.getAction(); int y= (int) e.getRawY(); switch (action) { case MotionEvent.ACTION_DOWN: lastY = y; break; case MotionEvent.ACTION_MOVE: //y移动坐标 int m = y - lastY; //记录下此刻y坐标 this.lastY = y; if(m > 6 && canScroll()){ return true; } break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_CANCEL: break; } return false; } private boolean canScroll() { // TODO Auto-generated method stub View childView; if(getChildCount()>1){ childView = this.getChildAt(1); if(childView instanceof ListView){ int top =((ListView)childView).getChildAt(0).getTop(); int pad =((ListView)childView).getListPaddingTop(); if((Math.abs(top-pad)) < 3&& ((ListView) childView).getFirstVisiblePosition() == 0){ return true; }else{ return false; } }else if(childView instanceof ScrollView){ if(((ScrollView)childView).getScrollY() == 0){ return true; }else{ return false; } } } return false; } /** * 刷新监听接口 * @author Nono * */ public interface RefreshListener{ public void onRefresh(RefreshableView view); } }
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/app_bg" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dip" android:gravity="center" android:text="@string/hello" android:textColor="@color/black" /> <com.nono.refreshDemo.RefreshableView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/refresh_root" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scroll_view_root" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/linear_root" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第一行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第二行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第三行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第四行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第五行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第六行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第七行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第八行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第九行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/item_bg" android:gravity="center" android:text="第十行哈哈哈哈哈哈" android:textColor="@color/black" android:textSize="30sp" /> </LinearLayout> </ScrollView> </com.nono.refreshDemo.RefreshableView> </LinearLayout>
refresh_top_item.xml:
<?xml version="1.0" encoding="utf-8"?> <!-- android:layout_marginTop="-50.0dip"隐藏 --> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="50.0dip" android:layout_marginTop="-50.0dip" xmlns:android="http://schemas.android.com/apk/res/android"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:src="@drawable/refresh_arrow_down" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" android:gravity="center" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminateBehavior="repeat" android:max="10000" android:visibility="gone" /> <TextView android:id="@+id/refresh_hint" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5.0dip" android:gravity="center_vertical" android:text="松开手指刷新" android:textSize="14.0sp" /> </LinearLayout> <LinearLayout android:id="@+id/refresh_time_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="3dp" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:text="上次刷新时间:" android:textSize="10sp" /> <TextView android:id="@+id/refresh_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0分钟" android:textSize="10sp" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="前" android:textSize="10sp" /> </LinearLayout> </LinearLayout> <View android:layout_width="fill_parent" android:layout_height="5dp" android:layout_alignParentBottom="true" android:background="#ffc8b67a" /> </RelativeLayout> </LinearLayout>
相关推荐
本文将深入探讨如何实现下拉刷新功能,主要针对Android平台,因为提供的标签并未明确指定语言。 首先,我们要理解下拉刷新的基本原理。它通常包含以下几个部分: 1. **手势检测**:系统需要识别用户的下拉动作,并...
有时候,为了提升用户体验,我们希望在WebView中实现下拉刷新的功能,就像原生的ListView或RecyclerView那样。本篇文章将深入探讨如何在Android的WebView中实现这一特性。 首先,下拉刷新是一种常见的用户界面设计...
`PullToRefreshListFragment`这个名字暗示了这是一个针对ListFragment的下拉刷新实现。ListFragment是Android SDK中的一个类,用于在Fragment中展示ListView。集成下拉刷新功能后,用户在列表顶部下拉即可刷新列表...
本教程将基于提供的`PullToRefreshTest`项目,详细介绍如何在Android中快速实现下拉刷新功能。我们将讨论以下几个关键知识点: 1. **SwipeRefreshLayout**: Android SDK提供了一个名为`SwipeRefreshLayout`的布局...
为了提供更好的用户体验,开发者经常需要在用户滚动到ListView顶部时实现下拉刷新功能,以及在滚动到底部时加载更多数据,即上拉加载。这个过程通常涉及到对ListView的自定义适配器、滚动监听和网络请求等技术。 ...
本教程将详细介绍如何在ListView中实现下拉刷新功能,让应用更具交互性和实时性,就像微博那样显示最新的更新内容。下拉刷新功能使得用户无需离开当前页面就能获取到最新的信息,提升了用户体验。 首先,我们需要...
本篇文章将深入探讨如何实现RecyclerView的上拉加载更多和下拉刷新功能,这在许多应用中都是必不可少的特性。 首先,我们需要理解RecyclerView的基本用法。RecyclerView提供了一个Adapter来绑定数据,并通过...
本教程将指导你在Android Studio中为ListView实现下拉刷新功能。 1. **下拉刷新概念** 下拉刷新(Pull-to-Refresh)是一种常见的UI设计模式,允许用户通过从列表顶部向下拉动来触发数据的更新。这种功能常见于新闻...
本篇文章将深入探讨如何实现一个无痕过渡的下拉刷新控件,旨在提供一个更加流畅、自然的用户体验。 首先,我们来看一下现有市场上一些下拉刷新控件存在的普遍问题: 1. 当滑动控件处于初始位置时,用户向下拖动后...
"android下拉刷新实例"是指在Android平台上实现类似于iPhone的下拉刷新效果的示例代码。 在Android中,实现下拉刷新功能通常使用第三方库,如SwipeRefreshLayout或PullToRefresh。这两个库都提供了简单的API,可以...
"安卓的下拉刷新效果demo"是一个针对这一功能的示例代码,适用于初学者理解和实现下拉刷新功能。 在Android开发中,PullListview通常指的是实现下拉刷新功能的一种方式,它基于ListView这一基本组件进行扩展。...
"Android中自定义ListView控件实现下拉刷新" Android中自定义ListView控件实现下拉刷新是 Android 开发中常见的需求。下拉刷新(Pull-to-Refresh)是指在ListView中下拉时,触发刷新操作的机制。下拉刷新可以提高...
这个"Android应用源码 ListView下拉刷新 Demo"提供了一个实际的例子,帮助开发者了解如何在ListView中实现这一功能。 1. **SwipeRefreshLayout**:Android SDK 提供了一个名为SwipeRefreshLayout的布局容器,它是...
4. **Activity的下拉刷新**:在Activity中,下拉刷新通常与一个包含ListView或RecyclerView的布局关联。可以将下拉刷新逻辑封装到一个自定义的布局中,然后在Activity的布局中引用这个自定义布局。也可以利用`...
本文将深入探讨如何创建一个自定义的下拉刷新Viewgroup,它继承自FrameLayout并实现了下拉刷新的功能,提供了一种独特的视觉效果。 首先,让我们理解下拉刷新(Pull-to-Refresh)的概念。这是一种常见的用户界面...
在Android应用开发中,"仿qq空间实现下拉刷新上拉加载"是一个常见的功能需求,主要涉及到了Android UI设计、滚动事件处理、网络请求以及数据加载等多个知识点。下面将详细阐述这些技术点。 1. **SwipeRefreshLayout...
本示例是关于如何在Android应用中自定义实现下拉刷新效果的一个Demo,详细步骤和源码解析可以在提供的博客链接中找到。 一、下拉刷新原理 下拉刷新的基本工作原理是监听用户的滑动事件,当用户在列表顶部向下拉动到...
4. **接口回调**:为了将刷新请求传递给实际的数据加载逻辑,下拉刷新组件通常提供一个接口供Activity或Fragment实现。当用户触发刷新时,这个接口会被调用,使得开发者可以在合适的时机执行数据加载操作。 5. **...
"actionbar下拉刷新demo eclipse" 是一个专为Eclipse IDE设计的实例,旨在展示如何在Android应用中集成ActionBar并实现下拉刷新的效果。这个demo将帮助开发者理解如何在ActionBar上添加自定义视图,同时实现下拉刷新...