Android开发中更新UI时runOnUIthread(Runnable)与Handler.post(Runnable)的区别及如何选择

      我们都知道,android中的View不是线程安全的,只有主线程/UI线程(主线程和UI是等同的)才能更新UI,否则会报错。runOnUIthread(Runnale)和Handler.post(Runnable)都是将更新UI的操作提交到主线程/UI线程中执行,很多人以为这两种方法是一样的,之前我也以为是一样的,而且为了方便,我也一直是使用runOnUIthread()这一个方法的,但是昨天在项目中解决的一个问题,让我有了不同的认识。

       接下来跟大家讲下我的一个项目,其中涉及ScrollView嵌套RecyclerView的情况(不懂的可以忽略,类似于ScrollView嵌套ListView,之后有空会补上ScrollView嵌套ListView、RecyclerView的问题),即RecyclerView只能固定高度才能显示(ListView也一样),所以需要动态设置RecyclerView的高度:

      动态设置View的高度先不多说了,就说通过接口回调机制动态更新这个RcyclerView的高度的时候,经本人实践,必须使用Handler.post(Runnable r)这种方法才能有效更新,使用RunOnUIThread(Runnable r)这种方法无效。

     我去google了一下,原因是runOnUIThread()这个方法比较适合在异步线程之前去更新进度条之类的UI操作,在线程执行过程之中动态更新UI的方法最好还是选用Handler.post()这一种方法。

    引:runOnUiThread is basically suited to show a progress dialog or do some UI manipulations before an AsyncTask call. If you want to update the UI in the middle of a thread execution, then the best approach is to create a Handler which will update your UI, and let the thread continue running, for example, updating a text view periodically after a few sec, say timer functionality.

      总之,使用runOnUiThread(Runnable r)和Handler.post(Runnable r)这两种方式去更新UI是有区别的,最好的方式是使用Handler,post()方法

  

不多说了,直接上代码:

public class RecyclerViewAdapter  extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {

    private Context context;
    private List<String> list;
    private OnClickListener onClickListener;
    private Reset reset;

    public RecyclerViewAdapter(Context context) {
        this.context=context;
    }

    public void setList(List<String> list){
        this.list=list;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView= LayoutInflater.from(context).inflate(R.layout.test)
        MyViewHolder holder=new MyViewHolder(itemView);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        holder.textView.setText(list.get(position));
        if(reset!=null){                            //回调方法,返回Fragmeng中set RecyclerView的LayoutParams 
            reset.resetHeight(holder.itemView);
        }
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(onClickListener!=null) {
                    onClickListener.OnItemClick(position);
                }
            }
        });

    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        TextView textView;
        public MyViewHolder(View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.tv_test);
        }
    }

    public interface OnClickListener{
        public void OnItemClick(int position);
    }

    public void setOnClickListener(OnClickListener onClickListener){
        this.onClickListener=onClickListener;
    }

    public interface Reset{
        void resetHeight(View itemView);
}
    public void setReset(Reset reset){
        this.reset=reset;
    }
}


 

在fragment中实现接口RecyclerAdapter.Reset,,实现该接口的resetHeight(View itemView)的方法

private RecyclerView recyclerView;
private List<String> list;
@Override
public void resetHeight(View itemView) {
    int count=list.size();
    itemView.measure(0,0);
    final ViewGroup.LayoutParams params=recyclerView.getLayoutParams();
    params.height=count*itemView.getMeasuredHeight();
    android.os.Handler handler=new android.os.Handler();
    //第一种方法,是有效的
    handler.post(new Runnable() {
        @Override
        public void run() {
            recyclerView.setLayoutParams(params);
        }
    });
    
    //第二种方法,无效
    getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            recyclerView.setLayoutParams(params);
        }
    });
}


      


       


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值