অ্যান্ড্রয়েড তালিকাভিউ শিরোনাম


122

আমার তালিকার ভিউ রয়েছে যা এর উপর এক ধরণের ইভেন্ট রয়েছে। ইভেন্টগুলি দিন অনুসারে বাছাই করা হয় এবং আমি এটিতে প্রতিদিনের সাথে তারিখের সাথে শিরোনাম রাখতে চাই এবং তারপরে ইভেন্টগুলি নীচে শুনি।

এখানে আমি কীভাবে তালিকাটি তৈরি করি:

ArrayList<TwoText> crs = new ArrayList<TwoText>();

crs.add(new TwoText("This will be header", event.getDate()));

for (Event event : events) {
    crs.add(new TwoText(event.getStartString() + "-" + event.getEndString(), event.getSubject()));
}

arrayAdapter = new TwoTextArrayAdapter(this, R.layout.my_list_item, crs);
lv1.setAdapter(arrayAdapter);

এবং আমার ক্লাস টু টেক্সটটি এমন দেখাচ্ছে:

public class TwoText {
    public String classID;
    public String state;

    public TwoText(String classID, String state) {
        this.classID = classID;
        this.state = state;
    }
}

এবং আমার টু টেক্সটআরএএডাপ্টার শ্রেণিটি এটি দেখায়:

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class TwoTextArrayAdapter extends ArrayAdapter<TwoText> {

    private ArrayList<TwoText> classes;
    private Activity con;
    TextView seperator;

    public TwoTextArrayAdapter(Activity context, int textViewResourceId, ArrayList<TwoText> classes) {
        super(context, textViewResourceId, classes);
        this.con = context;
        this.classes = classes;

    }

    @Override

    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;

        if (v == null) {

            LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            v = vi.inflate(R.layout.my_list_item, null);

        }

        TwoText user = classes.get(position);

        if (user != null) {

            TextView content1 = (TextView) v.findViewById(R.id.list_content1);

            TextView content2 = (TextView) v.findViewById(R.id.list_content2);

            if (content1 != null) {

                content1.setText(user.classID);
            }   
            if(content2 != null) {

                content2.setText(user.state);
            }
        }
        return v;
    }
}

এবং এটি my_list_item.xML

<?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="match_parent"
    android:orientation="vertical" >

    <TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/list_content1"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="5dip"
            android:clickable="false"
            android:gravity="center"
            android:longClickable="false"
            android:paddingBottom="1dip"
            android:paddingTop="1dip"
            android:text="sample"
            android:textColor="#ff7f1d"
            android:textSize="17dip"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/list_content2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="5dip"
            android:clickable="false"
            android:gravity="center"
            android:linksClickable="false"
            android:longClickable="false"
            android:paddingBottom="1dip"
            android:paddingTop="1dip"
            android:text="sample"
            android:textColor="#6d6d6d"
            android:textSize="17dip" />
    </LinearLayout>

</LinearLayout>

এই মুহুর্তে আমি যা করি তা হ'ল আমি নিয়মিত তালিকার অবজেক্ট হিসাবে শিরোনাম যুক্ত করছি, তবে আইডি এটি শিরোনাম হিসাবে পছন্দ করে এবং আমার ক্ষেত্রে এটির একটি তারিখ থাকে।

শিরোনামের জন্য আমার এক্সএমএলে এই কোডটি রয়েছে:

<TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

এবং যখন এটি অনিবার্য হয় তখন আমি এটি লুকিয়ে রাখার চেষ্টা করেছি এবং যখন প্রয়োজনীয় ছিল তখন এটি দেখিয়েছি তবে আমি আমার বাকী কোডটি বিশৃঙ্খলা করে ফেলেছি। আমি আরও কয়েকটি টিউটোরিয়াল চেষ্টা করেছি কিন্তু সেগুলির প্রভাবও একই ছিল।

কীভাবে কেউ আমাকে সেই সহজ উপায়ে পরিচালনা করতে পারেন?

উত্তর:


334

এখানে কিভাবে আমি এটা করতে, কি হয় এর getItemViewType এবং getViewTypeCount মধ্যে Adapterবর্গ। getViewTypeCountতালিকায় আমাদের কত প্রকারের আইটেম রয়েছে তা ফিরিয়ে দেয়, এক্ষেত্রে আমাদের একটি শিরোনাম আইটেম এবং একটি ইভেন্ট আইটেম রয়েছে, তাই দুটি। getItemViewTypeফেরত উচিত কি ধরনের Viewআমরা ইনপুট আছে position

