آموزش SwipeView در RecyclerView
سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش SwipeView در RecyclerView می پردازیم در این آموزش از SwipeView برای حذف یا ویرایش بروی هر RecyclerView می پردازیم در ادامه می توانید پیش نمایشی از SwipeView در RecyclerView مشاهده کنید با ما همراه باشید.
این آموزش بسیار کاربردی و بسیار متریال دیزاین است.
ابتدا باید وارد فایل Build.gradle از نوع Module شده سپس در بخش dependencies خط های زیر را قرار دهید.
1 2 | compile 'com.android.support:design:23.1.1' compile 'com.android.support:recyclerview-v7:23.1.1' |
پروژه را sync کنید.
در اکتیویتی اصلی که در اینجا نام آن برابر با activity_main.xml است کدهای زیر را قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?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 ایجاد کرده و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 | <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 خود درست کنید و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?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 ایجاد کرده و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?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 ایجاد کرده و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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 اکتیویتی اصلی ما است) و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | package ir.programchi.ir; 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 اضافه کنید و با درگ از راست به چپ می توانید هر آیتم را ویرایش کنید.
تمامی عکس های برنامه در حالت های مختلف
این آموزش هم به پایان رسید.
موفق و پیروز باشید.
سلام
ممنون از اموزشتون
فقط من در کلاس DataAdapter متد onBindViewHolder رو شناساسس نمیکنه و خطا میگیره
چکار باید بکنم؟
سلام کد تست شد مشکلی ندارد.