您的位置:首页 > 其它

朝花夕拾----新组件的学习和使用

2015-06-26 17:45 459 查看
【转载请注明出处:/article/1366936.html CSDN 废墟的树】

今天来学习总结一下,Android 后添加的一些新的组件和UI效果,Material Dialog,SwipeRefreshLayout,ListPopupWindow,PopupMenu等。

Material Dialog



你还在为使用 Material Dialog 去引用第三方的library包么?现在告诉你一个好消息,其实Android 在V7包里面已经实现了 Material 风格的对话框,并且兼容到底版本了。你只需要在你的代码中使用V7中的Dialog即可实现以上图片效果了。代码如下:

private void showDialog1() {
android.support.v7.app.AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("让我们一起飞,我带着你,你带着钱,来一场说走就走的旅行")
.setNegativeButton("取消", null)
.setPositiveButton("确定", null)
.setTitle("Material Design Dialog")
.show();
}

是不是很赞,和之前的Dialog使用无任何差别,妈妈再也不用担心我使用Material Dialog对话框了。

SwipeRefreshLayout



原来谷歌已经实现了 Material Design 风格的下拉刷新组件,这个新的组件SwipeRefreshLayout是ViewGroup在V4包下面,你只需按照如下使用:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!--可滑动的组件,比如ScrollView,ListView,GridView,等-->
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">

<!--添加自己的内容-->

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

SwipeRefreshLayout组件下包裹一个可滑动的组件即可实现下拉刷新效果。然后在Java代码中使用如下:

swipeRefreshLayout = findView(R.id.swipe_container);

//设置下拉刷新监听事件
swipeRefreshLayout.setOnRefreshListener(this);
//设置进度条的颜色
swipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE, Color.GREEN);
//设置圆形进度条大小
swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);
//设置进度条背景颜色
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(Color.DKGRAY);
//设置下拉多少距离之后开始刷新数据
swipeRefreshLayout.setDistanceToTriggerSync(50);

其中包括以下常用方法:

setColorSchemeColors() 设置进度条颜色,可设置多个值,进度条颜色在这多个颜色值之间变化
setSize() 设置下拉出现的圆形进度条的大小,有两个值:SwipeRefreshLayout.DEFAULT 和 SwipeRefreshLayout.LARGE
setProgressBackgroundColorSchemeColor()设置圆形进度条背景颜色。
setDistanceToTriggerSync() 设置手势操作下拉多少距离之后开始刷新数据

总结:当然 SwipeRefreshLayout 组件有很多不足之处,比如没有上拉刷新这个功能,不过网上已经有人实现了这一效果,想要的可以自己网上搜一把吧。

LinearLayoutCompat

最近在V7包中突然发现 LinearLayoutCompat 组件,处于好奇,百度了一把这个组件的作用:用于给LinerLayout 中的子元素item之间设置间隔线的,效果图如下:



你还在为给每个LinerLayout 的item元素添加分割线烦恼么?告诉你,不用烦恼啦!android 给你现成的组件,你只需简单配置即可。代码参考如下:

<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|center_horizontal"
android:orientation="vertical"
app:divider="@drawable/line"
app:dividerPadding="25dp"
app:showDividers="middle|beginning|end">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:text="CSDN 废墟的树"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:text="CSDN 废墟的树"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:text="CSDN 废墟的树"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:text="CSDN 废墟的树"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:text="CSDN 废墟的树"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:text="CSDN 废墟的树"
android:textSize="20sp"
android:textStyle="bold" />

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

LinearLayoutCompat其实就是LinerLayout组件,只是为了兼容低版本,所以你必须的引用 V7包下面的LinearLayoutCompat。 LinearLayoutCompat除了拥有LinerLayout原本的属性之外,主要有如下几种属性来实现 间隔线效果。

app:divider=”@drawable/line” 给分隔线设置颜色,这里你需要在drawable在定义shape资源,否则将没有效果。看下面
app:dividerPadding=”25dp” 给分隔线设置距离左右边距的距离。
app:showDividers=”middle|beginning|end” 分隔线显示的位置,有四种参数值:middle 每个item之间,beginning最顶端显示分隔线,end 最底端显示分隔线,none不显示间隔线。

注意 这三个属性需要使用 xmlns:app=”http://schemas.android.com/apk/res-auto” 命名空间

app:divider=”@drawable/line” 的资源代码如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/material_blue_grey_800" />
<!--需要设置高度,否则不显示-->
<size android:height="1px" />
</shape>

总结:以后你还需要自己画分割线么?看完LinearLayoutCompat组件是不是很高兴啊!!哈哈哈

ListPopupWindow



PopupWindow的简单实用,无需更多的去自定义,获取去确定PopupWindow的位置等,你只需要使用ListPopupWindow就能满足你简单的 PopupWindow 弹出框的使用了。直接上代码:

public void showListPopup(View view) {
String items[] = {"item1", "item2", "item3", "item4", "item5"};
final ListPopupWindow listPopupWindow = new ListPopupWindow(this);

//设置ListView类型的适配器
listPopupWindow.setAdapter(new ArrayAdapter<String>(SwipeRefreshActivity.this, android.R.layout.simple_list_item_1, items));

//给每个item设置监听事件
listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(SwipeRefreshActivity.this, "the position is" + position, Toast.LENGTH_SHORT).show();
//                listPopupWindow.dismiss();
}
});

//设置ListPopupWindow的锚点,也就是弹出框的位置是相对当前参数View的位置来显示,
listPopupWindow.setAnchorView(view);

//ListPopupWindow 距锚点的距离,也就是相对锚点View的位置
listPopupWindow.setHorizontalOffset(100);
listPopupWindow.setVerticalOffset(100);

//设置对话框的宽高
listPopupWindow.setWidth(300);
listPopupWindow.setHeight(600);
listPopupWindow.setModal(false);

listPopupWindow.show();

}

根据以上代码,你可以做如下事情:

listPopupWindow.setAnchorView(view); 设置弹出框显示的位置
listPopupWindow.setHorizontalOffset(100);距离锚点View水平距离
listPopupWindow.setVerticalOffset(100); 距离锚点View的垂直距离
listPopupWindow.setWidth(300);设置弹出框的大小

不用解释了吧!代码都有注释。望君自己研究然后去手写代码,这样学习更快。

PopupMenu

菜单弹出框,效果如下:



代码如下:

