Android Material Design 详解(使用support v7兼容5.0以下系统)

Material Design是Google在2014年的I/O大会上推出的全新设计语言。Material Design是基于Android 5.0(API level 21)的,兼容5.0以下的设备时需要使用版本号v21.0.0以上的support v7包中的appcpmpat,不过遗憾的是support包只支持Material Design的部分特性。使用eclipse或Android Studio进行开发时,直接在Android SDK Manager中将Extras->Android Support
Library升级至最新版即可。目前最新版本为:

com.android.support:appcompat-v7:21.0.3

本文中示例程序使用minSdkVersion=14,即属于使用support包实现Material Design风格。

使用Material Design的步骤:

一、使用Material主题

1.创建一个Android应用,应用主题Theme.AppCompat(或其子主题,如Theme.AppCompat.Light.DarkActionBar)

2.自定义程序所使用的主题的某些属性,示例:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!--ActionBar的颜色-->
        <item name="colorPrimary">@color/primary</item>
        <!-- 随主题而改变的颜色(如CheckBox的颜色)-->
        <item name="colorAccent">@color/accent</item>
        <!--状态栏的颜色 (使用support包时似乎无效。)-->
        <item name="colorPrimaryDark">@color/primary_dark</item>

        <!--ActionBar的样式-->
        <item name="actionBarStyle">@style/AppTheme.ActionBarStyle</item>
    </style>

    <style name="AppTheme.ActionBarStyle" parent="Widget.AppCompat.ActionBar.Solid">
        <item name="android:titleTextStyle">@style/AppTheme.ActionBar.TitleTextStyle</item>
    </style>

    <style name="AppTheme.ActionBar.TitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
        <!--ActionBar标题文字颜色-->
        <item name="android:textColor">@android:color/white</item>
    </style>

3.所有需要使用ActionBar的Activity必须继承自ActionBarActivity,因为即使使用了类似Theme.AppCompat.Light.DarkActionBar这样的主题,系统也不会自动添加ActionBar.

效果图:

  

相对于普通的ActionBar的变化:

(1)右侧三个小点的样式变了。(这个无所谓。。。)

(2)点击右侧三个小点(更多)时,下拉菜单不是从ActionBar的下面开始展开,而是直接从ActionBar之上开始!也许的确有办法把它改成旧的样式,不过查阅官方文档之后发现,Google对此的解释是:菜单是一个临时展现给用户的组件,因此应该悬浮在上面。也就是说,新的设计规则推荐的就是这种默认的样式。

二、使用RecyclerView

RecyclerView是Google在support v7包中提供的一个全新的组件。该组件是一个增强版的ListView,新特性:

1.提高了性能;

2.adapter中自动进行item复用,也就是说,以前的这种繁琐的写法不需要了:

if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.friends_item, parent, false);
            holder = new ViewHolder();

            holder.nameTV = (TextView) convertView.findViewById(R.id.friends_item_name);
            holder.phoneTV = (TextView) convertView.findViewById(R.id.friends_item_phone);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

3.预置了item的添加,删除,移动,修改时的动画,当且改动画也可以自定义。

效果图:

    

示例代码:

(1)主页面,获取到RecyclerView,设置adapter即可。

RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
 // use this setting to improve performance if you know that changes
 // in content do not change the layout size of the RecyclerView
  mRecyclerView.setHasFixedSize(true);

 // use a linear layout manager
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//data
 List<CityInfoBean> myDataset = new ArrayList<CityInfoBean>();
        for (int i = 0; i < 50; i++) {
            CityInfoBean city = new CityInfoBean();
            city.setCityName("Tianjin-" + i);
            city.setCityPhone("022-" + i);
            city.setLocation("Asia_" + i);

            myDataset.add(city);
        }

        RecyclerViewAdapter mAdapter = new RecyclerViewAdapter(this, myDataset);
        mRecyclerView.setAdapter(mAdapter);

//RecyclerView doesn't has a 'OnItemClickListener' or 'OnItemLongClickListener' like ListView,
 // so you should add the callback in adapter 

