آموزش SwipeView در RecyclerView

سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش SwipeView در RecyclerView می پردازیم در این آموزش از SwipeView  برای حذف یا ویرایش بروی هر RecyclerView  می پردازیم در ادامه می توانید پیش نمایشی از SwipeView در RecyclerView مشاهده کنید با ما همراه باشید.

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

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

پروژه را sync کنید.
در اکتیویتی اصلی که در اینجا نام آن برابر با 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:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/card_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_add" />
</android.support.design.widget.CoordinatorLayout>

در کدهای بالا خطاهایی برای شما نمایش داده می شود برای اینکه این خطاها را حل کنید مثل زیر عمل کنید.
یک فایل به نام dimens.xml در مسیر res/values ایجاد کرده و کدهای زیر را در آن قرار دهید.

<resources>
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
</resources>

بعد از این کار عکس های زیر را دانلود کرده و در پوشه drawable قرار دهید.
لینک دانلود
یک فایل به نام row_layout.xml در layout خود درست کنید و کدهای زیر را در آن قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_marginBottom="1dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_country"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="15dp"
        android:layout_gravity="center"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold" />
</LinearLayout>

کد بالا در آیتم های RecyclerView نمایش داده می شود (شکل ظاهری هر آیتم)
یک فایل به نام dialog_layout.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <EditText
        android:id="@+id/et_country"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

کد بالا یک دیالوگ است که برای Edit کردن هر آیتم در ادامه استفاده می شود. (این layout در ادامه در Alert ما Inflate می شود)
یک فایل جاوا به نام DataAdapter.java ایجاد کرده و کدهای زیر را در آن قرار دهید.

package ir.programchi;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class DataAdapter extends RecyclerView.Adapter {
    private ArrayList countries;
    public DataAdapter(ArrayList countries) {
        this.countries = countries;
    }
    @Override
    public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_layout, viewGroup, false);
        return new ViewHolder(view);
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.tv_country.setText(countries.get(i));
    }
    @Override
    public int getItemCount() {
        return countries.size();
    }
    public void addItem(String country) {
        countries.add(country);
        notifyItemInserted(countries.size());
    }
    public void removeItem(int position) {
        countries.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, countries.size());
    }
    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView tv_country;
        public ViewHolder(View view) {
            super(view);
            tv_country = (TextView)view.findViewById(R.id.tv_country);
        }
    }
}

کار کد بالا به دست آوردن View هر آیتم و در صورت نیاز اضافه کردن یا حذف یک آیتم است.
حالا به بخش نهایی پروژه میرسیم.
واره فایل MainActivity.java شده (در اینجا MainActivity اکتیویتی اصلی ما است) و کدهای زیر را در آن قرار دهید.

package ir.orjinakteb.com;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private ArrayList countries =  new ArrayList<>();
    private DataAdapter adapter;
    private RecyclerView recyclerView;
    private AlertDialog.Builder alertDialog;
    private EditText et_country;
    private int edit_position;
    private View view;
    private boolean add = false;
    private Paint p = new Paint();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
        initDialog();
    }
    private void initViews(){
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(this);
        recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(layoutManager);
        adapter = new DataAdapter(countries);
        recyclerView.setAdapter(adapter);
        countries.add("Australia");
        countries.add("India");
        countries.add("United States of America");
        countries.add("Germany");
        countries.add("Russia");
        adapter.notifyDataSetChanged();
        initSwipe();
    }
    private void initSwipe(){
        ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int position = viewHolder.getAdapterPosition();
                if (direction == ItemTouchHelper.LEFT){
                    adapter.removeItem(position);
                } else {
                    removeView();
                    edit_position = position;
                    alertDialog.setTitle("Edit Country");
                    et_country.setText(countries.get(position));
                    alertDialog.show();
                }
            }
            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView,
               RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
                Bitmap icon;
                if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
                    View itemView = viewHolder.itemView;
                    float height = (float) itemView.getBottom() - (float) itemView.getTop();
                    float width = height / 3;
                    if(dX > 0){
                        p.setColor(Color.parseColor("#388E3C"));
                        RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
                        c.drawRect(background,p);
                        icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_edit);
                        RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop()
                        + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
                        c.drawBitmap(icon,null,icon_dest,p);
                    } else {
                        p.setColor(Color.parseColor("#D32F2F"));
                        RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),
                        (float) itemView.getRight(), (float) itemView.getBottom());
                        c.drawRect(background,p);
                        icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_delete);
                        RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float)
                        itemView.getRight() - width,(float)itemView.getBottom() - width);
                        c.drawBitmap(icon,null,icon_dest,p);
                    }
                }
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        };
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
        itemTouchHelper.attachToRecyclerView(recyclerView);
    }
    private void removeView(){
        if(view.getParent()!=null) {
            ((ViewGroup) view.getParent()).removeView(view);
        }
    }
    private void initDialog(){
        alertDialog = new AlertDialog.Builder(this);
        view = getLayoutInflater().inflate(R.layout.dialog_layout,null);
        alertDialog.setView(view);
        alertDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if(add){
                    add =false;
                    adapter.addItem(et_country.getText().toString());
                    dialog.dismiss();
                } else {
                    countries.set(edit_position,et_country.getText().toString());
                    adapter.notifyDataSetChanged();
                    dialog.dismiss();
                }
            }
        });
        et_country = (EditText)view.findViewById(R.id.et_country);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.fab:
                removeView();
                add = true;
                alertDialog.setTitle("Add Country");
                et_country.setText("");
                alertDialog.show();
                break;
        }
    }
}

کدهای بالا را ما سعی کردیم به صورت ساده ترین شکل برای شما قرار دهیم همینطور هر بخش را به صورت Void در آوردیم تا توضیح دادن آن ساده تر باشد (در این آموزش دیگر نحوه حذف آیتم و اضافه کردن آیتم توضیح داده نخواهد قبلا هر کدام را به صورت جداگانه در سایت قرار دادیم در ادمه لینک آن را قرار می دهم. )

آموزش اضافه و حذف کردن در Recyclerview

اولین void ما که initViews است تمامی view ها را find می کند  و یکسری داده sample در Recyclerview قرار می دهد.
دومین void ما که initSwipe همان swipe کردن به چپ و راست را برای ما handle می کند در بالا یک void دیگر به نام onChildDraw وجود دارد که در صورتی که به سمت چپ و راست siwpe کنید رنگ بخشی از رنگ Recyclerview را تغییر می دهد.
void که نام آن removeView هرآیتم را حذف می کند و در صورتی که بروی FloatinActionButton کلیک کنید می توانید یک آیتم جدید به Recyclerview  اضافه کنید و با درگ از راست به چپ می توانید هر آیتم را ویرایش کنید.
 
تمامی عکس های برنامه در حالت های مختلف

 
 
این آموزش هم به پایان رسید.
 
موفق و پیروز باشید.

مطالعه بیشتر