یکی از عناصر اصلی در طراحی متریال دیزاین ، Cardview می باشد. با استفاده از کارد ویو شما می توانید اطلاعات را در کارت با سایه های روبه پایین و گوشه های شعاع دار که با سایر پلت فرم ها سازگار می باشد، قرار دهید. Cardview گسترش یافته ی FrameLayout می باشد. در ادامه با آموزش Recyclerview و Cardview در اندروید با آموزشگاه های برنامه نویسی در مشهد همراه باشید.
هنگامی که Cardview با RecyclerView ترکیب شوند، در نهایت خروجی بسیار زیبا برای UI را به همراه خواهد داشت. در این مطلب قصد داریم نحوه ی ادغام CardView و RecyclerView را برای ایجاد یک برنامه ی موسیقی زیبا که آلبوم های موسیقی را با تصویر و عنوان نمایش میدهد را آموزش دهیم.
اضافه کردن CardView
برای استفاده از CardView در برنامه ی خود در مرحله ی اول باید بتوانید موارد وابسته به CardView را در build.grade اضافه و پروژه را sync کنید.
build.gradle dependencies { // CardView compile 'com.android.support:cardview-v7:23.3.+' }
ویجت <android.support.v7.widget.CardView> را به لایه های خود اضافه کنید و سایر ویجت های UI مانند ImageView و TextView را در داخل آن قرار دهید. در Cardview زیر کاملا مشخص است که تنها یک TextView در آن قرار گرفته شده است.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:card_view="http://schemas.android.com/apk/res-auto"> <android.support.v7.widget.CardView 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"> <TextView android:text="Hello Card" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v7.widget.CardView> </LinearLayout>
بعد از انجام این مراحل، کار را برای ایجاد پروژه ی جدید ادامه خواهیم داد.
ایجاد پروژه ی جدید
- یک پروژه ی جدید را در اندروید استودیو از منوی file/new project ایجاد کنید. در این مرحله اگر از شما درخواست شد تا فعالیت پیش فرض را انتخاب کنید، Empty Activity را انتخاب و ادامه دهید.
- فایل res.zip را دانلود و به پوشه ی پروژه ی خود اضافه کنید. این پوشه شامل چند آلبوم و آیکن های مورد نیاز برای این پروژه می باشد.
- رشته ها ی زیر را که شامل رنگ ، ابعاد و منابع dimen می شوند را به فایل های string.xml, color.xml و dimen.xml اضافه کنید.
strings.xml <resources> <string name="app_name">Card View</string> <string name="action_settings">Settings</string> <string name="action_add_favourite">Add to Favourites</string> <string name="action_play_next">Play Next</string> <string name="backdrop_title">LOVE MUSIC</string> <string name="backdrop_subtitle">This season top 20 albums</string> </resources>
colors.xml <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#F50057</color> <color name="colorPrimaryDark">#F50057</color> <color name="colorAccent">#FF4081</color> <color name="viewBg">#f1f5f8</color> <color name="album_title">#4c4c4c</color> </resources>
dimens.xml <resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="fab_margin">16dp</dimen> <dimen name="item_offset">10dp</dimen> <dimen name="detail_backdrop_height">250dp</dimen> <dimen name="backdrop_title">30dp</dimen> <dimen name="backdrop_subtitle">18dp</dimen> <dimen name="card_margin">5dp</dimen> <dimen name="card_album_radius">0dp</dimen> <dimen name="album_cover_height">160dp</dimen> <dimen name="album_title_padding">10dp</dimen> <dimen name="album_title">15dp</dimen> <dimen name="songs_count_padding_bottom">5dp</dimen> <dimen name="songs_count">12dp</dimen> <dimen name="ic_album_overflow_width">20dp</dimen> <dimen name="ic_album_overflow_height">30dp</dimen> <dimen name="ic_album_overflow_margin_top">10dp</dimen> </resources>
۴ . build.gradle را باز و وابستگی های CardView, RecycleView و Glide را اضافه کنید. RecycleView برای نمایش آلبوم به صورت شبکه ای استفاده می شود. CardView برای نمایش یک مورد از آیتم آلبوم به کار برده میشود. 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' }
۵ . برای ایجاد یک آلبوم واحد، ما به یک کلاس مدل نیاز داریم تا ویژگی های آلبوم مانند نام، تعداد آهنگ ها و تصویر کاور را نشان دهد. بنابراین یک کلاس به نام Album.java را ایجاد و کد زیر را اضافه کنید.
Album.java package info.androidhive.cardview; /** * Created by Lincoln on 18/05/16. */ public class Album { private String name; private int numOfSongs; private int thumbnail; public Album() { } public Album(String name, int numOfSongs, int thumbnail) { this.name = name; this.numOfSongs = numOfSongs; this.thumbnail = thumbnail; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getNumOfSongs() { return numOfSongs; } public void setNumOfSongs(int numOfSongs) { this.numOfSongs = numOfSongs; } public int getThumbnail() { return thumbnail; } public void setThumbnail(int thumbnail) { this.thumbnail = thumbnail; } }
۶ . برای نمایش کارت آلبوم به یک لایه ی xml نیاز داریم. یک لایه ی xml به نام album_card.xml زیر لایه ی res ایجاد کنید. در قطعه کد زیر متوجه میشوید که <android.support.v7.widget.CardView> را اضافه کرده ایم و تمام ویژگی های آلبوم مانند نام، تعداد آهنگ ها و همچنین تصویر کاور آلبوم اضافه شده اند. علاوه براین، یک آیتم ۳ نقطه هم برای باز شدن منوی popup برای ضربه زدن روی آن اضافه کرده ایم.
album_card.xml <LinearLayout xmlns:android="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.support.v7.widget.CardView 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"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView 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" /> <TextView 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" /> <TextView 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" /> <ImageView 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" /> </RelativeLayout> </android.support.v7.widget.CardView> </LinearLayout>
۷٫ یک فایل منو به نام menu_album.xml زیر res در فولدر منو res ⇒ menu ایجاد کنید. این منو یک منوی popup برای ضربه زدن روی آیکن نقطه ای روی هر یک از آیتم های کارت آلبوم نمایش خواهد داد.
menu_album.xml <menu 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"> <item android:id="@+id/action_add_favourite" android:orderInCategory="100" android:title="@string/action_add_favourite" /> <item android:id="@+id/action_play_next" android:orderInCategory="101" android:title="@string/action_play_next" /> </menu>
۸٫ برای اجرای RecyclerView، ما به یک کلاس آداپتور نیاز داریم که اطلاعات album_card.xml را با حفظ اطلاعات مناسب بارگزاری کند. یک کلاس به نام AlbumAdapter.java ایجاد و محتوای زیر را به آن اضافه کنید.
AlbumsAdapter.java package info.androidhive.cardview; import android.content.Context; import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; import java.util.List; /** * Created by Ravi Tamada on 18/05/16. */ public class AlbumsAdapter extends RecyclerView.Adapter<AlbumsAdapter.MyViewHolder> { private Context mContext; private List<Album> albumList; public class MyViewHolder extends RecyclerView.ViewHolder { public TextView title, count; public ImageView thumbnail, overflow; public MyViewHolder(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); } } public AlbumsAdapter(Context mContext, List<Album> albumList) { this.mContext = mContext; this.albumList = albumList; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.album_card, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { 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(new View.OnClickListener() { @Override public void onClick(View view) { showPopupMenu(holder.overflow); } }); } /** * Showing popup menu when tapping on 3 dots */ private void showPopupMenu(View view) { // inflate menu PopupMenu popup = new PopupMenu(mContext, view); MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.menu_album, popup.getMenu()); popup.setOnMenuItemClickListener(new MyMenuItemClickListener()); popup.show(); } /** * Click listener for popup menu items */ class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener { public MyMenuItemClickListener() { } @Override public boolean onMenuItemClick(MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.action_add_favourite: Toast.makeText(mContext, "Add to favourite", Toast.LENGTH_SHORT).show(); return true; case R.id.action_play_next: Toast.makeText(mContext, "Play next", Toast.LENGTH_SHORT).show(); return true; default: } return false; } } @Override public int getItemCount() { return albumList.size(); } }
۹٫ فایل های لایه ی activity_main.xml و content_main.xml را باز و AppBarLayout ، CollapsingToolbarLayout، Toolbar و RecyclerView را اضافه کنید.
activity_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" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout 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.support.design.widget.CollapsingToolbarLayout 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"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:scaleType="centerCrop" app:layout_collapseMode="parallax" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:orientation="vertical"> <TextView 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" /> <TextView 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" /> </LinearLayout> </RelativeLayout> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> </android.support.design.widget.CoordinatorLayout>
content_main.xml
content_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" android:background="@color/viewBg" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="info.androidhive.cardview.MainActivity" tools:showIn="@layout/activity_main"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false" android:scrollbars="vertical" /> </RelativeLayout>
۱۰٫ در نهایت، MainActivity.java را باز و تغییرات لازم را اعمال کنید.
()initCollapsingToolbar : عنوان تولبار را زمانی که تولبار collapsed یا expanded میشوند نمایش یا پنهان خواهد کرد.
() prepareAlbums: اطلاعات مورد نیاز آلبوم نمونه را برای RecyclerView اضافه میکند.
GridLayoutManager برای نمایش RecyclerView به حالت Grid به جای لیست استفاده میشود.
GridSpacingItemDecoration برای داشتن حاشیه های برابر اطراف آیتم شبکه ی RecyclerView استفاده میشود
AlbumsAdapter نمونه ایجاد شده را به RecyclerView اختصاص داده و آلبوم های CardView به صورت شبکه ای نمایش داده شوند.
MainActivity.java package info.androidhive.cardview; import android.content.res.Resources; import android.graphics.Rect; import android.os.Bundle; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.TypedValue; import android.view.View; import android.widget.ImageView; import com.bumptech.glide.Glide; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private AlbumsAdapter adapter; private List<Album> albumList; @Override protected void onCreate(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 = new ArrayList<>(); adapter = new AlbumsAdapter(this, albumList); RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2); recyclerView.setLayoutManager(mLayoutManager); recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true)); recyclerView.setItemAnimator(new DefaultItemAnimator()); 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 */ private void initCollapsingToolbar() { final CollapsingToolbarLayout 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(new AppBarLayout.OnOffsetChangedListener() { boolean isShow = false; int scrollRange = -1; @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { if (scrollRange == -1) { scrollRange = appBarLayout.getTotalScrollRange(); } if (scrollRange + verticalOffset == 0) { collapsingToolbar.setTitle(getString(R.string.app_name)); isShow = true; } else if (isShow) { collapsingToolbar.setTitle(" "); isShow = false; } } }); } /** * Adding few albums for testing */ private void prepareAlbums() { int[] covers = new int[]{ 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 = new Album("True Romance", 13, covers[0]); albumList.add(a); a = new Album("Xscpae", 8, covers[1]); albumList.add(a); a = new Album("Maroon 5", 11, covers[2]); albumList.add(a); a = new Album("Born to Die", 12, covers[3]); albumList.add(a); a = new Album("Honeymoon", 14, covers[4]); albumList.add(a); a = new Album("I Need a Doctor", 1, covers[5]); albumList.add(a); a = new Album("Loud", 11, covers[6]); albumList.add(a); a = new Album("Legend", 14, covers[7]); albumList.add(a); a = new Album("Hello", 11, covers[8]); albumList.add(a); a = new Album("Greatest Hits", 17, covers[9]); albumList.add(a); adapter.notifyDataSetChanged(); } /** * RecyclerView item decoration - give equal margin around grid item */ public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { private int spanCount; private int spacing; private boolean includeEdge; public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { this.spanCount = spanCount; this.spacing = spacing; this.includeEdge = includeEdge; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildAdapterPosition(view); // item position int column = 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 */ private int dpToPx(int dp) { Resources r = getResources(); return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics())); } }
اگر برنامه را اجرا کنید، نمایش شبکه ای CradView آلبوم را مشاهده خواهید کرد.
شما می توانید برای شرکت در کلاس های برنامه نویسی در مشهد و آموزش اندروید مشهد با ما در تماس باشید
من محمد آذرنیوا، نویسنده و مدرس دوره های برنامه نویسی ، طراحی وب و تحلیل گر پایگاه داده هستم و قصد دارم در این وبسایت مطالب کاربردی در این زمینه را با شما به اشتراک بگذارم …