当前位置:  编程技术>移动开发
本页文章导读:
    ▪便利实用的下拉刷新控件,支持ScrollView、AbsListView        方便实用的下拉刷新控件,支持ScrollView、AbsListView 最近要做一个下拉刷新的功能,网上找了很多例子,也看了一些开源的下拉刷新项目,但是小例子比较简单,效果和稳定性都差强人意,而.........
    ▪ 写在20110613:vendor机制、批改应用编译.mk文件、USB调试        写在20110613:vendor机制、修改应用编译.mk文件、USB调试 1.Vendor机制:   在主分支上建立分量,达到差异化编译的目的,主要体现在***_BUILD和***_CUSTOM两个文件,顾名思义,前者是差异化按.........
    ▪ 写在20110616:FM主要功能、两个定做、Handler、消息队列       写在20110616:FM主要功能、两个定制、Handler、消息队列 1..txt文本文件短信支持发送2..txt/网页书签的Mimetype均为text/plain,如何区分呢?3.两个定制:Flash U 同时支持内外部存储,不同存储设.........

[1]便利实用的下拉刷新控件,支持ScrollView、AbsListView
    来源: 互联网  发布时间: 2014-02-18
方便实用的下拉刷新控件,支持ScrollView、AbsListView

最近要做一个下拉刷新的功能,网上找了很多例子,也看了一些开源的下拉刷新项目,但是小例子比较简单,效果和稳定性都差强人意,而开源的项目又太庞大,看起来耗时费劲,所以只好综合一下各处的代码掌握其原理,自己实现一套下拉刷新功能。

 

该控件特点:

1.子控件必须是一个ScrollView或ListView;

2.支持自定义下拉布局;

3.自定义下拉布局可以不用处理下拉的各种状态(只需要实现几个接口即可),也可以自己处理各种下拉的状态。

 

先来看看效果图:



 



 



 

上代码:

首先看如何使用:

1.使用的布局:

 <LinearLayout 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"
    android:orientation="vertical" >

    <com.example.pulldown.PullDownScrollView
        android:id="@+id/refresh_root"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:background="#161616"
        android:orientation="vertical" >

        <ScrollView
            android:id="@+id/scrollview"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none" >

            <LinearLayout
                android:id="@+id/mainView"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="#1f1f1f"
                android:orientation="vertical" >

                <!-- 自已的布局 -->

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dip"
                    android:gravity="center"
                    android:text="@string/hello_world"
                    android:textColor="@android:color/white"
                    android:textSize="18sp" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dip"
                    android:gravity="center"
                    android:text="@string/hello_world"
                    android:textColor="@android:color/white"
                    android:textSize="18sp" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dip"
                    android:gravity="center"
                    android:text="@string/hello_world"
                    android:textColor="@android:color/white"
                    android:textSize="18sp" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dip"
                    android:gravity="center"
                    android:text="@string/hello_world"
                    android:textColor="@android:color/white"
                    android:textSize="18sp" />
            </LinearLayout>
        </ScrollView>
    </com.example.pulldown.PullDownScrollView>

</LinearLayout>

 2.UI使用:

   首先,Activity实现接口:

implements RefreshListener

 部分代码如下:

  package com.example.pulldown;

import com.example.pulldown.PullDownScrollView.RefreshListener;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity implements RefreshListener{
    private PullDownScrollView mPullDownScrollView; 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mPullDownScrollView = (PullDownScrollView) findViewById(R.id.refresh_root);  
        mPullDownScrollView.setRefreshListener(this);  
        mPullDownScrollView.setPullDownElastic(new PullDownElasticImp(this));  
    }
    @Override  
    public void onRefresh(PullDownScrollView view) {  
        new Handler().postDelayed(new Runnable() {  
              
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                mPullDownScrollView.finishRefresh("上次刷新时间:12:23");  
            }  
        }, 2000);  
    }  
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}
 

3.再来看看控件代码:

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.ScrollView;


/**
 * @author xwangly@163.com
 * @date 2013-7-9
 * 
 */
public class PullDownScrollView extends LinearLayout {

    private static final String TAG = "PullDownScrollView";

    private int refreshTargetTop = -60;
    private int headContentHeight;

    private RefreshListener refreshListener;

    private RotateAnimation animation;
    private RotateAnimation reverseAnimation;
    
