آموزش Swipe Cards در برنامه نویسی اندروید

سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش Swipe Cards در برنامه نویسی اندروید می پردازیم شاید Swipe Cards واژه تازه باشد که تا به حال آن را نشنیده باشید. از Swipe Cards در برنامه Tinder استفاده شده است Swipe Cards باعث متریال دیزاین شدن اپلیکیشن شما می شود توصیه می کنم از این آموزش در بخشی از برنامه خود استفاده کنید در ادامه می توانید پیش نمایشی از Swipe Cards را مشاهده کنید با ما هرماه باشید.
 

 
در این آموزش ما از دو کتاب خانه قدرتمند به نام های

  • glide (برای لود کردن عکس ها)
  • swipecards

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

compile 'com.github.bumptech.glide:glide:3.5.1'
compile 'com.lorentzos.swipecards:library:1.0.9'

پروژه را sync کنید.
وارد فایل AndroidManifest.xml شده سپس دسترسی های زیر را اضافه کنید.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

در layout خود یک فایل به نام item.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:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="center"
             android:layout_marginBottom="48dp"
             android:layout_marginLeft="20dp"
             android:layout_marginRight="20dp"
             android:layout_marginTop="64dp">
    <FrameLayout
        android:id="@+id/background"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="6dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:background="@drawable/shape2"
            android:gravity="center_horizontal"
            android:orientation="vertical" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="12dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:background="@drawable/shape1"
            android:gravity="center_horizontal"
            android:orientation="vertical" />
    </FrameLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="18dp"
        android:background="@drawable/shape"
        android:gravity="center_horizontal"
        android:orientation="vertical">
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/cardImage"
                android:layout_width="300dp"
                android:layout_height="200dp"
                android:padding="4dp"
                android:scaleType="centerCrop" />
        </FrameLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="top|center_horizontal"
            android:orientation="horizontal">
            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <TextView
                    android:id="@+id/bookText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="left"
                    android:padding="4dp"
                    android:textColor="#787878"
                    android:textSize="16sp"
                    tools:text="" />
            </ScrollView>
        </LinearLayout>
    </LinearLayout>
    <View
        android:id="@+id/item_swipe_left_indicator"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:alpha="0"
        android:background="@drawable/like" />
    <View
        android:id="@+id/item_swipe_right_indicator"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="right"
        android:alpha="0"
        android:background="@drawable/nope" />
</FrameLayout>

ممکن است در کد بالا خطاهایی داشته باشد ادامه دهید خطاها کم کم حذف می شوند در پروژه از یکسری عکس استفاده شده است در ادامه می توانید آنها را دانلود کنید سپس بعد از دانلود در پوشه drawable قرار دهید.
لینک دانلود
در پوشه drawable یک فایل به نام shape.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<shape xmlns:android="https://schemas.android.com/apk/res/android">
    <solid
        android:color="@android:color/white"
        />
    <corners
        android:radius="4dp" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
</shape>

درهمان پوشه یک فایل دیگر به نام shape1.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<shape xmlns:android="https://schemas.android.com/apk/res/android">
    <solid
        android:color="#ccc"
        />
    <corners
        android:radius="4dp" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
</shape>

و در آخر دوباره در همان پوشه یک فایل دیگر به نام shape2.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<shape xmlns:android="https://schemas.android.com/apk/res/android">
    <solid
        android:color="#aaa"
        />
    <corners
        android:radius="4dp" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
</shape>

یک کلاس جاوا به نام Data ایجاد کرده و کدهای زیر را در آن قرار دهید.

package ir.programchi;
/**
 * Created by Jefferson on 20/11/16.
 */
public class Data {
    private String description;
    private String imagePath;
    public Data(String imagePath, String description) {
        this.imagePath = imagePath;
        this.description = description;
    }
    public String getDescription() {
        return description;
    }
    public String getImagePath() {
        return imagePath;
    }
}

کد بالا به model یا کلاس getter و setter نیز معروف است.
وارد اکتیویتی اصلی شده (در اینجا نام آن برابر با activity_main.xml است ) و کدهای زیر را در آن قرار دهید.

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
              xmlns:app="https://schemas.android.com/apk/res-auto"
              xmlns:tools="https://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/background">
        <com.lorentzos.flingswipe.SwipeFlingAdapterView
            android:id="@+id/frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/background"
            app:rotation_degrees="15.5" />
    </FrameLayout>
</LinearLayout>

در بالا SwipeFlingAdapterView یا همان SwipeView قرار گرفته است که با درگ به سمت چپ و راست به عکس بعدی می رود.
و در آخر وارد فایل MainActivity.java شده و کدهای زیر را در آن قرار دهید.

package com.androidtutorialpoint.androidswipecards;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.lorentzos.flingswipe.SwipeFlingAdapterView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
    public static MyAppAdapter myAppAdapter;
    public static ViewHolder viewHolder;
    private ArrayList<Data> array;
    private SwipeFlingAdapterView flingContainer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        flingContainer = (SwipeFlingAdapterView) findViewById(R.id.frame);
        array = new ArrayList<>();
        array.add(new
        Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Katrina-Kaif.jpg",
            "Hi I am Katrina Kaif. \n" +
                "متن تست"));
        array.add(new Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Emma-Watson.jpg",
       "Hi I am Emma Watson. \n" +
                "متن تست دوم"));
        array.add(new Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Scarlett-Johansson.jpg",
       "Hi I am Scarlett Johansson. \n" +
                "متن تست سوم"));
        array.add(new Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Priyanka-Chopra.jpg",
        "Hi I am Priyanka Chopra. \n" +
                " متن تست سوم"));
        array.add(new Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Deepika-Padukone.jpg",
        "Hi I am Deepika Padukone. \n" +
                "متن تست چهارم"));
        array.add(new Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Anjelina-Jolie.jpg",
        "Hi I am Anjelina Jolie. \n" +
                "متن تست پنجم"));
        array.add(new Data("https://www.androidtutorialpoint.com/wp-content/uploads/2016/11/Aishwarya-Rai.jpg",
       "Hi I am Aishwarya Rai \n" +
                "متن تست ششم"));
        myAppAdapter = new MyAppAdapter(array, MainActivity.this);
        flingContainer.setAdapter(myAppAdapter);
        flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() {
            @Override
            public void removeFirstObjectInAdapter() {
            }
            @Override
            public void onLeftCardExit(Object dataObject) {
                array.remove(0);
                myAppAdapter.notifyDataSetChanged();
            }
            @Override
            public void onRightCardExit(Object dataObject) {
                array.remove(0);
                myAppAdapter.notifyDataSetChanged();
            }
            @Override
            public void onAdapterAboutToEmpty(int itemsInAdapter) {
            }
            @Override
            public void onScroll(float scrollProgressPercent) {
                View view = flingContainer.getSelectedView();
                view.findViewById(R.id.background).setAlpha(0);
                view.findViewById(R.id.item_swipe_right_indicator).setAlpha(scrollProgressPercent < 0 ? -scrollProgressPercent : 0);
                view.findViewById(R.id.item_swipe_left_indicator).setAlpha(scrollProgressPercent > 0 ? scrollProgressPercent : 0);
            }
        });
        flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() {
            @Override
            public void onItemClicked(int itemPosition, Object dataObject) {
                View view = flingContainer.getSelectedView();
                view.findViewById(R.id.background).setAlpha(0);
                myAppAdapter.notifyDataSetChanged();
            }
        });
    }
    public static class ViewHolder {
        public static FrameLayout background;
        public TextView DataText;
        public ImageView cardImage;
    }
    public class MyAppAdapter extends BaseAdapter {
        public List<Data> parkingList;
        public Context context;
        private MyAppAdapter(List<Data> apps, Context context) {
            this.parkingList = apps;
            this.context = context;
        }
        @Override
        public int getCount() {
            return parkingList.size();
        }
        @Override
        public Object getItem(int position) {
            return position;
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View rowView = convertView;
            if (rowView == null) {
                LayoutInflater inflater = getLayoutInflater();
                rowView = inflater.inflate(R.layout.item, parent, false);
                viewHolder = new ViewHolder();
                viewHolder.DataText = (TextView) rowView.findViewById(R.id.bookText);
                viewHolder.background = (FrameLayout) rowView.findViewById(R.id.background);
                viewHolder.cardImage = (ImageView) rowView.findViewById(R.id.cardImage);
                rowView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            viewHolder.DataText.setText(parkingList.get(position).getDescription() + "");
            Glide.with(MainActivity.this).load(parkingList.get(position).getImagePath()).into(viewHolder.cardImage);
            return rowView;
        }
    }
}

در بالا ابتدا یکسری داده تست به به swipeview داده شده است (feed) و هر کارد شامل یک عکس و متنی است اگر متن کمی طولانی باشد به صورت اتوماتیک یک scrollview به زیر هر swipeview  اضافه می شود (این کار اتوماتیک نیست کدش در بالا نوشته شده است) برای اینکه هر داده قرار بگیرد ابتدا باید position هر view به دست بیاید که در بالا این کار توسط void ی به نام getView انجام شده است و در آن layout که ساختیم Inflate می شود. هر swipeview دو مشخصه دارد onLeftCardExit و onRightCardExit در بالا برای هر آینم رویداد کلیک نیز تعریف شده است.
 
این آموزش به پایان رسید.
 
موفق و موید باشید.

مطالعه بیشتر