一個Demo學會用Android兼容包新控件

前言

偉大的Google爲Android推出了一系列的兼容包,最新的就是Design Support Library了,這裏咱們結合v7和v4中的幾個控件,來主要學習Design Support Library中的幾個新控件!一個Demo學會用它們!java

效果動圖GIF:

學習內容

經過本實例能夠學習到如下內容:android

  • Drawerlayout和NavigationView實現優雅的Google範兒側邊欄;git

  • 新控件CoordinatorLayout、AppBarLayout、Toolbar、FloatingActionButton的用法,以及Toolbar的漸變隱藏動畫效果;github

  • 官方Tabs組件TabLayout和ViewPager結合實現主界面內容區域;app

  • SwipeRefreshLayout和RecyclerView結合實現下拉刷新,以及RecyclerView的數據適配器RecyclerView.Adapter的用法,還有RecyclerView中item的點擊事件的實現方法;ide

  • 卡片式CardView的用法;佈局

  • 相似Toast的新控件Snackbar的用法。學習

佈局文件

在源碼中學習Android,是有種身臨其境的感受的。字體

學習Android解釋再多代碼都沒有用,由於解釋過了仍是不會用。所以,咱們這裏將佈局文件XML源碼貼出來供學習,放心,全部知識點都已經註釋在源碼中。gradle

styles.xml源碼

<resources>
 
    <style name="AppTheme" parent="MyThemeBlue"></style>
 
    <!-- 藍色爲主色調 -->
    <style name="MyThemeBlue" parent="Theme.AppCompat.Light.NoActionBar">
 
        <!--選中狀態icon的顏色和字體顏色-->
        <item name="colorPrimary">@color/main_blue_light</item>
        <item name="colorPrimaryDark">@color/main_blue_dark</item>
        <item name="colorAccent">@color/main_blue_light</item>
        <!--正常狀態下字體顏色和icon顏色-->
        <item name="android:textColorPrimary">@color/main_white</item>
 
    </style>
</resources>

colorPrimary、colorPrimaryDark、colorAccent、textColorPrimary的含義,請看博文《Android L+ Theme 與 Toolbar 實例》

主佈局activity_my.xml源碼(重點)

<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/id_drawerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- 第一個位置 -->
    <!-- 你的主界面內容,必須放置在Drawerlayout中的第一個位置
    根據本身的須要來放置控件,
        例如:LinearLayout佈局或者RelativeLayout佈局;
    也能夠是單個控件,
        如 TextView等  -->
    <include layout="@layout/content_main" />
 
 
    <!-- 第二個位置 -->
    <!-- 用來放Drawerlayout中的內容,
    這裏使用NavigationView來實現相似Google pLay中的側滑欄效果,
    必須在build.gradle中添加compile 'com.android.support:design:22.2.0';
    另外,若是不須要NavigationView效果,
    也能夠放置一個普通佈局文件就是一個普通的側滑欄了。
     -->
 
    <!--
     注意:
        若是使用NavigationView(其餘控件也是同樣)的特有屬性,須要加上命名空間:
                xmlns:app="http://schemas.android.com/apk/res-auto";
        另外,必定要添加android:layout_gravity="left"屬性。
     -->
 
    <!--
        屬性解析:
            app:headerLayout:    NavigationView中頭部的head部分的佈局,是本身實現的;
            app:menu:            指定Nav中的Menu佈局,就是本身寫Menu中的按鈕,要放在res/menu/文件夾下;
            app:itemTextColor:  用來設置Nav中,menu item的顏色選擇器。
        還有一些屬性:           和itemTextColor用法同樣,指定一個顏色選擇器,實現不一樣的顏色效果。
            app:itemIconTint:
            app:itemBackground:
    -->
    <android.support.design.widget.NavigationView
        android:id="@+id/id_navigationview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:itemTextColor="@color/selector_nav_menu_textcolor"
        android:layout_gravity="left" />
 
</android.support.v4.widget.DrawerLayout>

content_main.xml源碼(重點)

<?xml version="1.0" encoding="utf-8"?><!--
    CoordinatorLayout是此次新添加的一個加強型的FrameLayout,經過它能夠實現不少東西:
        例如:
            1.界面向上滾動逐漸隱藏Toolbar;
            2.在其中能夠放置浮動的View,就像Floating Action Button。
