您的位置:首页 > 移动开发 > Android开发

android 5.0+6.0新特性

2017-02-26 20:39 423 查看


5.android5.0介绍

1.十大新特性

(1). 全新Material Design设计风格

* 新的视觉语言,在基本元素的处理上,借鉴了传统的印刷设计,字体版式、网格系统、空间、比例、配色、图像使用等这些基础 的平面设计规范

(2). 支持多种设备

(3). 全新的通知中心设计

(4). 支持64位ART虚拟机

* 谷歌承诺所有性能都会比原来提升一倍,Android Lollipop支持更大的寄存器,支持新的指令集,提升了内存寻址空间,未来Android智能手机将支持4GB以上的内存。

(5). Project Volta电池续航改进计划

(6). 全新的“最近应用程序”

(7). 改进安全性

(8). 不同数据独立保存

(9). 改进搜索

(10). `新的API支持`,蓝牙4.1、USB Audio、多人分享等其它特性

2.Material Design

设计语言,设计标准,设计规范

(1)官网:http://www.google.com/design/spec/material-design/introduction.html

(2)中文翻译1:http://www.mobileui.cn/material-design/

(3)中文翻译2:http://design.1sters.com/#b


6.感受5.0新特性


7.默认的3个主题,修改主题

1.详情见------主题样式.html

2.



3.

android:colorPrimaryDark
应用的主要暗色调,statusBarColor默认使用该颜色
android:statusBarColor
状态栏颜色,默认使用colorPrimaryDark
android:colorPrimary
应用的主要色调,actionBar默认使用该颜色
android:windowBackground
窗口背景颜色
android:navigationBarColor
底部栏颜色
android:colorForeground
应用的前景色,ListView的分割线,switch滑动区默认使用该颜色
android:colorBackground
应用的背景色,popMenu的背景默认使用该颜色
android:colorAccent
一般控件的选种效果默认采用该颜色
android:colorControlNormal
控件的默认色调 
android:colorControlHighlight
控件按压时的色调
android:colorControlActivated
控件选中时的颜色,默认使用colorAccent
android:colorButtonNormal
默认按钮的背景颜色
android:textColor
Button,textView的文字颜色
android:textColorPrimaryDisableOnly
RadioButton checkbox等控件的文字
android:textColorPrimary
应用的主要文字颜色,actionBar的标题文字默认使用该颜色

4. value21-style.xml

[html] view
plain copy

<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">

<!--应用的主要暗色调-->

<item name="android:colorPrimaryDark">#ff3367d6</item>

<!--actionBar默认使用该颜色-->

<item name="android:colorPrimary">#ff4285f4</item>

<!--窗口背景颜色,不能直接引用-->

<item name="android:windowBackground">@color/windowbg</item>

<!--底部栏颜色-->

<item name="android:navigationBarColor">#ff030303</item>

</style>


8.主题切换效果

1.color.xml

[html] view
plain copy

<resources>

<color name="windowbg">#ff303030</color>

<!--红色-->

<color name="red_colorPrimaryDark">#ffb0120a</color>

<color name="red_colorPrimary">#ffe51c23</color>

<color name="red_windowBackground">#fff36c60</color>

<color name="red_navigationBarColor">#ffd01716</color>

<!--粉色-->

<color name="pink_colorPrimaryDark">#ff880e4f</color>

<color name="pink_colorPrimary">#ffe91e63</color>

<color name="pink_windowBackground">#fff06292</color>

<color name="pink_navigationBarColor">#ffc2185b</color>

</resources>

2.value21--styles.xml

[html] view
plain copy

<!--红色主题-->

<style name="AppTheme_Red" parent="android:Theme.Material.Light.DarkActionBar">

<!--应用的主要暗色调-->

<item name="android:colorPrimaryDark">@color/red_colorPrimaryDark</item>

<!--actionBar默认使用该颜色-->

<item name="android:colorPrimary">@color/red_colorPrimary</item>

<!--窗口背景颜色-->

<item name="android:windowBackground">@color/red_windowBackground</item>

<!--底部栏颜色-->

<item name="android:navigationBarColor">@color/red_navigationBarColor</item>

</style>

<!--粉色主题-->

<style name="AppTheme_Pink" parent="android:Theme.Material.Light.DarkActionBar">

<!--应用的主要暗色调-->

<item name="android:colorPrimaryDark">@color/pink_colorPrimaryDark</item>

<!--actionBar默认使用该颜色-->

<item name="android:colorPrimary">@color/pink_colorPrimary</item>

<!--窗口背景颜色-->

<item name="android:windowBackground">@color/pink_windowBackground</item>

<!--底部栏颜色-->

<item name="android:navigationBarColor">@color/pink_navigationBarColor</item>

</style>

3.主题切换-MainActivity

[java] view
plain copy

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//获取主题ID,设置主题

int themeId = getIntent().getIntExtra("themeId", -1);

if (themeId != -1) {

setTheme(themeId);

}

setContentView(R.layout.activity_main);

}

//设置主题必须在setContentView之前使用,所以要重启自己