অ্যান্ড্রয়েড তারপর আপনি ডান টাইপ ক্ষণস্থায়ী যত্ন নিতে হবে ViewconvertViewস্বয়ংক্রিয়ভাবে।

এখানে নীচের কোডটির ফলাফলটি কেমন দেখাচ্ছে:

প্রথমে আমাদের একটি ইন্টারফেস রয়েছে যা আমাদের দুটি তালিকার আইটেমের প্রকারটি কার্যকর করবে

public interface Item {
    public int getViewType();
    public View getView(LayoutInflater inflater, View convertView);
}

তারপরে আমাদের একটি অ্যাডাপ্টার রয়েছে যা একটি তালিকা গ্রহণ করে Item

public class TwoTextArrayAdapter extends ArrayAdapter<Item> {
    private LayoutInflater mInflater;

    public enum RowType {
        LIST_ITEM, HEADER_ITEM
    }

    public TwoTextArrayAdapter(Context context, List<Item> items) {
        super(context, 0, items);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getViewTypeCount() {
        return RowType.values().length;

    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).getViewType();
    }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
   return getItem(position).getView(mInflater, convertView);
}

সম্পাদনার জন্য আরও ভাল সম্পাদনা .. স্ক্রোল করার সময় লক্ষ্য করা যায়

private static final int TYPE_ITEM = 0; 
private static final int TYPE_SEPARATOR = 1; 

public View getView(int position, View convertView, ViewGroup parent)  {
    ViewHolder holder = null;
    int rowType = getItemViewType(position);
    View View;
    if (convertView == null) {
        holder = new ViewHolder();
        switch (rowType) {
            case TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.task_details_row, null);
                holder.View=getItem(position).getView(mInflater, convertView);
                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.task_detail_header, null);
                holder.View=getItem(position).getView(mInflater, convertView);
                break;
        }
        convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();
    }
    return convertView; 
} 

public static class ViewHolder {
    public  View View; } 
}

তারপরে আমরা ক্লাসগুলি প্রয়োগ করি Itemএবং সঠিক লেআউটগুলি স্ফীত করি। আপনার ক্ষেত্রে আপনার কাছে Headerক্লাস এবং ক্লাসের মতো কিছু থাকবে ListItem

   public class Header implements Item {
    private final String         name;

    public Header(String name) {
        this.name = name;
    }

    @Override
    public int getViewType() {
        return RowType.HEADER_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View view;
        if (convertView == null) {
            view = (View) inflater.inflate(R.layout.header, null);
            // Do some initialization
        } else {
            view = convertView;
        }

        TextView text = (TextView) view.findViewById(R.id.separator);
        text.setText(name);

        return view;
    }

}

এবং তারপর ListItemক্লাস

    public class ListItem implements Item {
    private final String         str1;
    private final String         str2;

    public ListItem(String text1, String text2) {
        this.str1 = text1;
        this.str2 = text2;
    }

    @Override
    public int getViewType() {
        return RowType.LIST_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View view;
        if (convertView == null) {
            view = (View) inflater.inflate(R.layout.my_list_item, null);
            // Do some initialization
        } else {
            view = convertView;
        }

        TextView text1 = (TextView) view.findViewById(R.id.list_content1);
        TextView text2 = (TextView) view.findViewById(R.id.list_content2);
        text1.setText(str1);
        text2.setText(str2);

        return view;
    }

}

এবং Activityএটি প্রদর্শিত একটি সহজ

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<Item> items = new ArrayList<Item>();
        items.add(new Header("Header 1"));
        items.add(new ListItem("Text 1", "Rabble rabble"));
        items.add(new ListItem("Text 2", "Rabble rabble"));
        items.add(new ListItem("Text 3", "Rabble rabble"));
        items.add(new ListItem("Text 4", "Rabble rabble"));
        items.add(new Header("Header 2"));
        items.add(new ListItem("Text 5", "Rabble rabble"));
        items.add(new ListItem("Text 6", "Rabble rabble"));
        items.add(new ListItem("Text 7", "Rabble rabble"));
        items.add(new ListItem("Text 8", "Rabble rabble"));

        TwoTextArrayAdapter adapter = new TwoTextArrayAdapter(this, items);
        setListAdapter(adapter);
    }

}

জন্য লেআউট R.layout.header

<?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="match_parent"
    android:orientation="horizontal" >

    <TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

</LinearLayout>

জন্য লেআউট R.layout.my_list_item

<?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="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/list_content1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dip"
        android:clickable="false"
        android:gravity="center"
        android:longClickable="false"
        android:paddingBottom="1dip"
        android:paddingTop="1dip"
        android:text="sample"
        android:textColor="#ff7f1d"
        android:textSize="17dip"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/list_content2"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dip"
        android:clickable="false"
        android:gravity="center"
        android:linksClickable="false"
        android:longClickable="false"
        android:paddingBottom="1dip"
        android:paddingTop="1dip"
        android:text="sample"
        android:textColor="#6d6d6d"
        android:textSize="17dip" />

</LinearLayout>

জন্য লেআউট R.layout.activity_main.xml

<RelativeLayout 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"
    tools:context=".MainActivity" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

আপনি ফ্যানসিয়ার পেতে এবং ব্যবহার করতে পারেন ViewHolders, অ্যাসিনক্রোনালি স্টাফ লোড করতে পারেন বা যা আপনার পছন্দ হয়।


5
আপনার সমাধানটি এখানে পছন্দ হয়েছে তবে আপনি যেহেতু একটি অ্যারেএডাপ্টার প্রসারিত করছেন তাই আপনার নিজের আইটেমের তালিকাটি ট্র্যাক করা উচিত নয়। অ্যারেএডাপ্টারে কেবল অভ্যন্তরীণভাবে ট্র্যাক করা একটি ব্যবহার করুন। অন্যথায় আপনি আপনার আইটেমগুলি সঞ্চয় করতে মেমরির পরিমাণ দ্বিগুণ করছেন
জে সায়ার

3
দুর্দান্ত সমাধান। আমি কেবলমাত্র এটি অ্যাডাপ্টারে যুক্ত করব, যদি শিরোনামগুলি ক্লিকযোগ্য না হয় (যা কোনও নির্মাণকারীতে সেট করা যেতে পারে) @ ওভাররাইড পাবলিক বুলিয়ানটি সক্ষম (পূর্ববর্তী অবস্থান) {রিটার্ন (getItem (অবস্থান) .getViewType () == RowType.LIST_ITEM .ordinal ()); }
dwbrito

2
তালিকার ভিউ স্ক্রোল করা হলে সারিগুলি এলোমেলো হয়ে যাচ্ছে? যে কেউ দয়া করে গাইড করতে পারে
i_raqz

1
গুগল কেন কেবল 3 লাইন কোডের সাহায্যে এটি ঘটতে পারে না?
ওজনোগওয়া জুড ওচালিফু

4
এই উত্তরটি আমি এসও-তে পেয়েছি এমন একটি সেরা উত্তর - পরিষ্কার, সংক্ষিপ্ত এবং ভালভাবে ব্যাখ্যা করা হয়েছে। আমার অবশ্য তালিকাভিউয়ের ফলাফলটি একটি অর্ধ-এলোমেলো ক্রমে রয়েছে (প্রথম শিরোনাম এবং আইটেমগুলি ঠিক ছিল, নিম্নলিখিতগুলি জগাখিচুড়ি করা হয়েছিল) নিয়ে সমস্যা হয়েছে, আমি সমস্যাটি কী তা জানতে পেরেছি। 'পারফরম্যান্সের জন্য ইডিআইটি বেটারের নীচে কোডের ব্লকটি .. স্ক্রোল করার সময় লক্ষ্য করা যেতে পারে' এটি আমার জন্য গোলমাল করেছিল - এটি কাস্টম অ্যারেএডাপ্টার ক্লাস থেকে সরানো আমার জন্য সমস্যাটি স্থির করেছে। যারা এলোমেলো ফলাফল পাচ্ছে তাদের প্রত্যেককে এটি চেষ্টা করার পরামর্শ দিচ্ছি। যদিও একটি দুর্দান্ত উত্তরের জন্য ধন্যবাদ। সত্যিই আমাকে সাহায্য করেছে!
ব্লুপ্রিন্টক্রিস

9

আপনি সম্ভবত একটি এক্সপেন্ডেবললিস্টভিউ খুঁজছেন যা আইটেম (শিশুদের) আলাদা করতে শিরোলেখ (গ্রুপ) রয়েছে)

