# ListView

> एकल या बहु चयन के साथ, स्क्रॉल करने योग्य और एम्बेड करने योग्य टेक्स्ट आइटम की सूची।

Source: https://crossfly.dev/hi/docs/ui/widgets/listview — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# ListView

`ListView` चयन के लिए **टेक्स्ट** आइटम की एक स्क्रॉल करने योग्य सूची है, जो किसी भी कंटेनर में एम्बेड करने के लिए तैयार है। प्रत्येक आइटम एक क्लिक करने योग्य "कार्ड" बन जाता है। चयन मोड कंस्ट्रक्टर में `ItemType` के माध्यम से तय होता है: `SINGLE` (टच चयन करता है और पुष्टि करता है) या `MULTIPLE` (चेकबॉक्स + "पुष्टि करें" बटन)।

`VirtualListView` के विपरीत, `ListView` **प्रति आइटम एक कंपोनेंट बनाता है** (कोई रीसाइक्लिंग नहीं) — यह छोटी/मध्यम सूचियों (दर्जनों आइटम) के लिए आदर्श है, हजारों पंक्तियों के लिए नहीं।

> 🟡 · **पैकेज:** `dev.crossfly.ui` · **एक्सटेंड करता है:** `Component` · **स्टाइल:** `ListViewStyle` (आइटम/header/बटन) + `WindowStyle` (बैकग्राउंड, `selectionWindowStyle()` के माध्यम से)

## कब उपयोग करें
- किसी स्क्रीन में एम्बेडेड सेलेक्टर (विकल्प मेनू, फ़िल्टर, श्रेणी चयन)।
- कुछ दर्जन टेक्स्ट आइटम जहां स्क्रॉल के बिना सटीक ऊंचाई उपयोगी है (`computeIdealHeight`)।
- स्पष्ट पुष्टि के साथ बहु-चयन (`MULTIPLE`)।

## कब उपयोग न करें
- बड़ी सूचियां (सैकड़ों/हज़ारों) → [`VirtualListView`](/docs/ui/widgets/virtuallistview) का उपयोग करें, जो कंपोनेंट को रीसाइकल करता है।
- चयन का मोडल पॉपअप → [`ListViewWindow`](/docs/ui/widgets/listviewwindow) का उपयोग करें, जो `ListView` को एक `Window` में लपेटता है।
- छवि/कई फ़ील्ड वाली समृद्ध पंक्तियां → `itemFactory(...)` का उपयोग करें या [सूची आइटम](/docs/ui/widgets/list-items) के साथ सूची को हाथ से बनाएं।

## दिखावट
केंद्रित टेक्स्ट कार्ड का ऊर्ध्वाधर स्तंभ, वैकल्पिक हेडर (शीर्षक + बैक आइकन) के साथ और, `MULTIPLE` में, फ़ुटर में "पुष्टि करें" बटन। `SINGLE` में प्रत्येक कार्ड एक `LabelItem` है; `MULTIPLE` में, एक `CheckLabelItem` (चेकबॉक्स + लेबल)।

## पूरा उदाहरण (कॉपी करें, पेस्ट करें और चलाएं)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** चलाने योग्य मुख्य स्क्रीन। launcher (classname) की ओर संकेत करें और चलाएँ: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      ListView list = new ListView(new String[]{"Um", "Dois", "Três"}, ListView.ItemType.SINGLE)
         .showHeader(false);
      list.onConfirm(e -> System.out.println("Escolhido: " + list.getSelectedText()));

      add(LAY_FILL, list);   // सूचियां LAY_FILL उपयोग करती हैं (ऊंचाई अवशोषित करती हैं)
   }
}
```

> नीचे दिए गए स्निपेट **केवल मुख्य भाग** दिखाते हैं (जो `onShow()` के अंदर जाता है)। चलाने के लिए, उन्हें ऊपर के `MainWindow` ढांचे में रखें।

## बुनियादी उपयोग
```java
// SINGLE, बिना हेडर, स्वचालित ऊंचाई (बिना स्क्रॉल)
ListView list = new ListView(new String[]{"Um", "Dois", "Três"}, ListView.ItemType.SINGLE)
   .showHeader(false);