    private final static int RATIO = 2;
    private int preY = 0;
    private boolean isElastic = false;
    private int startY;
    private int state;
    
    private String note_release_to_refresh = "松开更新";
    private String note_pull_to_refresh = "下拉刷新";
    private String note_refreshing = "正在更新...";
    
    private IPullDownElastic mElastic;
    

    public PullDownScrollView(Context context) {
        super(context);
        init();

    }

    public PullDownScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        animation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        animation.setInterpolator(new LinearInterpolator());
        animation.setDuration(250);
        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(200);
        reverseAnimation.setFillAfter(true);
    }
    /**
     * 刷新监听
     * @param listener
     */
    public void setRefreshListener(RefreshListener listener) {
        this.refreshListener = listener;
    }
    /**
     * 下拉布局
     * @param elastic
     */
    public void setPullDownElastic(IPullDownElastic elastic) {
        mElastic = elastic;
        
        headContentHeight = mElastic.getElasticHeight();
        refreshTargetTop = - headContentHeight;
        LayoutParams lp = new LinearLayout.LayoutParams(
                LayoutParams.FILL_PARENT, headContentHeight);
        lp.topMargin = refreshTargetTop;
        addView(mElastic.getElasticLayout(), 0, lp);
    }
    
    /**
     * 设置更新提示语
     * @param pullToRefresh 下拉刷新提示语
     * @param releaseToRefresh 松开刷新提示语
     * @param refreshing 正在刷新提示语
     */
    public void setRefreshTips(String pullToRefresh, String releaseToRefresh, String refreshing) {
        note_pull_to_refresh = pullToRefresh;
        note_release_to_refresh = releaseToRefresh;
        note_refreshing = refreshing;
    }
    /*
     * 该方法一般和ontouchEvent 一起用 (non-Javadoc)
     * 
     * @see
     * android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Logger.d(TAG, "onInterceptTouchEvent");
        printMotionEvent(ev);
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            preY = (int) ev.getY();
        }
        if (ev.getAction() == MotionEvent.ACTION_MOVE) {

            Logger.d(TAG, "isElastic:" + isElastic + " canScroll:"+ canScroll() + " ev.getY() - preY:"+(ev.getY() - preY));
            if (!isElastic && canScroll()
                    && (int) ev.getY() - preY >= headContentHeight / (3*RATIO)
                    && refreshListener != null && mElastic != null) {

                isElastic = true;
                startY = (int) ev.getY();
                Logger.i(TAG, "在move时候记录下位置startY:" + startY);
                return true;
            }

        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Logger.d(TAG, "onTouchEvent");
        printMotionEvent(event);
        handleHeadElastic(event);
        return super.onTouchEvent(event);
    }

    private void handleHeadElastic(MotionEvent event) {
        if (refreshListener != null && mElastic != null) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Logger.i(TAG, "down");
                break;
            case MotionEvent.ACTION_UP:

                Logger.i(TAG, "up");
                if (state != IPullDownElastic.REFRESHING && isElastic) {
                    
                    if (state == IPullDownElastic.DONE) {
                        // 什么都不做
                        setMargin(refreshTargetTop);
                    }
                    if (state == IPullDownElastic.PULL_To_REFRESH) {
                        state = IPullDownElastic.DONE;
                        setMargin(refreshTargetTop);
                        changeHeaderViewByState(state, false);
                        Logger.i(TAG, "由下拉刷新状态,到done状态");
                    }
                    if (state == IPullDownElastic.RELEASE_To_REFRESH) {
                        state = IPullDownElastic.REFRESHING;
                        setMargin(0);
                        changeHeaderViewByState(state, false);
                        onRefresh();
                        Logger.i(TAG, "由松开刷新状态,到done状态");
                    }

                }
                isElastic = false;
                break;
            case MotionEvent.ACTION_MOVE:
                Logger.i(TAG, "move");
                int tempY = (int) event.getY();
                
                if (state != IPullDownElastic.REFRESHING && isElastic) {
                    // 可以松手去刷新了
                    if (state == IPullDownElastic.RELEASE_To_REFRESH) {
                        if (((tempY - startY) / RATIO < headContentHeight)
                                && (tempY - startY) > 0) {
                            state = IPullDownElastic.PULL_To_REFRESH;
                            changeHeaderViewByState(state, true);
                            Logger.i(TAG, "由松开刷新状态转变到下拉刷新状态");
                        } else if (tempY - startY <= 0) {
                            state = IPullDownElastic.DONE;
                            changeHeaderViewByState(state, false);
                            Logger.i(TAG, "由松开刷新状态转变到done状态");
                        }
                    }
                    if (state == IPullDownElastic.DONE) {
                        if (tempY - startY > 0) {
                            state = IPullDownElastic.PULL_To_REFRESH;
                            changeHeaderViewByState(state, false);
                        }
                    }
                    if (state == IPullDownElastic.PULL_To_REFRESH) {
                        // 下拉到可以进入RELEASE_TO_REFRESH的状态
                        if ((tempY - startY) / RATIO >= headContentHeight) {
                            state = IPullDownElastic.RELEASE_To_REFRESH;
                            changeHeaderViewByState(state, false);
                            Logger.i(TAG, "由done或者下拉刷新状态转变到松开刷新");
                        } else if (tempY - startY <= 0) {
                            state = IPullDownElastic.DONE;
                            changeHeaderViewByState(state, false);
                            Logger.i(TAG, "由DOne或者下拉刷新状态转变到done状态");
                        }
                    }
                    if (tempY - startY > 0) {
                        setMargin((tempY - startY)/2 + refreshTargetTop);
                    }
                }
                break;
            }
        }
    }
    
    /**
     * 
     */
    private void setMargin(int top) {
        LinearLayout.LayoutParams lp = (LayoutParams) mElastic.getElasticLayout()
                .getLayoutParams();
        lp.topMargin = top;
        // 修改后刷新
        mElastic.getElasticLayout().setLayoutParams(lp);
        mElastic.getElasticLayout().invalidate();
    }

    private void changeHeaderViewByState(int state, boolean isBack) {

        mElastic.changeElasticState(state, isBack);
        switch (state) {
        case IPullDownElastic.RELEASE_To_REFRESH:
            mElastic.showArrow(View.VISIBLE);
            mElastic.showProgressBar(View.GONE);
            mElastic.showLastUpdate(View.VISIBLE);
            mElastic.setTips(note_release_to_refresh);

            mElastic.clearAnimation();
            mElastic.startAnimation(animation);
            Logger.i(TAG, "当前状态,松开刷新");
            break;
        case IPullDownElastic.PULL_To_REFRESH:
            mElastic.showArrow(View.VISIBLE);
            mElastic.showProgressBar(View.GONE);
            mElastic.showLastUpdate(View.VISIBLE);
            mElastic.setTips(note_pull_to_refresh);

            mElastic.clearAnimation();

            // 是由RELEASE_To_REFRESH状态转变来的
            if (isBack) {
                mElastic.startAnimation(reverseAnimation);
            }
            Logger.i(TAG, "当前状态,下拉刷新");
            break;
        case IPullDownElastic.REFRESHING:
            mElastic.showArrow(View.GONE);
            mElastic.showProgressBar(View.VISIBLE);
            mElastic.showLastUpdate(View.GONE);
            mElastic.setTips(note_refreshing);

            mElastic.clearAnimation();
            Logger.i(TAG, "当前状态,正在刷新...");
            break;
        case IPullDownElastic.DONE:
            mElastic.showProgressBar(View.GONE);
            mElastic.clearAnimation();
//            arrowImageView.setImageResource(R.drawable.goicon);
            // tipsTextview.setText("下拉刷新");
            // lastUpdatedTextView.setVisibility(View.VISIBLE);
            Logger.i(TAG, "当前状态,done");
            break;
        }
    }

    private void onRefresh() {
        // downTextView.setVisibility(View.GONE);
//        scroller.startScroll(0, i, 0, 0 - i);
//        invalidate();
        if (refreshListener != null) {
            refreshListener.onRefresh(this);
        }
    }

    /**
     * 
     */
    @Override
    public void computeScroll() {
//        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();
//        }
    }

    /**
     * 结束刷新事件,UI刷新完成后必须回调此方法
     * @param text 一般传入:“上次更新时间:12:23”
     */
    public void finishRefresh(String text) {
        if (mElastic == null) {
            Logger.d(TAG, "finishRefresh mElastic:" + mElastic);
            return;
        }
        state = IPullDownElastic.DONE;
        mElastic.setLastUpdateText(text);
        changeHeaderViewByState(state,false);
        Logger.i(TAG, "执行了=====finishRefresh");

        mElastic.showArrow(View.VISIBLE);
        mElastic.showLastUpdate(View.VISIBLE);
        setMargin(refreshTargetTop);
//        scroller.startScroll(0, i, 0, refreshTargetTop);
//        invalidate();
    }

    private boolean canScroll() {
        View childView;
        if (getChildCount() > 1) {
            childView = this.getChildAt(1);
            if (childView instanceof AbsListView) {
                int top = ((AbsListView) childView).getChildAt(0).getTop();
                int pad = ((AbsListView) childView).getListPaddingTop();
                if ((Math.abs(top - pad)) < 3
                        && ((AbsListView) childView).getFirstVisiblePosition() == 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (childView instanceof ScrollView) {
                if (((ScrollView) childView).getScrollY() == 0) {
                    return true;
                } else {
                    return false;
                }
            }

        }
        return canScroll(this);
    }
    
    /**
     * 子类重写此方法可以兼容其它的子控件,目前只兼容AbsListView和ScrollView
     * @param view
     * @return
     */
    public boolean canScroll(PullDownScrollView view) {
        return false;
    }

    private void printMotionEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Logger.d(TAG, "down");
            break;
        case MotionEvent.ACTION_MOVE:
            Logger.d(TAG, "move");
            break;
        case MotionEvent.ACTION_UP:
            Logger.d(TAG, "up");
        default:
            break;
        }
    }
    /**
     * 刷新监听接口
     */
    public interface RefreshListener {
        public void onRefresh(PullDownScrollView view);
    }

}

 

4.接口:

import android.view.View;
import android.view.animation.Animation;

/**
 * @author xwangly@163.com
 * @date 2013-7-10
 * 下拉控件接口
 */
public interface IPullDownElastic {
    public final static int RELEASE_To_REFRESH = 0;
    public final static int PULL_To_REFRESH = 1;
    public final static int REFRESHING = 2;
    public final static int DONE = 3;

    public View getElasticLayout();

    public int getElasticHeight();

    public void showArrow(int visibility);

    public void startAnimation(Animation animation);

    public void clearAnimation();

    public void showProgressBar(int visibility);

    public void setTips(String tips);

    public void showLastUpdate(int visibility);

    public void setLastUpdateText(String text);
    
    /**
     * 可以不用实现此方法,PullDownScrollView会处理ElasticLayout布局中的状态 
     * 如果需要特殊处理,可以实现此方法进行处理
     * 
     * @param state  @see RELEASE_To_REFRESH
     * @param isBack 是否是松开回退
     */
    public void changeElasticState(int state, boolean isBack);

}

 5.默认实现:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;


/**
 * @author xwangly@163.com
 * @date   2013-7-10
 * 默认下拉控件布局实现
 */
public class PullDownElasticImp implements IPullDownElastic {
    private View refreshView;
    private ImageView arrowImageView;
    private int headContentHeight;
    private ProgressBar progressBar;
    private TextView tipsTextview;
    private TextView lastUpdatedTextView;
    
