Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果)

根据需求实现类似QQ侧滑效果,之前看到过很多实现方式通过SlidingMenu,但是既然官方推出了自己的专属控件,那么使用DrawerLayout就是不二选择。且看下文。

一、先来看看官方文档解释

DrawerLayout充当窗口内容的顶层容器,允许交互式“抽屉”的观点,以从窗口的边缘拉出。抽屉的定位和布局是使用控制机器人:layout_gravity 属性对应到您想要的抽屉,从出现的观点哪边儿的观点:左或右。(或者在启动支持布局方向平台版本/结束)。要使用DrawerLayout,定位你的主要内容视图的第一个孩子,宽度和高度match_parent。添加抽屉为孩子意见的主要内容视图后,设置layout_gravity适当。抽屉通常使用match_parent的高度与宽度固定。DrawerLayout.DrawerListener可以用来监测抽屉意见的状态和运动。避免进行昂贵的操作,如动画,因为它可能会导致口吃过程中的布局; 尝试在执行昂贵的操作STATE_IDLE状态。DrawerLayout.SimpleDrawerListener提供每个回调方法的默认/无操作实现。

二、再来看看继承关系

Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果)_第1张图片
这里写图片描述

三、效果图(真实图和效果图)
Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果)_第2张图片
QQ6.6版本侧滑截图

说明: 此图来自网络。
Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果)_第3张图片
实现的效果截图

说明: 此图是实现的效果截图,在模拟器上运行的,建议换作真机看效果,状态栏的渐变更明显。
模拟器运行gif效果图

说明: 此图是模拟器运行的完整效果图,建议使用真机看效果。涉及的知识点:状态栏的设置,渐变效果;属性动画;TabLayout使用;最主要的DrawerLayout的使用。

下面就来看代码片段

主页面的布局




    

        

            

            

            
        

        
            
            
            
        
        

        
    

    



说明: 在这里可以看到,最外层布局是DrawerLayout,里面嵌套了两层布局,一层是RelativeLayout,一层是include进来的draw_menu_layout,这里需要说明一下,drawerlayout的子布局第一层是主页面的内容,第二层是侧滑的内容,所以才有上面的布局。当然也可以有第三层布局,作为第二层的子布局使用。

左侧布局内容




    

    

        

            

            
        

        

            

            
        
    


说明: 这里就是一个不同的布局了,和平时写法没啥区别。需要注意的是使用FrameLayout的原因。

下面就来看看我们的主页代码:

package com.example.mjj.drawerlayoutqq;

import android.animation.ObjectAnimator;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 仿QQ6.6.0版本侧滑效果
 * 

* DrawerLayout内容偏移,背景动画,主页面导航图标渐变,状态栏渐变色. *