public void red(View v) {

//结束自己

finish();

//不用动画

overridePendingTransition(0, 0);//紧挨着finish方法或者对应的startActivity方法就可以

//重启自己

Intent intent = new Intent(MainActivity.this, MainActivity.class);

//告知需要切换的主题

intent.putExtra("themeId", R.style.AppTheme_Red);

startActivity(intent);

overridePendingTransition(0, 0);//紧挨着finish方法或者对应的startActivity方法就可以

}

public void pink(View v) {

finish();

overridePendingTransition(0, 0);//紧挨着finish方法或者对应的startActivity方法就可以

//重启自己

Intent intent = new Intent(MainActivity.this, MainActivity.class);

//告知需要切换的主题

intent.putExtra("themeId", R.style.AppTheme_Pink);

startActivity(intent);

overridePendingTransition(0, 0);//紧挨着finish方法或者对应的startActivity方法就可以

}

5.主题不仅可以对Application和Activity使用,也可以对某一个控件单使用,或者是在xml布局中给一个根节点控件设置android:theme属性,来修改它和它所有子控件的主题。

6.Material Design主题只有在API级别为21以上才可使用,在v7支持库中提供了部分控件的Material Design主题样式,如果想使应用在android的所有版本上都能统一风格,我们可以对控件效果做自定义或者使用一些第三方的兼容包。目前最有效的做法是针对21版本创建value-21资源目录,使用Material Design风格主题,在其他版本使用v7的Theme.AppCompat.Light风格主题。

7.项目中使用Material Design风格

1. 设置应用的 `targetSdkVersion` 和 `targetSdkVersion` 为21

2. 在values目录下的style资源文件中创建一个style,让其继承自 `android:Theme.Material`

3. 在AndroidManifest中指定应用的主题或者Activity的主题为我们设定的样式


9.toolBar的使用

1.toolBar

Toolbar是应用的内容的标准工具栏,`可以说是Actionbar的升级版`,两者不是独立关系,要使用Toolbar还是得跟ActionBar扯上关系的。相比Actionbar Toolbar最明显的一点就是变得很`自由,可随处放置`,因为它是作为一个`ViewGroup来定义使用的`,所以单纯使用ActionBar已经稍显过时了,它的一些方法已被标注过时。

2.引入v7,v4包,修改build.gradle,兼容2.2

(1)引入v7包,去除actionBar value

[html] view
plain copy

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

<!-- Customize your theme here. -->

</style>

(2)创建ToolBar的布局 include_toolbar.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.Toolbar

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="#ff0000">

</android.support.v7.widget.Toolbar>

(3)使用toolbar

a.布局中

[html] view
plain copy

<include layout="@layout/include_toolbar"></include>

b.代码

[java] view
plain copy

/**

* 1.需要继承我们的actionBarActivity

*/

public class MainActivity extends ActionBarActivity {

private Toolbar mToolbar;

private DrawerLayout mDrawerLayout;

private ActionBarDrawerToggle mToggle;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}

private void initView() {

mToolbar = (Toolbar) findViewById(R.id.main_toolbar);

//Set a Toolbar to act as the ActionBar for this Activity window.

setSupportActionBar(mToolbar);

}


10.drawerlayout和actionbardrawertoggle的集成

1.接上

2.布局

[html] view
plain copy

<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=".MainActivity">

<include

android:id="@+id/main_toolbar"

layout="@layout/include_toolbar"></include>

<android.support.v4.widget.DrawerLayout

android:id="@+id/main_drawerlayout"

android:layout_width="match_parent"

android:layout_height="match_parent"

>

<!--menu-->

<FrameLayout

android:layout_width="180dp"

android:layout_height="match_parent"

android:layout_gravity="left"

android:background="#00ff00"></FrameLayout>

<!--content-->

<FrameLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#ff7dffd6"></FrameLayout>

</android.support.v4.widget.DrawerLayout>

</LinearLayout>

3.MainActivity

[java] view
plain copy

/**

* 1.需要继承我们的actionBarActivity

*/

public class MainActivity extends ActionBarActivity {

private Toolbar mToolbar;

private DrawerLayout mDrawerLayout;

private ActionBarDrawerToggle mToggle;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

initDrawerLayout();

}

private void initDrawerLayout() {

mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R

.string.open, R.string.close);

//同步状态

mToggle.syncState();

//设置监听

mDrawerLayout.setDrawerListener(mToggle);

}

private void initView() {

mToolbar = (Toolbar) findViewById(R.id.main_toolbar);

//Set a Toolbar to act as the ActionBar for this Activity window.

setSupportActionBar(mToolbar);

mDrawerLayout = (DrawerLayout) findViewById(R.id.main_drawerlayout);

}


11.阴影和裁剪效果

1.布局

[html] view
plain copy

<RelativeLayout 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:background="#ffffff"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<!--红色-->

<View

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_margin="10dp"

android:background="#ff0000"

android:elevation="11dp"/>

<!--绿色-->

<View

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_marginLeft="60dp"

android:layout_marginTop="60dp"

android:background="#00ff00"

android:elevation="10dp"/>

<!--圆形的shape-->

<View

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_marginLeft="180dp"

android:layout_marginTop="180dp"

android:background="@drawable/shape_circle"

android:elevation="10dp"/>

<!--圆形的图片-->

<View

android:id="@+id/ivHead"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_marginLeft="180dp"