-->
<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/id_coordinatorlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
 
 
    <!--
        AppBarLayout跟它的名字同樣,把容器類的組件所有做爲AppBar。
            將AppBarLayout放在CoordinatorLayout中,就能夠實現滾動效果。
            本例中,TabLayout在界面滾動時,隨着Toolbar的逐漸隱藏,將佔據Toolbar的位置,
                達到節省屏幕空間,界面動畫效果的目的。
    -->
    <android.support.design.widget.AppBarLayout
        android:id="@+id/id_appbarlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
 
 
        <!--
 
        屬性解析:
            app:theme:指定Toolbar的樣式,包括ActionbarToggle和popupMenu的指示圖標顏色
            app:popupTheme:指定popupMenu溢出後的樣式
            app:title:    指定Toolbar中主Title的內容
        -->
 
        <!--
            app:layout_scrollFlags的意思是:
 
                設置的layout_scrollFlags有以下幾種選項:
                    scroll: 全部想滾動出屏幕的view都須要設置這個flag- 沒有設置這個flag的view將被固定在屏幕頂部。
                    enterAlways: 這個flag讓任意向下的滾動都會致使該view變爲可見,啓用快速「返回模式」。
                    enterAlwaysCollapsed: 當你的視圖已經設置minHeight屬性又使用此標誌時,你的視圖只能以最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。
                    exitUntilCollapsed: 當視圖會在滾動時,它一直滾動到設置的minHeight時徹底隱藏。
 
            須要注意的是,後面兩種模式基本只有在CollapsingToolbarLayout纔有用,
            而前面兩種模式基本是須要一塊兒使用的,也就是說,這些flag的使用場景,基本已經固定了。
        -->
        <android.support.v7.widget.Toolbar
            android:id="@+id/id_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:title="@string/toolbar_title" />
 
        <!--
            Tabs選項卡,和ViewPager搭配使用能夠增大界面的內容展現量,實現各類個性化分類內容展現而不互相干擾!
            Google在Design support library中提供官方的Tab組件,它就是TabLayout。
            相比Github上面開源的第三方庫,這個更加簡單易用。
 
            有如下經常使用屬性:
                app:tabGravity="fill"  表示TabLayout中的Tabs要佔滿屏幕的width;
                app:tabSelectedTextColor:Tab被選中字體的顏色;
                app:tabTextColor:Tab未被選中字體的顏色;
                app:tabIndicatorColor:Tab指示器下標的顏色;
        -->
        <android.support.design.widget.TabLayout
            android:id="@+id/id_tablayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabGravity="fill"
            app:tabIndicatorColor="@color/main_white" />
 
    </android.support.design.widget.AppBarLayout>
 
    <!--
        咱們經常使用的ViewPager,很少說了。你會發現多了一個 app:layout_behavior 屬性,沒錯,
            若是你使用CoordinatorLayout來實現Toolbar滾動漸變消失動畫效果,那就必須在它下面的那個控件中加入這個屬性,
            而且下面的這個控件必須是可滾動的。
        當設置了layout_behavior的控件滑動時,就會觸發設置了layout_scrollFlags的控件發生狀態的改變。
    -->
    <android.support.v4.view.ViewPager
        android:id="@+id/id_viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 
 
    <!--
        這是一個浮動按鈕。因爲FloatingActionButton是重寫ImageView的,
        全部FloatingActionButton擁有ImageView的一切屬性。
 
        屬性介紹:
            app:backgroundTint : FAB的背景色。
            app:elevation      :FAB的陰影效果。
            app:rippleColor    :設置漣漪的顏色,默認是由背景色生成的暗色調,能夠本身指定。
            app:pressedTranslationZ  :FAB動畫效果,在它被按下的時候陰影就會增大。
    -->
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/id_floatingactionbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:src="@mipmap/ic_action_plusone"
        app:backgroundTint="@color/main_blue_light"
        app:elevation="6dp"
        app:pressedTranslationZ="12dp"
        app:rippleColor="@color/main_blue_dark" />
 
</android.support.design.widget.CoordinatorLayout>

frag_main.xml源碼(Fragment的佈局)

<?xml version="1.0" encoding="utf-8"?>
 
 
<!--
 
SwipeRefreshLayout是偉大的Google在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/id_swiperefreshlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
 
    <!--
            使用RecyclerView須要在build.gradle中添加
           compile 'com.android.support:recyclerview-v7:22.2.0'
    -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/id_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
 
 
</android.support.v4.widget.SwipeRefreshLayout>

item_main.xml源碼(RecyclerView中item)

<!--
    CardView就是一個卡片樣式的FrameLayout。
 
    參數介紹:
        app:cardBackgroundColor  :   背景顏色
        app:cardCornerRadius    :   設置圓角。
        app:cardElevation       :    陰影。
        app:cardMaxElevation    :       最大陰影。
        app:cardPreventCornerOverlap  : 在v20和以前的版本中添加內邊距,
                                    這個屬性是爲了防止卡片內容和邊角的重疊。
 
       app:cardUseCompatPadding  :  設置內邊距,v21+的版本和以前的版本仍舊具備同樣的計算方式