    private Context mContext;
    public PullDownElasticImp(Context context) {
        mContext = context;
        init();
    }
    

    private void init() {
        // 刷新视图顶端的的view
        refreshView = LayoutInflater.from(mContext).inflate(
                R.layout.refresh_top_item, null);

        // 指示器view
        arrowImageView = (ImageView) refreshView
                .findViewById(R.id.head_arrowImageView);
        // 刷新bar
        progressBar = (ProgressBar) refreshView
                .findViewById(R.id.head_progressBar);
        // 下拉显示text
        tipsTextview = (TextView) refreshView.findViewById(R.id.refresh_hint);
        // 下来显示时间
        lastUpdatedTextView = (TextView) refreshView
                .findViewById(R.id.refresh_time);

        headContentHeight = Utils.dip2px(mContext, 50);
    }

    /**
     * @return
     * 
     */
    @Override
    public View getElasticLayout() {
        return refreshView;
    }

    /**
     * @return
     * 
     */
    @Override
    public int getElasticHeight() {
        return headContentHeight;
    }

    /**
     * @param show
     * 
     */
    @Override
    public void showArrow(int visibility) {
        arrowImageView.setVisibility(visibility);
    }

    /**
     * @param animation
     * 
     */
    @Override
    public void startAnimation(Animation animation) {
        arrowImageView.startAnimation(animation);
    }

