android windowistranslucent 转场动画,android recyclerview点击跳转到viewpager共享元素动画...

今天做项目的时候用到了Transition动画。也就是android5.0中出现的。基本的使用方式我们都知道是用TransitionName在两个activity中进行绑定。现在的场景是activityA中有个recyclerview,点击item的时候跳转到activityB。B中是一个类似全屏的viewpager。item中的图片元素共享的viewpager指定的Item上。并且viewpager可以动态删除item,返回的A的时候item也要同步数量。

想想实现功能应该不难。难的地方在于两个页面的item数量不一样,共享元素view的位置可能也不一样。如果B当中已经改变了item的数量和选中的viewpager的position的位置,A那边的共享元素该如何改变呢。现在开始展现真正的轮子了。

1、基本使用

设置两个activity的style中 android:windowContentTransitions 为true

false

true

true

false

true

共享元素关键点是绑定的view和view的TransitionName,那么我们就要给itemView设置transitionName了。这里我们使用url给item设置TransitionName,如果item的url一样那么可以自己想想,保持唯一就行了。

ViewCompat.setTransitionName(holder.itemView, ims.get(position).url);

ViewCompat是support兼容类。不然就要写一堆判断了很是烦。

启动activity绑定transitionView,将list和选中的item传入

ActivityOptionsCompat options =

ActivityOptionsCompat.makeSceneTransitionAnimation(A.this,

holder.itemView, ViewCompat.getTransitionName(holder.itemView));

Intent intent = new Intent(A.this, B.class);

intent.putExtra(B.INTENT_SELECT_POSITION, imgs.get(holder.getAdapterPosition()));

intent.putParcelableArrayListExtra(B.INTENT_IMGS, imgs);

ActivityCompat.startActivityForResult(A.this, intent, REQUEST_CODE_PREVIEW, options.toBundle());

之后我们到了B的Activity,这里我们不要为viewpager的每个itemview设置transitionName,我们直接给viewpager设置transitionName,以为viewpager选中页的两边都会加载view,处理起来稍微有点麻烦,直接设置viewpager的transitionName反而方便连贯。

//currentItem是我从上个页面传进来的Item

ViewCompat.setTransitionName(viewPager, currentItem.url);

....

//设置选中的item

viewPager.setCurrentItem(i);

@Override

public void onBackPressed() {

checkFinish(RESULT_OK);

}

/**

* 通过转场动画finish

*/

private void checkFinish(int resultCode) {

Intent intent = new Intent();

intent.putParcelableArrayListExtra(INTENT_IMGS, imgs);

setResult(resultCode, intent);

supportFinishAfterTransition();

}

2、进阶使用

基本的点击返回效果我们就搞好了,可是还是会出现动画不连贯的效果。一头雾水的搜了一下

//如果共享元素需要通过AsyncTask,一个Loader,或其他类似的进行数据加载在被调用的

//Activity决定它们最终的表现,数据被分发返回到主线程之前框架可以开始过渡。

supportPostponeEnterTransition()//暂时阻止共享元素过渡

supportStartPostponedEnterTransition//确认元素都已经摆放完成恢复过度

因为viewpager.setCurrentItem之后UI毕竟是在默认300ms完成绘制。所以我们要等待viewpager完全展示完成才能进行过渡动画的渲染。

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

supportPostponeEnterTransition();

....//更新ui

//监听viewpager布局树已经绘制完成

viewPager.getViewTreeObserver().addOnGlobalLayoutListener(new

ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

viewPager.getViewTreeObserver().removeOnGlobalLayoutListener(this);

//释放

supportStartPostponedEnterTransition();

}

});

}

这样我们的连贯效果就实现了。

3、完成实现

因为我们知道B页面是带有删除和翻页功能的,所以我们就要进行页面之间切换时候的ui数据整理。我试着在onActivityResult中用supportPostponeEnterTransition和supportStartPostponedEnterTransition实现数据的变换,发现效果并没有实现,onActivityResult在过渡动画后才调用。所以还是搜索一下

/**

* Called when an activity you launched with an activity transition exposes this

* Activity through a returning activity transition, giving you the resultCode

* and any additional data from it. This method will only be called if the activity

* set a result code other than {@link #RESULT_CANCELED} and it supports activity

* transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.

*

*

The purpose of this function is to let the called Activity send a hint about

* its state so that this underlying Activity can prepare to be exposed. A call to

* this method does not guarantee that the called Activity has or will be exiting soon.

* It only indicates that it will expose this Activity's Window and it has

* some data to pass to prepare it.

*

* @param resultCode The integer result code returned by the child activity

* through its setResult().

* @param data An Intent, which can return result data to the caller

* (various data can be attached to Intent "extras").

*/

public void onActivityReenter(int resultCode, Intent data) {

//当你使用了过度动画返回时候就会调用此方法,通过supportPostponeEnterTransition和supportStartPostponedEnterTransition可以延缓动画的发生

//只要resultCode不是RESULT_CANCELED并且 Window#FEATURE_ACTIVITY_TRANSITIONS这个已经在theme里设置了

}

@Override

public void onActivityReenter(int resultCode, Intent data) {

if (resultCode == RESULT_OK && data != null) {

//针对classloader回收 我这里出现了这个问题,如果没有请忽略

data.setExtrasClassLoader(getClass().getClassLoader());

ArrayList limgs = data.getParcelableArrayListExtra(B.INTENT_IMGS);

imgs = limgs;

adapter.setIms(imgs);

adapter.notifyDataSetChanged();

supportPostponeEnterTransition();

binding.recyclerview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

recyclerview.getViewTreeObserver().removeOnGlobalLayoutListener(this);

supportStartPostponedEnterTransition();

}

});

}

super.onActivityReenter(resultCode, data);

}

满怀希望的试一试。结果懵逼,切换了还是没效果。。。==。B页面的共享viewpager的TransitionName还是原来的。我们要在返回的时候设置viewpager的TransitionName为当前选中的item的url。

B中

/**

* 通过转场动画finish

*/

private void checkFinish(int resultCode) {

Intent intent = new Intent();

setEnterShareCallback(currentItem);

intent.putParcelableArrayListExtra(INTENT_IMGS, imgs);

setResult(resultCode, intent);

supportFinishAfterTransition();

}

private void setEnterShareCallback(String url) {

//设置共享元素们的回调

setEnterSharedElementCallback(new SharedElementCallback() {

@Override

public void onMapSharedElements(List names, Map sharedElements) {

sharedElements.clear();

names.clear();

if (currentItem==null){

return;

}

names.add(url);

sharedElements.put(url,viewPager);

}

});

}

哈哈 。可以了。不过最后一步中,感觉只需要设置viewpager的TransitionName就行了,没试过。有时间再试试吧。

4、遇到的问题

项目加载网络图片会出现一些问题。如果使用glide的话要禁用动画加载dontAnimate。

还有部分时候会出现viewpager翻页会出现返回动画失效的问题,我们在返回的时候需要进行view的替换

@Override

protected void onCreate(Bundle savedInstanceState) {

setExitSharedElementCallback(new SharedElementCallback() {

@Override

public void onMapSharedElements(List names, Map sharedElements) {

//isBack为成员变量 如果启动B页面设置为false,onActivityReenter后为true

if (isBack) {

names.clear();

names.add(shareName);

sharedElements.clear();

sharedElements.put(shareName, shareView);

}

}

});

}

public void onActivityReenter(){

//更新adapter

.......

recyclerview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

notifyCallView(data);

recyclerview.getViewTreeObserver().removeOnGlobalLayoutListener(this);

supportStartPostponedEnterTransition();

}

});

}

private void notifyCallView(Intent data) {

//遍历recyclerview.getchildCount 从B页面返回的url值

.....

shareName = url;

shareView = viewHolder.itemView;

}

over

点击数:735