* Created by Mjj on 2016/12/7. */ public class MainActivity extends AppCompatActivity { private SystemBarTintManager tintManager; private DrawerLayout mDrawerLayout; private ImageView ivNavigation; private ImageView ivDrawerBg; // 侧边有动画效果的背景图片 private TextView tvCenter, tvRight; private int[] tabIcons = {R.drawable.ngq, R.drawable.nti, R.drawable.nbb}; private TabLayout tabLayout; private ViewPager viewPager; private ListView listView; private String strings[] = {"开通会员", "QQ钱包", "个性装扮", "我的收藏", "我的相册", "我的文件", "我的日程", "我的名片夹"}; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { setTranslucentStatus(true); tintManager = new SystemBarTintManager(this); tintManager.setStatusBarTintEnabled(true); tintManager.setStatusBarTintColor(Color.parseColor("#14B6F6")); } setContentView(R.layout.activity_main); initView(); } private void initView() { ivNavigation = (ImageView) findViewById(R.id.iv_navigation_icon); mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawer_layout); // 设置侧滑背景图片的动画 ivDrawerBg = (ImageView) findViewById(R.id.iv_drawer_bg); float curTranslationY = ivDrawerBg.getTranslationY(); ObjectAnimator animator = ObjectAnimator.ofFloat(ivDrawerBg, "translationY", curTranslationY, -70f, 60, curTranslationY); animator.setDuration(5000); animator.setRepeatCount(ObjectAnimator.INFINITE); animator.start(); tvCenter = (TextView) findViewById(R.id.tv_center); tvRight = (TextView) findViewById(R.id.tv_right); tabLayout = (TabLayout) findViewById(R.id.tab_main_bottom); viewPager = (ViewPager) findViewById(R.id.vp_main_contents); // 同时添加图标和文字需要自定义view,此种方式无效,和适配器关联的时候,就被隐藏掉了. // tabLayout.addTab(tabLayout.newTab().setIcon(tabIcons[0])); // tabLayout.addTab(tabLayout.newTab().setIcon(tabIcons[1])); // tabLayout.addTab(tabLayout.newTab().setIcon(tabIcons[2])); MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), tabIcons, this); viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); //设置监听 ivNavigation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { toggle(); } }); listView = (ListView) mDrawerLayout.findViewById(R.id.id_draw_menu_item_list_select); listView.setAdapter(new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, strings)); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { Toast.makeText(MainActivity.this, strings[i], Toast.LENGTH_SHORT).show(); } }); mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { /** * @param drawerView * @param slideOffset 偏移(0-1) */ @Override public void onDrawerSlide(View drawerView, float slideOffset) { // 导航图标渐变效果 ivNavigation.setAlpha(1 - slideOffset); // 判断是否左菜单并设置移动(如果不这样设置,则主页面的内容不会向右移动) if (drawerView.getTag().equals("left")) { View content = mDrawerLayout.getChildAt(0); int offset = (int) (drawerView.getWidth() * slideOffset); content.setTranslationX(offset); // 缩放效果(之前QQ效果) // content.setTranslationX(1 - slideOffset * 0.5f); // content.setTranslationY(1 - slideOffset * 0.5f); } tintManager.setStatusBarAlpha(1 - slideOffset); } @Override public void onDrawerOpened(View drawerView) { } @Override public void onDrawerClosed(View drawerView) { } /** * 当抽屉滑动状态改变的时候被调用 * 状态值是STATE_IDLE(闲置-0),STATE_DRAGGING(拖拽-1),STATE_SETTLING(固定-2)中之一。 * 抽屉打开的时候,点击抽屉,drawer的状态就会变成STATE_DRAGGING,然后变成STATE_IDLE. * * @param newState */ @Override public void onDrawerStateChanged(int newState) { } }); } // 设置状态栏透明状态 private void setTranslucentStatus(boolean on) { Window win = getWindow(); WindowManager.LayoutParams winParams = win.getAttributes(); final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; if (on) { winParams.flags |= bits; } else { winParams.flags &= ~bits; } win.setAttributes(winParams); } /** * 自定义NavigationIcon设置关联DrawerLayout */ private void toggle() { int drawerLockMode = mDrawerLayout.getDrawerLockMode(GravityCompat.START); if (mDrawerLayout.isDrawerVisible(GravityCompat.START) && (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_OPEN)) { mDrawerLayout.closeDrawer(GravityCompat.START); } else if (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_CLOSED) { mDrawerLayout.openDrawer(GravityCompat.START); } } }

说明: 就是最核心的代码了,关于每个部分的功能都有注释,就不多说了。完整代码已上传至github,关注“code小生”查看链接地址。

建议:关于TabLayout使用不是很清楚的可以看看《TabLayout两种添加tab方式,结合ViewPager+Fragment实现常见界面视图》、《Android App之底部tab导航常用实现方案总结》关于本文想更近一步阅读,请看《Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果》

你可能感兴趣的:(Android之高仿QQ6.6.0侧滑效果(背景动画、透明+沉浸式状态栏、渐变效果))