    /**
     * 
     * 
     */
    @Override
    public void clearAnimation() {
        arrowImageView.clearAnimation();
    }

    /**
     * @param show
     * 
     */
    @Override
    public void showProgressBar(int visibility) {
        progressBar.setVisibility(visibility);
    }

    /**
     * @param tips
     * 
     */
    @Override
    public void setTips(String tips) {
        tipsTextview.setText(tips);
    }

    /**
     * @param show
     * 
     */
    @Override
    public void showLastUpdate(int visibility) {
        lastUpdatedTextView.setVisibility(visibility);
    }

    /**
     * @param text
     * 
     */
    public void setLastUpdateText(String text) {
        lastUpdatedTextView.setText(text);
    }


    /**
     * @param state
     * @param isBack
     * 
     */
    @Override
    public void changeElasticState(int state, boolean isBack) {
        // TODO Auto-generated method stub
        
    }

}

 

6.默认实现的布局:

<?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="-50.0dip"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0.0dip"
        android:layout_weight="1.0"
        android:gravity="center"
        android:orientation="horizontal" >

        <!-- 箭头图像、进度条 -->

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="30dip" >

            <!-- 箭头 -->

            <ImageView
                android:id="@+id/head_arrowImageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:src="/blog_article/@drawable/goicon/index.html" />

            <!-- 进度条 -->

            <ProgressBar
                android:id="@+id/head_progressBar"
                
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:visibility="gone" />
        </FrameLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="center"
            android:orientation="vertical" >

            <!-- 提示 -->

            <TextView
                android:id="@+id/refresh_hint"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下拉刷新"
                android:textColor="#f2f2f2"
                android:textSize="16sp" />

            <!-- 最近更新 -->

            <TextView
                android:id="@+id/refresh_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="上次更新"
                android:textColor="#b89766"
                android:textSize="10sp" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

 6.图片资源:

@drawable/goicon



 

 

完结

 

 

 修改:从原工程中独立出来,并附上简单的工程,见附件。

1 楼 freezingsky 19 小时前  
写得很好。继续努力!

    
[2] 写在20110613:vendor机制、批改应用编译.mk文件、USB调试
    来源: 互联网  发布时间: 2014-02-18
写在20110613:vendor机制、修改应用编译.mk文件、USB调试
1.Vendor机制:
   在主分支上建立分量,达到差异化编译的目的,主要体现在***_BUILD和***_CUSTOM两个文件,顾名思义,前者是差异化按项目分门别类的编译脚本,后者是按项目分类的各应用相关定制的文件抽取存放位置

2.是否把某个应用编译进去,可以在该应用对应的工程目录下的.mk文件中修改脚本
3.ADB设备识别不了:检查手机驱动是否安装、设置中“允许USB调试”选项是否开启。

    
[3] 写在20110616:FM主要功能、两个定做、Handler、消息队列
    来源: 互联网  发布时间: 2014-02-18
写在20110616:FM主要功能、两个定制、Handler、消息队列
1..txt文本文件短信支持发送
2..txt/网页书签的Mimetype均为text/plain,如何区分呢?
3.两个定制:Flash U 同时支持内外部存储,不同存储设备之间相互拷贝等操作
            DRM  用到第三方API或者自研的API
4.MessageQueue和Handler、Looper
4.1 Message
  Message消息,理解为线程间交流的信息,处理数据后台线程需要更新UI,则发送Message内含一些数据给UI线程。
4.2 Handler
   Handler处理者,是Message的主要处理者,负责Message的发送,Message内容的执行处理。后台线程就是通过传进来的 Handler对象引用来sendMessage(Message)。而使用Handler,需要implement 该类的 handleMessage(Message)方法,它是处理这些Message的操作内容,例如Update UI。通常需要子类化Handler来实现handleMessage方法。
4.3 Message Queue
   Message Queue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被 Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。
4.4 Looper
   Looper是每条线程里的Message Queue的管家。Android没有Global的Message Queue,而Android会自动替主线程(UI线程)建立Message Queue,但在子线程里并没有建立Message Queue。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper() 得到当前线程的Looper就有可能为NULL。对于子线程使用Looper,查看API Doc

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
网站运营/SEO iis7站长之家
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3