বিষয়টিতে দুর্দান্ত টিউটোরিয়াল: এখানে


আমি চাই না সেগুলি প্রসারিত হোক
রোহিত মালিশ

যদি এটাই একমাত্র সমস্যা হয় তবে আপনি ভিউগুলিকে প্রসারিত / সংকুচিত হওয়া রোধ করতে অন আইটেমিক্লিক পদ্ধতিটিকে ওভাররাইড করতে পারেন।
সাইতো মিয়ার

তবে আমার এখনও তাদের অন্যান্য লক্ষ্যে ক্লিকযোগ্য হতে হবে
রোহিত মালিশ

এর ... আমি বলতে onGroupClickচাইছিলাম যে উইচ কেবল "শিরোনাম" এ ক্লিক করে এবং আপনার ক্লিক বা এই জাতীয় কিছু অক্ষম করতে হবে না, কেবল কোনও পতন ক্রিয়া বাতিল করুন এবং সমস্ত গোষ্ঠী শুরু থেকে প্রসারিত করতে সেট করুন।
সাইতো মিয়ার

আমি সম্মত যে ExpandableListViewবেশিরভাগ ক্ষেত্রে সবচেয়ে ভাল। তবে আমার এমন পরিস্থিতি আছে যেখানে আমি কখনও কখনও ফ্ল্যাট তালিকা এবং আমার ক্রিয়াকলাপের অন্যান্য সময়ে শিরোনামগুলির সাথে তালিকা প্রদর্শন করতে চাই। দুঃখজনকভাবে, ExpandableListAdapterইন্টারফেসটি ইন্টারফেসটি প্রসারিত করে না ListAdapterতাই বহুবর্ষবাদের জন্য আমি @ অ্যান্টিউ এর সমাধানটি ব্যবহার করতে বাধ্য হচ্ছি।
21

3

বিকল্প হিসাবে, একটি দুর্দান্ত তৃতীয় পক্ষের লাইব্রেরি রয়েছে কেবল এই ব্যবহারের ক্ষেত্রে designed এর মাধ্যমে আপনাকে অ্যাডাপ্টারে সংরক্ষণ করা ডেটার ভিত্তিতে শিরোনাম তৈরি করতে হবে। এগুলিকে রোলডেক্স অ্যাডাপ্টার বলা হয় এবং এটি ব্যবহার করা হয় ExpandableListViews। তাদের সহজেই শিরোনামগুলির সাথে সাধারণ তালিকার মতো আচরণ করার জন্য কাস্টমাইজ করা যায়।

ওপি'র Eventঅবজেক্টগুলি ব্যবহার করা এবং শিরোনামগুলি Dateজড়িত এর সাথে সম্পর্কিত এর উপর ভিত্তি করে ... কোডটি দেখতে এরকম কিছু লাগবে:

কার্যক্রম

    //There's no need to pre-compute what the headers are. Just pass in your List of objects. 
    EventDateAdapter adapter = new EventDateAdapter(this, mEvents);
    mExpandableListView.setAdapter(adapter);

অ্যাডাপ্টার

private class EventDateAdapter extends NFRolodexArrayAdapter<Date, Event> {

    public EventDateAdapter(Context activity, Collection<Event> items) {
        super(activity, items);
    }

    @Override
    public Date createGroupFor(Event childItem) {
        //This is how the adapter determines what the headers are and what child items belong to it
        return (Date) childItem.getDate().clone();
    }

