加入收藏 | 设为首页 | 会员中心 | 我要投稿 江门站长网 (https://www.0750zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Android模仿QQ空间的下拉更新的功能达成

发布时间:2021-11-22 14:25:56 所属栏目:教程 来源:互联网
导读:看看今天模仿的QQ空间的下拉更新个应用吧 首先看看布局 1.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 androi

看看今天模仿的QQ空间的下拉更新个应用吧
首先看看布局
 
1.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:orientation="vertical" >  
  
    <EditText  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:drawableLeft="@drawable/write"  
        android:lines="1"  
        android:padding="5px"  
        android:singleLine="true"  
        android:text="写说说" />  
  
    <TabHost  
        android:id="@+id/tabhost"  
        android:background="@drawable/bg"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent" >  
  
        <LinearLayout  
            android:id="@+id/linearLayout1"  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            android:orientation="vertical" >  
  
            <TabWidget  
                android:id="@android:id/tabs"  
                android:layout_width="match_parent"  
                android:layout_height="wrap_content" >  
            </TabWidget>  
  
            <FrameLayout  
                android:id="@android:id/tabcontent"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent" >  
  
                <LinearLayout  
                    android:id="@+id/tab1"  
                    android:layout_width="match_parent"  
                    android:layout_height="match_parent"  
                    >  
  
                    <com.wang.MyListView  
                        android:id="@+id/listView"  
                        android:layout_width="fill_parent"  
                        android:layout_height="fill_parent"  
                        />  
                </LinearLayout>  
  
                <LinearLayout  
                    android:id="@+id/tab2"  
                    android:layout_width="match_parent"  
                    android:layout_height="match_parent"  
                     >  
                </LinearLayout>  
  
                <LinearLayout  
                    android:id="@+id/tab3"  
                    android:layout_width="match_parent"  
                    android:layout_height="match_parent"  
                     >  
                </LinearLayout>  
            </FrameLayout>  
        </LinearLayout>  
    </TabHost>  
  
</LinearLayout>  
2.list的条目布局list_item.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:gravity="center_vertical"  
    android:orientation="horizontal" >  
  
    <ImageView  
        android:id="@+id/imageView_item"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginLeft="5dp"  
        android:src="@drawable/icon" />  
  
    <TextView  
        android:id="@+id/textView_item"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginLeft="10dp"  
        android:textColor="#FFFFFF"  
        />  
  
</LinearLayout>  
3. 刷新布局refresh.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="wrap_content" >  
  
    <RelativeLayout  
        android:id="@+id/head_contentLayout"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:paddingLeft="30dp" >  
  
        <FrameLayout  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:layout_alignParentLeft="true"  
            android:layout_centerVertical="true" >  
  
            <ImageView  
                android:id="@+id/head_arrowImageView"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:layout_gravity="center"  
                android:src="@drawable/down" />  
  
            <ProgressBar  
                android:id="@+id/head_progressBar"  
                style="?android:attr/progressBarStyleSmall"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:layout_gravity="center"  
                android:visibility="gone" />  
        </FrameLayout>  
  
        <LinearLayout  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:layout_centerHorizontal="true"  
            android:gravity="center_horizontal"  
            android:orientation="vertical" >  
  
            <TextView  
                android:id="@+id/head_tipsTextView"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:text="下拉可以刷新"  
                android:textSize="15dp" />  
  
            <TextView  
                android:id="@+id/head_lastUpdatedTextView"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:text="上次更新时间:"  
                android:textSize="12dp" />  
        </LinearLayout>  
    </RelativeLayout>  
  
</LinearLayout>  
4.看看主活动实现的过程PullrefreshDemoActivity.xml
package com.wang;  
  
import java.util.LinkedList;  
  
import com.wang.MyListView.OnRefreshListener;  
  
import android.app.Activity;  
import android.content.res.Resources;  
import android.os.AsyncTask;  
import android.os.Bundle;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.view.Window;  
import android.view.WindowManager;  
import android.widget.BaseAdapter;  
import android.widget.TabHost;  
import android.widget.TextView;  
  
public class PullrefreshDemoActivity extends Activity {  
    private LinkedList<String> data;  
    private BaseAdapter adapter;  
  
    public void onCreate(Bundle savedInstanceState) {  
        // 去除标题栏   
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        // 设置全屏,取消状态栏   
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
                WindowManager.LayoutParams.FLAG_FULLSCREEN);  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
          
         TabHost tabhost=(TabHost)findViewById(R.id.tabhost);  
            tabhost.setup();  
            tabhost.addTab(tabhost.newTabSpec("tab1").setIndicator("好友动态").setContent(R.id.tab1));  
              
            tabhost.addTab(tabhost.newTabSpec("tab2").setIndicator("我的动态").setContent(R.id.tab2));  
            tabhost.addTab(tabhost.newTabSpec("tab3").setIndicator("我的应用").setContent(R.id.tab3));  
  
        data = new LinkedList<String>();  
        for (int i = 30; i < 40; i++) {  
            // 输出list——item上的数据   
            data.add(String.valueOf("暑假第" + i + "天,我们一直很宅,想家ing ..."));  
        }  
  
        final MyListView listView = (MyListView) findViewById(R.id.listView);  
        adapter = new BaseAdapter() {  
  
            // 得到一个视图,显示在指定位置上的数据在数据集,可以创建一个视图从XML布局文件   
            public View getView(int position, View convertView, ViewGroup parent) {  
                // 上下文全局应用程序对象   
                convertView = LayoutInflater.from(getApplicationContext())  
                        .inflate(R.layout.list_item, null);  
                // 实例化组件   
                TextView textView = (TextView) convertView  
                        .findViewById(R.id.textView_item);  
                // 设置文本本内容   
                textView.setText(data.get(position));  
                return convertView;  
            }  
  
            // 得到行相关联id列表中指定的位置。   
            public long getItemId(int position) {  
                return position;  
            }  
  
            // 获得相关的数据项中的指定位置的数据集   
            public Object getItem(int position) {  
                return data.get(position);  
            }  
  
            // 获得项目在数据集适配器的个数。   
            public int getCount() {  
                return data.size();  
            }  
  
        };  
  
        listView.setAdapter(adapter);  
  
        listView.setonRefreshListener(new OnRefreshListener() {  
            public void onRefresh() {  
  
                new AsyncTask<Void, Void, Void>() {  
                    // ...b表示多个参数   
                    protected Void doInBackground(Void... params) {  
                        try {  
                            //    
                            Thread.sleep(1000);  
                        } catch (Exception e) {  
                            e.printStackTrace();  
                        }  
                              
                            // 增加一条数据到list中   
                            data.addFirst("刷新后内容:每天都是新的一天!!!,親!要努力奋斗哦!!!");  
                          
                        return null;  
                    }  
  
                    protected void onPostExecute(Void result) {  
                        adapter.notifyDataSetChanged();  
                        listView.onRefreshComplete();  
                    }  
  
                }.execute(null);  
            }  
        });  
    }  
}  
5.接着是列表实现个过程MyListView.xml
package com.wang;  
  