list.onConfirm(e -> System.out.println("Escolhido: " + list.getSelectedText()));
contents.add(.95f, list);
```

## कंस्ट्रक्टर
| कंस्ट्रक्टर | विवरण |
|---|---|
| `ListView(String[] items, ItemType itemType)` | बिना शीर्षक वाली सूची |
| `ListView(String title, String[] items, ItemType itemType)` | हेडर में शीर्षक वाली सूची |

`ItemType` (`UIConstants` में परिभाषित): `SINGLE` या `MULTIPLE`। निर्माण के बाद मोड **अपरिवर्तनीय** है।

## प्रॉपर्टीज़ और अनुकूलन
| प्रॉपर्टी / मेथड | प्रकार | डिफ़ॉल्ट | क्या करता है |
|---|---|---|---|
| `addItem(String)` | `ListView` | — | एक आइटम जोड़ता है (आलसी rebuild; `null` को अनदेखा करता है) |
| `addItems(String...)` | `ListView` | — | कई आइटम जोड़ता है (एकमात्र invalidation) |
| `showHeader(boolean)` | `ListView` | `true` | हेडर दिखाता/छिपाता है (शीर्षक + बैक) |
| `title(String)` | `ListView` | `null` | शीर्षक सेट करता है |
| `confirmText(String)` | `ListView` | `"Confirmar"` | बटन का टेक्स्ट (केवल `MULTIPLE`) |
| `itemStyle(ComponentStyle)` | `ListView` | थीम | सभी आइटम की स्टाइल का ओवरराइड |
| `confirmButtonStyle(ComponentStyle)` | `ListView` | थीम | पुष्टि बटन की स्टाइल |
| `headerStyle(LabelStyle)` | `ListView` | थीम | हेडर की स्टाइल |
| `itemFactory(ItemFactory)` | `ListView` | `null` | कस्टम आइटम फ़ैक्ट्री (`text`, `index` प्राप्त करती है) |
| `closeAction(Runnable)` | `ListView` | `null` | क्लोज़ ऐक्शन (`ListViewWindow` `this::hide` की ओर इंगित करता है) |
| `computeIdealHeight(int width)` | `int` | — | स्क्रॉल के बिना सटीक ऊंचाई, या `itemFactory` होने पर `-1` |

### चयन पूछताछ
`getSelectedCount()`, `getSelectedIndex()`, `getSelectedText()`, `getSelectedIndices()`, `getSelectedTexts()`, `isSelected(int)`, `getSelectionState()` (`boolean[]`)।

## कॉलबैक और इवेंट
| कॉलबैक | कब ट्रिगर होता है |
|---|---|
| `onConfirm(Component.Action)` | `SINGLE`: किसी आइटम को टच करने पर। `MULTIPLE`: "पुष्टि करें" को टच करने पर |

`SINGLE` में, टच पिछले चयन को साफ़ करता है, इंडेक्स को चिह्नित करता है, `onConfirm` ट्रिगर करता है और `close()` कॉल करता है। `MULTIPLE` में, टच आइटम के चेकबॉक्स को टॉगल करता है; पुष्टि बटन से आती है।

## स्थितियां
- **SINGLE** — एक समय में केवल एक आइटम चिह्नित; टच पहले से ही पुष्टि करता है और बंद कर देता है।
- **MULTIPLE** — कई आइटम चिह्नित करने योग्य; पुष्टि से पहले भी `getSelectionState()` के माध्यम से स्थिति की पूछताछ की जा सकती है।
- हेडर और फ़ुटर बटन वैकल्पिक हैं (`showHeader`/`title` और `ItemType` पर निर्भर)।

### स्वचालित ऊंचाई वाला MULTIPLE
```java
ListView multi = new ListView(new String[]{"Vermelho", "Verde", "Azul"},
      ListView.ItemType.MULTIPLE)
   .showHeader(false)
   .confirmText("Aplicar");
multi.getStyle().autoHeight(Relative.ofFont(9f));
multi.onConfirm(e -> {
   for (String t : multi.getSelectedTexts())
      System.out.println("marcado: " + t);
});
contents.add(.95f, multi);
```

### `itemFactory` के साथ कस्टम पंक्तियां
```java
ListView list = new ListView(labels, ListView.ItemType.SINGLE).showHeader(false);
list.itemFactory((text, index) -> {
   Component row = new Component();
   row.style(Styles.component().pressable().ingap(Gap.ofFont(.3f)));
   row.setLayout(new GridLayout(Position.START, Position.CENTER));
   row.add(new Label(text));
   return row;
});
list.onConfirm(e -> System.out.println("idx = " + list.getSelectedIndex()));
contents.add(.95f, list);
```

## सर्वोत्तम अभ्यास
- कई `addItem(...)` के बजाय `addItems(...)` को प्राथमिकता दें — एकमात्र लेआउट invalidation।
- जब आप सटीक ऊंचाई वाली **स्क्रॉल-रहित** सूची चाहें तो `computeIdealHeight(width)` का उपयोग करें (`itemFactory` होने पर `-1` लौटाता है, क्योंकि कस्टम आइटम सामान्य रूप से मापने योग्य नहीं होते)।
- आइटम का पुनर्निर्माण आलसी है (अगले लेआउट में होता है), जिसमें चौड़ाई बदलने पर भी शामिल है।

## सामान्य गलतियां
- **हज़ारों आइटम के लिए `ListView` का उपयोग करना** — यह रीसाइकल नहीं करता; मेमोरी रैखिक रूप से बढ़ती है। [`VirtualListView`](/docs/ui/widgets/virtuallistview) पर माइग्रेट करें।
- **`MULTIPLE` में हर टच पर `onConfirm` की उम्मीद करना** — `MULTIPLE` में कॉलबैक केवल "पुष्टि करें" बटन पर ट्रिगर होता है; हर चिह्न पर प्रतिक्रिया देने के लिए `getSelectionState()` की पूछताछ करें।
- **यह मानना कि बिना आइटम वाला कंस्ट्रक्टर मौजूद है** — कंस्ट्रक्टर को `items` और `ItemType` की आवश्यकता होती है; `new String[]{}` से शुरू करें और `addItems(...)` का उपयोग करें।

## यह भी देखें
- क्षेत्र गाइड: [`ui/`](/docs/ui) · रेसिपी: [`cookbook/`](/docs/cookbook)
- संबंधित कंपोनेंट: [`ListViewWindow`](/docs/ui/widgets/listviewwindow) · [`VirtualListView`](/docs/ui/widgets/virtuallistview) · [सूची आइटम (`LabelItem`/`CheckLabelItem`)](/docs/ui/widgets/list-items)