    @Override
    public View getChildView(LayoutInflater inflater, int groupPosition, int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {
        //Inflate your view

        //Gets the Event data for this view
        Event event = getChild(groupPosition, childPosition);

        //Fill view with event data
    }

    @Override
    public View getGroupView(LayoutInflater inflater, int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        //Inflate your header view

        //Gets the Date for this view
        Date date = getGroup(groupPosition);

        //Fill view with date data
    }

    @Override
    public boolean hasAutoExpandingGroups() {
        //This forces our group views (headers) to always render expanded.
        //Even attempting to programmatically collapse a group will not work.
        return true;
    }

    @Override
    public boolean isGroupSelectable(int groupPosition) {
        //This prevents a user from seeing any touch feedback when a group (header) is clicked.
        return false;
    }
}

1

আমি শিরোনাম হিসাবে তারিখটি (যেমন 01 ডিসেম্বর, 2016) তৈরি করতে কী করেছি। আমি স্টিকিহাইডারলিস্টভিউ লাইব্রেরি ব্যবহার করেছি

https://github.com/emilsjolander/StickyListHeaders

তারিখটিকে মিলিতে দীর্ঘ রূপান্তর করুন [সময়টি অন্তর্ভুক্ত করবেন না] এবং এটিকে শিরোনাম আইডি হিসাবে তৈরি করুন।

@Override
public long getHeaderId(int position) {
    return <date in millis>;
}

1

পূর্ববর্তীগুলির বিস্তারিত এবং সহায়ক উত্তরের উপর ভিত্তি করে এখানে একটি নমুনা প্রকল্প রয়েছে যা কার্যকর করে aListView যা একাধিক শিরোনাম সহ যা স্ক্রোলিং কর্মক্ষমতা উন্নত করতে অন্তর্ভুক্ত করে।

এই প্রকল্পে, উপস্থাপিত বস্তুগুলি ListViewশ্রেণি HeaderItemবা বর্গের উদাহরণ RowItem, উভয়ই বিমূর্ত শ্রেণির সাবক্লাস Item। প্রতিটি উপক্লাস Itemকাস্টম অ্যাডাপ্টারে পৃথক দর্শন প্রকারের সাথে সম্পর্কিত ItemAdapter,। পদ্ধতি getView()উপর ItemAdapterপ্রতিনিধিদের একটি স্বতন্ত্র প্রতিটি তালিকা আইটেম জন্য সৃষ্টি getView()অন পদ্ধতি HeaderItemবা RowItem, তার উপর নির্ভর করে Itemঅবস্থান থেকে পাস এ ব্যবহার উপশ্রেণী getView()অ্যাডাপ্টারের উপর পদ্ধতি। প্রতিটি Itemসাবক্লাস নিজস্ব ভিউ ধারক সরবরাহ করে।

নীচের মতামত ধারকগণ বাস্তবায়িত হয়। getView()উপর পদ্ধতি Itemউপশ্রেণী কিনা তা পরীক্ষা করুন Viewবস্তু প্রেরণ করা হত getView()উপর পদ্ধতি ItemAdapterনাল হয়। যদি তা হয় তবে উপযুক্ত বিন্যাসটি স্ফীত হয় এবং একটি দর্শন ধারক অবজেক্টটি তাত্ক্ষণিকভাবে এবং স্ফীতিত ভিউয়ের সাথে যুক্ত হয় View.setTag()। যদি Viewবস্তুটি শূন্য না হয়, তবে একটি ভিউ ধারক অবজেক্টটি ইতিমধ্যে দর্শনটির সাথে সম্পর্কিত ছিল এবং ভিউ ধারক এর মাধ্যমে পুনরুদ্ধার করা হবে View.getTag()। যেভাবে ভিউ হোল্ডারগুলি ব্যবহৃত হয় তা নিম্নলিখিত কোড স্নিপেট থেকে পাওয়া যাবে HeaderItem:

@Override
View getView(LayoutInflater i, View v) {
    ViewHolder h;
    if (v == null) {
        v = i.inflate(R.layout.header, null);
        h = new ViewHolder(v);
        v.setTag(h);
    } else {
        h = (ViewHolder) v.getTag();
    }
    h.category.setText(text());
    return v;
}

private class ViewHolder {
    final TextView category;