(2)adapter,RecyclerViewAdapter.java:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    private Context context;
    private List<CityInfoBean> mDataset;

    public RecyclerViewAdapter(Context context, List<CityInfoBean> myDataset) {
        this.context = context;
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list_item, parent, false);
        // set the view's size, margins, paddings and layout parameters

        final ViewHolder vh = new ViewHolder(v);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = vh.getPosition();
                Toast.makeText(v.getContext(), "Item click. Position:" +
                        position, Toast.LENGTH_SHORT).show();
            }
        });

        v.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                int position = vh.getPosition();
//                Toast.makeText(v.getContext(), "Item long click. Position:" +
//                        position, Toast.LENGTH_SHORT).show();

                showDialog(position);

                return true;
            }
        });

        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.cityNameTV.setText(mDataset.get(position).getCityName());
        holder.phoneTV.setText(mDataset.get(position).getCityPhone());
        holder.addrTV.setText(mDataset.get(position).getLocation());
    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }

    private void showDialog(final int position) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("Choose operation");

        String[] dialogItems = new String[]{
                context.getString(R.string.delete_one_item),
                context.getString(R.string.add_one_item),
                context.getString(R.string.move_one_item),
                context.getString(R.string.change_one_item),
                context.getString(R.string.add_many_items),
        };
        builder.setItems(dialogItems, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case 0:
                        //delete this item
                        mDataset.remove(position);
                        notifyItemRemoved(position);
                        break;
                    case 1:
                        //add one item
                        mDataset.add(position, new CityInfoBean("New City", "010", "Asia"));
                        notifyItemInserted(position);
                        break;
                    case 2:
                        //TODO remember to change the data set...
                        //move one item to another position
                        notifyItemMoved(position, position + 2);
                        //May cause IndexOutOfBoundsException. This is just a demo!
                        break;
                    case 3:
                        //change one item
                        mDataset.get(position).setCityName("City name changed");
                        notifyItemChanged(position);
                        break;
                    case 4:
                        //add many items
                        List<CityInfoBean> insertList = new ArrayList<CityInfoBean>();
                        insertList.add(new CityInfoBean("New City 01", "010", "Asia"));
                        insertList.add(new CityInfoBean("New City 02", "020", "America"));

                        mDataset.addAll(position, insertList);
                        notifyItemRangeInserted(position, insertList.size());
                        break;
                    default:
                        break;
                }
            }
        });

        builder.create().show();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView cityNameTV, phoneTV, addrTV;

        public ViewHolder(View v) {
            super(v);

            cityNameTV = (TextView) v.findViewById(R.id.city_name);
            phoneTV = (TextView) v.findViewById(R.id.city_phone);
            addrTV = (TextView) v.findViewById(R.id.city_addr);
        }
    }
}

(3)主页面布局文件:

recycler_layout.xml:

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

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

</LinearLayout>

二、使用CardView

CardView是Google在support v7包中提供了另一个全新组件,可以很方便的实现“卡片式布局”(具有投影/圆角 的立体效果)。CardView继承自FrameLayout,因此如果内部需要互不重叠的放置多个组件时,可能需要再嵌套一个LinearLayout或RelativeLayout等。

效果图:

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:card_view="http://schemas.android.com/apk/res-auto">

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="6dp"
        card_view:cardCornerRadius="4dp"
        card_view:cardBackgroundColor="@color/card_bg"
        card_view:cardElevation="4dp">

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

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:contentDescription="@null"
                android:src="@drawable/ic_launcher" />

            <TextView
                android:id="@+id/info_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textSize="18sp"
                android:text="@string/example_text" />

        </LinearLayout>

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

</LinearLayout>

属性解释:

cardCornerRadius:圆角大小;

cardElevation:投影的深度;

cardBackgroundColor:卡片的背景色。

时间: 2024-10-14 09:26:41

Android Material Design 详解(使用support v7兼容5.0以下系统)的相关文章

