android.widget.ListView,译为"列表视图"


设置项目间的分割线:

android:devider="@android:color/daker"

android:deviderHeight="10dp"

android:devider="@null"分割线为透明

android:scrollBar="none"隐藏滚动条

android:listSelector="#00000000"取消点击效果

listview.setSelection(N); 设置ListView需要显示在第几页


平滑移动:

mListView.smoothScrollBy(distance,duration);mListView.smoothScrollByOffset(offset);mListView.smoothScrollToPosition(index);

遍历Listview中的所有item:

for (int i = 0; i < list.getChildCount(); i++) {View view=list.getChildAt(i);}

处理空的ListView:

<FrameLayout 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="@+id/listView1"        android:layout_width="match_parent"        android:layout_height="match_parent" >    </ListView>    <ImageView        android:id="@+id/img"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:src="@drawable/ic_launcher" /></FrameLayout>

ListView list=(ListView) findViewById(R.id.listView1);list.setEmptyView(findViewById(R.id.img));

滑动监听:

ontouchlistener

ListView list=(ListView) findViewById(R.id.listView1);list.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View arg0, MotionEvent arg1) {// TODO Auto-generated method stubswitch (arg1.getAction()) {case MotionEvent.ACTION_DOWN://触摸时操作break;case MotionEvent.ACTION_MOVE://移动时操作break;case MotionEvent.ACTION_UP://离开时操作break;}return false;}});}


onscrollListener:

list.setOnScrollListener(new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView arg0, int arg1) {// TODO Auto-generated method stubswitch (arg1) {case OnScrollListener.SCROLL_STATE_IDLE://滑动停止时break;case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://正在滚动    break;case OnScrollListener.SCROLL_STATE_FLING://手指抛动时,即手指用力滑动//在离开后listview由于惯性继续滑动break;}}@Overridepublic void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {// TODO Auto-generated method stub//滑动时一直调用//arg0-firstVisibleItem 当前能看见的第一个item id(从0开始)//arg2-visibleitemcount 当前能看见的item总数//arg3-toallitemcount 整个list的item总数if (arg1+arg2==arg3&&arg3-count>0) {//滚到最后一行}if (arg1>lastVisibleitemposition) {//上滑}else if (arg1<lastVisibleitemposition) {//下滑}lastVisibleitemposition=arg1;}});}

获取可视区域最后一个id:

list.getLastVisiblePosition();
获取可视区域第一个item的id

list.getFirstVisiblePosition();







列表视图的显示需要三个元素:

1.ListVeiw 用来展示列表的View。

2.适配器 用来把数据映射到ListView上的中介。

3.数据 具体的将被映射的字符串,图片,或者基本组件。

适配器类型通常用ArrayAdapter,SimpleAdapter,SimpleCursorAdapter和BaseAdapter。

ArrayAdapter:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="match_parent" >       <ListView              android:id="@+id/list_view"              android:layout_width="match_parent"              android:layout_height="match_parent" >       </ListView></LinearLayout>

public class MainActivity extends Activity {          
  private String[] data = { "A", "B", "C", "D","E", "F", "G", "H", "I", "J" };         
       @Override            protected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);            ArrayAdapter<String> adapter = new ArrayAdapter<String>(            MainActivity.this, android.R.layout.simple_list_item_1, data);            ListView listView = (ListView) findViewById(R.id.list_view);            listView.setAdapter(adapter);      }}




只能显示一段文本的 ListView 实在是太单调了, 我们现在就来对 ListView 的界面进行定制,让它可以显示更加丰富的内容