android:layout_marginTop="300dp"

android:background="@mipmap/head"

android:elevation="10dp"/>

</RelativeLayout>

2.在xml布局中,可以通过android:outlineProvider来指定轮廓的判定方式:

(1)none 即使设置了Z属性,也不会显示阴影

(2)background 会按照背景来设置阴影形状

(3)bounds 会按照View的大小来描绘阴影

(4)paddedBounds 和bounds类似,不过阴影会稍微向右偏移一点

3. 在代码中,我们可以通过setOutlineProvider来指定一个View的轮廓:

[html] view
plain copy

ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {

public void getOutline(View view, Outline outline) {

// 可以指定圆形,矩形,圆角矩形,path

outline.setOval(0, 0, view.getWidth(), view.getHeight());

}

};

View.setOutlineProvider(viewOutlineProvider );

4.注意:如果采用图片作为背景,即使在xml布局中指定android:outlineProvider为background也不会显示阴影,只有通过代码中指定轮廓来显示。

5.MainActivity

[java] view
plain copy

private View mIvHead;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mIvHead = (View) findViewById(R.id.ivHead);

//设置轮廓

mIvHead.setOutlineProvider(new ViewOutlineProvider() {

@Override

public void getOutline(View view, Outline outline) {

//设置view对应的轮廓

outline.setOval(0, 0, view.getWidth() - 20, view.getHeight() - 20);

}

});

mIvHead.setClipToOutline(true);

}


12.selector定义新方式

1.tint属性

tint属性一个颜色值,可以对图片做颜色渲染,我们可以给view的背景设置tint色值,给ImageView的图片设置tint色值,也可以给任意Drawable或者NinePatchDrawable设置tint色值。

在应用的主题中也可以通过设置 android:tint来给主题设置统一的颜色渲染。

tint的渲染模式有总共有16种,xml文件中可以使用6种,代码中我们可以设置16种,渲染模式决定了渲染颜色和原图颜色的取舍和合成规则:-----------两种图片合成的效果



PorterDuff.Mode.CLEAR
所绘制不会提交到画布上。
PorterDuff.Mode.SRC
显示上层绘制图片
PorterDuff.Mode.DST
显示下层绘制图片
PorterDuff.Mode.SRC_OVER
正常绘制显示,上下层绘制叠盖。
PorterDuff.Mode.DST_OVER
上下层都显示。下层居上显示。
PorterDuff.Mode.SRC_IN
取两层绘制交集。显示上层。
PorterDuff.Mode.DST_IN
取两层绘制交集。显示下层。
PorterDuff.Mode.SRC_OUT
取上层绘制非交集部分。
PorterDuff.Mode.DST_OUT
取下层绘制非交集部分。
PorterDuff.Mode.SRC_ATOP
取下层非交集部分与上层交集部分
PorterDuff.Mode.DST_ATOP
取上层非交集部分与下层交集部分
PorterDuff.Mode.XOR
取两层绘制非交集。两层绘制非交集。
PorterDuff.Mode.DARKEN
上下层都显示。变暗
PorterDuff.Mode.LIGHTEN
上下层都显示。变亮
PorterDuff.Mode.MULTIPLY
取两层绘制交集
PorterDuff.Mode.SCREEN
上下层都显示。

2.ic_launcher_f.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"

android:src="@mipmap/ic_launcher"

android:tint="#ff58ffd6"

android:tintMode="multiply"

>

<!--android:tint="#ff58ffd6" 合成颜色-->

<!--android:tintMode="multiply" 合成规则-->

</bitmap>

3.selector_bg.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/ic_launcher_f" android:state_pressed="true"></item>

<item android:drawable="@mipmap/ic_launcher"></item>

</selector>

4.activity_main.xml

[html] view
plain copy

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@drawable/selector_bg"

android:onClick="click"

android:text="@string/hello_world"

/>


13.Palette调色版功能

1.Android Material Design之Toolbar与Palette实践:http://blog.csdn.net/jdsjlzx/article/details/41441083

2.需要导入相关的包:v7和

3.

[java] view
plain copy

private void initView() {

mIv_muted = findViewById(R.id.iv_Muted);

mIv_muted_light = findViewById(R.id.iv_Muted_light);

mIv_vibrant = findViewById(R.id.iv_Vibrant);

}

public void click(View v) {

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.h17);

// 如果操作本来就属于后台线程,可以使用:

// Palette p = Palette.generate(bitmap);

// 如果在主线程中,我们可以使用异步的方式:

Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {

public void onGenerated(Palette palette) {

mIv_muted.setBackgroundColor(palette.getMutedColor(Color.BLACK));

mIv_muted_light.setBackgroundColor(palette.getLightMutedColor(Color.BLACK));

mIv_vibrant.setBackgroundColor(palette.getVibrantColor(Color.BLACK));

}

});

}

4.详情见图片和颜色.html

5.

Vibrant
鲜艳的
Vibrant
dark鲜艳的暗色
Vibrant
light鲜艳的亮色
Muted
柔和的
Muted
dark柔和的暗色
Muted
light柔和的亮色

6.对图片取色是一个比较消耗性能的操作,其内部会对图片的像素值进来遍历以分析对比,所以我们要在异步线程中去完成。

7.