-->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/id_cardview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    app:cardBackgroundColor="@color/main_blue_light"
    app:cardCornerRadius="4dp"
    app:cardElevation="5dp"
    app:cardMaxElevation="10dp"
    app:cardPreventCornerOverlap="true"
    app:cardUseCompatPadding="true">
 
    <TextView
        android:id="@+id/id_textview"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:textColor="@color/main_white"
        android:textSize="30sp" />
 
</android.support.v7.widget.CardView>

menu_nav.xml的源碼(NavagationView中菜單)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
 
 
    <group android:checkableBehavior="single">
 
        <item
            android:id="@+id/nav_menu_home"
            android:icon="@mipmap/ic_home_white_48dp"
            android:title="主頁" />
 
        <item
            android:id="@+id/nav_menu_categories"
            android:icon="@mipmap/ic_sort_by_alpha_white_48dp"
            android:title="分類" />
 
        <item
            android:id="@+id/nav_menu_feedback"
            android:icon="@mipmap/ic_message_white_48dp"
            android:title="反饋" />
        <item
            android:id="@+id/nav_menu_setting"
            android:icon="@mipmap/ic_settings_white_48dp"
            android:title="設置" />
 
    </group>
</menu>

header_nav.xml源碼(NavagationView的head)

<?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="220dp"
    android:background="@drawable/ic_user_background"
    android:gravity="center"
    android:orientation="vertical">
 
        <!--
            一個顯示圓形頭像的自定義ImageView
        -->
    <com.sunjiajia.androidnewwidgetsdemo.view.RoundedImageView
        android:id="@+id/id_header_face"
        android:layout_width="110dp"
        android:layout_height="110dp"
        android:scaleType="fitXY"
        android:src="@drawable/author" />
 
    <TextView
        android:id="@+id/id_header_authorname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/header_author_name"
        android:textColor="@android:color/black"
        android:textSize="16sp" />
 
    <TextView
        android:id="@+id/id_header_url"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/header_author_url"
        android:textColor="@android:color/black"
        android:textSize="18sp" />
</LinearLayout>

Java代碼

Java代碼寫法比較簡單,這裏只給出RecyclerView.Adapter的寫法(包括item點擊事件)。

RecyclerView.Adapter寫法源碼

package com.sunjiajia.androidnewwidgetsdemo.adapter;
 
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
 
import com.sunjiajia.androidnewwidgetsdemo.R;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * Created by Monkey on 2015/6/29.
 */
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHolder> {
 
    // 點擊事件接口
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
 
        void onItemLongClick(View view, int position);
    }
 
    public OnItemClickListener mOnItemClickListener;
 
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }
 
 
    public Context mContext;
    public List<String> mDatas;
    public LayoutInflater mLayoutInflater;
 
    public MyRecyclerViewAdapter(Context mContext) {
        this.mContext = mContext;
        mLayoutInflater = LayoutInflater.from(mContext);
        // 這裏是模擬數據。
        mDatas = new ArrayList<>();
        for (int i = 'A'; i <= 'z'; i++) {
            mDatas.add((char) i + "");
        }
    }
 
    /**
     * 建立ViewHolder
     */
    @Override
    public MyRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View mView = mLayoutInflater.inflate(R.layout.item_main, parent, false);
        MyRecyclerViewHolder mViewHolder = new MyRecyclerViewHolder(mView);
        return mViewHolder;
    }
 
    /**
     * 綁定ViewHoler,給item中的控件設置數據
     */
    @Override
    public void onBindViewHolder(final MyRecyclerViewHolder holder, final int position) {
        //點擊事件在這裏實現,主要是利用RecyclerView中填充的佈局控件能夠被點擊這個原理
        if (mOnItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onItemClick(holder.itemView, position);
                }
            });
 
            // 長點擊事件
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mOnItemClickListener.onItemLongClick(holder.itemView, position);
                    return true;
                }
            });
 
        }
 
        holder.mTextView.setText(mDatas.get(position));
    }
 
    @Override
    public int getItemCount() {
        return mDatas.size();
    }
}

MyRecyclerViewHolder.java源碼

package com.sunjiajia.androidnewwidgetsdemo.adapter;
 
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
 
import com.sunjiajia.androidnewwidgetsdemo.R;
 
/**
 * Created by Monkey on 2015/6/29.
 */
public class MyRecyclerViewHolder extends RecyclerView.ViewHolder {
 
    public TextView mTextView;
 
    public MyRecyclerViewHolder(View itemView) {
        super(itemView);
        mTextView = (TextView) itemView.findViewById(R.id.id_textview);
    }
}

結語

在源碼中學習Android,是有種身臨其境的感受的。

整個Demo的源碼我放在了GitHub上,謝謝star一下~
在看源碼過程當中若是發現什麼問題,請在留言,看到必定回覆。

源碼地址:
AndroidNewWidgetsDemo

來自: http://sunjiajia.com/2015/07/02/android-new-widgets-demo/

相關文章
相關標籤/搜索