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

wj4630 8年前發布 | 4K 次閱讀 安卓開發 Android開發 移動開發

前言

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

效果動圖GIF:

Design Support Library Demo

學習內容

通過本實例可以學習到以下內容:

  • Drawerlayout和NavigationView實現優雅的Google范兒側邊欄;
  • 新控件CoordinatorLayout、AppBarLayout、Toolbar、FloatingActionButton的用法,以及Toolbar的漸變隱藏動畫效果;
  • 官方Tabs組件TabLayout和ViewPager結合實現主界面內容區域;
  • SwipeRefreshLayout和RecyclerView結合實現下拉刷新,以及RecyclerView的數據適配器RecyclerView.Adapter<ViewHolder>的用法,還有RecyclerView中item的點擊事件的實現方法;
  • 卡片式CardView的用法;
  • 類似Toast的新控件Snackbar的用法。

布局文件

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

學習Android解釋再多代碼都沒有用,因為解釋過了還是不會用。因此,我們這里將布局文件XML源碼貼出來供學習,放心,所有知識點都已經注釋在源碼中。

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></code></pre>

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

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

<android.support.v4.widget.DrawerLayout xmlns:android="

<!-- 第一個位置 -->
<!-- 你的主界面內容,必須放置在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></code></pre>

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

<!--
    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></code></pre>

frag_main.xml源碼(Fragment的布局)

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

<!--

SwipeRefreshLayout是偉大的Google在v4包中給出的下拉刷新組件。

--> <android.support.v4.widget.SwipeRefreshLayout xmlns:android="

<!--
        使用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></code></pre>

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

<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></code></pre>

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

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns: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></code></pre>

header_nav.xml源碼(NavagationView的head)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="

    <!--
        一個顯示圓形頭像的自定義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></code></pre>

Java代碼

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

RecyclerView.Adapter<ViewHolder>寫法源碼

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();
}

}</code></pre>

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);
    

    } }</code></pre>

     

     

     

     

     

    來自:http://www.jianshu.com/p/533f5ecee306

     

 本文由用戶 wj4630 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!