p.getVibrantColor(int defaultColor);
p.getDarkVibrantColor(int defaultColor);
p.getLightVibrantColor(int defaultColor);
p.getMutedColor(int defaultColor);
p.getDarkMutedColor(int defaultColor);
p.getLightMutedColor(int defaultColor);



14.按钮的水波纹反馈

1.见全新的动画.html

(1)触摸反馈

(2)圆形展示

(3)曲线运动

(4)视图状态变化

(5)矢量图动画

(6)转场动画

(7)普通转场动画

(8)共享转场动画

(9)组合转场动画

2.布局

[html] view
plain copy

<Button

android:layout_width="150dp"

android:layout_height="150dp"

android:text="默认效果"/>

<Button

android:layout_width="150dp"

android:layout_height="150dp"

android:layout_marginTop="20dp"

android:background="?android:selectableItemBackground"

android:text="selectableItemBackground效果"/>

<Button

android:layout_width="150dp"

android:layout_height="150dp"

android:layout_marginTop="20dp"

android:background="?android:selectableItemBackgroundBorderless"

android:text="selectableItemBackgroundBorderless"/>

<Button

android:id="@+id/btn_cutstom_animation"

android:layout_width="150dp"

android:layout_height="150dp"

android:layout_marginTop="20dp"

android:background="#ff5cffbf"

android:text="selectableItemBackgroundBorderless"/>

3.

[java] view
plain copy

mCustomAnimation = (Button) findViewById(R.id.btn_cutstom_animation);

mCustomAnimation.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

/*

view 操作的视图

centerX 动画开始的中心点X

centerY 动画开始的中心点Y

startRadius 动画开始半径

startRadius 动画结束半径

*/

int centerX = mCustomAnimation.getWidth() / 2;

int centerY = mCustomAnimation.getHeight() / 2;

float startRadius = 0;

float endRadius = mCustomAnimation.getWidth();

Animator animator = ViewAnimationUtils.createCircularReveal(mCustomAnimation,

centerX,

centerY, startRadius, endRadius);

animator.setDuration(3000);

animator.start();

}

});


15.矢量图展示,矢量图动画

1.详情见全新的动画.html

2.矢量图展示

(1)布局

[html] view
plain copy

<View

android:layout_width="100dp"

android:layout_height="100dp"

android:background="@drawable/vector_xin"

></View>

(2)vector_xin.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<vector xmlns:android="http://schemas.android.com/apk/res/android"

android:width="600px"

android:height="600px"

android:viewportHeight="600"

android:viewportWidth="600"

>

<path

android:fillColor="#ff0000"

android:pathData="m272.36969,90.10716c14.5986,0 26.44617,-10.93784 26.44617,-24.43066c0,-13.50066 -11.84756,-24.44545 -26.44617,-24.44545c-14.61017,0 -26.46236,10.94479 -26.46236,24.44545c0,13.49283 11.84758,24.43066 26.46236,24.43066zm74.16827,105.36101l-23.73206,-81.31308c-0.22348,-0.73847 -0.53455,-1.44301 -0.9101,-2.09345c-2.69809,-7.61726 -10.43979,-13.13331 -19.58011,-13.13331l-60.06725,0c-9.53197,0 -17.53633,5.98904 -19.8911,14.11715c-0.16129,0.35566 -0.29031,0.73074 -0.41013,1.11668l-23.31035,81.30994c-1.55295,5.33005 1.87091,10.80814 7.65184,12.24348c5.77171,1.42679 11.6978,-1.73773 13.25305,-7.06851l18.30589,-63.87151l7.62418,0l-33.22247,115.56409l31.3055,0l0,79.7836c0,6.13647 5.38002,11.10779 12.0296,11.10779c6.63574,0 12.02499,-4.9675 12.02499,-11.10779l0,-79.7836l9.56192,0l0,79.7836c0,6.13647 5.38693,11.10779 12.03876,11.10779c6.63342,0 12.02264,-4.9675 12.02264,-11.10779l0,-79.7836l31.29181,0l-33.34705,-115.56409l7.82477,0l18.64224,63.87151c1.55295,5.33078 7.4837,8.4953 13.25308,7.06851c5.75784,-1.43535 9.18631,-6.91733 7.64032,-12.24742l0,0z"></path>

</vector>

(3)pathData 矢量图制作

http://editor.method.ac

3.矢量动画

(1)例子:http://blog.csdn.net/ljx19900116/article/details/41806875

(2)详情见 全新的动画.html

(3)

<vector>元素的矢量资源,在res/drawable/(文件夹)

<animated-vector>元素的矢量资源动画,在res/drawable/(文件夹)

< objectAnimator>元素的一个或多个对象动画器,在res/anim/(文件夹)

(4)布局

[html] view
plain copy

<!--矢量图动画-->

<View

android:id="@+id/triangle"

android:layout_width="50dp"

android:layout_height="50dp"

android:background="@drawable/animated_vector_triangle"

></View>

(5)drawable----vector_triangle.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<vector xmlns:android="http://schemas.android.com/apk/res/android"

android:width="64dp"

android:height="64dp"

android:viewportHeight="600"

android:viewportWidth="600"

>

<path

android:name="v"

android:fillColor="#000000"

android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z"/>

