Android群英传读书笔记——第十二章:Android 5.X新特性详解

第十二章目录

  • 12.1 Android5.X UI设计初步 
    • 12.1.1 材料的形态模拟
    • 12.1.2 更加真实的动画
    • 12.1.3 大色块的使用
  • 12.2 Material Design主题
  • 12.3 Palette
  • 12.4 视图与阴影
  • 12.5 Tinting和Clipping 
    • 12.5.1 Tinting(着色)
    • 12.5.2 Clipping(裁剪)
  • 12.6 列表与卡片 
    • 12.6.1 RecyclerView
    • 12.6.2 CardView
  • 12.7 Android过渡动画
  • 12.8 Material Design动画效果 
    • 12.8.1 Ripple效果
    • 12.8.2 Circular Reveal
    • 12.8.3 View state changes Animation
  • 12.9 Toolbar
  • 12.10 Notification 
    • 12.10.1 基本的Notification
    • 12.10.2 折叠式Notification
    • 12.10.3 悬挂式Notification
    • 12.10.4 显示等级的Notification

第十二章读书笔记

Android 9.0都出了半年多了,我还在学习Android 5.0的知识,真是醉了,加油吧!

2014年,发布Android5.X,全新设计的UI和更加优化的性能

Android 5.X UI设计初步

Android 5.X 新特性分析

12.1 Android 5.X UI设计初步

  • Android 5.X开始使用新的设计风格Material Design,翻译就是“材料设计”,不知道对不对

12.1.1 材料的形态模拟

  • Google通过模拟自然界的形态变化、关线与阴影、纸与纸之间的空间层级关系,带来一种真实的空间感
  • 那种按钮都会是有阴影效果的,就是感觉很新潮

12.1.2 更加真实的动画

  • 好的动画效果可以更好的引导用户,给用户非常愉悦的体验

12.1.3 大色块的使用

  • Material Design中采用大量高饱和、适中亮度的大色块来突出界面的主次
  • Google的Design网站上,有整个Material Design的设计,网址:http://www.google.com/design/#resources

12.2 Material Design 主题

Material Design提供默认的三种主题

@android:style/Theme.Material (dark version)        
@android:style/Theme.Material.Light (light version)     
@android:style/Theme.Material.Light.DarkActionBar

同时也提出了Color Palette的概念,可以自己设定系统区域的颜色

可以通过使用自定义Style来创建自己的Color Palette颜色主题

<resources>
    <!-- inherit from the material theme-->
    <style name="AppTheme" parent="android:Theme.Material">
        <!-- Main theme color-->
        <!-- your app branding color for the app bar-->
        <item name="colorPrimary">#BEBEBE</item>
        <!-- derker variant for thr status bar and contextual app bars-->
        <item name="colorPrimaryDark">#FF5AEBFF</item>
        <!--theme ui controls like checkBoxs and text fields-->
        <item name="colorAccent">#FFFF4130</item>
    </style>
</resources>

12.3 Palette

Android5.X使用Palette来提取颜色,从而让主题能够动态适应当前页面的色调

Android内置了几种提取颜色的种类:

  • Vibrant(充满活力的)
  • Vibrant dark(充满活力的黑)
  • Vibrant light(充满活力的白)
  • Muted(柔和的)
  • Muted dark(柔和的黑)
  • Muted light(柔和的白)

使用Palette需要在Dependencies中添加依赖:

compile 'com.android.support:palette-v7:21.0.2'

这可以给Palette传进一个Bitmap对象,并调用它的Palette.generate()静态方法或者Palette.generateAsync()方法创建一个Palette

下面例子演示如何通过加载图片的柔和色调来改变状态栏和Actionbar的色调:

public class PaletteActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.palette);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.test);
        // 创建Palette对象
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                // 通过Palette来获取对应的色调
                Palette.Swatch vibrant =
                        palette.getDarkVibrantSwatch();
                // 将颜色设置给相应的组件
                getSupportActionBar().setBackgroundDrawable(
                        new ColorDrawable(vibrant.getRgb()));
                Window window = getWindow();
                window.setStatusBarColor(vibrant.getRgb());
            }
        });
    }
}

12.4 视图与阴影

  • Material Design最重要的特点就是拟物扁平化

12.4.1 阴影效果