import java.text.SimpleDateFormat;  
import java.util.Date;  
  
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.LinearInterpolator;  
import android.view.animation.RotateAnimation;  
import android.widget.AbsListView;  
import android.widget.BaseAdapter;  
import android.widget.ImageView;  
import android.widget.LinearLayout;  
import android.widget.ListView;  
import android.widget.AbsListView.OnScrollListener;  
import android.widget.ProgressBar;  
import android.widget.TextView;  
  
public class MyListView extends ListView implements OnScrollListener {  
  
    private static final String TAG = "listview";  
  
    private final static int RELEASE_To_REFRESH = 0;  
    private final static int PULL_To_REFRESH = 1;  
    private final static int REFRESHING = 2;  
    private final static int DONE = 3;  
    private final static int LOADING = 4;  
  
    // 实际的padding的距离与界面上偏移距离的比例   
    private final static int RATIO = 3;  
  
    private LayoutInflater inflater;  
  
    private LinearLayout headView;  
  
    private TextView tipsTextview;  
    private TextView lastUpdatedTextView;  
    private ImageView arrowImageView;  
    private ProgressBar progressBar;  
  
    private RotateAnimation animation;  
    private RotateAnimation reverseAnimation;  
  
    // 用于保证startY的值在一个完整的touch事件中只被记录一次   
    private boolean isRecored;  
  