public class Hero {private String name;private int image;public Hero(String name,int image){this.name=name;this.image=image;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getImage() {return image;}public void setImage(int image) {this.image = image;}}

Hero 类中只有两个字段,name 表示英雄的名字,image 表示英雄的肖像id。然后需要为 ListView 的子项指定一个我们自定义的布局,在 layout 目录下新建hero_item.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"     >    <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_marginLeft="17dp"        android:layout_marginTop="14dp"        android:layout_toRightOf="@+id/imageView1"        android:text="TextView" />    <ImageView        android:id="@+id/imageView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"        android:layout_marginLeft="24dp"        android:src="@drawable/ic_launcher" /></RelativeLayout>


在这个布局中,我们定义了一个 ImageView 用于显示英雄的图片,又定义了一个TextView 用于显示英雄的名字。接下来需要创建一个自定义的适配器,这个适配器继承自 ArrayAdapter,并将泛型指定为 Hero 类。新建类 HeroAdapter,代码如下所示:

public class HeroAdapter extends ArrayAdapter<Hero> {public int resourceId;public HeroAdapter(Context context, int resource, List<Hero> objects) {super(context, resource, objects);// TODO Auto-generated constructor stubresourceId=resource;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubHero hero=getItem(position);View view=LayoutInflater.from(getContext()).inflate(resourceId, null);ImageView img=(ImageView)view.findViewById(R.id.imageView1);TextView txt=(TextView)view.findViewById(R.id.textView1);img.setImageResource(hero.getImage());txt.setText(hero.getName());return view;}}
HeroAdapter 重写了父类的一组构造函数,用于将上下文、ListView 子项布局的 id和数据都传递进来。另外又重写了 getView()方法,这个方法在每个子项被滚动到屏幕内的
时候会被调用。在 getView 方法中,首先通过 getItem()方法得到当前项的 Hero实例,然后 使 用 LayoutInflater 来 为 这 个 子 项 加 载 我 们 传 入 的 布 局 , 接 着 调 用 View 的findViewById()方法分别获取到 ImageView 和 TextView 的实例,并分别调用它们的setImageResource()和 setText()方法来设置显示的图片和文字,最后将布局返回,这样
我们自定义的适配器就完成了。 下面修改 MainActivity 中的代码,如下所示:

public class MainActivity extends Activity {private List<Hero> heroList=new ArrayList<Hero>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initHero();        HeroAdapter adapter=new HeroAdapter(MainActivity.this, R.layout.hero_item, heroList);        ListView listView = (ListView) findViewById(R.id.listView1);        listView.setAdapter(adapter);    }    private void initHero() {// TODO Auto-generated method stub    Hero ez = new Hero("EZ", R.drawable.a);    heroList.add(ez);    Hero mangseng = new Hero("盲僧", R.drawable.b);    heroList.add(mangseng);    Hero manwang = new Hero("蛮王", R.drawable.c);    heroList.add(manwang);    Hero kapai = new Hero("卡牌", R.drawable.d);    heroList.add(ez);    Hero debang = new Hero("德邦", R.drawable.e);    heroList.add(debang);    Hero yasuo = new Hero("亚索", R.drawable.g);    heroList.add(ez);    }
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>
<span style="font-family: Arial, Helvetica, sans-serif;"></span>

可以看到,这里添加了一个initHero()方法,用于初始化所有的水果数据。在 Hero类的构造函数中将水果的名字和对应的图片 id 传入,然后把创建好的对象添加到水果列表中。 接着我们在 onCreate()方法中创建了 HeroAdapter对象, 并将 HeroAdapter作为适配器传递给了 ListView。这样定制 ListView 界面的任务就完成了。


之所以说 ListView 这个控件很难用,就是因为它有很多的细节可以优化,其中运行效率就是很重要的一点。目前我们 ListView 的运行效率是很低的,因为在 HeroAdapter的
getView()方法中每次都将布局重新加载了一遍,当 ListView 快速滚动的时候这就会成为性能的瓶颈。仔细观察,getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。修改 HeroAdapter中的代码,

public class HeroAdapter extends ArrayAdapter<Hero> {public int resourceId;public HeroAdapter(Context context, int resource, List<Hero> objects) {super(context, resource, objects);// TODO Auto-generated constructor stubresourceId=resource;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubHero hero=getItem(position);View view;if (convertView==null) {view=LayoutInflater.from(getContext()).inflate(resourceId, null);}else{view=convertView;}ImageView img=(ImageView)view.findViewById(R.id.imageView1);TextView txt=(TextView)view.findViewById(R.id.textView1);img.setImageResource(hero.getImage());txt.setText(hero.getName());return view;}}




可以看到,现在我们在 getView()方法中进行了判断,如果 convertView 为空,则使用 LayoutInflater 去加载布局,如果不为空则直接对 convertView 进行重用。这样就大大
提高了 ListView 的运行效率,在快速滚动的时候也可以表现出更好的性能。不过, 目前我们的这份代码还是可以继续优化的, 虽然现在已经不会再重复去加载布局,
但是每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例。我们可以借助一个 ViewHolder 来对这部分性能进行优化,修改 HeroAdapter中的代
码,如下所示:

public class HeroAdapter extends ArrayAdapter<Hero> {public int resourceId;public HeroAdapter(Context context, int resource, List<Hero> objects) {super(context, resource, objects);// TODO Auto-generated constructor stubresourceId=resource;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubHero hero=getItem(position);View view;ViewHolder viewHolder;if (convertView==null) {view=LayoutInflater.from(getContext()).inflate(resourceId, null);viewHolder=new ViewHolder();viewHolder.img=(ImageView)view.findViewById(R.id.imageView1);viewHolder.txt=(TextView)view.findViewById(R.id.textView1);view.setTag(viewHolder);}else{view=convertView;viewHolder=(ViewHolder) view.getTag();}viewHolder.img.setImageResource(hero.getImage());viewHolder.txt.setText(hero.getName());return view;}class ViewHolder{ImageView img;TextView txt;}}
我们新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView为空的时候,创建一个 ViewHolder 对象,并将控件的实例都存放在 ViewHolder 里,然
后调用 View 的 setTag()方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用 View 的 getTag()方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder 里,就没有必要每次都通过 findViewById()方法来获取控件实例了
ListView点击事件
public class MainActivity extends Activity {private List<Hero> heroList=new ArrayList<Hero>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initHero();        HeroAdapter adapter=new HeroAdapter(MainActivity.this, R.layout.hero_item, heroList);        ListView listView = (ListView) findViewById(R.id.listView1);        listView.setAdapter(adapter);        listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {// TODO Auto-generated method stubHero hero = heroList.get(arg2);Toast.makeText(MainActivity.this, hero.getName(),Toast.LENGTH_SHORT).show();}});    }
........................}

可以看到, 我们使用了 setOnItemClickListener()方法来为 ListView 注册了一个监听器,当用户点击了 ListView 中的任何一个子项时就会回调 onItemClick()方法,在这个方
法中可以通过 position 参数判断出用户点击的是哪一个子项,然后获取到相应的英雄,并通过 Toast 将英雄的名字显示出来。





动态修改ListView
public class MainActivity extends Activity implements OnClickListener{private List<String> mdata;private ArrayAdapter<String> adapter;private ListView list;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn=(Button) findViewById(R.id.btnAdd);btn.setOnClickListener(this);mdata = new ArrayList<String>();for (int i = 0; i < 20; i++) {mdata.add("" + i);}list = (ListView) findViewById(R.id.listView1);adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1, mdata);list.setAdapter(adapter);for (int i = 0; i < list.getChildCount(); i++) {View view=list.getChildAt(i);}}//public void btnAdd(View view) {//mdata.add("new");//adapter.notifyDataSetChanged();//list.setSelection(mdata.size() - 1);//}@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubswitch (arg0.getId()) {case R.id.btnAdd:mdata.add("new");adapter.notifyDataSetChanged();list.setSelection(mdata.size()-1);break;default:break;}}}




更多相关文章

  1. Android(安卓)页面布局属性全
  2. Android相对布局属性全集
  3. Android菜鸟日记7
  4. Android控件之TextView(显示文本框控件)
  5. Android系列之浅谈AndroidGallery控件使用方法详解
  6. Layout属性介绍
  7. Android(安卓)- Android实现定时器的方法
  8. Android(安卓)强制横屏
  9. android —— 自定义控件 最简单下拉刷新,Google最新(可刷新任何控

随机推荐

  1. Android(安卓)Handler解析
  2. 怎么把数组从android客户端传递到php服务
  3. Android(安卓)通过listView+RadioButton
  4. Android中隐式意图(Intent)用法
  5. 程序媛也话Android(安卓)之 自定义控件(垂
  6. Android系统目录/system/etc下自建文件存
  7. John Gruber:iPhone 改变了 Android(安卓)
  8. AsyncTask 完全解析
  9. Android(安卓)最简单的导航栏实现
  10. InputFilter实现EditText文本输入过滤器