Android 5.X在以往的X、Y属性上添加了—Z,对应垂直方向上的变化

  • elevation是静态的成员,在xml中直接设置
  • translationZ可以在代码中使用来实现动画效果
Z = elevation + translationZ;
  • 在xml中设置
android:elevation="XXdp"
  • 在代码中设置
view.setTranslationZ(xxx);
  • 通常还可以和属性动画一起使用
if(flag){
    view.animate().translationZ(100);
    flag = false;
}else {
    view.animate().translationZ(0);
    flag = true;
}

12.5 Tinting和Clipping

12.5.1 Tinting(着色)

  • 使用非常简单,XML文件中配置好tint和tintMode就可以了,至于代码的效果大家自己实际操作一下就好了

12.5.2 Clipping(裁剪)

  • Clipping可以让我们改变一个视图的外形
  • 首先需要使用ViewOutlineProvider来修改outline,然后再通过setOutlinProvider将outline作用给视图
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View v1 = findViewById(R.id.tv_rect);
        View v2 = findViewById(R.id.tv_circle);
        //获取Outline
        ViewOutlineProvider viewOutlineProvider1 = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                //修改outline为特定形状
                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 30);
            }
        };
        //获取Outline
        ViewOutlineProvider viewOutlineProvider2 = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                //修改outline为特定形状
                outline.setOval(0, 0, view.getWidth(), view.getHeight());
            }
        };
        //重新设置形状
        v1.setOutlineProvider(viewOutlineProvider1);
        v2.setOutlineProvider(viewOutlineProvider2);
    }
}

12.6 列表与卡片

12.6.1 RecyclerView

  • 这个在项目中已经用烂了,也没啥要说的了,而且这本书讲这块讲的不多
  • 例子中点击事件加了一个增加高度的动画效果
  • 点击事件必须自己定义回调接口:
public OnItemClickListener mOnItemClickListener;

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
    mOnItemClickListener = onItemClickListener;
}

public interface OnItemClickListener {
    void onItemClick(View view, int position);
}

12.6.2 CardView

  • 这个没啥说的,就是多了圆角,阴影等等一些属性

12.7 Activity过渡动画

在Activity之间的跳转中,通过overridePendingtransition(int inId,int outId)这个方法给Activity添加一些切换动画,效果也是差强人意

Android5.X提供了三种Transition类型的动画:

  • 进入:一个进入的过渡动画决定Activity中的所有视图怎么进入屏幕
  • 退出:一个退出的过渡动画决定Activity中的所有视图怎么退出屏幕
  • 共享元素:一个共享元素过渡动画决定两个Activity之间的过渡,怎么共享他们的视图

其中,进人和退出效果包括:

  • explode(分解)一一从屏幕中间进或出,移动视图
  • slide(滑动)——从屏幕边缘进或出,移动视图
  • fade(淡出) 一一通过改变屏幕上视图的不透明度达到添加或者移除视图

共享元素包括(简单的说ActivityA的指定的View不会消失,带着View跳转到ActivityB中):

  • changeBounds——改变目标视图的布局边界
  • changeClipBounds——裁剪目标视图边界
  • changeTransfrom——改变目标视图的缩放比例和旋转角度
  • changeImageTransfrom——改变目标图片的大小和缩放比例

这里比如ActivityA跳转到ActivityB,运用这三种过渡动画

// 在ActivityA中修改:
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

// 而在ActivityB,只需要设置以下代码:
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// 或者在ActivityB的样式文件设置如下代码:
<item name="android:windowContentTransitions">true</item>

// 那么接下来可以设置进入ActivityB的动画效果:
getWindow().setEnterTransition(new Explode());
getWindow().setEnterTransition(new Slide());
getWindow().setEnterTransition(new Fade());

// 或者是设置离开ActivityB的动画效果:
getWindow().setExitTransition(new Explode());
getWindow().setExitTransition(new Slide());
getWindow().setExitTransition(new Fade());

下面是共享元素的使用

// 首先在ActivityA中设置共享元素的属性:
android:transitionName="XXX"

// 同时在ActivityB中设置相同的共享元素的属性:
android:transitionName="XXX"

// 在代码中使用共享元素,首先是单个共享元素:
startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this,view,"share").toBundle());

// 或者一个视图中有多个共享元素,通过Pair.create()来创建多个共享元素:
startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this,
    Pair.create(view,"share"),Pair.create(fab,"fab")).toBundle());