    private int headContentWidth;  
    private int headContentHeight;  
  
    private int startY;  
    private int firstItemIndex;  
  
    private int state;  
  
    private boolean isBack;  
  
    private OnRefreshListener refreshListener;  
  
    private boolean isRefreshable;  
  
    public MyListView(Context context) {  
        super(context);  
        // 调用下面初始化的函数   
        init(context);  
    }  
  
    public MyListView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        // 调用下面初始化的函数   
        init(context);  
    }  
  
    private void init(Context context) {  
  
        // 获得LayoutInflater从给定的上下文。   
        inflater = LayoutInflater.from(context);  
  
        // 实例化布局XML文件转换成相应的视图对象。   
        headView = (LinearLayout) inflater.inflate(R.layout.refresh, null);  
  
        arrowImageView = (ImageView) headView  
                .findViewById(R.id.head_arrowImageView);  
        // 设置最小宽度 和高度   
        arrowImageView.setMinimumWidth(70);  
        arrowImageView.setMinimumHeight(50);  
        // 实例化布局XML文件转换成相应的视图对象。   
        progressBar = (ProgressBar) headView  
                .findViewById(R.id.head_progressBar);  
        tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);  
        lastUpdatedTextView = (TextView) headView  
                .findViewById(R.id.head_lastUpdatedTextView);  
  
        // 调用下拉刷新的方法   
        measureView(headView);  
        // d得到原始高度和宽度   
        headContentHeight = headView.getMeasuredHeight();  
        headContentWidth = headView.getMeasuredWidth();  
  
        // 设置填充。视图可能添加的空间要求显示滚动条,这取决于风格和知名度的滚动条   
        headView.setPadding(0, -1 * headContentHeight, 0, 0);  
        headView.invalidate();  
  
        // 标签用来识别一个日志消息的来源。标识类或活动日志调用发生   
        Log.v("size", "width:" + headContentWidth + " height:"  
                + headContentHeight);  
  
        // 添加一个固定视图出现在列表的顶部   
        addHeaderView(headView, null, false);  
        // 设置监听事件   
        setOnScrollListener(this);  
  
        // 动画效果实现下拉和松开时候图片的 180度 旋转 注意0, -180,和他是有区别的 -180, 0,   
        animation = new RotateAnimation(0, -180,  
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
        // 设置加速度曲线为这个动画。默认值为一个线性插值。   
        animation.setInterpolator(new LinearInterpolator());  
        animation.setDuration(300);  
        // 如果fillAfter是真的,转换,该动画执行完成时将会持续下去   
        animation.setFillAfter(true);  
  
        reverseAnimation = new RotateAnimation(-180, 0,  
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
        // 设置加速度曲线为这个动画。默认值为一个线性插值。   
        reverseAnimation.setInterpolator(new LinearInterpolator());  
        reverseAnimation.setDuration(300);  
        // 如果fillAfter是真的,转换,该动画执行完成时将会持续下去   
        reverseAnimation.setFillAfter(true);  
  
        // 设置状态   
        state = DONE;  
        // 设置不可刷新状态   
        isRefreshable = false;  
    }  
  
    // 回调方法时要调用的列表或网格已经滚动。这将完成之后调用的滚动方法   
    public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,  
            int arg3) {  
        firstItemIndex = firstVisiableItem;  
    }  
  
    /*
     * 回调方法调用而列表视图或网格视图被滚动。 如果这个视图被滚动,将调用此方法在接下来的一局画卷的呈现 *
     */  
    public void onScrollStateChanged(AbsListView arg0, int arg1) {  
    }  
  
    // 触摸事件监听   
    public boolean onTouchEvent(MotionEvent event) {  
  
        // 判断是否可以刷新   
        if (isRefreshable) {  
            // 根据动作相应不同的方法   
            switch (event.getAction()) {  
  
            // 当按住屏幕向下拉屏幕的时候   
            case MotionEvent.ACTION_DOWN:  
                if (firstItemIndex == 0 && !isRecored) {  
                    isRecored = true;  
                    startY = (int) event.getY();  
                    Log.v(TAG, "在下拉的时候记录当前位置‘");  
                }  
                break;  
  
            // 当按住屏幕向上松屏幕的时候   
            case MotionEvent.ACTION_UP:  
  
                if (state != REFRESHING && state != LOADING) {  
                    if (state == DONE) {  
  
                    }  
                    if (state == PULL_To_REFRESH) {  
                        state = DONE;  
                        changeHeaderViewByState();  
  
                        Log.v(TAG, "由下拉刷新状态,到done状态");  
                    }  
                    if (state == RELEASE_To_REFRESH) {  
                        state = REFRESHING;  
                        changeHeaderViewByState();  
                        onRefresh();  
  
                        Log.v(TAG, "由松开刷新状态,到done状态");  
                    }  
                }  
  
                isRecored = false;  
                isBack = false;  
  
                break;  
  
            // 当按住屏幕移动时候   
            case MotionEvent.ACTION_MOVE:  
                int tempY = (int) event.getY();  
  
                if (!isRecored && firstItemIndex == 0) {  
                    Log.v(TAG, "在move时候记录下位置");  
                    isRecored = true;  
                    startY = tempY;  
                }  
  
                if (state != REFRESHING && isRecored && state != LOADING) {  
  
                    /***
                     * , 当前的位置一直是在head,否则如果当列表超出屏幕的话, 当在上推的时候,列表会同时进行滚动
                     */  
                    // 可以松手去刷新了   
                    if (state == RELEASE_To_REFRESH) {  
  
                        setSelection(0);  
  
                        // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步   
                        if (((tempY - startY) / RATIO < headContentHeight)  
                                && (tempY - startY) > 0) {  
                            state = PULL_To_REFRESH;  
                            changeHeaderViewByState();  
  
                            Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");  
                        }  
                        // 一下子推到顶了   
                        else if (tempY - startY <= 0) {  
                            state = DONE;  
                            // 调用改变时候的方法,更新UI   
                            changeHeaderViewByState();  
  
                            Log.v(TAG, "由松开刷新状态转变到done状态");  
                        } else {  
                        }  
                    }  
                    // 还没有到达显示松开刷新的时候   
                    if (state == PULL_To_REFRESH) {  
  
                        setSelection(0);  
  
                        // 下拉到可以进入RELEASE_TO_REFRESH的状态   
                        if ((tempY - startY) / RATIO >= headContentHeight) {  
                            state = RELEASE_To_REFRESH;  
                            isBack = true;  
                            // 调用改变时候的方法,更新UI   
                            changeHeaderViewByState();  
  
                            Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");  
                        }  
                        // 上推到顶了   
                        else if (tempY - startY <= 0) {  
                            state = DONE;  
                            // 调用改变时候的方法,更新UI   
                            changeHeaderViewByState();  
  
                            Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");  
                        }  
                    }  
  
                    // done状态下   
                    if (state == DONE) {  
                        if (tempY - startY > 0) {  
                            state = PULL_To_REFRESH;  
                            // 调用改变时候的方法,更新UI   
                            changeHeaderViewByState();  
                        }  
                    }  
  
                    // 更新headView的size   
                    if (state == PULL_To_REFRESH) {  
                        headView.setPadding(0, -1 * headContentHeight  
                                + (tempY - startY) / RATIO, 0, 0);  
  
                    }  
  
                    // 更新headView的paddingTop   
                    if (state == RELEASE_To_REFRESH) {  
                        headView.setPadding(0, (tempY - startY) / RATIO  
                                - headContentHeight, 0, 0);  
                    }  
  
                }  
  
                break;  
            }  
        }  
  
        return super.onTouchEvent(event);  
    }  
  
    // 当状态改变时候,调用该方法,以更新界面   
    private void changeHeaderViewByState() {  
        // 根据当前的状态进行判断   
        switch (state) {  
  
        // 下拉时候,松开既可刷新   
        case RELEASE_To_REFRESH:  
            // 设置视图 VISIBLE 可见 ,GONE 不可见   
            arrowImageView.setVisibility(View.VISIBLE);  
            progressBar.setVisibility(View.GONE);  
            tipsTextview.setVisibility(View.VISIBLE);  
            lastUpdatedTextView.setVisibility(View.VISIBLE);  
  
            // 现在开始指定的动画。   
            arrowImageView.clearAnimation();  
            arrowImageView.startAnimation(animation);  
  
            tipsTextview.setText("松开既可刷新");  
  
            Log.v(TAG, "当前状态,松开即可刷新");  
            break;  
  
        // 开始时候,下拉刷新   
        case PULL_To_REFRESH:  
            // 设置视图 VISIBLE 可见 ,GONE 不可见   
            progressBar.setVisibility(View.GONE);  
            tipsTextview.setVisibility(View.VISIBLE);  
            lastUpdatedTextView.setVisibility(View.VISIBLE);  
            // 现在开始指定的动画。   
            arrowImageView.clearAnimation();  
            arrowImageView.setVisibility(View.VISIBLE);  
  
            if (isBack) {  
                isBack = false;  
                // 现在开始指定的动画。   
                arrowImageView.clearAnimation();  
                arrowImageView.startAnimation(reverseAnimation);  
  
                tipsTextview.setText("下拉刷新");  
            } else {  
                tipsTextview.setText("下拉刷新");  
            }  
            Log.v(TAG, "当前状态,下拉刷新");  
            break;  
  
        case REFRESHING:  
  
            headView.setPadding(0, 0, 0, 0);  
            // 设置视图 VISIBLE 可见 ,GONE 不可见   
            progressBar.setVisibility(View.VISIBLE);  
            // 现在开始指定的动画。   
            arrowImageView.clearAnimation();  
            arrowImageView.setVisibility(View.GONE);  
            tipsTextview.setText("正在刷新...");  
            lastUpdatedTextView.setVisibility(View.VISIBLE);  
  
            Log.v(TAG, "当前状态,正在刷新...");  
            break;  
        case DONE:  
            // 设置填充。视图可能添加的空间要求显示滚动条   
            headView.setPadding(0, -1 * headContentHeight, 0, 0);  
            // 设置视图 VISIBLE 可见 ,GONE 不可见   
            progressBar.setVisibility(View.GONE);  
            // 现在开始指定的动画。   
            arrowImageView.clearAnimation();  
            arrowImageView.setImageResource(R.drawable.down);  
            tipsTextview.setText("下拉刷新");  
            lastUpdatedTextView.setVisibility(View.VISIBLE);  
  
            Log.v(TAG, "当前状态");  
            break;  
        }  
    }  
  
    public void setonRefreshListener(OnRefreshListener refreshListener) {  
        this.refreshListener = refreshListener;  
        isRefreshable = true;  
    }  
  
    public interface OnRefreshListener {  
        public void onRefresh();  
    }  
  
    // 设置更新时间   
    public void onRefreshComplete() {  
        state = DONE;  
        //   
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");  
        String date = format.format(new Date());  
        lastUpdatedTextView.setText("最近更新:" + date);  
        changeHeaderViewByState();  
    }  
  
    private void onRefresh() {  
        if (refreshListener != null) {  
            refreshListener.onRefresh();  
        }  
    }  
  
    // 下拉刷新的   
    private void measureView(View child) {  
        // v这组布局参数宽度和高度   
        ViewGroup.LayoutParams p = child.getLayoutParams();  
        if (p == null) {  
            // 创建一个新组布局参数指定的宽度(填充)和高度(包裹)。   
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,  
                    ViewGroup.LayoutParams.WRAP_CONTENT);  
        }  
  
        // d得到childWidthSpec(高度或宽度)的子视图   
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);  
        int lpHeight = p.height;  
        int childHeightSpec;  
        if (lpHeight > 0) {  
            // 创建一个测量规范基于所提供的大小和模式   
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,  
                    MeasureSpec.EXACTLY);  
        } else {  
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,  
                    MeasureSpec.UNSPECIFIED);  
        }  
        // 找出一个视图应该多大。父供应约束信息在宽度和高度参数   
        child.measure(childWidthSpec, childHeightSpec);  
    }  
  
    public void setAdapter(BaseAdapter adapter) {  
        // 设置最近刷新的时间   
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");  
        String date = format.format(new Date());  
        lastUpdatedTextView.setText("最近更新:" + date);  
        super.setAdapter(adapter);  
    }  
  
}  
6.接着就可以看到运行结果了

(编辑:江门站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读