ANDROID L——Material Design详解(UI控件)

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lollipop(5.0). 前几天发现Android5.0正式版的sdk已经可以下载了,而且首次搭载Android L系统的Nexus 6和 Nexus 9也即将上市. 所以是时候开始学习Android L了! 关于Android L如何配置模拟器和创建项目,如果大家有兴趣的话可以看看我之前的一篇文章: A

ANDROID L——Material Design详解(视图和阴影)

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: 昨天凌晨Google刚刚确认Android L就是Android Lollipop(5.0). Google之前就已经提前推出了Android L Developer Preview(开发者预览版)来帮助开发者更快的了解Android特性,而不久前也推出了64位的模拟器镜像,而且首次搭载Android L系统的Nexus 6和 Nexus 9也即将上市. 相信And

ANDROID L——Material Design详解(动画篇)

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lollipop(5.0). 前几天发现Android5.0正式版的sdk已经可以下载了,而且首次搭载Android L系统的Nexus 6和 Nexus 9也即将上市. 所以是时候开始学习Android L了! 关于Android L如何配置模拟器和创建项目,如果大家有兴趣的话可以看看我之前的一篇文章: A

[转]ANDROID L——Material Design详解(动画篇)

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 转自:http://blog.csdn.net/a396901990/article/details/40187203 Android L: Google已经确认Android L就是Android Lollipop(5.0). 前几天发现Android5.0正式版的sdk已经可以下载了,而且首次搭载Android L系统的Nexus 6和 Nexus 9也即将上市. 所以是时候开始学习

ANDROID L——Material Design详解(主题和布局)

Android L: Android L可能就是Android Lollipop或者Lemon Pie(4.5或者5.0),因为Google一直以来都是用甜点为版本命名. Google之前就已经提前推出了Android L Developer Preview(开发者预览版)来帮助开发者更快的了解Android特性,而不久前也推出了64位的模拟器镜像.相信Android L正式版也不远了,所以是时候开始学习Android L了. 关于Android L如何配置模拟器和创建项目,如果大家有兴趣的话可

[转]Android 5.0——Material Design详解(动画篇)

Material Design:Google推出的一个全新的设计语言,它的特点就是拟物扁平化. Material Design包含了很多内容,今天跟大家分享一下Material新增的动画: 在Android L中新增了如下几种动画: * middot;Touch feedback(触摸反馈) * middot;Reveal effect(揭露效果) * middot;Activity transitions(Activity转换效果) * middot;Curved motion(曲线运动) *

Android Material Design 兼容库的使用

Android Material Design 兼容库的使用 mecury 前言:近来学习了Android Material Design 兼容库,为了把这个弄懂,才有了这篇博客,这里先推荐两篇博客:1.Android Material Design 兼容库的使用详解2.Android应用Design Support Library完全使用实例第一篇博客是这个兼容库的详细解析,我参考了里面的许多内容,第二篇是兼容库的大致介绍,如果你能把这两篇全部弄懂,我这篇也没有必要看了.说了这么多,开始正文吧

android:ToolBar详解

这篇文章因为是台湾人写的,语言风格很别致.本文在原文的基础上做了一些微调(主要是繁体字的问题). 今年(2014) 的 google i/o 发表令多数人为之一亮的 material design,而 google 也从「google i/o 2014」 开始,大家也陆陆续续地看到其更新的 android app 皆套用了这个设计介面.当然,这个设计介面著实让大家感到惊艳外,更让 android 开发者开始担心未来 app 的界面处理了. 不过,所幸有着之前 actionbar 的经验后,and

Android Material Design学习之RecyclerView代替 ListView

前言 # Android Material Design越来越流行,以前很常用的 ListView 现在也用RecyclerView代替了,实现原理还是相似的.笔者实现一下 RecyclerView,代码比较简单,适合初学者,如有错误,欢迎指出. 源码地址(欢迎star) https://github.com/studychen/SeeNewsV2 本文链接 http://blog.csdn.net/never_cxb/article/details/50495505,转载请注明出处. 复习 L