UI控件--ListView

简单的ListView用法

ArrayAdapter
  • ArrayAdapter是只包含字符串的一个简单适配器
  • 首先在在布局文件中添加ListView控件
  • 然后在代码实例化适配器,同时指定listview中内容的布局方式和要显示的内容,最后为listview添加监听事件
public class MainActivity extends AppCompatActivity {

    private ListView list;
    //设置字符串数组存储要在列表中显示的内容
    private String[] data={"Apple","nihao","shijie","Apple","nihao","shijie","Apple","nihao","shijie","Apple","nihao","shijie","Apple",
            "nihao","shijie","Apple","nihao","shijie","Apple","nihao","shijie","Apple","nihao","shijie","Apple","nihao","shijie"};
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list= (ListView) findViewById(R.id.listView);
        //创建最常用的ArrayAdapter实例,第一个参数当前上下文,第二个参数ListView子项布局的id,第三个参数是适配的数据
        //android.R.layout.simple_list_item_1是android系统内置的布局文件
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,data);
        list.setAdapter(adapter);
        //为listView添加监听事件
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String str=(String)list.getItemAtPosition(position);
                Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
            }
        });
    }
}
  • 效果如图所示:
    这里写图片描述
SimpleAdapter
  • SimpleAdapter是扩展性很好的一个适配器,我们可以条目的布局细节,然后再将数据和布局文件中的控件一一对应即可。
  • 比如这样的布局
    这里写图片描述
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textView" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:id="@+id/imageView" />
</LinearLayout>
  • 逻辑代码如下
public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private List<Map<String,Object>> datalist2;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        SimpleAdapter adapter1=new SimpleAdapter(this,datalist2,R.layout.layout_simpleadapter,new String[]{"icon","text"},new int[]{R.id.imageView,R.id.textView});
        listView.setAdapter(adapter1);
    }

    private void init() {
        listView= (ListView) findViewById(R.id.listView);

        datalist2=new ArrayList<>();
        for (int i=0;i<50;i++){
            Map<String,Object> map=new HashMap<>();
            map.put("icon",R.mipmap.ic_launcher);
            map.put("text",i+"条数据" );
            datalist2.add(map);
        }
    }
}
  • 重点注意此处
SimpleAdapter adapter1=new SimpleAdapter(this,datalist2,R.layout.layout_simpleadapter,new String[]{"icon","text"},new int[]{R.id.imageView,R.id.textView});
  • 第二个参数自定义的布局文件
  • 第三个参数,添加的数据对应的键的值
  • 第四个参数于第三个参数务必一一对应,第四个参数放置他们对应的id

这里写图片描述

SimpleAdapter相比于自定义的Adapter的区别

SimpleAdapter不用再自己写adapter中的各个方法的实现,只需要将SimpleAdapter实例化出来就可以了
同样也由于不用自己写adapter中的各个方法的实现,所以我们无法对lsitview实现效率优化。

定制ListView的界面

  • 既然要自定义listview的界面,首先新建布局文件,将布局按自己要求写好
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content">


    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:id="@+id/imageView" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/textView" />
</LinearLayout>

这里写图片描述
- 新建一个工具类,用来存放每个条目中个空间信息,如这个条目中图片的id和文本的内容

package com.lingzhuo.applist;

/**
 * Created by Wang on 2016/3/17.
 */
public class App {
    private String name;
    private int picId;

    public App(String name, int picId) {
        this.name = name;
        this.picId = picId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPicId() {
        return picId;
    }

    public void setPicId(int picId) {
        this.picId = picId;
    }
}
  • 由于是自定义listview控件,所以系统自带的适配器就无法完成适配,因此必去自己重写适配器和其中的方法
public class MyAdapter extends ArrayAdapter<App> {
    private int layoutId;
    //textViewResourceId条目布局文件的id
    public MyAdapter(Context context, int textViewResourceId, List<App> objects) {
        super(context,textViewResourceId, objects);
        layoutId=textViewResourceId;
    }

    //每当listview滚动的时候,每有一个新的条目进入屏幕范围,就会调用一次这个方法
    public View getView(int position, View convertView, ViewGroup parent) {
        App app=getItem(position);
        //加载定义的条目的布局文件
        View view= LayoutInflater.from(getContext()).inflate(R.layout.item_layout,null);
        ImageView imageView= (ImageView) view.findViewById(R.id.imageView);
        TextView textView= (TextView) view.findViewById(R.id.textView);
        imageView.setImageResource(app.getPicId());
        textView.setText(app.getName());
        return view;
    }
}
  • 适配器定义完毕,就需要在主布局中加入listview控件,并得到它,实例化自己的适配器,将适配器与listview绑定到一起就可以了,还可以对listview添加点击监听事件
public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private List<App> applist=new ArrayList<>();
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        listView= (ListView) findViewById(R.id.listView);
        //实例化自己定义的适配器
        final MyAdapter adapter=new MyAdapter(getApplicationContext(),R.layout.item_layout,applist);
        listView.setAdapter(adapter);
        //添加监听事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                App app= (App) listView.getItemAtPosition(position);
                Toast.makeText(MainActivity.this, app.getName(), Toast.LENGTH_SHORT).show();
            }
        });


    }
    //初始化条目的各种显示信息
    private void init() {
        App qq=new App("QQ",R.drawable.qq);
        applist.add(qq);
        App as=new App("AS",R.drawable.as);
        applist.add(as);
        App baidu=new App("baidu",R.drawable.baidu);
        applist.add(baidu);
        App dream=new App("dream",R.drawable.dream);
        applist.add(dream);
        App eclipse=new App("eclipse",R.drawable.eclipse);
        applist.add(eclipse);
        App gy=new App("gy",R.drawable.gy);
        applist.add(gy);
        App music=new App("music",R.drawable.music);
        applist.add(music);
        App pot=new App("pot",R.drawable.pot);
        applist.add(pot);
        App vs=new App("vs",R.drawable.vs);
        applist.add(vs);
        applist.add(qq);
        applist.add(as);
        applist.add(baidu);
        applist.add(dream);
        applist.add(eclipse);
        applist.add(gy);
        applist.add(music);
        applist.add(pot);
        applist.add(vs);
    }
}
  • 效果图如下:
    这里写图片描述

ListView的效率优化

  • 在getView(int position, View convertView, ViewGroup parent)方法中,还有一个convertView参数,这个参数用于将之前加载好的进行缓存,以便之后可以重用
  • 简单说就是,滚动list的时候,convertView就是那个滚出屏幕的条目,这个条目可以复用,用来显示正在进入屏幕的那个条目,这样就避免了一直创建view,可以提高效率
public View getView(int position, View convertView, ViewGroup parent) {
        App app=getItem(position);
        View view;
        //判断convertView,为空就加载布局文件,
        if (convertView==null){
            view= LayoutInflater.from(getContext()).inflate(R.layout.item_layout,null);
        }else{
            view=convertView;
        }
        ImageView imageView= (ImageView) view.findViewById(R.id.imageView);
        TextView textView= (TextView) view.findViewById(R.id.textView);
        imageView.setImageResource(app.getPicId());
        textView.setText(app.getName());
        return view;
    }
  • 上面的代码虽然不会在重复加载布局文件了,但在每次getView()中还是会调用findViewById()方法来获取一次控件的实例。所以我们可以使用ViewHolder来对这部分进行优化
public View getView(int position, View convertView, ViewGroup parent) {
        App app=getItem(position);
        View view;
        ViewHolder viewHolder;
        //判断convertView,为空就加载布局文件,同时对view和viewHolder进行实例化
        if (convertView==null){
            view= LayoutInflater.from(getContext()).inflate(R.layout.item_layout,null);
            viewHolder=new ViewHolder();
            viewHolder.imageView=(ImageView) view.findViewById(R.id.imageView);
            viewHolder.textView=(TextView) view.findViewById(R.id.textView);
            //将viewHolder存储在view中
            view.setTag(viewHolder);
        }else{
        //若不为空,直接进行复用view和viewHolder
            view=convertView;
            viewHolder= (ViewHolder) view.getTag();
        }
        //在对viewHolder中的控件进行赋值即可
        viewHolder.imageView.setImageResource(app.getPicId());
        viewHolder.textView.setText(app.getName());
        return view;
    }
    //新建一个内部类,在这个类中,定义在条目中每个空间的实例
    class ViewHolder{
        ImageView imageView;
        TextView textView;
    }

在此基础上制作的界面

这里写图片描述
注意,在list中添加了checkbox,button等这种控件后,list的点击事件会失效,具体原因是因为发生了焦点抢夺,只需要我们对checkbox、button等控件添加android:focusable=”false”这个属性,就可以解决焦点抢夺的问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值