一整个过渡动画的例子

 布局就不贴了,ActivityA:

public class TransitionsA extends Activity {

    private Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
    }

    // 设置不同动画效果
    public void explode(View view) {
        intent = new Intent(this, TransitionsB.class);
        intent.putExtra("flag", 0);
        startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    }
    // 设置不同动画效果
    public void slide(View view) {
        intent = new Intent(this, TransitionsB.class);
        intent.putExtra("flag", 1);
        startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    }
    // 设置不同动画效果
    public void fade(View view) {
        intent = new Intent(this, TransitionsB.class);
        intent.putExtra("flag", 2);
        startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    }
    // 设置不同动画效果
    public void share(View view) {
        View fab = findViewById(R.id.fab_button);
        intent = new Intent(this, TransitionsB.class);
        intent.putExtra("flag", 3);
        // 创建单个共享元素
//        startActivity(intent,
//                ActivityOptions.makeSceneTransitionAnimation(
//                        this, view, "share").toBundle());
        startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this,
                        // 创建多个共享元素
                        Pair.create(view, "share"),
                        Pair.create(fab, "fab")).toBundle());
    }
}

ActivityB:

public class TransitionsB extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        int flag = getIntent().getExtras().getInt("flag");
        // 设置不同的动画效果
        switch (flag) {
            case 0:
                getWindow().setEnterTransition(new Explode());
                break;
            case 1:
                getWindow().setEnterTransition(new Slide());
                break;
            case 2:
                getWindow().setEnterTransition(new Fade());
                getWindow().setExitTransition(new Fade());
                break;
            case 3:
                break;
        }
        setContentView(R.layout.activity_transition_to);
    }
}

12.8 Material Design 动画效果

  • Android 5.X的UI设计更是使用了大量的动画效果

12.8.1 Ripple效果

  • 顾名思义,水波纹效果
// 水波纹有边界
android:background="?android:attr/selectableItemBackground"

// 水波纹无边界
android:background="?android:attr/selectableItemBackgroundBorderless"
  • 同样的,也可以通过XML来声明一个ripple,然后在布局文件中使用
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorPrimary">
    <item>
        <shape android:shape="oval">
            <solid android:color="?android:colorAccent" />
        </shape>
    </item>
</ripple>

12.8.2 Circular Reveal

  • 意为“循环揭示”,这个动画效果具体变现为一个View以圆形的形式展开,揭示出来,通过ViewAnimationUtils.createCircularReveal()来创建动画,代码如下:
public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, 
    float endRadius) {
    return new RevealAnimator(view,centerX,centerY,startRadius,endRadius);
}

RevealAnimator的使用特别简单,主要就是几个关键的坐标点:

  • centerX 动画开始的中心点X
  • centerY 动画开始的中心点Y
  • startRadius 动画开始半径
  • endRadius 动画结束半径

接下来我们来看一下例子,了解下RevealAnimator的使用,首先用XML创建一个圆和方形:

public class CircularReveal extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circular_reveal);

        final View oval = findViewById(R.id.oval);
        oval.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animator animator = ViewAnimationUtils.createCircularReveal(oval,
                        oval.getWidth() / 2, oval.getHeight() / 2, oval.getWidth(), 0);
                animator.setInterpolator(new AccelerateDecelerateInterpolator());
                animator.setDuration(2000);
                animator.start();
            }
        });

        final View rect = findViewById(R.id.rect);
        rect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animator animator = ViewAnimationUtils.createCircularReveal(rect, 0, 0, 0,
                        (float) Math.hypot(rect.getWidth(), rect.getHeight()));
                animator.setInterpolator(new AccelerateInterpolator());
                animator.setDuration(2000);
                animator.start();
            }
        });
    }
}

12.8.3 View state changes Animation

  • 意为“视图状态改变动画”

StateListAnimator

视图动画效果,以前Selector用来修改背景达到点击的变化,现在Selector支持动画,在XML定义一个StateListAnimator,添加到Selector中:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:property="rotationX" 
        android:duration="@android:integer/config_shortAnimTime" 
        android:valueTo="360" 
        android:valuyeType="floatType" />
        </set>
    </item>
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:property="rotationX"
        android:duration="@android:integer/config_shortAnimTime" 
        android:valueTo="0" 
        android:valuyeType="floatType" />
        </set>
    </item>
</selector>

在布局中直接使用:

<Button
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="@drawable/anim_change" />

Animator是要开启的,所以必须在主代码中使用AnimatorInflater.loadStateListAnimator()方法,并且通过View.setStateListAnimator()方法分配到视图中

animated-selector

同样是一个状态改变的Selector,使用这个动画效果需要准备一套图片,然后类似帧动画一样,一张一张的播

<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/state_on"
        android:state_checked="true">
        <bitmap android:src="@drawable/ic_done_anim_030" />
    </item>
    <item android:id="@+id/state_off">
        <bitmap android:src="@drawable/ic_plus_anim_030" />
    </item>
    <transition
        android:fromId="@+id/state_on"
        android:toId="@+id/state_off">
        <animation-list>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_000" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_plus_anim_001" />
            </item>
            ...一直到30
        </animation-list>
    </transition>
    <transition
        android:fromId="@+id/state_off"
        android:toId="@+id/state_on">
        <animation-list>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_000" />
            </item>
            <item android:duration="16">
                <bitmap android:src="@drawable/ic_done_anim_001" />
            </item>
            ...一直到30
        </animation-list>
    </transition>
</animated-selector>

程序中直接使用

public class AnimatedSelectorActivity extends AppCompatActivity {

    private boolean mIsCheck;
    private static final int[] STATE_CHECKED = new int[]{
            android.R.attr.state_checked};
    private static final int[] STATE_UNCHECKED = new int[]{};
    private ImageView mImageView;
    private Drawable mDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animated_selector);
        mImageView = (ImageView) findViewById(R.id.image);
        mDrawable = getResources().getDrawable(R.drawable.fab_anim);
        mImageView.setImageDrawable(mDrawable);
    }

    public void anim(View view) {
        if (mIsCheck) {
            mImageView.setImageState(STATE_UNCHECKED, true);
            mIsCheck = false;
        } else {
            mImageView.setImageState(STATE_CHECKED, true);
            mIsCheck = true;
        }
    }
}

12.9 Toolbar

Toolbar与ActionBar最大的区别就是Toolbar更加自由、可控,这也是Google逐渐使用Toolbar替代Actionbar的原因,使用Toolbar必须引入appcompat-v7包,并设置主题为NoActionBar,使用以下代码进行设置:

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- toolbar颜色-->
        <item name="colorPrimary">@color/colorPrimary</item>
        <!-- 状态栏颜色-->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <!-- 窗口的背景颜色-->
        <item name="android:windowBackground">@android:color/white</item>
        <!-- add SearchView-->
        <item name="android:searchViewStyle">@style/MySearchView</item>
    </style>

    <style name="MySearchView" parent="Widget.AppCompat.SearchView" />
</resources>

记得先将主题设置为NoActionBar主题,在布局中声明ToolBar

<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize" />

在Menu文件夹中创建一个Menu的XML文件

<menu 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"
    tools:context=".MainActivity" >

    <item
        android:id="@+id/ab_search"
        android:orderInCategory="80"
        android:title="action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_share"
        android:orderInCategory="90"
        android:title="action_share"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="action_settings"
        app:showAsAction="never"/>

</menu>

在代码中使用

public class ToolbarActivity extends AppCompatActivity {

    private ShareActionProvider mShareActionProvider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toolbar);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setLogo(R.mipmap.ic_launcher);
        toolbar.setTitle("主标题");
        toolbar.setSubtitle("副标题");
        setSupportActionBar(toolbar);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }
}

修改布局实现侧滑

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.handsome.qunyingzhuang.chapter_12.Anli02.ToolbarActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- 内容界面 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/holo_blue_light"
            android:orientation="vertical">

            <Button
                android:layout_width="100dp"
                android:layout_height="match_parent"
                android:text="内容界面" />
        </LinearLayout>

        <!-- 侧滑菜单内容 必须指定其水平重力 -->
        <LinearLayout
            android:id="@+id/drawer_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:orientation="vertical">

            <Button
                android:layout_width="200dp"
                android:layout_height="match_parent"
                android:text="菜单界面" />
        </LinearLayout>
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>

代码中实现

public class ToolbarActivity extends AppCompatActivity {

    private ShareActionProvider mShareActionProvider;
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toolbar);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setLogo(R.mipmap.ic_launcher);
        toolbar.setTitle("主标题");
        toolbar.setSubtitle("副标题");
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        mDrawerToggle = new ActionBarDrawerToggle(
                this, mDrawerLayout, toolbar,
                R.string.abc_action_bar_home_description,
                R.string.abc_action_bar_home_description_format);
        mDrawerToggle.syncState();
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        /* ShareActionProvider配置 */
        mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menu
                .findItem(R.id.action_share));
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/*");
        mShareActionProvider.setShareIntent(intent);
        return super.onCreateOptionsMenu(menu);
    }
}

现在很多APP,微信、支付宝等头部都有很多的按钮,不知道是不是ToolBar实现的,但是都是类似的功能吧,看看需求是如何了,也有的项目是自己写一个常用的自定义控件TopBar

12.10 Notification

很明显,“通知”的意思

Android 5.X对Notification做了优化:

  • 长按Notification可以显示消息来源
  • 锁屏状态下,可以看到Notification的通知

12.10.1 基本的Notification

public class Notification01 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification01);
        //第一步:初始化
        Notification.Builder builder = new Notification.Builder(this);
        //第二步:构建点击之后的意图
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));
        //构造pendingdintent
        PendingIntent pendingIntent = PendingIntent.getActivities(this, 0, new Intent[]{intent}, 0);
        //第三步:设置通知栏的各种消息
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        builder.setContentText("Title");
        builder.setContentText("内容");
        builder.setSubText("text");
        //第四步:通过NotificationManager来发出
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(0, builder.build());
    }
}

12.10.2 折叠式Notification

public class Notification02 extends AppCompatActivity {

    private static final int NOTIFICATION_ID_COLLAPSE = 0x01;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification02);
        Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.sina.com"));
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
        // 通过RemoteViews来创建自定义的Notification视图
        RemoteViews contentView = newRemoteViews(getPackageName(),R.layout.notification);
        contentView.setTextViewText(R.id.textView,"show me when collapsed");
        Notification notification = builder.build();

        notification.contentView = contentView;
        // 通过RemoteViews来创建自定义的Notification视图
        RemoteViews expandedView =new RemoteViews(getPackageName(),R.layout.notification_expanded);
        notification.bigContentView = expandedView;

        NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        nm.notify(NOTIFICATION_ID_COLLAPSE, notification);
    }
}

12.10.3 悬挂式 Notification

  • 比如说微信在后台来新消息了
public class Notification03 extends AppCompatActivity {

    private static final int NOTIFICATION_ID_HEADSUP = 0x01;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification03);
        Notification.Builder builder = new Notification.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(Notification.PRIORITY_DEFAULT)
                .setCategory(Notification.CATEGORY_MESSAGE)
                .setContentTitle("Headsup Notification")
                .setContentText("I am a Headsup notification.");

        Intent push = new Intent();
        push.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        push.setClass(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, push, PendingIntent.FLAG_CANCEL_CURRENT);
        builder.setContentText("Heads-Up Notification on Android 5.0")
                .setFullScreenIntent(pendingIntent, true);

        NotificationManager nm = (NotificationManager)
                getSystemService(NOTIFICATION_SERVICE);
        nm.notify(NOTIFICATION_ID_HEADSUP, builder.build());
    }
}

12.10.4 显示等级的Notification

Notification分为三个等级:

  • VISIBILITY_PRIVATE:表明只有当没有锁屏的时候会显示
  • VISIBILITY_PUBLIC:表明在任何情况下都会显示
  • VISIBILITY_SECRET:表明在pin、password等安全锁和没有锁屏的情况下显示
// 设置Notification的等级非常简单,只需在案例三四五增加一句:
builder.setVisibility(Notification.VISIBILITY_PUBLIC);

// 同时,在Android 5.X改动挺多的,比如如下两种:

// 设置Notification背景颜色
builder.setColor(Color.RED);

//设置Notification的category接口,用来确定Notification的显示位置
builder.setCategory(Notification.CATEGORY_MESSAGE);

总结

其实这一章虽然内容多,但是都是一些比较简单的内容,看一看就应该差不多会了,即使忘了,再看一下就都能会用,想想现在Android 9.0都出了半年了,我还在学习Andorid 5.0的知识,这种感觉真是,不过不论何时,学习都不晚,加油吧!那么让我们在越来越多的实战中去巩固这些知识吧!

猜你喜欢

转载自blog.csdn.net/pengbo6665631/article/details/82461427