اضافه کردن ( کشیدن و رها کردن ) RecyclerView swipe برای حذف و undo

در این مطلب قصد داریم با اضافه کردن swipe ( کشیدن و رها کردن ) عملیات هایی مانند حذف و undo را به اپلیکیشن جی میل به recyclerview اضافه کنیم. با ما همراه باشید تا در این آموزش RecyclerView با ساخت یک پروژه ی جدید، این روند را بهتر درک کنید.

 

RecyclerView Swipe ( کشیدن و رها کردن ) چطور کار می کند؟ با ItemTouchHelper

به کمک کلاس ItemTouchHelper شما می توانید یک swipe را به recycler view اضافه کرده و سپس  عملیات کشیدن و رها کردن را در  پیاده سازی کنید . swipe کردن سطر، باعث میشود تا سطر از recyclerview حذف شود اما داده های موجود را بروزرسانی نمی کند.  شما می توانید یک سطر خالی که با swipe کردن یک سطر نمایش داده میشود را مشاهده کنید. لازم به ذکر است که باید حواستان به بروز رسانی لیست حذف شده ی آیتم ها با پاک شدن از آداپتور مجموعه داده باشد.

ItemTouchHelper.SimpleCallback نوعی روش فراخوانی مانند onmove() ،onswipe و ()onchilddraw برای زمانی می باشد که سطر swipe میشود. نمایش پس زمینه، حذف کردن آیتم ها از آداپتور می توانند با استفاده از متدهای فراخوانی انجام شوند.

در قطعه کد زیر ItemTouchHelper برداشته و به recyclerview اضافه میشود. این کد باید کمی تغییر داده شود تا swipe  و undo به درستی انجام شوند.

RecyclerView recyclerView = findViewById(R.id.recycler_view);
 
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }
 
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        // Row is swiped from recycler view
        // remove it from adapter
    }
 
    @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            // view the background view
        }
    };
         
// attaching the touch helper to recycler view
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);

تعریف جهت دهی های swipe

جهت دهی های swipe می توانند برای ایجاد ()simplecallback تصمیم گیری کنند. در این مقاله ما از جهت دهی های چپ به راست استفاده می کنیم. برای استفاده از سایر جهت دهی ها، باید با اپراتور | ترکیب کنید. با دستور زیر جهت های چپ، راست، بالا و پایین را تعریف می کنیم.

new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)

طراحی لایه ها

طرح بندی لایه ها برای اضافه کردن پس زمینه ی ردیف ها اهمیت زیادی دارد. بسیاری از افراد پس زمینه را روی یک بوم یا canvas با متد ()onChildDraw ایجاد می کنند. البته اگر پس زمینه کمی پیچیده باشد، این فرآیند بسیار خسته کننده خواهد شد. طراحی آن با  لایه های xml خیلی ساده تر می باشد، بنابراین پس زمینه و پیش زمینه را با روش ساده و با کمک framelayout مشخص می کنیم و لایه ی پیش زمینه را در بالا قرار می دهیم.

پیش زمینه معمولا در recyclerview قابل مشاهده می باشد و زمانیکه swipe بر روی پس زمینه انجام میشود، در یک موقعیت ثابت قابل مشاهده خواهد بود.

آموزش RecyclerView

مثال JSON، منوی رستوران

در این قسمت یک مثال JSON که شامل منوی رستوران و تصویر مناسب و نام می باشد را ارائه می دهیم. در این مثال قصد داریم تا این JSON را استفاده کنیم تا آیتم های غذا در لیست recyclerview نمایش داده شوند.

https://api.androidhive.info/json/menu.json

ایجاد پروژه جدید

برای ادامه ی کار در این آموزش RecyclerView نیاز به اطلاعات کافی در مورد ItemTouchHelper داریم تا یک پروژه ی جدید را شروع کنیم و خروجی مورد نظرمان را بدست آوریم.

۱- یک پروژه ی جدید در اندروید استودیو را از مسیر file/new project ایجاد و در نهایت basic activity را به عنوان قالب انتخاب کنید.

۲- bulid.gradle را که زیر پوشه ی app قرار دارد باز نموده و وابستگی های volley و recyclerview را اضافه کنید.

build.gradle
dependencies {
    implementation 'com.android.support:recyclerview-v7:26.1.0'
  
    // glide image library
    implementation 'com.github.bumptech.glide:glide:3.7.0'
     
    // volley http library
    implementation 'com.android.volley:volley:1.0.0'
    implementation 'com.google.code.gson:gson:2.6.2'
}

۳- منابع زیر را به strings.xml و dimens.xml و colors.xml اضافه کنید.