    ViewHolder(View v) {
        category = v.findViewById(R.id.category);
    }
}

লিস্টভিউয়ের সম্পূর্ণ বাস্তবায়ন অনুসরণ করে। জাভা কোডটি এখানে:

import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class MainActivity extends ListActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ItemAdapter(getItems()));
    }

    class ItemAdapter extends ArrayAdapter<Item> {
        final private List<Class<?>> viewTypes;

        ItemAdapter(List<Item> items) {
            super(MainActivity.this, 0, items);
            if (items.contains(null))
                throw new IllegalArgumentException("null item");
            viewTypes = getViewTypes(items);
        }

        private List<Class<?>> getViewTypes(List<Item> items) {
            Set<Class<?>> set = new HashSet<>();
            for (Item i : items) 
                set.add(i.getClass());
            List<Class<?>> list = new ArrayList<>(set);
            return Collections.unmodifiableList(list);
        }

        @Override
        public int getViewTypeCount() {
            return viewTypes.size();
        }

        @Override
        public int getItemViewType(int position) {
            Item t = getItem(position);
            return viewTypes.indexOf(t.getClass());
        }

        @Override
        public View getView(int position, View v, ViewGroup unused) {
            return getItem(position).getView(getLayoutInflater(), v);
        }
    }

    abstract private class Item {
        final private String text;

        Item(String text) {
            this.text = text;
        }

        String text() { return text; }

        abstract View getView(LayoutInflater i, View v);
    }

    private class HeaderItem extends Item {
        HeaderItem(String text) {
            super(text);
        }

        @Override
        View getView(LayoutInflater i, View v) {
            ViewHolder h;
            if (v == null) {
                v = i.inflate(R.layout.header, null);
                h = new ViewHolder(v);
                v.setTag(h);
            } else {
                h = (ViewHolder) v.getTag();
            }
            h.category.setText(text());
            return v;
        }

        private class ViewHolder {
            final TextView category;

            ViewHolder(View v) {
                category = v.findViewById(R.id.category);
            }
        }
    }

    private class RowItem extends Item {
        RowItem(String text) {
            super(text);
        }

        @Override
        View getView(LayoutInflater i, View v) {
            ViewHolder h;
            if (v == null) {
                v = i.inflate(R.layout.row, null);
                h = new ViewHolder(v);
                v.setTag(h);
            } else {
                h = (ViewHolder) v.getTag();
            }
            h.option.setText(text());
            return v;
        }

        private class ViewHolder {
            final TextView option;

            ViewHolder(View v) {
                option = v.findViewById(R.id.option);
            }
        }
    }

    private List<Item> getItems() {
        List<Item> t = new ArrayList<>();
        t.add(new HeaderItem("Header 1"));
        t.add(new RowItem("Row 2"));
        t.add(new HeaderItem("Header 3"));
        t.add(new RowItem("Row 4"));

        t.add(new HeaderItem("Header 5"));
        t.add(new RowItem("Row 6"));
        t.add(new HeaderItem("Header 7"));
        t.add(new RowItem("Row 8"));

        t.add(new HeaderItem("Header 9"));
        t.add(new RowItem("Row 10"));
        t.add(new HeaderItem("Header 11"));
        t.add(new RowItem("Row 12"));

        t.add(new HeaderItem("Header 13"));
        t.add(new RowItem("Row 14"));
        t.add(new HeaderItem("Header 15"));
        t.add(new RowItem("Row 16"));

        t.add(new HeaderItem("Header 17"));
        t.add(new RowItem("Row 18"));
        t.add(new HeaderItem("Header 19"));
        t.add(new RowItem("Row 20"));

        t.add(new HeaderItem("Header 21"));
        t.add(new RowItem("Row 22"));
        t.add(new HeaderItem("Header 23"));
        t.add(new RowItem("Row 24"));

        t.add(new HeaderItem("Header 25"));
        t.add(new RowItem("Row 26"));
        t.add(new HeaderItem("Header 27"));
        t.add(new RowItem("Row 28"));
        t.add(new RowItem("Row 29"));
        t.add(new RowItem("Row 30"));

        t.add(new HeaderItem("Header 31"));
        t.add(new RowItem("Row 32"));
        t.add(new HeaderItem("Header 33"));
        t.add(new RowItem("Row 34"));
        t.add(new RowItem("Row 35"));
        t.add(new RowItem("Row 36"));

        return t;
    }

}

এছাড়াও দুটি তালিকার আইটেম লেআউট রয়েছে, প্রতিটি আইটেম সাবক্লাসের জন্য একটি। headerশিরোনামটি ব্যবহৃত লেআউটটি এখানে :

<?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:background="#FFAAAAAA"
    >
    <TextView
        android:id="@+id/category"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:textColor="#FF000000"
        android:textSize="20sp"
        android:textStyle="bold"
        />
 </LinearLayout>

এবং এখানে rowরাউআইটেম দ্বারা ব্যবহৃত লেআউটটি রয়েছে:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    >
    <TextView
        android:id="@+id/option"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15sp"
        />
</LinearLayout>

ফলাফল তালিকার একটি অংশের চিত্র এখানে রয়েছে:

একাধিক শিরোলেখ সহ তালিকাগুলি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.