</vector>

(6)drawable---animated_vector_triangle.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<animated-vector

xmlns:android="http://schemas.android.com/apk/res/android"

android:drawable="@drawable/vector_triangle"

>

<target

android:name="v"

android:animation="@anim/path_morph"/>

<!--<target-->

<!--android:name="v" 指定名字.这个是后面需要-->

<!--android:animation="@anim/path_morph" 指定一个动画/>-->

</animated-vector>

(7)res/anim/path_morph.xml

[html] view
plain copy

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator

xmlns:android="http://schemas.android.com/apk/res/android"

android:duration="5000"

android:propertyName="pathData"

android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"

android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"

android:valueType="pathType">

</objectAnimator>

(8)

[java] view
plain copy

View triangle = findViewById(R.id.triangle);

Drawable drawable = triangle.getBackground();

if (drawable instanceof Animatable) {

((Animatable) drawable).start();

}


16.recycleView_列表和网格

1.单独的jar包:com.android.support:recyclerview-v7:22.2.1

2.


3.RecycleView---------------------详情见例子源码

(1)主布局

[html] view
plain copy

<RelativeLayout 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"

tools:context=".MainActivity">

<android.support.v7.widget.RecyclerView

android:id="@+id/recyclerView"

android:layout_width="match_parent"

android:layout_height="match_parent"

/>

</RelativeLayout>

(2)ListAdapter

[java] view
plain copy

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.MyHolder> {

private Context context;

private List<DataBean> datas;

public ListAdapter(Context context, List<DataBean> datas) {

this.context = context;

this.datas = datas;

}

@Override

public MyHolder onCreateViewHolder(ViewGroup viewGroup, int i) {//决定根布局

// TextView tv = new TextView(context);//根布局

View itemView = View.inflate(context, R.layout.item_list, null);

return new MyHolder(itemView);

}

@Override

public void onBindViewHolder(MyHolder myHolder, int position) {//填充数据

myHolder.setDataAndRefreshUI(datas.get(position));

}

@Override

public int getItemCount() {//条目总数

if (datas != null) {

return datas.size();

}

return 0;

}

public class MyHolder extends RecyclerView.ViewHolder {

//孩子对象

private TextView mTvName;

private ImageView mIvIcon;

public MyHolder(View itemView) {

super(itemView);

//初始化孩子对象

mTvName = (TextView) itemView.findViewById(R.id.tv_name);

mIvIcon = (ImageView) itemView.findViewById(R.id.iv_icon);

}

/**

* 设置itemView的数据展示

*

* @param dataBean

*/

public void setDataAndRefreshUI(DataBean dataBean) {

mTvName.setText(dataBean.text);

mIvIcon.setImageResource(dataBean.iconId);

}

}

}

(3)DataBean

[java] view
plain copy

public class DataBean {

public String text;

public int iconId;

}

(4)MainActivity

[java] view
plain copy

public class MainActivity extends Activity {

private RecyclerView mRecyclerView;

private List<DataBean> mDatas = new ArrayList<DataBean>();

private List<DataBean> mStraggerDatas = new ArrayList<DataBean>();

private int[] mListIcons = new int[]{R.mipmap.g1, R.mipmap.g2, R.mipmap.g3, R.mipmap.g4,

R.mipmap.g5, R.mipmap.g6, R.mipmap.g7, R.mipmap.g8, R.mipmap.g9, R.mipmap.g10, R

.mipmap.g11, R.mipmap.g12, R.mipmap.g13, R.mipmap.g14, R.mipmap.g15, R.mipmap

.g16, R.mipmap.g17, R.mipmap.g18, R.mipmap.g19, R.mipmap.g20, R.mipmap.g21, R

.mipmap.g22, R.mipmap.g23, R.mipmap.g24, R.mipmap.g25, R.mipmap.g26, R.mipmap

.g27, R.mipmap.g28, R.mipmap.g29};

private int[] mStraggeredIcons = new int[]{R.mipmap.p1, R.mipmap.p2, R.mipmap.p3, R

.mipmap.p4, R.mipmap.p5, R.mipmap.p6, R.mipmap.p7, R.mipmap.p8, R.mipmap.p9, R

.mipmap.p10, R.mipmap.p11, R.mipmap.p12, R.mipmap.p13, R.mipmap.p14, R.mipmap

.p15, R.mipmap.p16, R.mipmap.p17, R.mipmap.p18, R.mipmap.p19, R.mipmap.p20, R

.mipmap.p21, R.mipmap.p22, R.mipmap.p23, R.mipmap.p24, R.mipmap.p25, R.mipmap

.p26, R.mipmap.p27, R.mipmap.p28, R.mipmap.p29, R.mipmap.p30, R.mipmap.p31, R

.mipmap.p32, R.mipmap.p33, R.mipmap.p34, R.mipmap.p35, R.mipmap.p36, R.mipmap

.p37, R.mipmap.p38, R.mipmap.p39, R.mipmap.p40, R.mipmap.p41, R.mipmap.p42, R

.mipmap.p43, R.mipmap.p44};

private SwipeRefreshLayout mSwipeRefreshLayout;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//找到recyclerView

mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);

mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);

initData();

initListAdapterV();

}

