Android support library支持包常用控件介紹(二)

谷歌官方推出Material Design 設計理念已經有段時間了,爲支持更方便的實現
Material Design設計效果,官方給出了Android support design library 支持庫,讓開發者更容易的實現材料設計的效果。順便推薦官方的一個圖標庫:Material Icons

控件名稱
NavigationView
FloatingActionButton
TextInputLayout
Snackbar
TabLayout
AppBarLayout
CoordinatorLayout
CollapsingToolbarLayout
Coordinator.Behavior
BottomSheet
BottomSheetDialog

以上請參閱:Android support library支持包常用控件介紹(一)

控件名稱
Bottom Sheet

以下控件爲v7包中

控件名稱
RecyclerView
CardView
palette

以下控件爲v4包中

控件名稱
DrawerLayout
SwipeRefreshLayout

一、BottomSheetBehavior

  • compile ‘com.android.support:design:23.2.1’

*
Bottom Sheets控件,一個底部表,就是我們經常在分享或者地圖、音樂等app看到的效果。

Bottom Sheet

下面說下具體實現:

佈局文件:

<?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/cl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:behavior_hideable="true"
        app:behavior_peekHeight="50dp"
        app:layout_behavior="@string/bottom_sheet_behavior"
        >
        <!-- NestedScrollView裏設置你的底部表長什麼樣的-->

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

            <TextView
                android:id="@+id/tv"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="?attr/colorAccent"
                android:gravity="center"
                android:text="點擊 或者 拖動我"
                android:textColor="@android:color/white"/>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="centerCrop"
                android:layout_margin="10dp"
                android:src="@drawable/header"/>

            <ImageView
                android:layout_marginRight="10dp"
                android:layout_marginLeft="10dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="centerCrop"
                android:src="@drawable/header"/>

        </LinearLayout>


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

java代碼:

 // The View with the BottomSheetBehavior
        CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.cl);
        View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
        final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                //這裏是bottomSheet 狀態的改變,根據slideOffset可以做一些動畫
                Log.i("TAG", "newState--->" + newState);
//                ViewCompat.setScaleX(bottomSheet,1);
//                ViewCompat.setScaleY(bottomSheet,1);
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                //這裏是拖拽中的回調,根據slideOffset可以做一些動畫
                Log.i("TAG", "slideOffset=====》" + slideOffset);

            }
        });

        findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (behavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {
                    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                } else {
                    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                }
            }
        });
  • 通過附加一個BottomSheetBehavior 給CoordinatorLayout的子視圖,上文xml中的是NestedScrollView(adding app:layout_behavior = ” android.support.design.widget.BottomSheetBehavior”),當然,RecyclerView也是可以的。

    • app:behavior_hideable=”true”
    • app:behavior_peekHeight=”50dp”
  • peekHeight是當Bottom Sheets關閉的時候,底部下表我們能看到的高度,hideable 是當我們拖拽下拉的時候,bottom sheet是否能全部隱藏。 如果你需要監聽Bottom Sheets回調的狀態,可以通過setBottomSheetCallback來實現,onSlide方法是拖拽中的回調,根據slideOffset可以做一些動畫 onStateChanged方法可以監聽到狀態的改變,總共有5種:

  • STATE_COLLAPSED: 關閉Bottom Sheets,顯示peekHeight的高度,默認是0

  • STATE_DRAGGING: 用戶拖拽Bottom Sheets時的狀態
  • STATE_SETTLING: 當Bottom Sheets view釋放時記錄的狀態。
  • STATE_EXPANDED: 當Bottom Sheets 展開的狀態
  • STATE_HIDDEN: 當Bottom Sheets 隱藏的狀態

二、RecyclerView

  • compile ‘com.android.support:appcompat-v7:23.2.1’

  • RecylerView是support-v7包中的新組件,是一個強大的滑動組件,與經典的ListView相比,同樣擁有item回收複用的功能,這一點從它的名字recylerview即回收view也可以看出。

RecyclerView

recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this );
//設置佈局管理器
recyclerView.setLayoutManager(layoutManager);
//設置爲垂直佈局,這也是默認的
layoutManager.setOrientation(OrientationHelper. VERTICAL);
//設置Adapter
recyclerView.setAdapter( recycleAdapter);
 //設置分隔線
recyclerView.addItemDecoration( new DividerGridItemDecoration(this ));
//設置增加或刪除條目的動畫
recyclerView.setItemAnimator( new DefaultItemAnimator());

現在說下RecyclerView的常用操作,強烈推薦使用RecyclerView替代ListView。

    private RecyclerView recyclerView;
    private MyrecycleAdapter recycleAdapter;


    List<String> mData = new ArrayList<>();
        for (int i = 0;i<50;i++){
            mData.add("我是第"+(i+1)+"個");
        }
        recycleAdapter = new MyrecycleAdapter(mData);
        recyclerView = (RecyclerView) findViewById(R.id.rcyl_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this );
        //設置佈局管理器
        recyclerView.setLayoutManager(layoutManager);
        //設置爲垂直佈局,這也是默認的
        layoutManager.setOrientation(OrientationHelper.VERTICAL);
        //設置Adapter
        recyclerView.setAdapter(recycleAdapter);

adapter:

 class MyrecycleAdapter extends RecyclerView.Adapter<MyrecycleAdapter.MyViewHolder>{

        List<String> mData = new ArrayList<>();
        public MyrecycleAdapter(List<String> mData){
            this.mData = mData;
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            View view = View.inflate(parent.getContext(),R.layout.item_view,null);
            MyViewHolder holder= new MyViewHolder(view);
            return holder;

        }

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

            holder.tv.setText(mData.get(position));
        }

        @Override
        public int getItemCount() {

            return mData.size();
        }
         class MyViewHolder extends RecyclerView.ViewHolder{

             TextView tv;
             public MyViewHolder(View itemView) {
                 super(itemView);
                 tv = (TextView) itemView.findViewById(R.id.tv);
             }

         }
    }

xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:scrollbarAlwaysDrawVerticalTrack="true"
    android:id="@+id/rcyl_view"
    android:layout_height="match_parent"/>

item_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView  xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:id="@+id/tv"
        android:textSize="22sp"
        android:textColor="#000"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:gravity="center"/>

RecyclerView.Adapter,需要實現3個方法:

  1. onCreateViewHolder()
    這個方法主要生成爲每個Item inflater出一個View,但是該方法返回的是一個ViewHolder。該方法把View直接封裝在ViewHolder中,然後我們面向的是ViewHolder這個實例,當然這個ViewHolder需要我們自己去編寫。直接省去了當初的convertView.setTag(holder)和convertView.getTag()這些繁瑣的步驟。
  2. onBindViewHolder()
    這個方法主要用於適配渲染數據到View中。方法提供給你了一個viewHolder,而不是原來的convertView。
  3. getItemCount()
    這個方法就類似於BaseAdapter的getCount方法了,即總共有多少個條目。

這裏只是介紹下RecyclerView的基本常用操作,具體細節請參照博客:
* http://blog.csdn.net/lmj623565791/article/details/45059587

三、SwipeRefreshLayout

  • compile ‘com.android.support:appcompat-v7:23.2.1’

  • google自己推出的下拉刷新組件SwipeRefreshLayout。

SwipeRefreshLayout
沿用RecycleView的例子:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_height="match_parent"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent">

    <android.support.v7.widget.RecyclerView
        android:orientation="vertical"
        android:scrollbarAlwaysDrawVerticalTrack="true"
        android:id="@+id/rcyl_view"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>

</android.support.v4.widget.SwipeRefreshLayout>
final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_container);
               //設置刷新時動畫的顏色,可以設置4個
       swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light);

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                recyclerView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mData.add(0,"aaaa");
                        mData.add(0,"aaaa");
                        mData.add(0, "aaaa");

                        recycleAdapter.notifyDataSetChanged();

                        swipeRefreshLayout.setRefreshing(false);
                    }
                },2000);
            }
        });

除了OnRefreshListener接口外,SwipRefreshLayout中還有一些其他重要的方法,具體如下:

    1、setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):設置手勢滑動監聽器。

     2、setProgressBackgroundColor(int colorRes):設置進度圈的背景色。

     3、setColorSchemeResources(int… colorResIds):設置進度動畫的顏色。

     4、setRefreshing(Boolean refreshing):設置組件的刷洗狀態。

     5、setSize(int size):設置進度圈的大小,只有兩個值:DEFAULT、LARGE

四、CardView

  • compile ‘com.android.support:appcompat-v7:23.2.1’

  • CardView繼承至FrameLayout類,可以在一個卡片佈局中一致性的顯示內容,卡片可以包含圓角和陰影。經常在ListView和RecyclerView的Item佈局中,作爲一種容器使用。

CardView 提供了一個默認的elevation,也就是Z軸的陰影。和圓角角度,每一個卡片都能夠在不同的設備上保持相同的外觀。

CardView


<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="8dp"
    card_view:cardElevation="8dp">

<!-- Content View-->

</android.support.v7.widget.CardView>
  • cardElevation屬性被用來決定陰影的大小和柔和度。

1.增加波紋點擊效果

//添加如下屬性
 android:clickable="true"
 android:foreground="?android:attr/selectableItemBackground"

使用android:foreground=”?android:attr/selectableItemBackground”可以使CardView點擊產生波紋效果,由觸點向外擴散。目前測試僅在5.0以後系統有效。

2.保持兼容性(對更早版本的支持)

在Android L 之前的設備上,CardView爲了支持圓角效果加上了padding。對陰影效果來說,在Android L 之前,也會提供padding去繪製陰影面積,這些內容的padding是和elevation的屬性相關的:

  • padding的值:

    • 左右兩邊的值 = maxCardElevation + (1 - cos45)*cornerRadius
    • 上下兩邊的值 = maxCardElevation * 1.5 + (1 - cos45)*cornerRadius
  • 如果你想要給自己的內容加上padding的話,需使用新屬性:
    card_view:contentPadding

  • 如果改變CardView的背景,也需要使用新屬性:
    card_view:cardBackgroundColor
  • cardMaxElevation:最大卡片陰影的寬度

注意:

關於Android 5.0以上使用v7包的CardView沒有陰影效果的問題。在CardView添加如下屬性即可:
    card_view:cardPreventCornerOverlap="true"
    card_view:cardUseCompatPadding="true"

五、Palette

  • compile ‘com.android.support:palette-v7:22.2.0’

Palette類是Android5.0引進來的一個獲取Bitmap顏色值的類。也在v7 Library包中。

// 用來提取顏色的Bitmap
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                SuperAwesomeCardFragment.getBackgroundBitmapPosition(position));
        // Palette的部分 同步
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
            /**
             * 提取完之後的回調方法
             */
            @Override
            public void onGenerated(Palette palette) {
                Palette.Swatch vibrant = palette.getVibrantSwatch();

            }
        });
        //異步
        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener(){
        @Override
            public void onGenerated(Palette palette) {
                Palette.Swatch vibrant = palette.getVibrantSwatch();//有活力
                if(vibrant != null){
                    //vibrant.getRgb();
                    //vibrant.getTitleTextColor
                }

            }

        })

工具方法:

/**
     * 顏色加深處理
     *
     * @param RGBValues
     *            RGB的值,由alpha(透明度)、red(紅)、green(綠)、blue(藍)構成,
     *            Android中我們一般使用它的16進制,
     *            例如:"#FFAABBCC",最左邊到最右每兩個字母就是代表alpha(透明度)、
     *            red(紅)、green(綠)、blue(藍)。每種顏色值佔一個字節(8位),值域0~255
     *            所以下面使用移位的方法可以得到每種顏色的值,然後每種顏色值減小一下,在合成RGB顏色,顏色就會看起來深一些了
     * @return
     */
    private int colorBurn(int RGBValues) {
        int alpha = RGBValues >> 24;
        int red = RGBValues >> 16 & 0xFF;
        int green = RGBValues >> 8 & 0xFF;
        int blue = RGBValues & 0xFF;
        red = (int) Math.floor(red * (1 - 0.1));
        green = (int) Math.floor(green * (1 - 0.1));
        blue = (int) Math.floor(blue * (1 - 0.1));
        return Color.rgb(red, green, blue);
    }

對圖像的處理有可能是耗時操作,因此Palette類獲得的顏色通過onGenerated回調的方法來獲取。
Palette類獲得的顏色值有以下幾種類型:

Palette.Swatch a =

palette.getVibrantSwatch();//有活力
palette.getDarkVibrantSwatch();//有活力  暗色
palette.getLightVibrantSwatch();//有活力 亮色
palette.getMutedSwatch();//柔和
palette.getDarkMutedSwatch();//柔和 暗色
palette.getLightMutedSwatch();//柔和 亮色

a.getBodyTextColor();//內容顏色
a.getTitleTextColor();//標題顏色
a.getRgb();//rgb顏色

五、DrawerLayout

  • compile ‘com.android.support:appcompat-v7:23.2.1’

注:因爲v7中包含v4包,故這裏導入的v7.

  • 側滑抽屜效果的DrawerLayout。

這裏寫圖片描述

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <!-- -->
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

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

app_bar_main.xml:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tf.globalapplication.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:layout_scrollFlags="scroll|enterAlways" />
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

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

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

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

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

java:

 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
 setSupportActionBar(toolbar);

 DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        //drawer.setDrawerListener(toggle);
        drawer.addDrawerListener(toggle);
        toggle.syncState();
  • android:layout_gravity=”start” 表示側滑欄在左側。end爲在右側。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章