Heim >Java >javaLernprogramm >Detaillierte Erklärung von Android ListView
ListView ist eine häufig verwendete Komponente in der Android-Entwicklung. Sie zeigt bestimmte Inhalte in Form einer Liste an und kann entsprechend der Länge der Daten adaptiv angezeigt werden. Ich habe mir die Zeit genommen, die Verwendung von ListView zu klären, und ein kleines Beispiel geschrieben, wie unten gezeigt.
Die Anzeige der Liste erfordert drei Elemente:
1. ListVeiw-Ansicht zur Anzeige von Listen.
2. Der Adapter wird verwendet, um Daten dem Mediator in der ListView zuzuordnen.
3. Daten Die spezifische Zeichenfolge, das Bild oder die Basiskomponente, die zugeordnet wird.
Je nach Adaptertyp der Liste ist die Liste in drei Typen unterteilt: ArrayAdapter, SimpleAdapter und SimpleCursorAdapter
Von diesen ist ArrayAdapter der einfachste und kann nur eine Wortzeile anzeigen. SimpleAdapter bietet die beste Skalierbarkeit und kann verschiedene Effekte anpassen. SimpleCursorAdapter kann als einfache Kombination von SimpleAdapter und der Datenbank betrachtet werden, die den Inhalt der Datenbank in Form einer Liste anzeigen kann.
Wir beginnen mit der einfachsten ListView:
/** * @author allin * */ public class MyListView extends Activity { private ListView listView; //private List<String> data = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); listView = new ListView(this); listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData())); setContentView(listView); } private List<String> getData(){ List<String> data = new ArrayList<String>(); data.add("测试数据1"); data.add("测试数据2"); data.add("测试数据3"); data.add("测试数据4"); return data; } }
Der obige Code verwendet ArrayAdapter(Context context, int textViewResourceId, List8742468051c85b06f0a0af9e3e506b5c Objekte), um die Daten zusammenzustellen. Es ist nur ein Adapter erforderlich, um das ListView-Ansichtsobjekt und die Array-Daten zu verbinden und die beiden anzupassen. Für die Konstruktion des ArrayAdapter sind drei Parameter erforderlich: Dies und die Layoutdatei (beachten Sie, dass die Layoutdatei hier das Layout jeder Zeile beschreibt). Die Liste, android .R.layout.simple_list_item_1 ist eine vom System definierte Layoutdatei, die nur eine Textzeile und eine Datenquelle (eine Listensammlung) anzeigt. Gleichzeitig wird setAdapter () verwendet, um die endgültige Arbeit abzuschließen Die tatsächliche Struktur nach der Operation ist wie folgt:
SimpleCursorAdapter Die Erklärung von SDK lautet: Ein einfacher Adapter zum Zuordnen von Spalten aus a Cursor auf TextViews oder ImageViews, die in einer XML-Datei definiert sind. Sie können angeben, welche Spalten Sie möchten, welche Ansichten Sie anzeigen möchten und welche XML-Datei das Erscheinungsbild dieser Ansichten definiert aus dem Cursor in einer Liste erhalten und die angegebenen Spalten der entsprechenden TextView zuordnen. Das folgende Programm zeigt Kontakte aus dem Telefonbuch in einer Klassentabelle an Datenbankdaten und rufen Sie dann einen Cursor ab, der auf die Datenbank zeigt, und definieren Sie eine Layoutdatei (Sie können natürlich auch den mit dem System gelieferten Cursor = getContentResolver().query verwenden). (People.CONTENT_URI, null, null, null, null); Holen Sie sich zuerst einen Zeiger auf die Systemadressbuchdatenbank. Das Cursor-Objekt erhält die Datenquelle startManagingCursor(cursor); Wir übergeben den erhaltenen Cursor Objekt zur Aktivitätsverwaltung, sodass der Lebenszyklus von Cursor und Aktivität automatisch synchronisiert werden kann, sodass keine manuelle Verwaltung des Cursors erforderlich ist. Die ersten drei Parameter des SimpleCursorAdapter-Konstruktors sind die gleichen wie die von ArrayAdapter. Die letzten beiden Parameter sind: ein String-Array, das die Spalten der Datenbank enthält, und ein int-Array, das die entsprechende Komponenten-ID im Layout enthält Datei. Seine Funktion besteht darin, jede durch das String-Array dargestellte Datenspalte automatisch der Komponente mit der entsprechenden ID in der Layoutdatei zuzuordnen. Der obige Code ordnet die Daten in der Spalte NAME der Komponente mit der ID text1 in der Layoutdatei zu./** * @author allin * */ public class MyListView2 extends Activity { private ListView listView; //private List<String> data = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); listView = new ListView(this); Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null); startManagingCursor(cursor); ListAdapter listAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{People.NAME}, new int[]{android.R.id.text1}); listView.setAdapter(listAdapter); setContentView(listView); } }
Hinweis: Erforderliche Berechtigungen in AndroidManifest.xml: ddcf1f2c1370941dc9e6e48051b0c5d1715e355a41f150f13c9dfb3c5419088c
Nach dem Ausführen des Effekts ist wie unten gezeigt:
SimpleAdaptersimpleAdapter hat die beste Skalierbarkeit und kann verschiedene Layouts definieren und ImageView (Bild) einfügen, Sie können auch Button ( Button), CheckBox (Kontrollkästchen) usw. Die folgenden Codes erben direkt ListActivity. Der Unterschied besteht darin, dass viele Optimierungen für die Anzeige von ListView vorgenommen wurden.Das folgende Programm implementiert eine Klassentabelle mit Bildern.
Zuerst müssen Sie eine XML definieren, um den Inhalt jeder Spalte anzuzeigen
vlist.xml
Das Folgende ist der Implementierungscode:Die von simpleAdapter verwendeten Daten sind im Allgemeinen eine Liste, die aus HashMap besteht. Jeder Abschnitt der Liste entspricht jeder Zeile der ListView. Alle Schlüsselwertdaten von HashMap werden der Komponente mit der entsprechenden ID in der Layoutdatei zugeordnet. Da das System keine entsprechende Layoutdatei zur Verfügung hat, können wir selbst ein Layout vlist.xml definieren. Nehmen Sie als Nächstes die Anpassung vor. Die Parameter eines neuen SimpleAdapters sind: this, Layoutdatei (vlist.xml), Titel und Informationen von HashMap, img. Die Komponenten-ID, der Titel, die Informationen und das Bild der Layoutdatei. Jede Komponente der Layoutdatei wird jedem Element der HashMap zugeordnet, um die Anpassung abzuschließen.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5px"/> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFFFF" android:textSize="22px" /> <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFFFF" android:textSize="13px" /> </LinearLayout> </LinearLayout>Der Betriebseffekt ist wie folgt:
有按钮的ListView
但是有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的xml文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时就要研究一下ListView是如何现实的了,而且必须要重写一个类继承BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果单击按钮将删除此按钮的所在行。并告诉你ListView究竟是如何工作的。效果如下:
vlist2.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5px"/> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFFFF" android:textSize="22px" /> <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFFFF" android:textSize="13px" /> </LinearLayout> <Button android:id="@+id/view_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/s_view_btn" android:layout_gravity="bottom|right" /> </LinearLayout>
程序代码:
/** * @author allin * */ public class MyListView4 extends ListActivity { private List<Map<String, Object>> mData; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mData = getData(); MyAdapter adapter = new MyAdapter(this); setListAdapter(adapter); } private List<Map<String, Object>> getData() { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Map<String, Object> map = new HashMap<String, Object>(); map.put("title", "G1"); map.put("info", "google 1"); map.put("img", R.drawable.i1); list.add(map); map = new HashMap<String, Object>(); map.put("title", "G2"); map.put("info", "google 2"); map.put("img", R.drawable.i2); list.add(map); map = new HashMap<String, Object>(); map.put("title", "G3"); map.put("info", "google 3"); map.put("img", R.drawable.i3); list.add(map); return list; } // ListView 中某项被选中后的逻辑 @Override protected void onListItemClick(ListView l, View v, int position, long id) { Log.v("MyListView4-click", (String)mData.get(position).get("title")); } /** * listview中点击按键弹出对话框 */ public void showInfo(){ new AlertDialog.Builder(this) .setTitle("我的listview") .setMessage("介绍...") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .show(); } public final class ViewHolder{ public ImageView img; public TextView title; public TextView info; public Button viewBtn; } public class MyAdapter extends BaseAdapter{ private LayoutInflater mInflater; public MyAdapter(Context context){ this.mInflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return mData.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.vlist2, null); holder.img = (ImageView)convertView.findViewById(R.id.img); holder.title = (TextView)convertView.findViewById(R.id.title); holder.info = (TextView)convertView.findViewById(R.id.info); holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.img.setBackgroundResource((Integer)mData.get(position).get("img")); holder.title.setText((String)mData.get(position).get("title")); holder.info.setText((String)mData.get(position).get("info")); holder.viewBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showInfo(); } }); return convertView; } } }
下面将对上述代码,做详细的解释,listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到listView的长度(这也是为什么在开始的第一张图特别的标出列表长度),然后根据这个长度,调用getView()逐一绘制每一行。如果你的getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。
系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的布局。我们用LayoutInflater的方法将定义好的vlist2.xml文件提取成View实例用来显示。然后将xml文件中的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那 再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点就OK了。
运行效果如下图: