下載地址:https://pan.baidu.com/s/1_1x0nBdv8_QgEgnveOZEZw
CardView是Material Design中引入的另一個(gè)主要元素洞豁。使用CardView,您可以以卡片方式表示信息,其中陰影(仰角)和角半徑在整個(gè)平臺(tái)上看起來是一致的。CardView擴(kuò)展了FrameLayout,并支持返回Android 2.x.
當(dāng)CardView與RecyclerView結(jié)合使用時(shí)竖螃,您可以獲得美觀??的UI。在本文中,我們將學(xué)習(xí)如何通過創(chuàng)建一個(gè)漂亮的音樂應(yīng)用程序來集成CardView和RecyclerView箫荡,該應(yīng)用程序顯示帶有封面圖像和標(biāo)題的音樂專輯。
視頻演示
如何添加CardView渔隶?
要在應(yīng)用程序中使用CardView羔挡,請(qǐng)?jiān)赽uild.gradle中添加CardView依賴項(xiàng)并同步項(xiàng)目。
的build.gradle
dependencies {
????// CardView
????compile 'com.android.support:cardview-v7:23.3.+'
}
將小部件添加到您的布局中间唉,并將其他UI小部件(如TextViews绞灼,ImageViews)放入其中。您可以注意到呈野,下面的CardView小部件包含一個(gè)TextView低矮。
http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
xmlns:card_view="http://schemas.android.com/apk/res-auto"
????????android:id="@+id/card_view"
????????android:layout_gravity="center"
????????android:layout_width="250dp"
????????android:layout_height="250dp"
????????card_view:cardCornerRadius="4dp">
????????????android:text="Hello Card"
????????????android:layout_width="match_parent"
????????????android:layout_height="match_parent"/>
現(xiàn)在讓我們通過創(chuàng)建一個(gè)新項(xiàng)目來實(shí)現(xiàn)這一點(diǎn)。
1.創(chuàng)建新項(xiàng)目
1被冒。從File?NewProject在Android Studio中創(chuàng)建一個(gè)新項(xiàng)目军掂。當(dāng)它提示您選擇默認(rèn)活動(dòng)時(shí),請(qǐng)選擇清空活動(dòng)并繼續(xù)昨悼。
2蝗锥。下載此res.zip并將其添加到您的項(xiàng)目res文件夾中。此res文件夾包含此項(xiàng)目所需的幾個(gè)專輯封面和圖標(biāo)幔戏。
3玛追。將以下字符串,顏色和維度資源添加到strings.xml闲延,colors.xml和dimens.xml文件中痊剖。
strings.xml中
????Card View
????Settings
????Add to Favourites
????Play Next
????LOVE MUSIC
????This season top 20 albums
colors.xml
????#F50057
????#F50057
????#FF4081
????#f1f5f8
????#4c4c4c
dimens.xml
????16dp
????16dp
????16dp
????10dp
????250dp
????30dp
????18dp
????5dp
????0dp
????160dp
????10dp
????15dp
????5dp
????12dp
????20dp
????30dp
????10dp
4。打開build.gradle并添加CardView垒玲,RecyclerView和Glide依賴項(xiàng)陆馁。RecyclerView用于以網(wǎng)格方式顯示相冊(cè)。CardView用于顯示單個(gè)專輯項(xiàng)目合愈。Glide用于顯示專輯封面圖像叮贩。
的build.gradle
dependencies {
????compile fileTree(dir: 'libs', include: ['*.jar'])
????testCompile 'junit:junit:4.12'
????compile 'com.android.support:appcompat-v7:23.3.0'
????compile 'com.android.support:design:23.3.0'
????// RecyclerView
????compile 'com.android.support:recyclerview-v7:23.3.+'
????// CardView
????compile 'com.android.support:cardview-v7:23.3.+'
????// Glide
????compile 'com.github.bumptech.glide:glide:3.7.0'
}
5击狮。要?jiǎng)?chuàng)建單個(gè)專輯的實(shí)例,我們需要一個(gè)表示專輯屬性的模型類益老,如名稱彪蓬,歌曲數(shù)量和封面圖像。因此捺萌,創(chuàng)建一個(gè)名為Album.java的類并添加以下代碼档冬。
Album.java
packageinfo.androidhive.cardview;
/**
?* Created by Lincoln on 18/05/16.
?*/
publicclassAlbum {
????privateString name;
????privateintnumOfSongs;
????privateintthumbnail;
????publicAlbum() {
????}
????publicAlbum(String name, intnumOfSongs, intthumbnail) {
????????this.name = name;
????????this.numOfSongs = numOfSongs;
????????this.thumbnail = thumbnail;
????}
????publicString getName() {
????????returnname;
????}
????publicvoidsetName(String name) {
????????this.name = name;
????}
????publicintgetNumOfSongs() {
????????returnnumOfSongs;
????}
????publicvoidsetNumOfSongs(intnumOfSongs) {
????????this.numOfSongs = numOfSongs;
????}
????publicintgetThumbnail() {
????????returnthumbnail;
????}
????publicvoidsetThumbnail(intthumbnail) {
????????this.thumbnail = thumbnail;
????}
}
6。我們還需要一個(gè)xm布局來顯示相冊(cè)卡桃纯。在res?布局下創(chuàng)建名為album_card.xml的xml布局酷誓。在這里您可以注意到我添加了并添加了所有相冊(cè)屬性,如名稱态坦,歌曲數(shù)量和封面圖像盐数。我還添加了一個(gè)3點(diǎn)圖標(biāo),在點(diǎn)擊它時(shí)會(huì)顯示一個(gè)彈出菜單伞梯。
album_card.xml
http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
????android:layout_width="match_parent"
????android:layout_height="wrap_content">
????????android:id="@+id/card_view"
????????android:layout_width="match_parent"
????????android:layout_height="match_parent"
????????android:layout_gravity="center"
????????android:layout_margin="@dimen/card_margin"
????????android:elevation="3dp"
????????card_view:cardCornerRadius="@dimen/card_album_radius">
????????????android:layout_width="match_parent"
????????????android:layout_height="match_parent">
????????????????android:id="@+id/thumbnail"
????????????????android:layout_width="match_parent"
????????????????android:layout_height="@dimen/album_cover_height"
????????????????android:background="?attr/selectableItemBackgroundBorderless"
????????????????android:clickable="true"
????????????????android:scaleType="fitXY"/>
????????????????android:id="@+id/title"
????????????????android:layout_width="match_parent"
????????????????android:layout_height="wrap_content"
????????????????android:layout_below="@id/thumbnail"
????????????????android:paddingLeft="@dimen/album_title_padding"
????????????????android:paddingRight="@dimen/album_title_padding"
????????????????android:paddingTop="@dimen/album_title_padding"
????????????????android:textColor="@color/album_title"
????????????????android:textSize="@dimen/album_title"/>
????????????????android:id="@+id/count"
????????????????android:layout_width="match_parent"
????????????????android:layout_height="wrap_content"
????????????????android:layout_below="@id/title"
????????????????android:paddingBottom="@dimen/songs_count_padding_bottom"
????????????????android:paddingLeft="@dimen/album_title_padding"
????????????????android:paddingRight="@dimen/album_title_padding"
????????????????android:textSize="@dimen/songs_count"/>
????????????????android:id="@+id/overflow"
????????????????android:layout_width="@dimen/ic_album_overflow_width"
????????????????android:layout_height="@dimen/ic_album_overflow_height"
????????????????android:layout_alignParentRight="true"
????????????????android:layout_below="@id/thumbnail"
????????????????android:layout_marginTop="@dimen/ic_album_overflow_margin_top"
????????????????android:scaleType="centerCrop"
????????????????android:src="@drawable/ic_dots"/>
7玫氢。在res??菜單文件夾下創(chuàng)建一個(gè)名為menu_album.xml的菜單文件。點(diǎn)擊每個(gè)相冊(cè)卡片項(xiàng)目上的圓點(diǎn)圖標(biāo)壮锻,此菜單將顯示為彈出菜單。
menu_album.xml
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/action_add_favourite"
????????android:orderInCategory="100"
????????android:title="@string/action_add_favourite"/>
????????android:id="@+id/action_play_next"
????????android:orderInCategory="101"
????????android:title="@string/action_play_next"/>
8猜绣。要呈現(xiàn)RecyclerView,我們需要一個(gè)適配器類敬特,通過保留適當(dāng)?shù)男畔?b>擴(kuò)充album_card.xml掰邢。創(chuàng)建一個(gè)名為AlbumsAdapter.java的類并添加以下內(nèi)容。
AlbumsAdapter.java
packageinfo.androidhive.cardview;
importandroid.content.Context;
importandroid.support.v7.widget.PopupMenu;
importandroid.support.v7.widget.RecyclerView;
importandroid.view.LayoutInflater;
importandroid.view.MenuInflater;
importandroid.view.MenuItem;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.ImageView;
importandroid.widget.TextView;
importandroid.widget.Toast;
importcom.bumptech.glide.Glide;
importjava.util.List;
/**
?* Created by Ravi Tamada on 18/05/16.
?*/
publicclassAlbumsAdapter extendsRecyclerView.Adapter {
????privateContext mContext;
????privateList albumList;
????publicclassMyViewHolder extendsRecyclerView.ViewHolder {
????????publicTextView title, count;
????????publicImageView thumbnail, overflow;
????????publicMyViewHolder(View view) {
????????????super(view);
????????????title = (TextView) view.findViewById(R.id.title);
????????????count = (TextView) view.findViewById(R.id.count);
????????????thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
????????????overflow = (ImageView) view.findViewById(R.id.overflow);
????????}
????}
????publicAlbumsAdapter(Context mContext, List albumList) {
????????this.mContext = mContext;
????????this.albumList = albumList;
????}
????@Override
????publicMyViewHolder onCreateViewHolder(ViewGroup parent, intviewType) {
????????View itemView = LayoutInflater.from(parent.getContext())
????????????????.inflate(R.layout.album_card, parent, false);
????????returnnewMyViewHolder(itemView);
????}
????@Override
????publicvoidonBindViewHolder(finalMyViewHolder holder, intposition) {
????????Album album = albumList.get(position);
????????holder.title.setText(album.getName());
????????holder.count.setText(album.getNumOfSongs() + " songs");
????????// loading album cover using Glide library
????????Glide.with(mContext).load(album.getThumbnail()).into(holder.thumbnail);
????????holder.overflow.setOnClickListener(newView.OnClickListener() {
????????????@Override
????????????publicvoidonClick(View view) {
????????????????showPopupMenu(holder.overflow);
????????????}
????????});
????}
????/**
?????* Showing popup menu when tapping on 3 dots
?????*/
????privatevoidshowPopupMenu(View view) {
????????// inflate menu
????????PopupMenu popup = newPopupMenu(mContext, view);
????????MenuInflater inflater = popup.getMenuInflater();
????????inflater.inflate(R.menu.menu_album, popup.getMenu());
????????popup.setOnMenuItemClickListener(newMyMenuItemClickListener());
????????popup.show();
????}
????/**
?????* Click listener for popup menu items
?????*/
????classMyMenuItemClickListener implementsPopupMenu.OnMenuItemClickListener {
????????publicMyMenuItemClickListener() {
????????}
????????@Override
????????publicbooleanonMenuItemClick(MenuItem menuItem) {
????????????switch(menuItem.getItemId()) {
????????????????caseR.id.action_add_favourite:
????????????????????Toast.makeText(mContext, "Add to favourite", Toast.LENGTH_SHORT).show();
????????????????????returntrue;
????????????????caseR.id.action_play_next:
????????????????????Toast.makeText(mContext, "Play next", Toast.LENGTH_SHORT).show();
????????????????????returntrue;
????????????????default:
????????????}
????????????returnfalse;
????????}
????}
????@Override
????publicintgetItemCount() {
????????returnalbumList.size();
????}
}
9伟阔。打開布局文件主要活動(dòng)activity_main.xml和content_main.xml辣之,添加AppBarLayout,CollapsingToolbarLayout皱炉,Toolbar和RecyclerView怀估。
activity_main.xml中
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:background="@android:color/white"
????android:fitsSystemWindows="true">
????????android:id="@+id/appbar"
????????android:layout_width="match_parent"
????????android:layout_height="@dimen/detail_backdrop_height"
????????android:fitsSystemWindows="true"
????????android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
????????????android:id="@+id/collapsing_toolbar"
????????????android:layout_width="match_parent"
????????????android:layout_height="match_parent"
????????????android:fitsSystemWindows="true"
????????????app:contentScrim="?attr/colorPrimary"
????????????app:expandedTitleMarginEnd="64dp"
????????????app:expandedTitleMarginStart="48dp"
????????????app:expandedTitleTextAppearance="@android:color/transparent"
????????????app:layout_scrollFlags="scroll|exitUntilCollapsed">
????????????????android:layout_width="wrap_content"
????????????????android:layout_height="wrap_content">
????????????????????android:id="@+id/backdrop"
????????????????????android:layout_width="match_parent"
????????????????????android:layout_height="match_parent"
????????????????????android:fitsSystemWindows="true"
????????????????????android:scaleType="centerCrop"
????????????????????app:layout_collapseMode="parallax"/>
????????????????????android:layout_width="wrap_content"
????????????????????android:layout_height="wrap_content"
????????????????????android:layout_centerInParent="true"
????????????????????android:gravity="center_horizontal"
????????????????????android:orientation="vertical">
????????????????????????android:id="@+id/love_music"
????????????????????????android:layout_width="wrap_content"
????????????????????????android:layout_height="wrap_content"
????????????????????????android:text="@string/backdrop_title"
????????????????????????android:textColor="@android:color/white"
????????????????????????android:textSize="@dimen/backdrop_title"/>
????????????????????????android:layout_width="wrap_content"
????????????????????????android:layout_height="wrap_content"
????????????????????????android:text="@string/backdrop_subtitle"
????????????????????????android:textColor="@android:color/white"
????????????????????????android:textSize="@dimen/backdrop_subtitle"/>
????????????????android:id="@+id/toolbar"
????????????????android:layout_width="match_parent"
????????????????android:layout_height="?attr/actionBarSize"
????????????????app:layout_collapseMode="pin"
????????????????app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
content_main.xml
content_main.xml
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"
????android:background="@color/viewBg"
????app:layout_behavior="@string/appbar_scrolling_view_behavior"
????tools:context="info.androidhive.cardview.MainActivity"
????tools:showIn="@layout/activity_main">
????????android:id="@+id/recycler_view"
????????android:layout_width="match_parent"
????????android:layout_height="wrap_content"
????????android:clipToPadding="false"
????????android:scrollbars="vertical"/>
10。最后打開MainActivity.java并進(jìn)行必要的更改合搅。
>?initCollapsingToolbar()- 在折疊或展開工具欄時(shí)顯示或隱藏工具欄標(biāo)題多搀。
>?prepareAlbums()- 添加回收站視圖所需的樣本專輯數(shù)據(jù)。
>?GridLayoutManager用于以網(wǎng)格方式而不是列表顯示RecyclerView灾部。
>?GridSpacingItemDecoration用于在RecyclerView網(wǎng)格項(xiàng)周圍提供相等的邊距康铭。
>?AlbumsAdapter實(shí)例已創(chuàng)建并分配給RecyclerView,后者以網(wǎng)格方式呈現(xiàn)CardView相冊(cè)赌髓。
MainActivity.java
packageinfo.androidhive.cardview;
importandroid.content.res.Resources;
importandroid.graphics.Rect;
importandroid.os.Bundle;
importandroid.support.design.widget.AppBarLayout;
importandroid.support.design.widget.CollapsingToolbarLayout;
importandroid.support.v7.app.AppCompatActivity;
importandroid.support.v7.widget.DefaultItemAnimator;
importandroid.support.v7.widget.GridLayoutManager;
importandroid.support.v7.widget.RecyclerView;
importandroid.support.v7.widget.Toolbar;
importandroid.util.TypedValue;
importandroid.view.View;
importandroid.widget.ImageView;
importcom.bumptech.glide.Glide;
importjava.util.ArrayList;
importjava.util.List;
publicclassMainActivity extendsAppCompatActivity {
????privateRecyclerView recyclerView;
????privateAlbumsAdapter adapter;
????privateList albumList;
????@Override
????protectedvoidonCreate(Bundle savedInstanceState) {
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_main);
????????Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
????????setSupportActionBar(toolbar);
????????initCollapsingToolbar();
????????recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
????????albumList = newArrayList<>();
????????adapter = newAlbumsAdapter(this, albumList);
????????RecyclerView.LayoutManager mLayoutManager = newGridLayoutManager(this, 2);
????????recyclerView.setLayoutManager(mLayoutManager);
????????recyclerView.addItemDecoration(newGridSpacingItemDecoration(2, dpToPx(10), true));
????????recyclerView.setItemAnimator(newDefaultItemAnimator());
????????recyclerView.setAdapter(adapter);
????????prepareAlbums();
????????try{
????????????Glide.with(this).load(R.drawable.cover).into((ImageView) findViewById(R.id.backdrop));
????????} catch(Exception e) {
????????????e.printStackTrace();
????????}
????}
????/**
?????* Initializing collapsing toolbar
?????* Will show and hide the toolbar title on scroll
?????*/
????privatevoidinitCollapsingToolbar() {
????????finalCollapsingToolbarLayout collapsingToolbar =
????????????????(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
????????collapsingToolbar.setTitle(" ");
????????AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
????????appBarLayout.setExpanded(true);
????????// hiding & showing the title when toolbar expanded & collapsed
????????appBarLayout.addOnOffsetChangedListener(newAppBarLayout.OnOffsetChangedListener() {
????????????booleanisShow = false;
????????????intscrollRange = -1;
????????????@Override
????????????publicvoidonOffsetChanged(AppBarLayout appBarLayout, intverticalOffset) {
????????????????if(scrollRange == -1) {
????????????????????scrollRange = appBarLayout.getTotalScrollRange();
????????????????}
????????????????if(scrollRange + verticalOffset == 0) {
????????????????????collapsingToolbar.setTitle(getString(R.string.app_name));
????????????????????isShow = true;
????????????????} elseif(isShow) {
????????????????????collapsingToolbar.setTitle(" ");
????????????????????isShow = false;
????????????????}
????????????}
????????});
????}
????/**
?????* Adding few albums for testing
?????*/
????privatevoidprepareAlbums() {
????????int[] covers = newint[]{
????????????????R.drawable.album1,
????????????????R.drawable.album2,
????????????????R.drawable.album3,
????????????????R.drawable.album4,
????????????????R.drawable.album5,
????????????????R.drawable.album6,
????????????????R.drawable.album7,
????????????????R.drawable.album8,
????????????????R.drawable.album9,
????????????????R.drawable.album10,
????????????????R.drawable.album11};
????????Album a = newAlbum("True Romance", 13, covers[0]);
????????albumList.add(a);
????????a = newAlbum("Xscpae", 8, covers[1]);
????????albumList.add(a);
????????a = newAlbum("Maroon 5", 11, covers[2]);
????????albumList.add(a);
????????a = newAlbum("Born to Die", 12, covers[3]);
????????albumList.add(a);
????????a = newAlbum("Honeymoon", 14, covers[4]);
????????albumList.add(a);
????????a = newAlbum("I Need a Doctor", 1, covers[5]);
????????albumList.add(a);
????????a = newAlbum("Loud", 11, covers[6]);
????????albumList.add(a);
????????a = newAlbum("Legend", 14, covers[7]);
????????albumList.add(a);
????????a = newAlbum("Hello", 11, covers[8]);
????????albumList.add(a);
????????a = newAlbum("Greatest Hits", 17, covers[9]);
????????albumList.add(a);
????????adapter.notifyDataSetChanged();
????}
????/**
?????* RecyclerView item decoration - give equal margin around grid item
?????*/
????publicclassGridSpacingItemDecoration extendsRecyclerView.ItemDecoration {
????????privateintspanCount;
????????privateintspacing;
????????privatebooleanincludeEdge;
????????publicGridSpacingItemDecoration(intspanCount, intspacing, booleanincludeEdge) {
????????????this.spanCount = spanCount;
????????????this.spacing = spacing;
????????????this.includeEdge = includeEdge;
????????}
????????@Override
????????publicvoidgetItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
????????????intposition = parent.getChildAdapterPosition(view); // item position
????????????intcolumn = position % spanCount; // item column
????????????if(includeEdge) {
????????????????outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
????????????????outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
????????????????if(position < spanCount) { // top edge
????????????????????outRect.top = spacing;
????????????????}
????????????????outRect.bottom = spacing; // item bottom
????????????} else{
????????????????outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
????????????????outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /??? spanCount) * spacing)
????????????????if(position >= spanCount) {
????????????????????outRect.top = spacing; // item top
????????????????}
????????????}
????????}
????}
????/**
?????* Converting dp to pixel
?????*/
????privateintdpToPx(intdp) {
????????Resources r = getResources();
????????returnMath.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
????}
}
如果您現(xiàn)在運(yùn)行該應(yīng)用程序从藤,您可以看到網(wǎng)格中顯示的專輯CardViews催跪。
你好!我是androidhive和編程愛好者的創(chuàng)始人夷野。我的技能包括Android懊蒸,iOS,PHP悯搔,Ruby on Rails等等骑丸。如果您有任何想法,我希望我發(fā)展鳖孤?我們來聊聊吧:ravi@androidhive.info