<think>好的,我现在要回答用户的问题:如何使用Prometheus实现类似Smokeping的地址监控功能,并提供配置示例。首先,我需要回忆一下Prometheus和Smokeping各自的功能特点。Smokeping主要用于网络延迟和可达性的监控,而Prometheus是一个基于时间序列的监控系统,通常用于应用和服务的指标收集。用户的需求是将两者的功能结合起来,用Prometheus监控网络地址,类似于Smokeping所做的。 首先,我应该考虑Prometheus本身是否具备这样的能力。Prometheus主要通过exporter来收集数据,但默认情况下,它可能没有内置的网络探测功能。这时候,可能需要使用特定的exporter或者工具来补充。例如,Blackbox Exporter是Prometheus官方提供的一个用于探测HTTP、HTTPS、DNS、TCP和ICMP等的工具,非常适合用来监控网络端点的可达性和延迟。这应该是一个关键的组件。 接下来,我需要构建一个配置示例。用户可能需要一个具体的配置来参考,比如如何配置Blackbox Exporter,以及在Prometheus的配置文件中如何设置job来抓取数据。例如,在Prometheus的配置文件中添加一个job,指定使用Blackbox Exporter的探测模块,定义目标地址和探测参数。同时,可能需要配置不同的探测类型,比如ICMP ping、TCP连接测试或者HTTP请求。 然后,关于数据展示,用户可能需要使用Grafana来创建仪表盘,展示网络延迟、丢包率等指标。这部分需要指导用户如何配置Grafana的数据源为Prometheus,并导入合适的仪表盘模板,或者自行创建相关图表。 此外,告警规则也是一个重要部分。用户可能希望当网络不可达或延迟过高时触发告警。这时候需要在Prometheus中配置Alertmanager,定义相应的告警规则,比如当up指标为0时表示目标不可达,或者probe_duration_seconds超过某个阈值时发出警报。 还需要考虑一些优化和高级配置,比如调整探测频率、设置不同的探测参数(如超时时间、重试次数)等,以满足具体的监控需求。同时,可能需要结合其他工具或exporter来补充Prometheus的功能,比如结合smokeping_prober这样的第三方工具,或者自定义脚本进行更复杂的监控任务。 最后,要确保回答结构清晰,分步骤说明配置过程,并提供一个具体的配置示例,让用户能够直接参考和操作。同时,根据用户之前的引用内容,可能需要引用相关的配置示例或项目结构,比如之前提到的Prometheus配置中的job_name示例,以及Blackbox Exporter的使用方法。</think>以下是如何使用Prometheus实现类似Smokeping地址监控功能的配置方案,通过Blackbox Exporter实现网络层探测: ### 一、核心组件配置 1. **安装Blackbox Exporter** 部署支持ICMP/TCP/HTTP探测的官方组件: ```yaml # docker-compose.yml示例 services: blackbox-exporter: image: prom/blackbox-exporter ports: - "9115:9115" ``` 2. **Prometheus抓取配置** 在`prometheus.yml`中添加探测任务(支持ICMP/PING监控): ```yaml scrape_configs: - job_name: 'network-monitoring' metrics_path: /probe params: module: [icmp] # 使用ICMP模块 static_configs: - targets: - 8.8.8.8 # 监控目标1 - 192.168.1.1 # 监控目标2 relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:9115 # Blackbox Exporter地址 ``` 该配置可实现与Smokeping相似的连续网络探测能力[^1] ### 二、关键监控指标 | 指标名称 | 类型 | 说明 | |------------------------------|---------|-----------------------------| | probe_success | Gauge | 目标可达性(1=正常,0=异常) | | probe_duration_seconds | Gauge | 最后一次探测耗时 | | probe_icmp_duration_seconds | Summary | ICMP往返时间分布统计 | ### 三、Grafana可视化配置 建议使用`10479`号仪表盘模板(Blackbox Exporter官方模板),主要包含: - 网络拓扑状态矩阵 - 延迟变化趋势图 - 丢包率统计 - 可用性热力图 ### 四、告警规则示例 ```yaml # alert.rules groups: - name: network-alerts rules: - alert: HostDown expr: probe_success{job="network-monitoring"} == 0 for: 2m annotations: summary: "{{ $labels.instance }} 无法访问" - alert: HighLatency expr: avg_over_time(probe_duration_seconds[5m]) > 0.5 labels: severity: warning annotations: description: "{{ $labels.instance }} 平均延迟超过500ms" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值