strings.xml
<resources>
    <string name="app_name">Recycler Swipe</string>
    <string name="action_settings">Settings</string>
    <string name="my_cart">My Cart</string>
    <string name="delete">DELETE</string>
</resources>
dimens.xml
<resources>
    <dimen name="activity_padding_horizontal">16dp</dimen>
    <dimen name="padd_10">10dp</dimen>
    <dimen name="ic_delete">30dp</dimen>
    <dimen name="thumbnail">90dp</dimen>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#111</color>
    <color name="colorPrimaryDark">#FFF</color>
    <color name="colorAccent">#ea3732</color>
    <color name="bg_row_background">#fa315b</color>
    <color name="item_name">#535353</color>
    <color name="description">#a9a9a9</color>
</resources>

۴- styles.xml را باز کنید و به زیر استایل ها اضافه کنید تا تم  lighter به پروژه تان اضافه شود. این کار باعث میشود تا متن تیره تر از پیش زمینه ی سفیدی که در تولبار داریم به نظر برسد.

styles.xml
<resources>
 
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
 
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
 
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Light" />
 
    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
 
</resources>

۵- یک کلاس به نام MyApplication.java ایجاد کنید و آنرا از applications گسترش دهید (extend). این یک کلاس تک هست که برای ایجاد کتابخانه ی volley به کار میرود.

MyApplication.java
import android.app.Application;
import android.text.TextUtils;
 
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
 
public class MyApplication extends Application {
 
    public static final String TAG = MyApplication.class
            .getSimpleName();
 
    private RequestQueue mRequestQueue;
 
    private static MyApplication mInstance;
 
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
 
    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
 
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
 
        return mRequestQueue;
    }
 
    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }
 
    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
 
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

۶-  کلاس AndroidManifest.xml را باز کنید و کلاس MyApplication را به گره application اضافه کنید.مجوزهای internet را درست مانند زمانی که http را فراخوانی می کنیم اضافه کنید.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.recyclerviewswipe">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

تا این مرحله از کار، منابع آماده هستند. حال باید recyclerview را اضافه کنیم و داده ها را با تجزیه و تحلیل جیسون خروجی بگیریم.

۷-  فایل لایه ی MainActivity.java را باز کنید و recyclerview را اضافه نمایید. از قسمت my activity ما به دو فایل لایه ی activity_main.xml و content_main.xml نیاز داریم.

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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="info.androidhive.recyclerviewswipe.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="@android:color/white"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
 
    </android.support.design.widget.AppBarLayout>
 
    <include layout="@layout/content_main" />
 
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="info.androidhive.recyclerviewswipe.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:scrollbars="vertical" />
     
</android.support.constraint.ConstraintLayout>

۸-یک کلاس به نام Item.class ایجاد کنید و قطعه کد زیر را اضافه نمایید. کلاس POJO شامل آیتم های منو به نام های name، price، description و آدرس تصویر thumbnail می باشد.

Item.java
/**
 * Created by ravi on 26/09/17.
 */
 
public class Item {
    int id;
    String name;
    String description;
    double price;
    String thumbnail;
 
    public Item() {
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public double getPrice() {
        return price;
    }
 
    public void setPrice(double price) {
        this.price = price;
    }
 
    public String getThumbnail() {
        return thumbnail;
    }
 
    public void setThumbnail(String thumbnail) {
        this.thumbnail = thumbnail;
    }
}

۹- یک لایه ی xml به نام cart_list_item.xml  زیر res/layout ایجاد کنید. این لایه هر سطر در recyclerview را با کمک کلاس آداپتور خارج می کند. در اینجا ما یک imageview را برای thumbnail  و چند textviews را برای نمایش آیتم name،  description و price اضافه کرده ایم.

cart_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
 
    <RelativeLayout
        android:id="@+id/view_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_row_background">
 
        <ImageView
            android:id="@+id/delete_icon"
            android:layout_width="@dimen/ic_delete"
            android:layout_height="@dimen/ic_delete"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/padd_10"
            android:src="@drawable/ic_delete_white_24dp" />
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/padd_10"
            android:layout_toLeftOf="@id/delete_icon"
            android:text="@string/delete"
            android:textColor="#fff"
            android:textSize="13dp" />
 
    </RelativeLayout>
 
    <RelativeLayout
        android:id="@+id/view_foreground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:padding="@dimen/padd_10">
 
