Theory
चालीस Events, एक Screen
FestConnect Mobile (आपकी BCA305-02 app) ने एक LinearLayout में मुट्ठी भर events दिखाए, एक-एक TextView: 5 के लिए fine, इस साल के 40 के लिए absurd। 40 TextViews hard-code करना कोई option नहीं है, और अगले साल की list वैसे भी अलग होगी।
Screen को एक ऐसा widget चाहिए जो एक data list ले और demand पर rows manufacture करे, scrolling included। Android का classic answer, और syllabus का, है ListView, और interesting part वह middleman है जो यह employ करता है।
Theory
Thali Server
एक ListView एक canteen counter है जिसमें fixed number की thalis (row views) हैं: सिर्फ़ उतनी जितनी screen पर fit हों।
Adapter kitchen (आपकी data array) और counter के बीच खड़ा server है: हर position के लिए, यह एक thali लेता है, उसमें उस item का food भरता है, और hand over करता है। Scroll कीजिए, और top से slide off हुई thali wipe होती है और नीचे enter हो रही row के लिए REFILL होती है: कोई 10000 items के लिए 10000 plates नहीं cook करता।
Theory
Simple ListView, Formally
तीन pieces plain version wire करते हैं:
- आपकी layout XML में ListView
- आपका data: एक String array या ArrayList
- उन्हें connect करने वाला एक ArrayAdapter, एक built-in row layout दिया गया:
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, events);
listView.setAdapter(adapter);
simple_list_item_1 Android का stock one-TextView row है। Taps position से आते हैं: setOnItemClickListener((parent, view, position, id) -> ...): position directly आपकी data array को index करता है।
Practical
Event List, Simple Form
public class EventListActivity extends AppCompatActivity {
String[] events = { "Garba Night", "Coding Contest", "Robo Race" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_list);
ListView list = findViewById(R.id.eventList);
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this, android.R.layout.simple_list_item_1, events);
list.setAdapter(adapter);
list.setOnItemClickListener((parent, view, position, id) ->
Toast.makeText(this, events[position] + " selected",
Toast.LENGTH_SHORT).show());
}
}
Theory
Custom ListView: आपकी अपनी Row
Committee चाहती है हर row name, venue AND seats left दिखाए: stock one-liner row यह नहीं कर सकती। एक custom ListView = 2 additions:
- आपकी design की हुई एक row layout XML (event_row.xml: दो TextViews और एक ImageView)
- एक custom adapter: ArrayAdapter extend कीजिए और getView(position, convertView, parent) override कीजिए: अपनी row layout inflate कीजिए, इसके pieces findViewById कीजिए,
positionपर data से fill कीजिए, row return कीजिए।
getView thali-filling moment है: यह per VISIBLE row एक बार चलता है, और हर बार row scroll करके view में आने पर फिर।
Practical
Custom Adapter का Heart: Recycling के साथ getView
public class EventAdapter extends ArrayAdapter<Event> {
public EventAdapter(Context c, ArrayList<Event> events) {
super(c, 0, events);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) { // no recycled thali?
convertView = LayoutInflater.from(getContext())
.inflate(R.layout.event_row, parent, false);
}
Event e = getItem(position); // this row's data
TextView name = convertView.findViewById(R.id.rowName);
TextView seats = convertView.findViewById(R.id.rowSeats);
name.setText(e.name);
seats.setText(e.seatsLeft + " seats");
return convertView; // the filled row
}
}
Quiz
getView में, convertView parameter क्या है, और Android इसे आपको क्यों pass करता है?
- User ने आख़िर में जो row tap किया, highlighting के लिए
- एक recycled row view जो screen से बाहर scroll हुई, REUSE के लिए offered ताकि आप सिर्फ़ null होने पर inflate करें
- खुद parent ListView
- Layout XML की एक copy एक View की तरह, हर call में freshly inflated
Show the answer
एक recycled row view जो screen से बाहर scroll हुई, REUSE के लिए offered ताकि आप सिर्फ़ null होने पर inflate करें
convertView वह wiped thali है: एक row object जो screen से slide off हुई, वापस hand की गई ताकि आप एक नई inflate करने की बजाय इसे refill कर सकें: inflation (views में XML parse करना) expensive है, और recycling यही वजह है एक 10000-row list सिर्फ़ एक दर्जन row objects alive के साथ smoothly scroll करती है। Canonical pattern exactly listing जैसा है: null होने पर inflate कीजिए, वरना reuse कीजिए। Option D describe करता है आपका code check के WITHOUT wastefully क्या करता: classic laggy-list bug। Options A और C parameter को पूरी तरह mislabel करते हैं: taps click listener से आते हैं, और parent एक separate argument है।
Think first
Simple या Custom? 3 Lists पर Rule कीजिए
तीन FestConnect screens: (a) एक filter के लिए department names की एक plain list, (b) name + venue + seats + एक photo वाली events list, (c) rules की एक list, एक-एक sentence। Tap करने से पहले हर एक के लिए simple ArrayAdapter या custom adapter decide कीजिए।
Show the answer
(a) और (c): simple ArrayAdapter simple_list_item_1 के साथ: per row एक string exactly इसकी shape है, और इसके लिए एक custom adapter लिखना benefit के बिना ceremony है। (b): custom adapter: per row multiple fields और एक image को आपकी अपनी row layout और getView चाहिए। Decision rule: per row एक string = stock; कुछ भी richer = custom। WHY कहना (row layout का shape adapter choice drive करता है) वह है जो answer को correct से full-marks में upgrade करता है।
Watch out
ListView Traps
हर Call पर Inflate करना: convertView null-check skip करना काम करता है, फिर real data पर stutter करता है: THE performance bug जो examiners describe करते हैं और spot करने को कहते हैं।
setAdapter भूल जाना: बिना adapter वाला ListView silently blank है: कोई error नहीं, कोई rows नहीं।
notifyDataSetChanged: data list बदलने के बाद, adapter.notifyDataSetChanged() call कीजिए वरना screen stale rows दिखाती रहती है: adapter आपकी ArrayList नहीं watch करता; आपको इसे ring करना ज़रूरी है।
Theory
Adapter Idea ListView से आगे निकलता है
Shape hold कीजिए: data + row template + position से एक row fill करने वाला function। Android का modern RecyclerView यह same idea है recycling compulsory बनाई गई, और Unit 5 का Flutter ListView.builder(itemCount, itemBuilder) यह फिर है Dart में: itemBuilder getView IS है nicer clothes के साथ। Middleman एक बार सीखिए और आप जो भी list framework कभी मिलें वह एक dialect है। अगला lesson: वे widgets जो dates pick करते हैं और progress दिखाते हैं: DatePicker, TimePicker, ProgressBar।
Summary
Key takeaways
- ListView scrollable rows render करता है; एक ADAPTER data को rows से bridge करता है।
- Simple form: android.R.layout.simple_list_item_1 के साथ ArrayAdapter, per row एक string।
- Custom form: आपकी अपनी row XML + getView(position, convertView, parent) override करने वाला adapter।
- Recycle: सिर्फ़ convertView null होने पर inflate कीजिए, वरना refill कीजिए: smooth-scroll secret।
- Row taps position के साथ setOnItemClickListener से आते हैं; position आपके data को index करता है।
- Data बदला? adapter.notifyDataSetChanged() वरना screen stale रहती है।
- Memory hook: कम thalis, एक server, endless queue।