Andorid 开发中咱们经常会用到listview这个控件,而listview中如何获取到子item的控件并设置相应事件则相对复杂,而且自定义listview经常须要自定义适配器等等,下面这篇文章将主要介绍如何获取item控件并设置响应事件,主要实现如何点击listview子item中的一个按钮跳转到下一个Activity。废话很少说直接上代码:java
package com.example.demo_listitem; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; public class MainActivity extends Activity { private ListView list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); list=(ListView) findViewById(R.id.listView1)**//找到Listview控件** Cadapter ca=new Cadapter(this);**//获得一个Cadapter对象(自定义适配器)** list.setAdapter(ca);**//为listview绑定适配器** } **//定义一个获得数据的方法** public ArrayList<HashMap<String, Object>> getData() { ArrayList<HashMap<String, Object>> listitem=new ArrayList<HashMap<String, Object>>();**//动态数组,装数据** for(int i=0;i<20;i++) { **//利用散列映射添加简单数据** HashMap<String, Object> map=new HashMap<String,Object>(); map.put("title", "hello world"); listitem.add(map); } return listitem;**//返回数据源** } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
最重要的地方,自定义适配器:Cadatper(继承自BaseAdapter)
(PS:使用BaseAdapter必须写一个类继承它,同时BaseAdapter是一个抽象类,继承它必须实现它的方法。而最重要的方法就是getView()方法,在此方法内item的绘制(核心的核心),item内控件的寻找,事件的设定都能作。当开始绘制listview时,首先会调用其getCount()方法,获得listview的长度,而后根据这个长度来绘制listview的每个item)android
package com.example.demo_listitem; import android.content.Context; import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.WebView.FindListener; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class Cadapter extends BaseAdapter{ private Context context1; private LayoutInflater mInflater; public Cadapter(Context context) { context1=context;**//将当前页面的对象赋给context1** this.mInflater=LayoutInflater.from(context1); } @Override public int getCount() { MainActivity m=new MainActivity(); return m.getData().size();**//返回listview长度** } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null) { **//绘制子item** convertView=mInflater.inflate(R.layout.activity_listitem, null); **//获得各个控件** holder=new ViewHolder();**//存放控件的对象** holder.tv=(TextView) convertView.findViewById(R.id.textView1); holder.bt=(Button) convertView.findViewById(R.id.button1); convertView.setTag(holder); **//将数据和convertView绑定在一块儿** } else { holder=(ViewHolder) convertView.getTag(); } MainActivity m=new MainActivity(); holder.tv.setText(m.getData().get(position).get("title").toString());**//为item中的Textview设置数据** **//按钮的点击事件** holder.bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent=new Intent(context1,NextActivity.class); context1.startActivity(intent); } }); return convertView; } }
(getview中的代码,其实彻底能够不用convertView以及holder,直接加入item布局和设计相应的组件属性就好了,这样作虽然行得通,但只适用于listview中item个数较少的时候可行,当item个数达到1000,10000,1000000就行不通了,由于每一个item系统都会绘制一次(getView()一次),item个数较少时还好,当大量的item须要绘制时,会耗费大量的资源在绘制上,这显然实不可取的。
因此,以上代码是通过优化过的,优化之处在于使用convertView和ViewHolder的使用,convertViewconvertView至关于一个缓存,当滑动时,有的条目变为不可见,它缓存了此条目的数据,后面再出来的条目只须要更新数据就能够了,这样大大节省了系统资料的开销
而ViewHolder也是对listview的进一步优化,将holder(找到的控件)用setTag绑定到convertView上,用的时候再用getTag()取出,不用每次都去findviewById,节约系统开销)web
package com.example.deo_listitem; import android.app.Activity; import android.os.Bundle; public class NextActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_next); } }
package com.example.demo_listitem; import android.widget.Button; import android.widget.TextView; public final class ViewHolder { public TextView tv; public Button bt; }
<?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" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>
<?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" android:weightSum="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="80dp" android:orientation="vertical" android:background="#ddc200" android:weightSum="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:orientation="vertical" android:layout_weight="0.5" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.5" android:orientation="vertical" > <Button android:id="@+id/button1" style="?android:attr/buttonStyleSmall" android:layout_width="112dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="下一页" /> </LinearLayout> </LinearLayout> </LinearLayout>
<?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" android:background="#ddc200" > </LinearLayout>
convertView原理:当初始显示一屏listview时,convertView的值为空,(由于没有旧的item,旧的指:滑动时移出屏幕的item),当屏幕移动时,有的item滑到屏幕外面,成了旧的item,convertView会回收这些成为旧了的item并缓存起来,若是有新的item产生,则getview()中的convertView就不是空的,而是移出屏幕的item的值(旧item),咱们须要作的就是将须要显示的数据填充进去就好了,也就是说convertView至关于一个缓存,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只须要更新数据就能够了,这样大大节省了系统资料的开销。数组