private void initListAdapterV() {

//设置layoutManager

LinearLayoutManager layoutManger = new LinearLayoutManager(MainActivity.this);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initData() {

for (int i = 0; i < mListIcons.length; i++) {

int iconId = mListIcons[i];

DataBean dataBean = new DataBean();

dataBean.iconId = iconId;

dataBean.text = "我是item" + i;

mDatas.add(dataBean);

}

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

return super.onOptionsItemSelected(item);

}

}

(5)item_list.xml

[html] view
plain copy

<RelativeLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:paddingBottom="8dp">

<ImageView

android:id="@+id/iv_icon"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true"

android:layout_centerVertical="true"

android:layout_margin="10dp"

android:src="@mipmap/ic_launcher"/>

<TextView

android:id="@+id/tv_name"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_toRightOf="@+id/iv_icon"

android:text="Name"/>

</RelativeLayout>

4.在上基础上点击右上角菜单栏切换各种显示状态

(1)meau_main.xml

[html] view
plain copy

<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/action_list_v"

android:orderInCategory="100"

android:title="纵向的列表"

app:showAsAction="never"/>

<item

android:id="@+id/action_list_h"

android:orderInCategory="100"

android:title="横向的列表"

app:showAsAction="never"/>

<item

android:id="@+id/action_grid_v"

android:orderInCategory="100"

android:title="纵向的网格"

app:showAsAction="never"/>

<item

android:id="@+id/action_grid_h"

android:orderInCategory="100"

android:title="横向的网格"

app:showAsAction="never"/>

<item

android:id="@+id/action_stragger_v"

android:orderInCategory="100"

android:title="纵向的瀑布流"

app:showAsAction="never"/>

<item

android:id="@+id/action_stragger_h"

android:orderInCategory="100"

android:title="横向的瀑布流"

app:showAsAction="never"/>

</menu>

(2)菜单点击事件 MainActivity

[java] view
plain copy

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.action_list_v:

initListAdapterV();

break;

case R.id.action_list_h:

initListAdapterH();

break;

case R.id.action_grid_v:

initGridAdapterV();

break;

case R.id.action_grid_h:

initGridAdapterH();

break;

case R.id.action_stragger_v:

initStaggeredGridAdapterV();

break;

case R.id.action_stragger_h:

initStaggeredGridAdapterH();

break;

default:

break;

}

return super.onOptionsItemSelected(item);

}

(3)设置layoutManager和对应的adapter

[java] view
plain copy

private void initListAdapterV() {

//设置layoutManager

LinearLayoutManager layoutManger = new LinearLayoutManager(MainActivity.this);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initListAdapterH() {

//设置layoutManager

LinearLayoutManager layoutManger = new LinearLayoutManager(MainActivity.this,

LinearLayoutManager.HORIZONTAL, false);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initGridAdapterV() {

//设置layoutManager

LinearLayoutManager layoutManger = new GridLayoutManager(MainActivity.this, 2);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initGridAdapterH() {

//设置layoutManager

LinearLayoutManager layoutManger = new GridLayoutManager(MainActivity.this, 2,

LinearLayoutManager.HORIZONTAL, false);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initStaggeredGridAdapterV() {

//设置layoutManager

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,

StaggeredGridLayoutManager.VERTICAL);

mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

//设置adapter

StraggerAdapter adapter = new StraggerAdapter(MainActivity.this, mStraggerDatas);

mRecyclerView.setAdapter(adapter);

}

private void initStaggeredGridAdapterH() {

//设置layoutManager

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,

StaggeredGridLayoutManager.HORIZONTAL);

mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

//设置adapter

StraggerAdapter adapter = new StraggerAdapter(MainActivity.this, mStraggerDatas);

mRecyclerView.setAdapter(adapter);

}

(4)完整MainActivity

[java] view
plain copy

public class MainActivity extends Activity {

private RecyclerView mRecyclerView;

private List<DataBean> mDatas = new ArrayList<DataBean>();

private List<DataBean> mStraggerDatas = new ArrayList<DataBean>();

private int[] mListIcons = new int[]{R.mipmap.g1, R.mipmap.g2, R.mipmap.g3, R.mipmap.g4,

R.mipmap.g5, R.mipmap.g6, R.mipmap.g7, R.mipmap.g8, R.mipmap.g9, R.mipmap.g10, R

.mipmap.g11, R.mipmap.g12, R.mipmap.g13, R.mipmap.g14, R.mipmap.g15, R.mipmap

.g16, R.mipmap.g17, R.mipmap.g18, R.mipmap.g19, R.mipmap.g20, R.mipmap.g21, R

.mipmap.g22, R.mipmap.g23, R.mipmap.g24, R.mipmap.g25, R.mipmap.g26, R.mipmap

.g27, R.mipmap.g28, R.mipmap.g29};

private int[] mStraggeredIcons = new int[]{R.mipmap.p1, R.mipmap.p2, R.mipmap.p3, R

.mipmap.p4, R.mipmap.p5, R.mipmap.p6, R.mipmap.p7, R.mipmap.p8, R.mipmap.p9, R

.mipmap.p10, R.mipmap.p11, R.mipmap.p12, R.mipmap.p13, R.mipmap.p14, R.mipmap

.p15, R.mipmap.p16, R.mipmap.p17, R.mipmap.p18, R.mipmap.p19, R.mipmap.p20, R

.mipmap.p21, R.mipmap.p22, R.mipmap.p23, R.mipmap.p24, R.mipmap.p25, R.mipmap

.p26, R.mipmap.p27, R.mipmap.p28, R.mipmap.p29, R.mipmap.p30, R.mipmap.p31, R

.mipmap.p32, R.mipmap.p33, R.mipmap.p34, R.mipmap.p35, R.mipmap.p36, R.mipmap

.p37, R.mipmap.p38, R.mipmap.p39, R.mipmap.p40, R.mipmap.p41, R.mipmap.p42, R

.mipmap.p43, R.mipmap.p44};

private SwipeRefreshLayout mSwipeRefreshLayout;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//找到recyclerView

mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);

mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);

initData();

initListAdapterV();

//initListener();

}

private void initListAdapterV() {

//设置layoutManager

LinearLayoutManager layoutManger = new LinearLayoutManager(MainActivity.this);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initListAdapterH() {

//设置layoutManager

LinearLayoutManager layoutManger = new LinearLayoutManager(MainActivity.this,

LinearLayoutManager.HORIZONTAL, false);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initGridAdapterV() {

//设置layoutManager

LinearLayoutManager layoutManger = new GridLayoutManager(MainActivity.this, 2);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

private void initGridAdapterH() {

//设置layoutManager

LinearLayoutManager layoutManger = new GridLayoutManager(MainActivity.this, 2,

LinearLayoutManager.HORIZONTAL, false);

mRecyclerView.setLayoutManager(layoutManger);

//设置adapter

ListAdapter adapter = new ListAdapter(MainActivity.this, mDatas);

mRecyclerView.setAdapter(adapter);

}

//瀑布流-----在下节

private void initStaggeredGridAdapterV() {

//设置layoutManager

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,

StaggeredGridLayoutManager.VERTICAL);

mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

//设置adapter

StraggerAdapter adapter = new StraggerAdapter(MainActivity.this, mStraggerDatas);

mRecyclerView.setAdapter(adapter);

}

//瀑布流-----在下节

private void initStaggeredGridAdapterH() {

//设置layoutManager

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,

StaggeredGridLayoutManager.HORIZONTAL);

mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

//设置adapter

StraggerAdapter adapter = new StraggerAdapter(MainActivity.this, mStraggerDatas);

mRecyclerView.setAdapter(adapter);

}

private void initData() {

for (int i = 0; i < mListIcons.length; i++) {

int iconId = mListIcons[i];

DataBean dataBean = new DataBean();

dataBean.iconId = iconId;

dataBean.text = "我是item" + i;

mDatas.add(dataBean);

}

for (int i = 0; i < mStraggeredIcons.length; i++) {

int iconId = mStraggeredIcons[i];

DataBean dataBean = new DataBean();

dataBean.iconId = iconId;

dataBean.text = "我是item" + i;

mStraggerDatas.add(dataBean);

}

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.menu_main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.action_list_v:

initListAdapterV();

break;

case R.id.action_list_h:

initListAdapterH();

break;

case R.id.action_grid_v:

initGridAdapterV();

break;

case R.id.action_grid_h:

initGridAdapterH();

break;

case R.id.action_stragger_v:

initStaggeredGridAdapterV();

break;

case R.id.action_stragger_h:

initStaggeredGridAdapterH();

break;

default:

break;

}

return super.onOptionsItemSelected(item);

}

}


17.瀑布流的实现

1.接上

2.item布局

[html] view
plain copy

<RelativeLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:padding="5dp">

<ImageView

android:id="@+id/item_straggered_iv"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:scaleType="centerCrop"

android:src="@mipmap/ic_launcher"/>

<TextView

android:id="@+id/item_straggered_tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@id/item_straggered_iv"

android:layout_centerHorizontal="true"

android:gravity="center"

android:text="gagaga"

android:textColor="#212121"

android:textSize="16sp"/>

</RelativeLayout>

3.StraggerAdapter.Java

[java] view
plain copy

public class StraggerAdapter extends RecyclerView.Adapter<StraggerAdapter.MyHolder> {

private Context context;

private List<DataBean> datas;

public StraggerAdapter(Context context, List<DataBean> datas) {

this.context = context;

this.datas = datas;

}

@Override

public MyHolder onCreateViewHolder(ViewGroup viewGroup, int i) {//决定根布局

// TextView tv = new TextView(context);//根布局

View itemView = View.inflate(context, R.layout.item_stragger, null);

return new MyHolder(itemView);

}

@Override

public void onBindViewHolder(MyHolder myHolder, int position) {//填充数据

myHolder.setDataAndRefreshUI(datas.get(position));

}

@Override

public int getItemCount() {//条目总数

if (datas != null) {

return datas.size();

}

return 0;

}

public class MyHolder extends RecyclerView.ViewHolder {

//孩子对象

private TextView mTvName;

private ImageView mIvIcon;

public MyHolder(View itemView) {

super(itemView);

//初始化孩子对象

mTvName = (TextView) itemView.findViewById(R.id.item_straggered_tv);

mIvIcon = (ImageView) itemView.findViewById(R.id.item_straggered_iv);

}

/**

* 设置itemView的数据展示

*

* @param dataBean

*/

public void setDataAndRefreshUI(DataBean dataBean) {

mTvName.setText(dataBean.text);

mIvIcon.setImageResource(dataBean.iconId);

}

}

}

4.MainActivity中

[java] view
plain copy

private void initStaggeredGridAdapterV() {

//设置layoutManager

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,

StaggeredGridLayoutManager.VERTICAL);

mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

//设置adapter

StraggerAdapter adapter = new StraggerAdapter(MainActivity.this, mStraggerDatas);

mRecyclerView.setAdapter(adapter);

}

瀑布流 上面是纵向瀑布流

private void initStaggeredGridAdapterH() {

//设置layoutManager

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,

StaggeredGridLayoutManager.HORIZONTAL);

mRecyclerView.setLayoutManager(staggeredGridLayoutManager);

//设置adapter

StraggerAdapter adapter = new StraggerAdapter(MainActivity.this, mStraggerDatas);

mRecyclerView.setAdapter(adapter);

}


18.cardView引入

1.在cardview独立的包中

2.直接套在布局中

[html] view
plain copy

<?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"

android:layout_width="match_parent"

android:layout_height="wrap_content"

>

<android.support.v7.widget.CardView

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="5dp"

>

<RelativeLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:paddingBottom="8dp">

<ImageView

android:id="@+id/iv_icon"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true"

android:layout_centerVertical="true"

android:layout_margin="10dp"

android:src="@mipmap/ic_launcher"/>

<TextView

android:id="@+id/tv_name"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_toRightOf="@+id/iv_icon"

android:text="Name"/>

</RelativeLayout>

</android.support.v7.widget.CardView>

</FrameLayout>

3.可以设置各种属性,圆角,z轴大小.....


19.swiperefreshLayout的使用

1.下拉刷新

2.使用

(1)

[html] view
plain copy

<RelativeLayout 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"

tools:context=".MainActivity">

<android.support.v4.widget.SwipeRefreshLayout

android:id="@+id/swipeRefreshLayout"

android:layout_width="match_parent"

android:layout_height="wrap_content"

>

<android.support.v7.widget.RecyclerView

android:id="@+id/recyclerView"

android:layout_width="match_parent"

android:layout_height="match_parent"

/>

</android.support.v4.widget.SwipeRefreshLayout>

</RelativeLayout>

(2)

[java] view
plain copy

private SwipeRefreshLayout mSwipeRefreshLayout;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//找到recyclerView

mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);

//下拉刷新控件

mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);

// initData();

//initListAdapterV();

initListener();

}

private void initListener() {

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {

@Override

public void onRefresh() {

//模拟加载数据

new Thread(new Runnable() {

@Override

public void run() {

SystemClock.sleep(2000);

MainActivity.this.runOnUiThread(new Runnable() {

@Override

public void run() {

//停止刷新操作

mSwipeRefreshLayout.setRefreshing(false);

//得到adapter.然后刷新

mRecyclerView.getAdapter().notifyDataSetChanged();

}

});

}

}).start();

;

}

});

}


20.兼容性

1.虽然Material Design新增了许多新特性,但是并不是所有新内容对对下保持了兼容。

2.使用v7包------------v7 support libraries r21 及更高版本包含了以下Material Design特性:

(1). 使用Theme.AppCompat主题包含调色板主体属性,可以对应用的主题做统一的配色,但是不包括状态栏和底部操作栏

(2). RecyclerView和CardView被独立出来,只要引入jar包,即可适配7以上的所有版本。

(3). Palette类用于从图片提取主色调

3.系统组件--------------Theme.AppCompat主题中提供了这些组件的Material Design style:

(1). EditText

(2). Spinner

(3). CheckBox

(4). RadioButton

(5). SwitchCompat

(6). CheckedTextView

(7). Color Palette

4.以下特性只在Android 5.0 (API level 21) 及以上版本中可用:

(1). 转场动画

(2). 触摸反馈

(3). 圆形展示动画

(4). 路径动画

(5). 矢量图

(6). tint染色

所以在代码中遇上使用这些api的地方需要进行版本判断

[java] view
plain copy

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

// 使用新特性

} else {

// 用其他替代方式

}

5. RippleDrawable 提供触摸反馈特效,即5.0的button按压下的水波纹效果。

(1). [https://github.com/03uk/RippleDrawable](https://github.com/03uk/RippleDrawable)

(2). [https://github.com/siriscac/RippleView](https://github.com/siriscac/RippleView)

(3). [https://github.com/balysv/material-ripple](https://github.com/balysv/material-ripple)

6.状态动画

[https://github.com/NghiaTranUIT/Responsive-Interaction-Control](https://github.com/NghiaTranUIT/Responsive-Interaction-Control)

7.Material Design风格的对话框

[https://github.com/lewisjdeane/L-Dialogs](https://github.com/lewisjdeane/L-Dialogs)

8.Material Design风格兼容包

[https://github.com/navasmdc/MaterialDesignLibrary](https://github.com/navasmdc/MaterialDesignLibrary)

9.支持修改状态栏和底部操作栏

https://github.com/jgilfelt/SystemBarTint
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: