طراحی متریال دیزاین CardView در اندروید

سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش طراحی متریال دیزاین CardView در اندروید خواهیم پرداخت طراجی کارد یا CardView (کارت ویو ) یکی از بهترین شکل ظاهری را به اپلیکیشن شما می دهد و اگر دقت کرده باشید بیشتر اپلیکیشن های موبایل براساس همین سبک طراحی می شوند در ادامه می توانید پیش نمایشی از این آموزش را مشاهده کنید با ما همراه باشید.

 
همانطور که مشاهده می کنید کاملا متریال دیزاین پیاده سازی شده است.
 
ابتدا باید کتاب خانه های زیر را به پروژه خود اضافه کنید.

compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'

پروژه را sync کنید.
ابتدا یک فایل به نام fragment_card.xml ایجاد کرده و کدهای زیرا را در آن قرار دهید (Layout اصلی نیست )

<RelativeLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<android.support.v7.widget.RecyclerView
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</RelativeLayout>

در اینجا فقط RecyclerView که آیتم ها در آن نمایش داده می شود قرار داده ایم.
یک فایل به نام recycle_items.xml در پوشه layout ایجاد کرده و کدهای زیر را در آن قرار دهید.

<android.support.v7.widget.CardView
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:card_view="https://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    card_view:cardCornerRadius="4dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/card_height"
        android:orientation="vertical"
        android:weightSum="4">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dip"
            android:layout_weight="3.2"
            android:orientation="vertical">
            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center_horizontal">
                <ImageView
                    android:id="@+id/coverImageView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:scaleType="centerCrop"
                    />
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="left|bottom"
                    android:background="@android:drawable/screen_background_dark_transparent"
                    android:orientation="vertical">
                    <TextView
                        android:id="@+id/titleTextView"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:padding="16dp"
                        android:textSize="@dimen/text_size"
                        android:textColor="#FFFFFF"
                        android:textStyle="bold" />
                </LinearLayout>
            </FrameLayout>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dip"
            android:layout_weight="0.8"
            android:gravity="center|right"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/likeImageView"
                android:layout_width="@dimen/icon_width"
                android:layout_height="@dimen/icon_height"
                android:padding="@dimen/icon_padding"
                android:src="@drawable/ic_like" />
            <ImageView
                android:id="@+id/shareImageView"
                android:layout_width="@dimen/icon_width"
                android:layout_height="@dimen/icon_height"
                android:padding="@dimen/icon_padding"
                android:src="@drawable/ic_share" />
        </LinearLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>

کد بالا شکل ظاهری هر آیتم را مشخص می کند ممکن است بعد از اینکه کدهای بالا در layout خود قرار دهید به خطاهایی بخورید در بالا دو عکس در پوشه drawable قرار دادیم که در ادامه می توانید آنها را دانلود کرده و در پروژه خود قرار دهید. هنگامی که فایل را دانلود کنید یکسری عکس دیگر نیز در آن وجود دارد همه را در پوشه drawable کپی کنید.
لینک دانلود
در بالا باز هم خطا دارید وارد مسیر res/values شده فایل dimens.xml پیدا کرده یا اگر نبود آن را ایجا کرده و کدهای زیر را در آن قرار دهید.

<?xml version="1.0"?>
<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="activity_right_margin">10dp</dimen>
<dimen name="activity_left_margin">10dp</dimen>
<dimen name="icon_width">60dip</dimen>
<dimen name="icon_height">60dip</dimen>
<dimen name="icon_padding">8dp</dimen>
<dimen name="card_height">250dip</dimen>
<dimen name="text_size">18sp</dimen>
</resources>

حالا در Layout اصلی که نام آن برابر با activity_main.xml است کدهای زیر را قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:id="@+id/fragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
</FrameLayout>

برای اینکه فرگمنت در این layout نمایش داده شود از FrameLayout استفاده شده است.
باید یک کلاس Model به نام WonderModel.java ایجاد کرده و کدهای زیر را در آن قرار دهید.

package ir.programchi;
public class WonderModel {
    String cardName;
    int imageResourceId;
    int isfav;
    int isturned;
    public int getIsturned() {
        return isturned;
    }
    public void setIsturned(int isturned) {
        this.isturned = isturned;
    }
    public int getIsfav() {
        return isfav;
    }
    public void setIsfav(int isfav) {
        this.isfav = isfav;
    }
    public String getCardName() {
        return cardName;
    }
    public void setCardName(String cardName) {
        this.cardName = cardName;
    }
    public int getImageResourceId() {
        return imageResourceId;
    }
    public void setImageResourceId(int imageResourceId) {
        this.imageResourceId = imageResourceId;
    }
}

این کلاس به getter و setter نیز معروف است.
باید ما آداپتور سفارشی داشته باشیم تا Layout که در بالاتر ساختیم را Inflate کنیم پس یک آداپتور به نام
باید ما آداپتور سفارشی داشته باشیم تا Layout که در بالاتر ساختیم را Inflate کنیم پس یک آداتور به نام CardFragment.java ایجاد کرده و کدهای زیر را را در آن قرار دهید.

package ir.programchi;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class CardFragment extends Fragment {
    ArrayList<WonderModel> listitems = new ArrayList<>();
    RecyclerView MyRecyclerView;
    String Wonders[] = {"Chichen Itza","Christ the Redeemer","Great Wall of China","Machu Picchu","Petra","Taj Mahal","Colosseum"};
    int  Images[] = {
         R.drawable.chichen_itza,
         R.drawable.christ_the_redeemer,
         R.drawable.great_wall_of_china,
         R.drawable.machu_picchu,
         R.drawable.petra,
         R.drawable.taj_mahal,
         R.drawable.colosseum};
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initializeList();
        getActivity().setTitle("7 Wonders of the Modern World");
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_card, container, false);
        MyRecyclerView = (RecyclerView) view.findViewById(R.id.cardView);
        MyRecyclerView.setHasFixedSize(true);
        LinearLayoutManager MyLayoutManager = new LinearLayoutManager(getActivity());
        MyLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        if (listitems.size() > 0 & MyRecyclerView != null) {
            MyRecyclerView.setAdapter(new MyAdapter(listitems));
        }
        MyRecyclerView.setLayoutManager(MyLayoutManager);
        return view;
    }
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
        private ArrayList<WonderModel> list;
        public MyAdapter(ArrayList<WonderModel> Data) {
            list = Data;
        }
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
            // create a new view
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.recycle_items, parent, false);
            MyViewHolder holder = new MyViewHolder(view);
            return holder;
        }
        @Override
        public void onBindViewHolder(final MyViewHolder holder, int position) {
            holder.titleTextView.setText(list.get(position).getCardName());
            holder.coverImageView.setImageResource(list.get(position).getImageResourceId());
            holder.coverImageView.setTag(list.get(position).getImageResourceId());
            holder.likeImageView.setTag(R.drawable.ic_like);
        }
       @Override
        public int getItemCount() {
            return list.size();
        }
    }
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView titleTextView;
        public ImageView coverImageView;
        public ImageView likeImageView;
        public ImageView shareImageView;
        public MyViewHolder(View v) {
            super(v);
            titleTextView = (TextView) v.findViewById(R.id.titleTextView);
            coverImageView = (ImageView) v.findViewById(R.id.coverImageView);
            likeImageView = (ImageView) v.findViewById(R.id.likeImageView);
            shareImageView = (ImageView) v.findViewById(R.id.shareImageView);
            likeImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int id = (int)likeImageView.getTag();
                        if( id == R.drawable.ic_like){
                            likeImageView.setTag(R.drawable.ic_liked);
                            likeImageView.setImageResource(R.drawable.ic_liked);
                            Toast.makeText(getActivity(),titleTextView.getText()+" added to favourites",Toast.LENGTH_SHORT).show();
                        }else{
                            likeImageView.setTag(R.drawable.ic_like);
                            likeImageView.setImageResource(R.drawable.ic_like);
                            Toast.makeText(getActivity(),titleTextView.getText()+" removed from favourites",Toast.LENGTH_SHORT).show();
                        }
                }
            });
            shareImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Uri imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE +
                            "://" + getResources().getResourcePackageName(coverImageView.getId())
                            + '/' + "drawable" + '/' + getResources().getResourceEntryName((int)coverImageView.getTag()));
                    Intent shareIntent = new Intent();
                    shareIntent.setAction(Intent.ACTION_SEND);
                    shareIntent.putExtra(Intent.EXTRA_STREAM,imageUri);
                    shareIntent.setType("image/jpeg");
                    startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
                }
            });
        }
    }
    public void initializeList() {
        listitems.clear();
        for(int i =0;i<7;i++){
            WonderModel item = new WonderModel();
            item.setCardName(Wonders[i]);
            item.setImageResourceId(Images[i]);
            item.setIsfav(0);
            item.setIsturned(0);
            listitems.add(item);
        }
    }
}

زمانی که بروی دکمه لایک کلیک شود باید عکس آن تغییر کند و همینطور باید زمانی که بروی دکمه share کلیک شود باید عکس قابل اشترک گذاری باشد تمامی این بخش ها handle شده است
حالا باید در اکتویتی اصلی که در اینجا نام آن برابر با MainActivity.java کدهای زیر را قرار دهید.

package com.androidtutorialpoint.cardviewtutorial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
        if (fragment == null) {
            fragment = new CardFragment();
            ;
            fm.beginTransaction()
                    .add(R.id.fragmentContainer, fragment)
                    .commit();
        }
    }
}

کد بالا فرگمنت را در اکتیویتی load می کند.
 
 
این آموزش هم به پایان رسید.
 
موفق و پروز باشید.

مطالعه بیشتر