public void showPopupMenu(View view) {
//参数View 是设置当前菜单显示的相对于View组件位置,具体位置系统会处理
PopupMenu popupMenu = new PopupMenu(this, view);
//加载menu布局
popupMenu.getMenuInflater().inflate(R.menu.menu_main, popupMenu.getMenu());
//设置menu中的item点击事件
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {

return false;
}
});
//设置popupWindow消失的点击事件
popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
@Override
public void onDismiss(PopupMenu menu) {

}
});

popupMenu.show();
}

总结:PopupMenu 相对ListPopupWindow可定制化比较少。

Spinner



流行风格的下拉类别组件。你只需要在XML布局中使用 新的style主题即可实现如上效果

<Spinner
android:id="@+id/spinner"
style="@android:style/Widget.Holo.Light.Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Spinner>

后续如有发现好用的,美观的UI组件会继续添加。今天就暂且到这里吧,退朝!

【转载请注明出处:/article/1366936.html CSDN 废墟的树】

作者:feidu804677682 发表于2015/6/26 11:31:21 原文链接
阅读:99 评论:0 查看评论
Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
【转载请注明出处:/article/1366937.html CSDN 废墟的树】



上一篇博客我们学习了Android Design Support Library库中的 是个简单的组件,不了解的童鞋可以参考之前的博客

Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用

这篇博客我们继续学习Design库中的其他四个组件,分别是AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout。

同样,你需要在你的工程中引入

compile 'com.android.support:design:22.2.0'

AppBarLayout

效果图是这样的



AppBarLayout 是继承LinerLayout实现的一个ViewGroup容器组件,它是为了Material Design设计的App Bar,支持手势滑动操作。

默认的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作为AppBar。类似上面图片贴出来的效果,代码布局如下:

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">

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

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll"
app:tabIndicatorColor="@android:color/holo_red_dark"
app:tabSelectedTextColor="@android:color/holo_red_dark"
app:tabTextColor="@android:color/black" />

</android.support.design.widget.AppBarLayout>

此处将Toolbar 和Tablayout的组合部分共同构成 AppBar的效果。

注意: AppBarLayout必须作为Toolbar的父布局容器

AppBarLayout是支持手势滑动效果的,不过的跟CoordinatorLayout配合使用,接下来学习一下CoordinatorLayout组件怎么使用?

CoordinatorLayout



从开发文档中可以了解到,CoordinatorLayout是一个增强型的FrameLayout。它的作用有两个

作为一个布局的根布局
最为一个为子视图之间相互协调手势效果的一个协调布局

例如一下布局代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways" />

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill" />

</android.support.design.widget.AppBarLayout>

<!--可滑动的布局内容-->
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_discuss"
android:layout_gravity="bottom|end"/>

</android.support.design.widget.CoordinatorLayout>

从上面布局看到,CoordinatorLayout协调布局中包裹了两个布局,一个是NestedScrollView,一个是AppBarLayout,以及FAB按钮。

我们来看看CoordinatorLayout是怎么来协调这两个子视图手势操作的。

1.由于CoordinatorLayout是FrameLayout布局,我们可以通过

android:layout_gravity="bottom|end"

属性来控制组件在整个布局中的位置,比如上面效果中的FAB就是通过android:layout_gravity=”bottom|end”来确定 FAB的位置在底端的最右边的位置。

2.为了达到上面效果图的手势动画效果,我们必须做如下设置,通过app:layout_scrollFlags=”scroll|enterAlways” 属性来确定哪个组件是可滑动的

设置的layout_scrollFlags有如下几种选项:

scroll: 所有想滚动出屏幕的view都需要设置这个flag- 没有设置这个flag的view将被固定在屏幕顶部。
enterAlways: 这个flag让任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。
enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。

我们上面的布局中 给Toolbar设置了app:layout_scrollFlags属性,因此,Toolbar是可以滚动出屏幕,且向下滚动有可以出现。

3.为了使得Toolbar可以滑动,我们必须还得有个条件,就是CoordinatorLayout布局下包裹一个可以滑动的布局,比如 RecyclerView,NestedScrollView(经过测试,ListView,ScrollView不支持)具有滑动效果的组件。并且给这些组件设置如下属性来告诉CoordinatorLayout,该组件是带有滑动行为的组件,然后CoordinatorLayout在接受到滑动时会通知AppBarLayout 中可滑动的Toolbar可以滑出屏幕了。

app:layout_behavior="@string/appbar_scrolling_view_behavior"

总结: 为了使得Toolbar有滑动效果,必须做到如下三点:

CoordinatorLayout必须作为整个布局的父布局容器。
给需要滑动的组件设置 app:layout_scrollFlags=”scroll|enterAlways” 属性。
给你的可滑动的组件,也就是RecyclerView 或者 NestedScrollView 设置如下属性:

