RecyclerView به سبک Hero ها
یکی از آیتم های بسیار مهم در برنامه های اندروید لیست ها میباشند. در ابتدا برنامه نویسان اندروید از ListView استفاده میکردند. custom کردن لیست ها کمک بسیار زیادی به برنامه نویسان اندروید کرد و توانستند با ایجاد یک مدل مشخص در تعداد مورد نظر آن را تکرار کنند. اما با این حال لیست های جای خود را به RecyclerView دادند. توضیح راجب ساختار Recyclerview ممکن است خسته کننده باشد. ولی در این مقاله سعی بر این است که بهتر از این ابزار استفاده کنیم.
اگر شما برنامه نویس اندروید باشید و تا بحال با RecycvlerView کارکرده باشید حتما با این موضوعات برخورد کردید :
- وقت گیر بودن نوشتن Adapter برای RecycvlerView
- تغییر لیست به حالت اولیه وقتی به صورت موقت از برنامه خارج میشوید
برای مشکل اول از امکانات Android Studio استفاده میکنیم. برای اینکار یک Live Template میسازیم و همیشه از آن استفاده میکنیم.
به موقعیت
File -> Settings -> Editor -> Live Template
میرویم و یک Template جدید میسازیم :
در Abbreviation نام Template را قرار میدهیم و به صورت اختیاری میتوان برای آن Description قرارداد.
در Template Text مقدار زیر را قرار میدهیم :
import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import butterknife.ButterKnife; /** * Created In Zero To Hero By Vhdrjb. * Learn More at https://zerotohero.ir/ */ public class $S1$ extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context context; private ArrayList<$S2$> models; public $S1$(Context context, ArrayList<$S2$> models) { this.context = context; this.models = models; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.$S3$, parent, false); return new $S4$(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { } public ArrayList<$S2$> getModels() { return models; } @Override public int getItemCount() { return models.size(); } class $S4$ extends RecyclerView.ViewHolder { public $S4$(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } } }
در پایان Define را زده و Everywhere را انتخاب میکنیم :
حال یک کلاس میسازیم :
package vhdrjb.zerotohero; public class ZeroToHeroAdapter { }
مقداری که برای Template قرار دادیم را مینویسم و کلید Tab روی کیبرد را میزنیم . در محل هایی که اشاره گر متن قرارمیگیرد مقادیر مورد نظر را قرار میدهیم و جاهایی که نیاز به تکرار است ویرایشگر به صورت اتومات تکرار را انجام میدهد. برای مثال وقتی نام کلاس را ZeroToHeroAdapter قرار میدهید مقدار Constructor به صورت اتومات مقدار دهی میشود و در نهایت کلاس شما به این صورت میشود :
public class ZeroToHeroAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context context; private ArrayList<Models> models; public ZeroToHeroAdapter(Context context, ArrayList<Models> models) { this.context = context; this.models = models; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.model_view, parent, false); return new ModelView(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { } public ArrayList<Models> getModels() { return models; } @Override public int getItemCount() { return models.size(); } class ModelView extends RecyclerView.ViewHolder { public ModelView(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } } }
و عملا با کمترین زمان ممکن شما یک Adapter ساختید.
برای مشکل دوم RecyclerView را Custom میکنیم :
package vhdrjb.karkesh.util; import android.content.Context; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; /** * Created In Zero TO Hero by Vhdrjb. * learn more at https://zerotohero.ir/ */ public class HeroRecyclerView extends RecyclerView { private static final String SAVED_SUPER_STATE = "hero-list-state"; private static final String SAVED_LAYOUT_MANAGER = "hero-list-layout-state"; public HeroRecyclerView(Context context) { super(context); } public HeroRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public HeroRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); bundle.putParcelable(SAVED_SUPER_STATE, super.onSaveInstanceState()); bundle.putParcelable(SAVED_LAYOUT_MANAGER, this.getLayoutManager().onSaveInstanceState()); return bundle; } private Parcelable mLayoutManagerSavedState; @Override public void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { Bundle bundle = (Bundle) state; mLayoutManagerSavedState = bundle.getParcelable(SAVED_LAYOUT_MANAGER); state = bundle.getParcelable(SAVED_SUPER_STATE); } super.onRestoreInstanceState(state); } private void restorePosition() { if (mLayoutManagerSavedState != null) { this.getLayoutManager().onRestoreInstanceState(mLayoutManagerSavedState); mLayoutManagerSavedState = null; } } @Override public void setAdapter(Adapter adapter) { super.setAdapter(adapter); restorePosition(); } }
تا اینجا ما یک لیست ساخیتم تا وقتی که گوشی شما زنگ میخورد یا اینکه با زدن Home به صورت موقت از برنامه خارج میشوید هم لیست شما در آخرین حالتی که بود , بماند.
حالا برای استفاده و بهینه کردن استفاده از آن از چنین روشی استفاده میکنیم :
مند onSaveInstanceState را به این گونه مینویسم :
@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable("heroListState", list.onSaveInstanceState()); outState.putSerializable("HeroListData", adapter.getModels()); outState.putBoolean("heroListSaved", true); }
نکته مهم : کلاس مدل ها حتما باید به این صورت باشد :
public class Model implements Serializable
و چون خود ArrayList هم Serializable است بنابراین در هنگام ذخیره مشکلی پیش نمیاید.
در متد بالا Adapter همان Adapter که در بالا نوشتیم می باشد و list هم همان HeroRecyclerView میباشد.
برای برگرداندن لیست به حالت اولیه نیز از این روش استفاده میکنیم :
list.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); if (savedInstanceState != null) { if (savedInstanceState.getBoolean("heroListSaved",false)) { list.onRestoreInstanceState(savedInstanceState.getParcelable("heroListState")); ZeroToHeroAdapter = new ZeroToHeroAdapter(this, (ArrayList<Model>) savedInstanceState.getSerializable(VARS.HeroListData));
و نیاز است که
Bundle savedInstanceState
را به عنوان پارامتر ورودی به متد برگرداننده ارسال کنیم.
فایل کلاس Recyclerview را میتوانید از اینجا دریافت کنید
امیدواریم از این پس لیست هایی حرفه ای بسازیم !!!!
با ما همراه باشید ……
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.