Android 让Activity部分透明、并作出流畅的进场动画

让一个界面部分透明现在已经比较常见的了,比如网易云下面界面:
在这里插入图片描述
“歌单详情”这个View大概占屏幕高的3/4,界面除了这个view其他部分则变成了半透明状态。

怎么实现这个View呢?我自己主要研究了三套做法,并用实际开发项目的情况做了测试,作出下面的小结:

  1. 把这个界面做成一个PopWindow
    优势:完全能够满足任意动画要求,其实算是最好解决Activity半透明方案了。
    劣势:PopWindow内部不能做一些依赖性比较高的网络请求,如果我们要在这个界面请求数据或者一直监听外面Activity的数据,那么PopWindow做不到。
  2. 将该界面做成一个Dialog形式
    优势:和PopWindow一样,能够完成任意动画要求
    劣势:适配有问题,非常依赖外部Activty,如果我们切入到后台,把屏幕在全面屏和有虚拟键盘的屏来回切,那么再回到该界面中,Dialog可能会出现适配问题,而且为了这么一个Dialog去读 小米、华为的全面屏适配文档,很伤。(测试们很喜欢这么玩的)
  3. 将该界面做成一个Activity
    优势:可以完全解决上述两种情况劣势带来的问题,Activity在功能上比PopWindow和Dialog更多元更强大
    劣势:动画要自己琢磨,进场动画如果不处理的话会很僵硬。

综上所述,我使用第三种方案来做这个界面。

第一步:设置Activity的入场、出场动画(我们用View动画来做):

//进场动画  anim/bottom_in
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

</set>
//出场动画 anim/bottom_out
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromYDelta="25"
        android:toYDelta="100%p" />
</set>

然后在代码中布置好动画:

      Intent intent = new Intent(BeforeActivity.this, AfterActivity.class);
      startActivity(intent);
      overridePendingTransition(R.anim.bottom_in,R.anim.bottom_silent);

第二步:写activity的manifest配置:

//我们要将其设置为可以透明显示的
 <activity
            android:name=".XXXActivity"
            android:theme="@style/XXXTheme">
            <meta-data
                android:name="android.max_aspect"
                android:value="ratio_float" />
</activity>

   <style name="XXXTheme" parent="Theme.AppCompat">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowAnimationStyle">@null</item>
    </style>

第三步,在Activity的代码中设置状态栏透明:

//XXXActivity
    @Override
    protected void onCreateView(Bundle savedInstanceState) {
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_song_detail);
        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }

第四步:设置Activity的布局XML文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".song.mvp.view.SongDetailActivity">

    //View用来铺整个View,因为我们的RelativeLayout会用到background,这样的话如果有圆角,会出现很僵硬的白色
    //我们也是根据这个view来做透明
    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#636363"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

      
        <View
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/rl_bottom" />

        <RelativeLayout
            android:id="@+id/rl_bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
             android:background="#ffffff"
            android:layout_alignParentBottom="true">
            ....
        </RelativeLayout>
    </RelativeLayout>
</FrameLayout>

其实到这里已经差不多,但是Activity的出现会带一块黑黑的屏(就是我们透明view)进来,效果不太好
所以我们要让一开始这个view是透明的,在动画完成后该view变成半透明的

通过写alpha动画:

//view的透明变半透明动画
//view_to_translate
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="200"
        android:fromAlpha="0"
        android:toAlpha="0.7"/>
</set>

然后在Activity onStart的时候执行这个动画:

//设置延迟开始的时间还蛮关键的,能决定动画是否平滑
    @Override
    protected void onStart() {
        super.onStart();
         if (toTranslateIn == null) {
            toTranslateIn = AnimationUtils.loadAnimation(this, R.anim.view_to_translate_in);
            toTranslateIn.setFillAfter(true);
            toTranslateIn.setStartOffset(200);
        }
        findViewById(R.id.view).startAnimation(toTranslateIn);
    }

效果如下:
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值