        <ImageView
            android:id="@+id/thumbnail"
            android:layout_width="@dimen/thumbnail"
            android:layout_height="@dimen/thumbnail"
            android:layout_marginRight="@dimen/activity_padding_horizontal"
            android:scaleType="centerCrop" />
 
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/thumbnail"
            android:ellipsize="end"
            android:fontFamily="sans-serif-medium"
            android:maxLines="1"
            android:textColor="@color/item_name"
            android:textSize="17dp" />
 
        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/name"
            android:layout_marginTop="5dp"
            android:layout_toRightOf="@id/thumbnail"
            android:textColor="@color/description"
            android:textSize="12dp" />
 
        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_toRightOf="@id/thumbnail"
            android:textColor="@color/colorAccent"
            android:textStyle="bold" />
 
    </RelativeLayout>
</FrameLayout>

۱۰- یک کلاس به نام CartListAdapter.java را ایجاد کنید. این کلاس آداپتور برای پر کردن لایه ها با داده های مناسب در recyclerview استفاده میشود. ما همچنین دو متد اضافه برای کلاس removeItem() و restoreItem() اضافه کردیم تا عملیات حذف و اضافه کردن را به recyclerview انجام دهند.

CartListAdapter.java
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
 
import com.bumptech.glide.Glide;
 
import java.util.List;
 
public class CartListAdapter extends RecyclerView.Adapter<CartListAdapter.MyViewHolder> {
    private Context context;
    private List<Item> cartList;
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView name, description, price;
        public ImageView thumbnail;
        public RelativeLayout viewBackground, viewForeground;
 
        public MyViewHolder(View view) {
            super(view);
            name = view.findViewById(R.id.name);
            description = view.findViewById(R.id.description);
            price = view.findViewById(R.id.price);
            thumbnail = view.findViewById(R.id.thumbnail);
            viewBackground = view.findViewById(R.id.view_background);
            viewForeground = view.findViewById(R.id.view_foreground);
        }
    }
 
 
    public CartListAdapter(Context context, List<Item> cartList) {
        this.context = context;
        this.cartList = cartList;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cart_list_item, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        final Item item = cartList.get(position);
        holder.name.setText(item.getName());
        holder.description.setText(item.getDescription());
        holder.price.setText("₹" + item.getPrice());
 
        Glide.with(context)
                .load(item.getThumbnail())
                .into(holder.thumbnail);
    }
 
    @Override
    public int getItemCount() {
        return cartList.size();
    }
 
    public void removeItem(int position) {
        cartList.remove(position);
        // notify the item removed by position
        // to perform recycler view delete animations
        // NOTE: don't call notifyDataSetChanged()
        notifyItemRemoved(position);
    }
 
    public void restoreItem(Item item, int position) {
        cartList.add(position, item);
        // notify item added by position
        notifyItemInserted(position);
    }
}

۱۱- در این مرحله، قصد داریم  یک توابع swipe را به recyclerview اضافه کنیم. برای این منظور یک کلاس به نام RecyclerItemTouchHelper.java ایجاد کرده و کلاس را از ItemTouchHelper.SimpleCallback گسترش داده و متدهای مورد نیاز را override می کنیم.

()getDefaultUIUtil با ItemTouchHelper استفاده میشود تا زمانیکه UI تغییر می کند، تشخیص داده شود. ما از این تابع برای حفظ پس زمینه در حالت و موقعیت استاتیک و انتقال پیش زمینه استفاده میکنیم.

در ()onChildDrawOver، موقعیت X از پیش زمینه در حالیکه کاربر swipe می کند، تغییر داده میشود

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

RecyclerItemTouchHelper.java
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
 
/**
 * Created by ravi on 29/09/17.
 */
 
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
    private RecyclerItemTouchHelperListener listener;
 
    public RecyclerItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
        super(dragDirs, swipeDirs);
        this.listener = listener;
    }
 
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return true;
    }
 
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (viewHolder != null) {
            final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
 
            getDefaultUIUtil().onSelected(foregroundView);
        }
    }
 
    @Override
    public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
                                RecyclerView.ViewHolder viewHolder, float dX, float dY,
                                int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
        getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
                actionState, isCurrentlyActive);
    }
 
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
        getDefaultUIUtil().clearView(foregroundView);
    }
 
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder, float dX, float dY,
                            int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
 
        getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
                actionState, isCurrentlyActive);
    }
 
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
    }
 
    @Override
    public int convertToAbsoluteDirection(int flags, int layoutDirection) {
        return super.convertToAbsoluteDirection(flags, layoutDirection);
    }
 
    public interface RecyclerItemTouchHelperListener {
        void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
    }
}

۱۲- در نهایت، MainActivity.java را باز کنید و تغییرات را مانند زیر انجام دهید.

متد () prepareCart، جیسون را از url میگیرد و بعد از تجزیه و تحلیل، آیتم ها را به آداپتور لیست داده اضافه میکند.

RecyclerItemTouchHelper در اینجا ایجاد شده و به recyclerview اختصاص داده شده است. در اینجا تنها جهت چپ را تعریف کرده ایم.

متد onSwiped() زمانی فراخوانی میشود کهswipe  ارائه شود. گام مهم در اینجا حذف آیتم های ردیف می باشد. mAdapter.removeItem برای حذف سطر از recyclerview فراخوانی میشود.

هنگامی که سطر حذف میشود، snackbar برای نمایش یک پیام با گزینه ی undo استفاده میشود. بالای کلیک undo، سطر دوباره با متد mAdapter.restoreItem() به حالت قبل برمیگردد.

متغیرهای deletedItem و deletedIndex برای ذخیره سازی موقت آیتم های حذف شده و ایندکس تا زمانیکه snackbar نمایش داده میشود، کاربرد دارد.

MainActivity.java
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
 
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
 
import org.json.JSONArray;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity implements RecyclerItemTouchHelper.RecyclerItemTouchHelperListener {
 
    private static final String TAG = MainActivity.class.getSimpleName();
    private RecyclerView recyclerView;
    private List<Item> cartList;
    private CartListAdapter mAdapter;
    private CoordinatorLayout coordinatorLayout;
 
    // url to fetch menu json
    private static final String URL = "https://api.androidhive.info/json/menu.json";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle(getString(R.string.my_cart));
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
        recyclerView = findViewById(R.id.recycler_view);
        coordinatorLayout = findViewById(R.id.coordinator_layout);
        cartList = new ArrayList<>();
        mAdapter = new CartListAdapter(this, cartList);
 
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        recyclerView.setAdapter(mAdapter);
 
        // adding item touch helper
        // only ItemTouchHelper.LEFT added to detect Right to Left swipe
        // if you want both Right -> Left and Left -> Right
        // add pass ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT as param
        ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
        new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
 
 
        // making http call and fetching menu json
        prepareCart();
    }
 
    /**
     * method make volley network call and parses json
     */
    private void prepareCart() {
        JsonArrayRequest request = new JsonArrayRequest(URL,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        if (response == null) {
                            Toast.makeText(getApplicationContext(), "Couldn't fetch the menu! Pleas try again.", Toast.LENGTH_LONG).show();
                            return;
                        }
 
                        List<Item> items = new Gson().fromJson(response.toString(), new TypeToken<List<Item>>() {
                        }.getType());
 
                        // adding items to cart list
                        cartList.clear();
                        cartList.addAll(items);
 
                        // refreshing recycler view
                        mAdapter.notifyDataSetChanged();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // error in getting json
                Log.d(TAG, "Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
 
        MyApplication.getInstance().addToRequestQueue(request);
    }
 
    /**
     * callback when recycler view is swiped
     * item will be removed on swiped
     * undo option will be provided in snackbar to restore the item
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
        if (viewHolder instanceof CartListAdapter.MyViewHolder) {
            // get the removed item name to display it in snack bar
            String name = cartList.get(viewHolder.getAdapterPosition()).getName();
 
            // backup of removed item for undo purpose
            final Item deletedItem = cartList.get(viewHolder.getAdapterPosition());
            final int deletedIndex = viewHolder.getAdapterPosition();
 
            // remove the item from recycler view
            mAdapter.removeItem(viewHolder.getAdapterPosition());
 
            // showing snack bar with Undo option
            Snackbar snackbar = Snackbar
                    .make(coordinatorLayout, name + " removed from cart!", Snackbar.LENGTH_LONG);
            snackbar.setAction("UNDO", new View.OnClickListener() {
                @Override
                public void onClick(View view) {
 
                    // undo is selected, restore the deleted item
                    mAdapter.restoreItem(deletedItem, deletedIndex);
                }
            });
            snackbar.setActionTextColor(Color.YELLOW);
            snackbar.show();
        }
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds cartList to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
}

در نهایت  برنامه را اجرا کنید و تست های لازم را انجام دهید. مطمئن شوید که دستگاه تلفن شما به اینترنت متصل است. خروجی برنامه را در تصویر زیر مشاهده می کنید.

آموزش RecyclerView

RecyclerView

 

ورکشاپ رایگان دوره های تخصصی برنامه نویسی

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

درباره‌ی برنامه نویسان

همچنین ببینید

آموزش اندروید

گزارش دوره آموزش اندروید – جلسه هفتم

در جلسه هفتم از دوره آموزش اندروید مهندس آذرنیوا مدرس دوره به آموزش ساخت اپلیکیشن تعاملی …

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *