Android
RecyclerView और LayoutManagers
खोज…
GridLayoutManager डायनेमिक स्पैन काउंट के साथ
ग्रिडलेउटआउट लेआउट प्रबंधक के साथ एक रिसाइक्लेरव्यू बनाते समय आपको कंस्ट्रक्टर में स्पैन काउंट निर्दिष्ट करना होगा। स्पैन गणना कॉलम की संख्या को संदर्भित करती है। यह काफी स्पष्ट है और बड़े आकार या स्क्रीन ओरिएंटेशन को ध्यान में नहीं रखता है। एक दृष्टिकोण विभिन्न स्क्रीन आकारों के लिए कई लेआउट बनाना है। एक और अधिक गतिशील दृष्टिकोण नीचे देखा जा सकता है।
पहले हम एक कस्टम RecyclerView वर्ग बनाते हैं:
public class AutofitRecyclerView extends RecyclerView {
private GridLayoutManager manager;
private int columnWidth = -1;
public AutofitRecyclerView(Context context) {
super(context);
init(context, null);
}
public AutofitRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public AutofitRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
int[] attrsArray = {
android.R.attr.columnWidth
};
TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
columnWidth = array.getDimensionPixelSize(0, -1);
array.recycle();
}
manager = new GridLayoutManager(getContext(), 1);
setLayoutManager(manager);
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
if (columnWidth > 0) {
int spanCount = Math.max(1, getMeasuredWidth() / columnWidth);
manager.setSpanCount(spanCount);
}
}
}
यह वर्ग यह निर्धारित करता है कि पुनरावर्तन में कितने स्तंभ फिट हो सकते हैं। इसका उपयोग करने के लिए आपको इसे अपने लेआउट में डालना होगा। xml इस प्रकार है:
<?xml version="1.0" encoding="utf-8"?>
<com.path.to.your.class.autofitRecyclerView.AutofitRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/auto_fit_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="200dp"
android:clipToPadding="false"
/>
ध्यान दें कि हम स्तंभविशेषता का उपयोग करते हैं। उपलब्ध स्थान में कितने कॉलम फिट होंगे, यह निर्धारित करने के लिए रिसाइक्लेव्यू की आवश्यकता होगी।
आपकी गतिविधि / खंडन में आपको सिर्फ रिकेलिर्विए का संदर्भ मिलता है और इसके लिए एक एडॉप्टर सेट करना होता है (और कोई भी आइटम सजावट या एनिमेशन जिसे आप जोड़ना चाहते हैं)। प्रबंधक के बारे में एक सेट न करें
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.auto_fit_recycler_view);
recyclerView.setAdapter(new MyAdapter());
(जहां MyAdapter आपका एडेप्टर वर्ग है)
अब आपके पास एक recyclerview है जो स्क्रीन के आकार को फिट करने के लिए spancount (यानी कॉलम) को समायोजित करेगा। अंतिम जोड़ के रूप में आप कॉलम को recyclerview में रखना चाह सकते हैं (डिफ़ॉल्ट रूप से उन्हें layout_start से संरेखित किया गया है)। आप AutofitRecyclerView वर्ग को थोड़ा संशोधित करके ऐसा कर सकते हैं। Recyclerview में एक आंतरिक वर्ग बनाकर शुरू करें। यह एक वर्ग होगा जो ग्रिडलाइयूटमैनगर से निकलता है। यह पंक्तियों को केंद्र में रखने के लिए बाईं और दाईं ओर पर्याप्त पैडिंग जोड़ देगा:
public class AutofitRecyclerView extends RecyclerView {
// etc see above
private class CenteredGridLayoutManager extends GridLayoutManager {
public CenteredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CenteredGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public CenteredGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
@Override
public int getPaddingLeft() {
final int totalItemWidth = columnWidth * getSpanCount();
if (totalItemWidth >= AutofitRecyclerView.this.getMeasuredWidth()) {
return super.getPaddingLeft(); // do nothing
} else {
return Math.round((AutofitRecyclerView.this.getMeasuredWidth() / (1f + getSpanCount())) - (totalItemWidth / (1f + getSpanCount())));
}
}
@Override
public int getPaddingRight() {
return getPaddingLeft();
}
}
}
फिर जब आप AutofitRecyclerView में LayoutManager को सेट करते हैं, तो निम्न रूप से CenteredGridLayoutManager का उपयोग करें:
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
int[] attrsArray = {
android.R.attr.columnWidth
};
TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
columnWidth = array.getDimensionPixelSize(0, -1);
array.recycle();
}
manager = new CenteredGridLayoutManager(getContext(), 1);
setLayoutManager(manager);
}
और बस! आपके पास एक डायनामिक स्पैन्काउंट है, सेंटर एलाइनर ग्रिडवर्टमैनएगर आधारित रिसाइक्लेरव्यू।
सूत्रों का कहना है:
ग्रिडरेलआउट मैनेजर के साथ रिसाइकलव्यू में हेडर व्यू को जोड़ना
हेडर को ग्रिडरेलआउट के साथ एक रिसाइक्लेरव्यू में जोड़ने के लिए, पहले एडेप्टर को यह बताने की आवश्यकता होती है कि हेडर दृश्य पहली स्थिति है - सामग्री के लिए उपयोग किए जाने वाले मानक सेल के बजाय। इसके बाद, लेआउट प्रबंधक को बताया जाना चाहिए कि पहली स्थिति में पूरी सूची के * स्पैन काउंट के बराबर स्पान होना चाहिए। *
एक नियमित RecyclerView.Adcape क्लास लें और इसे निम्नानुसार कॉन्फ़िगर करें:
public class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM_VIEW_TYPE_HEADER = 0;
private static final int ITEM_VIEW_TYPE_ITEM = 1;
private List<YourModel> mModelList;
public HeaderAdapter (List<YourModel> modelList) {
mModelList = modelList;
}
public boolean isHeader(int position) {
return position == 0;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (viewType == ITEM_VIEW_TYPE_HEADER) {
View headerView = inflater.inflate(R.layout.header, parent, false);
return new HeaderHolder(headerView);
}
View cellView = inflater.inflate(R.layout.gridcell, parent, false);
return new ModelHolder(cellView);
}
@Override
public int getItemViewType(int position) {
return isHeader(position) ? ITEM_VIEW_TYPE_HEADER : ITEM_VIEW_TYPE_ITEM;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder h, int position) {
if (isHeader(position)) {
return;
}
final YourModel model = mModelList.get(position -1 ); // Subtract 1 for header
ModelHolder holder = (ModelHolder) h;
// populate your holder with data from your model as usual
}
@Override
public int getItemCount() {
return _categories.size() + 1; // add one for the header
}
}
फिर गतिविधि / खंड में:
final HeaderAdapter adapter = new HeaderAdapter (mModelList);
final GridLayoutManager manager = new GridLayoutManager();
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return adapter.isHeader(position) ? manager.getSpanCount() : 1;
}
});
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setAdapter(adapter);
एक ही दृष्टिकोण का उपयोग हेडर के अलावा या इसके बजाय एक पाद लेख को जोड़ने के लिए किया जा सकता है।
स्रोत: चिउ-की चान का स्क्वायर आइलैंड ब्लॉग
LinearLayoutManager के साथ सरल सूची
यह उदाहरण डेटासेट के रूप में कस्टम Place
ऑब्जेक्ट्स के ArrayList
का उपयोग करके छवि और नाम के साथ स्थानों की एक सूची जोड़ता है।
गतिविधि लेआउट
गतिविधि / खंड के लेआउट या जहां RecyclerView का उपयोग किया जाता है, वहां केवल RecyclerView होता है। कोई स्क्रॉल दृश्य या एक विशिष्ट लेआउट की आवश्यकता नहीं है।
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
डेटा मॉडल को परिभाषित करें
आप मॉडल के रूप में किसी भी वर्ग या आदिम डेटा प्रकार का उपयोग कर सकते हैं, जैसे int
, String
, float[]
या CustomObject
। RecyclerView इस ऑब्जेक्ट / आदिम की List
को संदर्भित करेगा।
जब कोई सूची आइटम अलग-अलग डेटा प्रकारों जैसे कि पाठ, संख्याओं, छवियों (उदाहरण के लिए स्थानों के साथ) को संदर्भित करता है, तो अक्सर कस्टम ऑब्जेक्ट का उपयोग करना एक अच्छा विचार होता है।
public class Place {
// these fields will be shown in a list item
private Bitmap image;
private String name;
// typical constructor
public Place(Bitmap image, String name) {
this.image = image;
this.name = name;
}
// getters
public Bitmap getImage() {
return image;
}
public String getName() {
return name;
}
}
सूची लेआउट
आपको एक xml लेआउट फ़ाइल निर्दिष्ट करनी होगी जिसका उपयोग प्रत्येक सूची आइटम के लिए किया जाएगा। इस उदाहरण में, ImageView
के लिए छवि और नाम के लिए एक TextView
ImageView
का उपयोग किया जाता है। LinearLayout
ImageView
को बाईं ओर और TextView
दाईं ओर स्थित करता है।
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="8dp">
<ImageView
android:id="@+id/image"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
एक RecyclerView एडाप्टर और ViewHolder बनाएँ
इसके बाद, आप के वारिस के लिए है RecyclerView.Adapter
और RecyclerView.ViewHolder
। एक सामान्य वर्ग संरचना होगी:
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
// ...
public class ViewHolder extends RecyclerView.ViewHolder {
// ...
}
}
सबसे पहले, हम ViewHolder
लागू करते हैं। यह केवल डिफ़ॉल्ट कंस्ट्रक्टर को विरासत में मिला है और कुछ क्षेत्रों में आवश्यक विचारों को सहेजता है:
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView nameView;
public ViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.image);
nameView = (TextView) itemView.findViewById(R.id.name);
}
}
एडेप्टर का निर्माता उपयोग किए गए डेटासेट सेट करता है:
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
private List<Place> mPlaces;
public PlaceListAdapter(List<Place> contacts) {
mPlaces = contacts;
}
// ...
}
हमारे कस्टम सूची आइटम लेआउट का उपयोग करने के लिए, हम onCreateViewHolder(...)
विधि को ओवरराइड करते हैं। इस उदाहरण में, लेआउट फ़ाइल को place_list_item.xml
कहा जाता है।
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
// ...
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.place_list_item,
parent,
false
);
return new ViewHolder(view);
}
// ...
}
onBindViewHolder(...)
, हम वास्तव में विचारों की सामग्री सेट करते हैं। हम उपयोग किए गए मॉडल को दिए गए स्थान पर List
में ढूंढकर प्राप्त करते हैं और फिर ViewHolder
के विचारों पर छवि और नाम सेट करते हैं।
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
// ...
@Override
public void onBindViewHolder(PlaceListAdapter.ViewHolder viewHolder, int position) {
Place place = mPlaces.get(position);
viewHolder.nameView.setText(place.getName());
viewHolder.imageView.setImageBitmap(place.getImage());
}
// ...
}
हमें getItemCount()
लागू करने की भी आवश्यकता है, जो केवल List
का आकार वापस करते हैं।
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
// ...
@Override
public int getItemCount() {
return mPlaces.size();
}
// ...
}
(यादृच्छिक डेटा उत्पन्न करें)
इस उदाहरण के लिए, हम कुछ यादृच्छिक स्थान उत्पन्न करेंगे।
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
List<Place> places = randomPlaces(5);
// ...
}
private List<Place> randomPlaces(int amount) {
List<Place> places = new ArrayList<>();
for (int i = 0; i < amount; i++) {
places.add(new Place(
BitmapFactory.decodeResource(getResources(), Math.random() > 0.5 ?
R.drawable.ic_account_grey600_36dp :
R.drawable.ic_android_grey600_36dp
),
"Place #" + (int) (Math.random() * 1000)
));
}
return places;
}
PlaceListAdapter और डेटासेट के साथ RecyclerView कनेक्ट करें
एडेप्टर के साथ एक RecyclerView
कनेक्ट करना बहुत आसान है। सूची लेआउट प्राप्त करने के लिए आपको LinearLayoutManager
को लेआउट प्रबंधक के रूप में सेट करना होगा।
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setAdapter(new PlaceListAdapter(places));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
किया हुआ!
StaggeredGridLayoutManager
- अपनी लेआउट xml फ़ाइल में अपना RecyclerView बनाएँ:
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
अपना डेटा रखने के लिए अपना मॉडल वर्ग बनाएं:
public class PintrestItem { String url; public PintrestItem(String url,String name){ this.url=url; this.name=name; } public String getUrl() { return url; } public String getName(){ return name; } String name; }
RecyclerView आइटम रखने के लिए एक लेआउट फ़ाइल बनाएँ:
<ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="centerCrop" android:id="@+id/imageView"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:id="@+id/name" android:layout_gravity="center" android:textColor="@android:color/white"/>
RecyclerView के लिए एडेप्टर क्लास बनाएँ:
public class PintrestAdapter extends RecyclerView.Adapter<PintrestAdapter.PintrestViewHolder>{ private ArrayList<PintrestItem>images; Picasso picasso; Context context; public PintrestAdapter(ArrayList<PintrestItem>images,Context context){ this.images=images; picasso=Picasso.with(context); this.context=context; } @Override public PintrestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.pintrest_layout_item,parent,false); return new PintrestViewHolder(view); } @Override public void onBindViewHolder(PintrestViewHolder holder, int position) { picasso.load(images.get(position).getUrl()).into(holder.imageView); holder.tv.setText(images.get(position).getName()); } @Override public int getItemCount() { return images.size(); } public class PintrestViewHolder extends RecyclerView.ViewHolder{ ImageView imageView; TextView tv; public PintrestViewHolder(View itemView) { super(itemView); imageView=(ImageView)itemView.findViewById(R.id.imageView); tv=(TextView)itemView.findViewById(R.id.name); } } }
अपनी गतिविधि या खंड में RecyclerView को तुरंत देखें:
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView); //Create the instance of StaggeredGridLayoutManager with 2 rows i.e the span count and provide the orientation StaggeredGridLayoutManager layoutManager=new new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); // Create Dummy Data and Add to your List<PintrestItem> List<PintrestItem>items=new ArrayList<PintrestItem> items.add(new PintrestItem("url of image you want to show","imagename")); items.add(new PintrestItem("url of image you want to show","imagename")); items.add(new PintrestItem("url of image you want to show","imagename")); recyclerView.setAdapter(new PintrestAdapter(items,getContext() );
अपनी build.gradle फ़ाइल में पिकासो निर्भरता जोड़ने के लिए मत भूलना:
compile 'com.squareup.picasso:picasso:2.5.2'