مجید آرتا 5,874 ارسال شده در 26 دی، ۱۳۹۵ اشتراک گذاری ارسال شده در 26 دی، ۱۳۹۵ سلام امیدوارم توی ایام امتحانات حالتون و خوب و خوش باشه. خب از اونجایی که این ویو ( RecyclerView ) بسیار پرکاربرد و مهم هستش، خوبه که حالت های مختلفی که احتمال داره ما نیازمون باشه رو بررسی کنیم. خود بنده خواستم از یک اداپتر واسه تمامی ریسایکر های خودم که لایوت های متخلفی داشتن استفاده کنن، یعنی توی چندین اکتیویتی باید از ریسایکلر با لایوت های مختلف استفاده می کردم، از اونجایی که توی برنامه نویسی اندروید با اندروید استودیو مبتدی هستم، دنبالش رفتم و پیادش کردم، مَثَل قشنگی میگن که « کَس نَخوارد پُشت من جُزء ناخن انگشت مَن». خب مثال های مختلفی توی سایت های خارجی بود، و من خواستم طبق نیاز خودم پیادش کنم. خب طبق فرضیه ای که من پیاده کردم پیش میریم. من توی برنامه ام 2تا اکتیویتی داشتم، اکتیویتی اول لیست یکسری اسم ( مثلا اسم کشور ) توی ریسایکر اول نشون میدیم. اکتیویتی دوم هم قراره که تمامی استان های کشوری که توی اکتیویتی اول کلیک شده رو نمایش بده، پس اینجا هم یک ریسایکلر ویو نیاز داریم، با لایوت مخصوص به خودش. من برای پر کردن ریسایکر ویو اولی یک کلاس و برای ریسایکلر ویو دومی یک کلاس دیگه میسازم. برای کشور این کلاس » public class Country { private int code; private String countryName; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } } و برای استان های کشور این کلاس رو می نویسیم » public class States { private int code; private String stateName; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getStateName() { return stateName; } public void setStateName(String stateName) { this.stateName = stateName; } } خب مشکل اونجاست که ما نمیدونیم از چندین لایوت چطور توی یک کلاس آداپتر استفاده کنیم. خب از اونجایی که که من دو تا لایوت دارم باید دوتا ViewHolder تعریف کنم، حالا به صورت InnerClass و یا به صورت فایل Java جداگانه ای.که من ترجیح میدم از نوع InnerClass.( تعریف کلاسی در داخل یک کلاس رو میگن InnerClass ). میریم که کلاس خام آداپتر رو پیاده کنیم » public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { } @Override public int getItemViewType(int position) { } public MyAdapter(List list){ } @Override public int getItemCount() { } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { } } خب بعدش میریم اون ویو هایی رو که توی اون دو تا لایوت ایجاد کردیم رو ViewHolder شون رو توی کلاس MyAdapter بنویسیم » public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context context; @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { } @Override public int getItemViewType(int position) { } public MyAdapter(List list){ } @Override public int getItemCount() { } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { } private class CountryViewHolder extends RecyclerView.ViewHolder { TextView txtCountryName; public MyAdapterHolder(View view) { super(view); context = view.getContext(); txtCountryName = (TextView)view.findViewById(R.id.txtCountryName); } } private class MyAdapterCodesHolder extends RecyclerView.ViewHolder { TextView txtStateName; public MyAdapterCodesHolder(View view) { super(view); txtStateName = (TextView)view.findViewById(R.id.txtStateName); } } } ما اینجا مرحله به مرحله داریم تکمیل می کنیم کدهارو دوباره قرار میدیم.خب یک متغییر Context تعریف کردیم.این متغییر رو واسه این تعریف کردیم که هر وقت روی هر کشور کلیک شد بتونیم بریم اکتیویتی بعدی.توی کلاسی بجز اکتیویتی باید از Context استفاده کنیم. خب میریم سراغ مرحله بعدی، تعریف کردن دو تا متغییر برای اینکه بتونیم تشخیص بدیم قراره کشور هارو نمایش بدیم یا استان ها رو، private final int COUNTRY = 1; private final int STATE = 2; همونجایی که Context رو تعریف کردیم اینارو هم تعریف می کنیم. یک متغییر از نوع List هم تعریف می کنیم، واسه اسامی کشور و استان نیازمون میشه » private List lists; این رو هم به صورت فیلد تعریف کنید، یعنی کنار همون متغییر های Int بالا. حالا کاری که ما باید انجام بدیم با دو تا تابع getItemViewType و onCreateViewHolder هستش. یعنی این دو تا واس کارمون باید مد نظرشون داشته باشیم، با اولی میتونیم شرط بزاریم که اگر ریسایکلر استان بود بیا مقدار متغییر STATE رو برگردون، یا اگر کشور بود بیا COUNTRY رو برگردون. بعد توی دومی یک ورودی به عنوان type داره، اینو بگیریم شرط بزاریم که اگر فلان مقدار بود بیا فلان لایوت رو لود کن. الان کد جفتشون رو میزارم بررسی کنید » @Override public int getItemViewType(int position) { if(lists.get(position) instanceof Country) return COUNTRY; else if(lists.get(position) instanceof States) return STATE; else return -1; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder viewHolder = null; LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if(viewType == COUNTRY){ View v1 = inflater.inflate(R.layout.item_country, parent, false); viewHolder = new CountryViewHolder(v1); }else if(viewType == STATE){ View v1 = inflater.inflate(R.layout.item_state, parent, false); viewHolder = new StateViewHolder(v1); } return viewHolder; } خب توی اولین تابع گفتیم اگر ایتم مورد بررسی مربوط به کلاس فلان بود، فلان مقدار رو برگردون. توی تابع دوم هم گفتیم مقدار viewType این بود بیا این لایوت رو لود کن. در نهایت میریم تا اطلاعات رو توی ریسایکلر ویو بایند کنیم یا به نوبه ای تزریق کنیم. از onBindViewHolder استفاده می کنیم » public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { switch (holder.getItemViewType()){ case COUNTRY: CountryViewHolder countryHolder = (CountryViewHolder)holder; Country country =(Country) lists.get(position); countryHolder.txtCountryName.setText(country.getCountryName()); break; case CODES: StateViewHolder stateHolder = (StateViewHolder)holder; States states = (States)lists.get(position); stateHolder.txtStateName.setText(states.setStateName()); break; } } خب دیگه همین، چیزخاصی نداره کلا. در نهایت کدی که نوشته میشه » public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context context; private final int COUNTRY = 1; private final int STATE = 2; private List lists; @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { switch (holder.getItemViewType()){ case COUNTRY: CountryViewHolder countryHolder = (CountryViewHolder)holder; Country country =(Country) lists.get(position); countryHolder.txtCountryName.setText(country.getCountryName()); break; case CODES: StateViewHolder stateHolder = (StateViewHolder)holder; States states = (States)lists.get(position); stateHolder.txtStateName.setText(states.setStateName()); break; } } @Override public int getItemViewType(int position) { if(lists.get(position) instanceof Country) return COUNTRY; else if(lists.get(position) instanceof States) return STATE; else return -1; } public MyAdapter(List list){ } @Override public int getItemCount() { return lists.size(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder viewHolder = null; LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if(viewType == COUNTRY){ View v1 = inflater.inflate(R.layout.item_country, parent, false); viewHolder = new CountryViewHolder(v1); }else if(viewType == STATE){ View v1 = inflater.inflate(R.layout.item_state, parent, false); viewHolder = new StateViewHolder(v1); } return viewHolder; } private class CountryViewHolder extends RecyclerView.ViewHolder { TextView txtCountryName; public MyAdapterHolder(View view) { super(view); context = view.getContext(); txtCountryName = (TextView)view.findViewById(R.id.txtCountryName); } } private class StateViewHolder extends RecyclerView.ViewHolder { TextView txtStateName; public MyAdapterCodesHolder(View view) { super(view); txtStateName = (TextView)view.findViewById(R.id.txtStateName); } } } آموزشی از انسر سنتر. امیدوارم مورد توجه قرار گرفته باشه. لینک ارسال به اشتراک گذاری در سایت های دیگر تنظیمات بیشتر اشتراک گذاری ...
ارسالهای توصیه شده
بایگانی شده
این موضوع بایگانی و قفل شده و دیگر امکان ارسال پاسخ نیست.