app:layout_behavior="@string/appbar_scrolling_view_behavior"
```

##CollapsingToolbarLayout

![这里写图片描述](http://img.blog.csdn.net/20150617115211729)

CollapsingToolbarLayout包裹 Toolbar 的时候提供一个可折叠的 Toolbar,一般作为AppbarLayout的子视图使用。

CollapsingToolbarLayout 提供以下属性和方法是用:

1. Collapsing title:ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。你可以调用setTitle(CharSequence)方法设置title。
2. Content scrim:ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim="?attr/colorPrimary"来改变背景。
3. Status bar scrim:状态栏的背景,调用方法setStatusBarScrim(Drawable)。还没研究明白,不过这个只能在Android5.0以上系统有效果。
4. Parallax scrolling children:CollapsingToolbarLayout滑动时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier="0.6"改变。
5. CollapseMode :子视图的折叠模式,有两种“pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode="parallax"来改变。

布局代码如下:


***总结:***  CollapsingToolbarLayout主要是提供一个可折叠的Toolbar容器,对容器中的不同视图设置layout_collapseMode折叠模式,来达到不同的折叠效果。

1.Toolbar 的高度layout_height必须固定,不能 “wrap_content”,否则Toolbar不会滑动,也没有折叠效果。
2.为了能让FloatingActionButton也能折叠且消失出现,我们必须给FAB设置锚点属性

app:layout_anchor="@id/appbar"

意思是FAB浮动按钮显示在哪个布局区域。

且设置当前锚点的位置

app:layout_anchorGravity=”bottom|end|right”

意思FAB浮动按钮在这个布局区域的具体位置。

两个属性共同作用才是的FAB 浮动按钮也能折叠消失,出现。

3.给需要有折叠效果的组件设置 layout_collapseMode属性。

【转载请注明出处:/article/1366937.html CSDN 废墟的树】

NavigationView



用于侧滑菜单中的menu布局。之前Google在V4包中推出自己的 DrawerLayout作为抽屉侧滑菜单,标准使用方法可以参考 google 原生态 抽屉式侧滑菜单 Android DrawerLayout 布局的使用介绍

当时的官方布局是这样的:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<!-- the main content view -->

<FrameLayout
android:id="@+id/frame_content"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>

<!-- the navigetion view -->

<ListView
android:id="@+id/drawer_list"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#9999cc"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" >
</ListView>

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

其实这次谷歌只是将上面的ListView布局替换成NavigationView了。简化了之前ListView写适配器的繁琐。

先如今布局改成如下:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- the main content view -->

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

<!-- the navigetion view -->

<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left"
android:fitsSystemWindows="true"
app:headerLayout="@layout/layout_header"
app:menu="@layout/layout_menu">

</android.support.design.widget.NavigationView>

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

其中NavigationView 中的 android:layout_gravity=”start” 属性来控制抽屉菜单从哪边滑出,一般“start ”从左边滑出,“end”从右边滑出。

这里最主要的两个属性分别是:

1.app:headerLayout: 给NavigationView添加头部布局

2.app:menu:给NavigationView添加menu菜单布局

app:headerLayout布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/img1"
android:gravity="center"
android:orientation="vertical">

<ImageView
android:layout_width="125dp"
android:layout_height="125dp"
android:scaleType="centerCrop"
android:src="@drawable/image" />

<TextView
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CSDN废墟的树博客"
android:textColor="@android:color/white" />

</LinearLayout>

app:menu 布局如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<group
android:checkableBehavior="single"
android:title="Home items">

<item
android:id="@+id/nav_blog"
android:icon="@drawable/ic_account_balance_black_24dp"
android:title="博客地址" />

<item
android:id="@+id/nav_ver"
android:icon="@drawable/ic_error_outline_black_36dp"
android:title="版本信息" />

<item
android:id="@+id/nav_about"
android:icon="@drawable/ic_error_outline_black_36dp"
android:title="关于我" />

</group>

<item android:title="Sub items">

<menu>

<item
android:id="@+id/sub_exit"
android:icon="@drawable/ic_power_settings_new_black_36dp"
android:title="退出应用" />

<item
android:id="@+id/sub_switch"
android:icon="@drawable/ic_settings_applications_black_36dp"
android:title="切换主题" />
</menu>
</item>

</menu>

代码中控制NavigationView

private void initNavigationView(){
navigationView = (NavigationView) findViewById(R.id.navigationView);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
//设置侧滑菜单选择监听事件
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
//关闭抽屉侧滑菜单
drawerLayout.closeDrawers();
return true;
}
});
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home){
//打开抽屉侧滑菜单
drawerLayout.openDrawer(GravityCompat.START);
}
return super.onOptionsItemSelected(item);
}

关于NavigationView中item的字体颜色和icon选中状态颜色是去当前主题theme中的

<--正常状态下字体颜色和icon颜色-->
<item name="android:textColorPrimary">@android:color/darker_gray</item>
<--选中状态icon的颜色和字体颜色-->
<item name="colorPrimary">@color/accent_material_light</item>

当然你可以通过如下方法或者属性来改变这一状态:

setItemBackgroundResource(int):给menu设置背景资源,对应的属性app:itemBackground
setItemIconTintList(ColorStateList):给menu的icon设置颜色,对应的属性app:itemIconTint
setItemTextColor(ColorStateList):给menu的item设置字体颜色,对应的属性app:itemTextColor

至此,Android Support Design Library库的使用基本学习完。

源码地址 https://github.com/xujinping/AndroidDesignLibrary/tree/master

作者:feidu804677682 发表于2015/6/17 19:46:22 原文链接
阅读:590 评论:0 查看评论
Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用
【转载请注明出处:/article/1366938.html CSDN 废墟的树】



在前不久的谷歌2015 I/O大会上,发布了Android新版本M,貌似从这个版本开始Android不在以数字命名版本了。

在这次的I/O大会上谷歌对Android并没有很大的改变,主要是修改完善之前Android L版本。不过在谷歌推出

Material Design设计风格之后,还是做了很多风格上的兼容,比如v7包的 RecyclerView,CardView,Palette等

这次的I/O大会上也继续完善了MD设计支持库,这次谷歌推出了Android Design Support Library 库,全面支持

MD设计风格的UI效果。Design Support Library库吸收了8 个新的 material design 组件!最低支持 Android

2.1,其实很多组件都是Github上比较火的,只是谷歌把它官方化了,便于开发者使用。今天我们来学习

FloatingActionButton,TextInputLayout,Snackbar,TabLayout 四种控件。

前提

为了能使用 这些 material design 组件,你需要去更新最新的SDK中的Extras支持库,如下图:



ps:在天朝上国,这种更新是需要翻墙的或者使用代理的,大家自行想办法。

更新完之后,在build.gralde文件下引入如下包:

compile 'com.android.support:design:22.2.0'

现在,我们可以开始使用Material Design组件啦!来看看新组件有什么特别的地方吧!

FloatingActionButton

顾名思义:这是一个浮动按钮。先上效果图啦!ps:没有效果图的UI博客很蛋疼的。



以上是三种不同效果的FloatingActionButton。XML布局代码如下:

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_discuss"
/>

由于FloatingActionButton是重写ImageView的,所有FloatingActionButton拥有ImageView的一切属性。为了

控制FloatingActionButton的大小,背景颜色,阴影的深度等,我们可以通过如下属性来控制这些效果:

app:fabSize :FloatingActionButton的大小,有两种赋值分别是 “mini” 和 “normal”,默认是“normal”.
app:backgroundTint:FloatingActionButton的背景颜色,默认的背景颜色是Theme主题中的

<item name="colorAccent">#ff0000</item>

颜色,不了解的童鞋们可以参考Android5.x新特性之 Toolbar和Theme的使用:/article/1366939.html

3. app:elevation :FloatingActionButton阴影的深度,默认是有阴影的,如果觉得默认阴影深度有点大,可以改变这个属性来修改阴影深度。

上面三个效果图的XML布局代码如下:

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<android.support.design.widget.FloatingActionButton
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_discuss"
app:fabSize="mini" />

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_discuss"
/>

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_discuss"
app:backgroundTint="#000af4"
app:fabSize="normal"
app:elevation="1dp"
/>

</LinearLayout>

注意点

不能通过 android:background 属性来改变 FloatingActionButton的背景颜色,只能通过app:backgroundTint属性改变,因为FloatingActionButton是继承自ImageView的。

TextInputLayout

该控件是用于EditView输入框的,主要解决之前EditView在获得焦点编辑时hint属性提示语消失,这一点在一个页

面有多个EditView输入框的时候不是很好,因为很有可能用户在输入多个EditView之后,不知道当前EditView需

要输入什么内容。为了解决这一问题,TextInputLayout就此诞生了。TextInputLayout是继承自LinearLayout容

器布局,因此我们需要将EditView包含在TextInputLayout之内才可以使用,言外之意:TextInputLayout不能单

独使用。废话不多说,先上效果图啊:



XML布局代码如下:

<android.support.design.widget.TextInputLayout
android:id="@+id/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"/>
</android.support.design.widget.TextInputLayout>

代码也可以看出TextInputLayout包裹着EditView。

为了达到以上效果,我们还需添加如下代码:

final TextInputLayout  inputLayout = findView(R.id.textInput);
inputLayout.setHint("请输入姓名:");

EditText editText = inputLayout.getEditText();
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length()>4){
inputLayout.setErrorEnabled(true);
inputLayout.setError("姓名长度不能超过4个");
}else{
inputLayout.setErrorEnabled(false);
}
}

@Override
public void afterTextChanged(Editable s) {
}
});

TextInputLayout 不仅能让EditView的提示语上弹显示在EditView之上,而且还能把错误信息显示在EditView之下。

TextInputLayout常用的方法有如下:

setHint():设置提示语。
getEditText():得到TextInputLayout中的EditView控件。
setErrorEnabled():设置是否可以显示错误信息。
setError():设置当用户输入错误时弹出的错误信息。

注意点

TextInputLayout不能单独使用,需要包裹EditView组件。

【转载请注明出处:/article/1366938.html CSDN 废墟的树】

Snackbar的使用

Snackbar提供了一个介于Toast和AlertDialog之间轻量级控件,它可以很方便的提供消息的提示和动作反馈。

废话不少说,妹子,上图:



Snackbar的使用和Toast很类似,调用代码如下:

final Snackbar snackbar = Snackbar.make(inputLayout,"测试弹出提示",Snackbar.LENGTH_LONG);
snackbar.show();
snackbar.setAction("取消",new View.OnClickListener() {
@Override
public void onClick(View v) {
snackbar.dismiss();
}
});

第一个参数View 可以是当前父布局中的任何一个view对象都可以。之后的参数和Toast参数一样。Snackbar可以

设置Action行为事件,使用的方法是public Snackbar setAction (CharSequence text, View.OnClickListener listener); 也可以为Snackbar设置多个Action行为事件。Action的字体颜色默认使用系统主题中的如下颜色

<item name="colorAccent">#ff0000</item>

当然你可以通过代码去改变Action的字体颜色:Snackbar setActionTextColor (int color);

注意

Snackbar可以同时设置多个Action行为事件
Snackbar是从整个界面的底部弹出。

TabLayout

Tabs选项卡,效果类似网易新闻客户端的Tab。其实实现Tabs选项卡的效果有很多中方法,Github上也有很多好

用的开源控件,只是这次谷歌把它官方化了,使得开发者无需引用第三方库,就能方便的使用。效果图:



XML布局如下:

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
<!--Tab被选中字体的颜色-->
app:tabSelectedTextColor="@android:color/holo_blue_bright"
<!--Tab未被选中字体的颜色-->
app:tabTextColor="@android:color/black"
<!--Tab指示器下标的颜色-->
app:tabIndicatorColor="@android:color/holo_blue_bright"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

常用的属性有三个:

app:tabSelectedTextColor:Tab被选中字体的颜色
app:tabTextColor:Tab未被选中字体的颜色
app:tabIndicatorColor:Tab指示器下标的颜色

TabLayout常用的方法如下:

- addTab(TabLayout.Tab tab, int position, boolean setSelected) 增加选项卡到 layout 中

- addTab(TabLayout.Tab tab, boolean setSelected) 同上

- addTab(TabLayout.Tab tab) 同上

- getTabAt(int index) 得到选项卡

- getTabCount() 得到选项卡的总个数

- getTabGravity() 得到 tab 的 Gravity

- getTabMode() 得到 tab 的模式

- getTabTextColors() 得到 tab 中文本的颜色

- newTab() 新建个 tab

- removeAllTabs() 移除所有的 tab

- removeTab(TabLayout.Tab tab) 移除指定的 tab

- removeTabAt(int position) 移除指定位置的 tab

- setOnTabSelectedListener(TabLayout.OnTabSelectedListener onTabSelectedListener) 为每个 tab 增加选择监听器

- setScrollPosition(int position, float positionOffset, boolean updateSelectedText) 设置滚动位置

- setTabGravity(int gravity) 设置 Gravity

- setTabMode(int mode) 设置 Mode,有两种值:TabLayout.MODE_SCROLLABLE和TabLayout.MODE_FIXED分别表示当tab的内容超过屏幕宽度是否支持横向水平滑动,第一种支持滑动,第二种不支持,默认不支持水平滑动。

- setTabTextColors(ColorStateList textColor) 设置 tab 中文本的颜色

- setTabTextColors(int normalColor, int selectedColor) 设置 tab 中文本的颜色 默认 选中

- setTabsFromPagerAdapter(PagerAdapter adapter) 设置 PagerAdapter

- setupWithViewPager(ViewPager viewPager) 和 ViewPager 联动

一般TabLayout都是和ViewPager共同使用才发挥它的优势,现在我们通过代码来看看以上方法的使用。

viewPager = findView(R.id.viewPager);

tabLayout = findView(R.id.tabs);
List<String> tabList = new ArrayList<>();
tabList.add("Tab1");
tabList.add("Tab2");
tabList.add("Tab3");
tabLayout.setTabMode(TabLayout.MODE_FIXED);//设置tab模式,当前为系统默认模式
tabLayout.addTab(tabLayout.newTab().setText(tabList.get(0)));//添加tab选项卡
tabLayout.addTab(tabLayout.newTab().setText(tabList.get(1)));
tabLayout.addTab(tabLayout.newTab().setText(tabList.get(2)));

List<Fragment> fragmentList = new ArrayList<>();
for (int i = 0; i < tabList.size(); i++) {
Fragment f1 = new TabFragment();
Bundle bundle = new Bundle();
bundle.putString("content", "http://blog.csdn.net/feiduclear_up \n CSDN 废墟的树");
f1.setArguments(bundle);
fragmentList.add(f1);
}

TabFragmentAdapter fragmentAdapter = new TabFragmentAdapter(getSupportFragmentManager(), fragmentList, tabList);
viewPager.setAdapter(fragmentAdapter);//给ViewPager设置适配器
tabLayout.setupWithViewPager(viewPager);//将TabLayout和ViewPager关联起来。
tabLayout.setTabsFromPagerAdapter(fragmentAdapter);//给Tabs设置适配器

就不解释了,都有注释,来看看以上代码的TabFragmentAdapter和TabFragment实现如下:

TabFragmentAdapter

public class TabFragmentAdapter extends FragmentStatePagerAdapter {

private List<Fragment> mFragments;
private List<String> mTitles;

public TabFragmentAdapter(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
super(fm);
mFragments = fragments;
mTitles = titles;
}

@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}

@Override
public int getCount() {
return mFragments.size();
}

@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}

TabFragment

public class TabFragment extends Fragment {

private String content;
private View view;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.item, container,false);
return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
content = getArguments().getString("content");
TextView tvContent = (TextView) view.findViewById(R.id.tv_tab_content);
tvContent.setText(content + "");
}
}

注意 :有这么一种情况,当Tabs中的内容超过了手机屏幕的宽度时,Tabs选项卡中的tab为什么不支持水平滑动?其实TabLayout是支持水平滑动的,只需要你在代码中添加如下一行即可:

tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);//设置tab模式

限于篇幅有点长,接下来的CoordinatorLayout , CollapsingToolbarLayout 和 AppBarLayout,NavigationView将

在下一篇博客学习。以上代码,如有疑问,欢迎共同讨论。

源码地址 https://github.com/xujinping/AndroidDesignLibrary/tree/master

作者:feidu804677682 发表于2015/6/15 16:44:21 原文链接
阅读:633 评论:4 查看评论
Android5.x新特性之 Toolbar和Theme的使用
转载请注明出处『Android5.x新特性之 Toolbar和Theme的使用:/article/1366939.html CSDN 废墟的树』

Android5.0以后谷歌大力推崇Material Design设计,有意统一之前Android style风格乱象的情况。上一篇博客我们学习了Android5.x 新控件之RecyclerView,CardView,Palette的使用。这篇文章来介绍Android5.x新特性之
Toolbar和Theme的使用.

注意 在使用Android5.x中的Toolbar和Theme需要在你的工程的build.gradle文件下引入如下配置

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
}

Toolbar

你还在为Android 的ActionBar的文字不能随意设置位置而烦恼么?你还在为ActionBar不能自定义添加自己的布局而烦恼么?现在告诉你一个好消息,当你看到这篇文章时,就不必烦恼了。Google在Android5.0以后推出了一个Toolbar来完全代替之前的Actionbar,Toolbar的出现解决了Actionbar的各种限制,Toolbar可以完全自定义和配置。我们从以下几个点了解Toolbar的使用

Toolbar的基础使用
Toolbar配置主题Theme
Toolbar中常用的控件设置
Toolbar的自定义

Toolbar的基础使用

我们从以下几点来一步一步的学习Toolbar的使用

Style(风格)
Layout(布局)
Activity(代码)

Style

为了能在你的Activity中使用Toolbar,你必须在工程里修改styles.xml文件里的主题风格,系统默认如下

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

这种Theme表示使用系统之前的ActionBar,那么我们想要使用Toolbar怎么办呢?

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

这个主题表示不使用系统的Actionbar了,这是第一步。

Layout布局

为了使用Toolbar,我们第二步是在你的activity_main.xml布局里添加Support v7提供的Toolbar,代码如下

<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.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
>
</android.support.v7.widget.Toolbar>

</RelativeLayout>

为了在你的UI中使用Toolbar,你得为每个activity布局添加Toolbar,并且给Toolbar设置一个id android:id=”@+id/toolbar”。这是第二部。

代码添加Toolbar

为了使用Toolbar,我们第三部是在你的Activity代码中做如下代码处理:

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

toolbar = findView(R.id.toolbar);
setSupportActionBar(toolbar);
}

代码中通过findView找到Toolbar,然后通过setSupportActionBar(toolbar);将Toolbar设置为Activity的导航栏。

通过上面的三个步骤,你就已经使用了Support v7提供的Toolbar了。看看那效果图。



是不是感觉很丑?没有一点MD设计的风格,不过别失望,这仅仅是为了让Toolbar正常工作而已,为了让Toolbar有Material Design风格,我们必须去设置Toolbar的主题风格。

Toolbar配置主题Theme

我们重新配置系统主题Theme,修改styles.xml代码如下:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<!--导航栏底色-->
<item name="colorPrimary">@color/accent_material_dark</item>
<!--状态栏底色-->
<item name="colorPrimaryDark">@color/accent_material_light</item>
<!--导航栏上的标题颜色-->
<item name="android:textColorPrimary">@android:color/black</item>
<!--Activity窗口的颜色-->
<item name="android:windowBackground">@color/material_blue_grey_800</item>
<!--按钮选中或者点击获得焦点后的颜色-->
<item name="colorAccent">#00ff00</item>
<!--和 colorAccent相反,正常状态下按钮的颜色-->
<item name="colorControlNormal">#ff0000</item>
<!--Button按钮正常状态颜色-->
<item name="colorButtonNormal">@color/accent_material_light</item>
<!--EditText 输入框中字体的颜色-->
<item name="editTextColor">@android:color/white</item>
</style>

各个属性就不解释了,注释都很清楚。我们来看看Toolbar怎么使用这些主题吧?

配置activity_main.xml中的Toolbar改成为如下:

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

相比上面的Toolbar配置,这里只多添加了 这么一行代码

android:background="?attr/colorPrimary"

给Toolbar设置背景属性,这里使用了styles.xml文件中如下属性

<!--导航栏底色-->
<item name="colorPrimary">@color/accent_material_dark</item>

经过如下配置再来看看效果图吧!



效果有点改进,我们继续发现Toolbar的优势吧!

Toolbar中常用的控件设置

那么Toolbar是否都有Actionbar的所有功能呢?毋庸置疑,来看代码:

toolbar = findView(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setTitle("主标题");
toolbar.setSubtitle("副标题");
toolbar.setLogo(R.drawable.ic_launcher);
toolbar.setNavigationIcon(android.R.drawable.ic_input_delete);

Toolbar可以设置 Title(主标题),Subtitle(副标题),Logo(logo图标)NavigationIcon(导航按钮)。

注意 如果你想要通过toolbar.setTitle(“主标题”);设置Toolbar的标题,你必须在调用它之前调用如下代码:

getSupportActionBar().setDisplayShowTitleEnabled(false);

上面代码用来隐藏系统默认的Title。

那么Toolbar能不能使用Menu菜单功能呢?答案是肯定的了。来看看加载如下menu菜单的Toolbar吧

<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_edit"
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
android:orderInCategory="80"
android:title="查找"
app:showAsAction="always" />

<item
android:id="@+id/action_share"
android:icon="@drawable/abc_ic_menu_share_mtrl_alpha"
android:orderInCategory="90"
android:title="分享"
app:showAsAction="always" />

<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

怎么给menu的各个Item添加点击事件呢?Toolbar给我们提供如下方法

Activity继承Toolbar的OnMenuItemClickListener接口

public class MainActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener

//实现接口
toolbar.setOnMenuItemClickListener(this);
@Override
public boolean onMenuItemClick(MenuItem item) {

switch (item.getItemId()) {
case R.id.action_edit:
Toast.makeText(this, "查找按钮", Toast.LENGTH_SHORT).show();
break;
case R.id.action_share:
Toast.makeText(this, "分享按钮", Toast.LENGTH_SHORT).show();
break;
}

return false;
}

至此,Toolbar添加控件就基本完结了,来看看效果如下



是不是很炫?我们还没有使用自定义的Toolbar呢?那怎么使用呢?

Toolbar的自定义

其实Toolbar是继承ViewGroup的一个容器控件,言外之意就是我们可以在Toolbar添加自己的布局了。看代码

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

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center_vertical"
android:text="标题"
android:textSize="18sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/abc_ic_menu_share_mtrl_alpha" />

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

效果图:



这样我们就可以任意给Toolbar布局了。也解决了标题不能居中的问题。有特殊需求的Toolbar的童鞋就可以自行补脑实现各种需求效果啦!

Android5.x Material Design 主题风格Theme配置

在通往Material Design风格的路上总是遥远的,但也阻挡不了我们学习的劲头,仅仅会使用Toolbar是不够的。除了Toolbar的风格,我们还可以通过设置Theme主题该控制Android很多控件的风格。直接上一张图片效果。



以上效果的主题配置如下:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<!--导航栏底色-->
<item name="colorPrimary">@color/accent_material_dark</item>
<!--状态栏底色-->
<item name="colorPrimaryDark">@color/accent_material_light</item>
<!--导航栏上的标题颜色-->
<item name="android:textColorPrimary">@android:color/black</item>
<!--Activity窗口的颜色-->
<item name="android:windowBackground">@color/material_blue_grey_800</item>
<!--按钮选中或者点击获得焦点后的颜色-->
<item name="colorAccent">#00ff00</item>
<!--和 colorAccent相反,正常状态下按钮的颜色-->
<item name="colorControlNormal">#ff0000</item>
<!--Button按钮正常状态颜色-->
<item name="colorButtonNormal">@color/accent_material_light</item>
<!--EditText 输入框中字体的颜色-->
<item name="editTextColor">@android:color/white</item>
</style>

1.colorPrimary: Toolbar导航栏的底色。

2.colorPrimaryDark:状态栏的底色,注意这里只支持Android5.0以上的手机。

3.textColorPrimary:整个当前Activity的字体的默认颜色。

4.android:windowBackground:当前Activity的窗体颜色。

5.colorAccent:CheckBox,RadioButton,SwitchCompat等控件的点击选中颜色

6.colorControlNormal:CheckBox,RadioButton,SwitchCompat等默认状态的颜色。

7.colorButtonNormal:默认状态下Button按钮的颜色。

8.editTextColor:默认EditView输入框字体的颜色。

源码下载

作者:feidu804677682 发表于2015/6/11 17:09:06 原文链接
阅读:629 评论:0 查看评论
Android5.x 新控件之RecyclerView,CardView,Palette的使用
『转载注明出处:/article/1366940.html CSDN废墟的树』

自Android5.0发布以来,谷歌推出全新的Material Desigen设计风格,时过一年多了,在国内也看到很多应用在慢

慢适应MD设计风格。其中比较好的app就是网易新闻客户端了,其设计风格基本符合MD要求。鉴于越来多App采

用MD设计风格,作为吊丝程序员的我们怎能落后呢?那就让我们来学习一些Android5.x新推出的一些控件吧。

先上效果图:



注明:我的开发环境是AS1.0 ,使用Eclipse的童鞋自行配置。为了能使用Android5.0的一些新控件,我们不

得不引用Support v7包,在AS里很好配置,直接在build.gradle文件下添加如下配置:

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:recyclerview-v7:21.0.3'
compile 'com.android.support:cardview-v7:21.0.3'
compile 'com.android.support:palette-v7:22.2.0'
}

RecyclerView控件

类似ListView ,GridView,RecyclerView也是一个继承ViewGroup的容器控件,用于在有限的界面视图情况下装

载更多的内容。我们通过代码来看看RecyclerView控件怎么使用的吧!先XML从布局看

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />

很简单,直接引用Support v7包里的RecyclerView就可以了,貌似布局文件里没有太多的配置,不像ListView和

GridView控件有很多配置比如:android:dividerHeight ,android:divider,android:numColumns等。这是因

为RecyclerView虽然也是容器控件,大多数的效果显示可以通过代码来控制显示,但是RecyclerView更加自由,

更加包容,用户更容易去定义它的内容显示方

式。接下来通过代码看怎么使用RecyclerView吧!

private void initViews() {
recylerView = findView(R.id.recyclerview);
//设置布局显示方式
recylerView.setLayoutManager(new LinearLayoutManager(this, LinearLayout.VERTICAL, true));
//设置添加删除item时候的动画
recylerView.setItemAnimator(new DefaultItemAnimator());
}

是不是感觉还是蛮简单的嘛?就两行代码,我们来看看setLayoutManager设置布局显示方式方法吧!

setLayoutManager()方法接受一个 LayoutManager 布局管理参数。参数类型可以有以下几种:

LinearLayoutManager:线性布局
GridLayoutManager:网格布局
StaggeredGridLayoutManager:流式布局

那么怎么new一个LayoutManager出来呢?举个例子:

new LinearLayoutManager(this, LinearLayout.VERTICAL, true)

第一个参数 Context ,第二个参数:布局方向LinearLayout.VERTICAL垂直和LinearLayout.HORIZONTAL水平,

第三个参数:表示是否从最后的Item数据开始显示,ture表示是,false就是正常显示—从开头显示。

setItemAnimator()方法的作用是设置当前RecyclerView容器有子Item改变时(添加item或者删除item)导致

整个布局的动画效果。一般我们new 一个系统默认的动画出来就好了。

RecyclerView适配器

既然RecyclerView是一个容器控件,那么里面总的装载内容吧,也就是的有一个自己的适配器。来看看适配器怎么

实现的吧!

/**
* Description:RecyclerView 适配器
* User: xjp
* Date: 2015/6/8
* Time: 10:15
*/

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {

private Context context;
private List<ModelBean> list;
private Resources res;

public RecyclerAdapter(Context context, List<ModelBean> list) {
this.context = context;
this.list = list;
res = context.getResources();
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_card_view, parent, false);
return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
final ModelBean bean = list.get(position);
holder.title.setText(bean.getTitle());
holder.imageView.setImageResource(bean.getResId());
}

@Override
public int getItemCount() {
return null == list ? 0 : list.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder {

private ImageView imageView;
private TextView title;

public MyViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.pic);
title = (TextView) view.findViewById(R.id.name);
}
}
}

看到嘛?我们是继承RecyclerView.Adapter类,实现里面的抽象方法即可。可以看到RecyclerView.Adapter适配

器里面有一套完整的机制来控制之ItemView的查找和显示。通过内部类MyViewHolder继承

RecyclerView.ViewHolder封装容器中的ItemView,实现onCreateViewHolder抽象方法来加载ItemView的布

局,实现onBindViewHolder抽象方法来绑定容器中的ItemView,进而进行赋值。

ItemView点击事件

细心的你会发现,很遗憾的是RecyclerView没有提供setItemOnClickListener点击监听方法。那么我们要监听每个

ItemView的点击事件怎么办呢?没关系!我们来看看代码中怎么实现吧!

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
final ModelBean bean = list.get(position);
holder.title.setText(bean.getTitle());
holder.imageView.setImageResource(bean.getResId());

/**
* 调用接口回调
*/
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != listener)
listener.onItemClick(position, bean);
}
});
}

/**
* 内部接口回调方法
*/
public interface OnItemClickListener {
void onItemClick(int position, Object object);
}

/**
* 设置监听方法
*
* @param listener
*/
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}

在RecyclerView的适配器类中定义了一个OnItemClickListener接口,然后在onBindViewHolder方法中设置每个holder.itemView的点击事件,外面调用setOnItemClickListener方法即可

adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position, Object object) {
Toast.makeText(MainActivity.this, ((ModelBean) object).getTitle(), Toast.LENGTH_SHORT).show();
}
});

RecyclerView添加,删除,更新数据

和ListView,GridView容器不一样的是,RecyclerView容器更新数据的方法有很多,不信你看:

notifyDataSetChanged():更新所有数据
notifyItemInserted(int position):在position位置插入数据的时候更新
notifyItemRemoved(int position):移除postion位置的数据的时候更新
notifyItemChanged(int position):当postion位置数据有改变时候更新
notifyItemMoved(int fromPosition, int toPosition):移除从位置formPosition到toPosition位置数据更新
notifyItemRangeChanged(int positionStart, int itemCount)
notifyItemRangeInserted(int positionStart, int itemCount)
notifyItemRangeRemoved(int positionStart, int itemCount)

如果你在代码里设置了RecyclerView的ItemView改变时有动画效果的话

recylerView.setItemAnimator(new DefaultItemAnimator());

在RecyclerView适配器更新数据的时候就会有系统默认的动画效果,童鞋们可以根据下面提供的源码看效果。

RecyclerView控件使用基本就

是以上内容,最后我会提供一个RecyclerView,CardView,Palette一起使用的源码例子,接着往下看吧骚年!

CardView控件

CardView称之为卡片,也是Android5.0推出来的 Support v7包里的widget,CardView是继承自FrameLayout。

从XML中看它是怎么使用的

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card="http://schemas.android.com/apk/res-auto"
android:layout_width="160dp"
android:layout_height="200dp"
android:layout_gravity="center"
card:cardBackgroundColor="@android:color/white"
card:cardCornerRadius="0dp"
card:cardElevation="2dp"
card:cardMaxElevation="@dimen/cardview_default_elevation">
<!--cardMaxElevation:最大卡片阴影的宽度-->
<!--cardElevation:卡片阴影的宽度-->
<!--cardBackgroundColor:卡片的背景颜色-->
<!--cardCornerRadius :卡片的圆角半径-->

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ImageView
android:id="@+id/pic"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_centerInParent="true"
android:layout_weight="3"
android:scaleType="fitXY"
android:src="@drawable/img1" />

<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clickable="true"
android:gravity="center"
android:padding="5dp"
android:text="图片描述"
android:textColor="@android:color/black"
android:textSize="16sp" />
</LinearLayout>

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

在使用CardView的时候需要引入属性命名空间,也就是加入以下代码

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

和自定义控件一样,引入命名空间是为了使用CardView的属性值,名字“card”可以任意。来看看CardView有哪

些常用的属性吧!

cardElevation:卡片阴影的宽度
cardMaxElevation:最大卡片阴影的宽度
cardBackgroundColor:卡片的背景颜色
cardCornerRadius :卡片的圆角半径

CardView只需要在XML布局文件里配置各种参数,代码中无需任何操作。其实CardView就是一个FrameLayout容器控件,只是添加了一些属性而已,使用很简单,只要掌握以上四种属性配置即可。

Palette

Palette类也是Android5.0引进来的一个获取Bitmap颜色值的一个类。google为了兼容前面的版本也把这个类放在

了Support v7 Library包里,需要使用该类可以在项目中引进

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

我们从代码中来看看它是怎么使用的

//异步获得bitmap图片颜色值
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
Palette.Swatch vibrant = palette.getVibrantSwatch();//有活力

if (vibrant != null) {
holder.title.setBackgroundColor(
vibrant.getRgb());
holder.title.setTextColor(
vibrant.getTitleTextColor());
}
}
});

由于在Android设备中,对图像的处理有可能是耗时操作,因此,Palette类通过异步接口onGenerated回调的方法

来获得Bitmap的颜色值。Palette类获得的颜色值有以下几种类型:

Palette.Swatch a = palette.getVibrantSwatch();//有活力
Palette.Swatch b = palette.getDarkVibrantSwatch();//有活力 暗色
Palette.Swatch c = palette.getLightVibrantSwatch();//有活力 亮色
Palette.Swatch d = palette.getMutedSwatch();//柔和
Palette.Swatch e = palette.getDarkMutedSwatch();//柔和 暗色
Palette.Swatch f = palette.getLightMutedSwatch();//柔和 亮色

我们从以上颜色中可以获取到如下颜色值:

int color1 = a.getBodyTextColor();//内容颜色
int color2 = a.getTitleTextColor();//标题颜色
int color3 = a.getRgb();//rgb颜色

综合例子

通过以上的了解,这里提供一个综合的例子来看看RecyclerView,CardView,Palette结合的使用。以后给出

MainActivity和Adapter的实现

package com.xjp.androidmddemo.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.xjp.androidmddemo.R;
import com.xjp.androidmddemo.activity.adapter.RecyclerAdapter;
import com.xjp.androidmddemo.activity.model.ModelBean;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnClickListener {

protected Toolbar toolbar;
protected TextView title;
protected Spinner spinner;
protected Button add;

private RecyclerView recylerView;
private List<ModelBean> beanList;
private RecyclerAdapter adapter;
private String des[] = {"云层里的阳光", "好美的海滩", "好美的海滩", "夕阳西下的美景", "夕阳西下的美景"
, "夕阳西下的美景", "夕阳西下的美景", "夕阳西下的美景", "好美的海滩"};

private int resId[] = {R.drawable.img1, R.drawable.img2, R.drawable.img2, R.drawable.img3,
R.drawable.img4, R.drawable.img5, R.drawable.img3, R.drawable.img1};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initData();
initSpinner();
}

private void initSpinner() {
String categorys[] = this.getResources().getStringArray(R.array.categorys);
ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categorys);

// 为adapter设置下拉菜单样式
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

// spinner设置adapter
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}

private void initViews() {

toolbar = findView(R.id.toolbar);
if (null != toolbar) {
setSupportActionBar(toolbar);
title = findView(R.id.toolbar_title);
spinner = findView(R.id.toolbar_category);
add = findView(R.id.button_add);
if (null != title) {
title.setText(getTitle());
}
}

add.setOnClickListener(this);

recylerView = findView(R.id.recyclerview);
//设置布局显示方式
recylerView.setLayoutManager(new LinearLayoutManager(this, LinearLayout.VERTICAL, true));
//设置添加删除item时候的动画
recylerView.setItemAnimator(new DefaultItemAnimator());
}

private void initData() {
beanList = new ArrayList<>();
for (int i = 0; i < 8; i++) {
ModelBean bean = new ModelBean();
bean.setResId(resId[i]);
bean.setTitle(des[i]);
beanList.add(bean);
}
adapter = new RecyclerAdapter(this, beanList);
recylerView.setAdapter(adapter);
adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() { @Override public void onItemClick(int position, Object object) { Toast.makeText(MainActivity.this, ((ModelBean) object).getTitle(), Toast.LENGTH_SHORT).show(); } });
}

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
recylerView.setLayoutManager(new LinearLayoutManager(this, LinearLayout.VERTICAL, true));
break;
case 1:
recylerView.setLayoutManager(new LinearLayoutManager(this, LinearLayout.HORIZONTAL, true));
break;
case 2:
recylerView.setLayoutManager(new GridLayoutManager(this, 2));
break;
case 3:
recylerView.setLayoutManager(new GridLayoutManager(this, 2, LinearLayout.HORIZONTAL, true));
break;
case 4:
recylerView.setLayoutManager(new StaggeredGridLayoutManager(2, LinearLayout.VERTICAL));
break;
}
}

@Override
public void onNothingSelected(AdapterView<?> parent) {

}

@Override
public void onClick(View v) {
ModelBean bean = new ModelBean();
bean.setTitle("这是新添加的");
bean.setResId(R.drawable.img5);
beanList.add(0, bean);
// adapter.notifyDataSetChanged();//更新全部数据
// adapter.notifyItemInserted(0);//在
// adapter.notifyItemRemoved(0);
// adapter.notifyItemChanged(0);
// adapter.notifyItemMoved(0,1);
// adapter.notifyItemRangeChanged(0,2);
// adapter.notifyItemRangeInserted(0,2);
// adapter.notifyItemRangeRemoved(0,2);

}

protected <T extends View> T findView(int id) {
return (T) findViewById(id);
}
}

............................

package com.xjp.androidmddemo.activity.adapter;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.xjp.androidmddemo.R;
import com.xjp.androidmddemo.activity.model.ModelBean;

import java.util.List;

/**
* Description:RecyclerView 适配器
* User: xjp
* Date: 2015/6/8
* Time: 10:15
*/

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {

private Context context;
private List<ModelBean> list;
private Resources res;
private OnItemClickListener listener;

public RecyclerAdapter(Context context, List<ModelBean> list) {
this.context = context;
this.list = list;
res = context.getResources();
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_card_view, parent, false);
return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {

final ModelBean bean = list.get(position);
holder.title.setText(bean.getTitle());
holder.imageView.setImageResource(bean.getResId());
Bitmap bitmap = BitmapFactory.decodeResource(res, bean.getResId());
//异步获得bitmap图片颜色值
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
Palette.Swatch vibrant = palette.getVibrantSwatch();//有活力
Palette.Swatch c = palette.getDarkVibrantSwatch();//有活力 暗色
Palette.Swatch d = palette.getLightVibrantSwatch();//有活力 亮色
Palette.Swatch f = palette.getMutedSwatch();//柔和
Palette.Swatch a = palette.getDarkMutedSwatch();//柔和 暗色
Palette.Swatch b = palette.getLightMutedSwatch();//柔和 亮色

if (vibrant != null) {
int color1 = vibrant.getBodyTextColor();//内容颜色
int color2 = vibrant.getTitleTextColor();//标题颜色
int color3 = vibrant.getRgb();//rgb颜色

holder.title.setBackgroundColor(
vibrant.getRgb());
holder.title.setTextColor(
vibrant.getTitleTextColor());
}
}
});

/**
* 调用接口回调
*/
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != listener)
listener.onItemClick(position, bean);
}
});
}

@Override
public int getItemCount() {
return null == list ? 0 : list.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder {

private ImageView imageView;
private TextView title;

public MyViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.pic);
title = (TextView) view.findViewById(R.id.name);
}
}

/**
* 内部接口回调方法
*/
public interface OnItemClickListener {
void onItemClick(int position, Object object);
}

/**
* 设置监听方法
*
* @param listener
*/
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}

}

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