博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
无需编写布局文件一行代码指定位置添加进度条
阅读量:7118 次
发布时间:2019-06-28

本文共 7484 字,大约阅读时间需要 24 分钟。

hot3.png

 在基类布局中加上一个全局的进度条,可能是比较简单的处理方式。

但是如果是为了更好的体验,我们可能需要在按钮点击位置,出现进度条。

出于这个想法,写了这个小工具,用法很简单,在需要显示进度条的view当作targertview传参进去就行了

hideTargetView使用来控制,进度条显示的时候,原来的view显示还是消失。

实现逻辑上,本来想不增加布局深度,想直接getDecorView从activity的viewTree中最近一个FrameLayout布局中,根据传参的view的位置的相同位置的放置一个progressbar,后来发现在我们布局中存在scrollview这种可以滚动的视图的时候,progressbar不会跟着一起滚动,挺尴尬。

然后才想到了这种替换当前布局为Framelayout的方式,但是这种方式也存在一个问题,就是在存在view间依赖的relativelayout等布局中会破坏视图间依赖,解决方式也很简单,我们编写布局的时候依赖之间的reference value传递的是id,那么我们把当前显示的view的id set到我们生成的Framelayout中就可以解决这个问题了。

public void showLoading(View v,boolean hideTargetView) {        PgBarUtils.getInstance()                .getBuilder(this)                .targertView(v)                .hideTargetView(hideTargetView)                .show();    }    public void hideLoadingView(View v) {        PgBarUtils.getInstance()                .getBuilder(this)                .hide(v);    }    @Override    protected void onDestroy() {        super.onDestroy();        PgBarUtils.getInstance().destroyActivity(this);    }

调用的地方通过单例工具获取对应view的progressbarBuilder实例。

不用担心对象重复庄创建的问题。

工具通过获取view作为key来进行progerssbar对象管理,没有则新建,有则获取。

另外记得在ondestroy中调用PgbarUtils的ondestroy方法来释放,对象就行了。

否则容易造成内存泄漏。

核心的实现代码在下面,有兴趣的可以看看,没兴趣看的直接拿去用好了,反正也就是个小工具。

import android.content.Context;import android.support.annotation.IntRange;import android.support.annotation.LayoutRes;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.ProgressBar;import java.util.HashMap;import java.util.concurrent.atomic.AtomicReference;/** * Author       : yizhihao (Merlin) * Create time  : 2017-07-02 10:57 * contact      : * 562536056@qq.com || yizhihao.hut@gmail.com * */public class PgBarUtils {    public static class Builder{        public static final int NO_ID = -0x1;        private View targetView;        private Context context;        private boolean hideTargetView;        private int layoutId = NO_ID;        private int mGravity;        private Builder(){            hideTargetView = true;            layoutId = NO_ID;            mGravity = Gravity.CENTER;        }        /**         * key  :target view         * view :injected progressbar         */        private HashMap
mBarStack = new HashMap<>(); public Builder layoutId(@LayoutRes int id){ layoutId = id; return this; } public Builder(Context context) { this.context = context; } public Builder targertView(View targetView){ this.targetView = targetView; return this; } /** * 当progressbar显示的时候是否,显示target view */ public Builder hideTargetView(boolean showTargetView) { this.hideTargetView = showTargetView; return this; } public Builder gravity(int gravity){ this.mGravity = gravity; return this; } public void show(){ ProgressBar bar = mBarStack.get(targetView); if(bar == null){ if(layoutId != NO_ID){ bar = (ProgressBar) LayoutInflater.from(context).inflate(layoutId,null); } if(bar == null) bar = new ProgressBar(context); bar.setTag(context.getClass().getName()); int size = Math.min(targetView.getWidth(),targetView.getHeight()); ViewGroup viewParent = (ViewGroup) targetView.getParent(); //replace target view with framelayout //then add target view and progressbar to the //new framelayout contianer viewParent.removeView(targetView); FrameLayout container = new FrameLayout(context); //当为相对布局或者其他组件之间存在依赖关系的时候,需要用容器布局 //替代他们的依赖,防止布局出现问题。 container.setId(targetView.getId()); container.setLayoutParams(targetView.getLayoutParams()); //add target view to the new container container.addView(targetView,new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); //create a progress bar and add to the new container FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(size,size); final int padding = DisplayUtils.dip2px(context,5); bar.setPadding(padding,padding,padding,padding); //progress bar 默认居target view的中间位置 switch (mGravity){ case Gravity.LEFT: if(targetView.getHeight() == size){ lp.leftMargin += (targetView.getWidth() - size) / 3; break; } case Gravity.RIGHT: if(targetView.getHeight() == size){ lp.leftMargin += (targetView.getWidth() - size) * 2 / 3; break; } case Gravity.TOP: if(targetView.getWidth() == size){ lp.topMargin += (targetView.getHeight() - size) / 3; break; } case Gravity.BOTTOM: if(targetView.getWidth() == size){ lp.topMargin += (targetView.getHeight() - size) * 2 / 3; break; } default: if(targetView.getWidth() > targetView.getHeight()){ lp.leftMargin += (targetView.getWidth() - size) / 2; }else{ lp.topMargin += (targetView.getHeight() - size) /2; } break; } container.addView(bar,lp); viewParent.addView(container); mBarStack.put(targetView,bar); } if(hideTargetView) targetView.setVisibility(View.INVISIBLE); bar.setVisibility(View.VISIBLE); } public void remove(){ mBarStack.clear(); mBarStack = null; } public void hide(View view){ view.setVisibility(View.VISIBLE); ProgressBar bar = mBarStack.get(view); if(bar != null) bar.setVisibility(View.GONE); } } private HashMap
builders = new HashMap<>(); public void destroyActivity(Context context){ final Builder builder = builders.remove(context.getClass().getName()); if(builder != null) builder.remove(); } public Builder getBuilder(Context context){ Builder builder = builders.get(context.getClass().getName()); if(builder == null){ builder = new Builder(context); builders.put(context.getClass().getName(),builder); } return builder; } private static final AtomicReference
INSTANCE = new AtomicReference
(); private PgBarUtils(){} public static PgBarUtils getInstance() { for (; ;) { PgBarUtils current = INSTANCE.get(); if (current != null) { return current; } current = new PgBarUtils(); if (INSTANCE.compareAndSet(null, current)) { return current; } } }}

 

转载于:https://my.oschina.net/mastere/blog/1480278

你可能感兴趣的文章
Comet和WebSocket
查看>>
使用委托进行异步编程
查看>>
silverlight 跨域socket
查看>>
编程不是功能实现了就可以了
查看>>
利用Dockerfile构建一个nginx容器
查看>>
Linux/Freebsd下时间转化
查看>>
微软MED-V虚拟化实战教程之一部署
查看>>
chmod和permission
查看>>
4-2 ADO.NET-查询和检索数据7
查看>>
JavaScript 资源列表
查看>>
Spring系列之AOP分析开篇(一)
查看>>
同时兼容iOS、Android、微信小程序的UI引擎
查看>>
Day7:html和css
查看>>
centOS7 安装Git
查看>>
超全的设计模式简介(45种)
查看>>
Modbus功能码
查看>>
iOS学习笔记20 地图(二)MapKit框架
查看>>
spring cloud互联网分布式微服务云平台规划分析--spring cloud定时调度平台
查看>>
postgreSQL 9.1 的安装、基本配置、简单使用
查看>>
Visual Sudio 复制窗体文件
查看>>