Android UI之ListView

本文介绍了Android开发中常用的ListView组件,探讨了xml布局文件在ListView中的应用,详细解析了BaseAdapter的工作原理及缓存机制。通过示例展示了如何使用xml文件配置ListView的item布局,并解释了BaseAdapter如何将数据源与界面显示绑定,实现数据和显示的解耦,同时讲解了ListView的缓存策略以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介:ListView组件是在Android APP开发中经常用到的组件,主要是用来显示列表以及相应按下触发完成界面的跳转。

xml文件在ListView中的使用:

xml的作用:xml文件在Android开发中往往承担了界面的布局的作用,其中包含了各个组件以及它们在界面上存储的位置;同时比如strings.xml文件可以配置activity中用到的字符串,dimens.xml文件可以配置边界的位置参数。MainActivity也有属于它的布局文件,其中ListView是其中的一个组件。xml文件类似于给具体内容的实现框定了一个格式,它规定了ListView中数据填充的形式,实现了M(模型)和V(视觉)的分离。
activity_main.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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.asynctask.MainActivity" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textSize="30sp"
        android:text="@string/title1" />

    <!-- ListView 由item.xml里的TextView给值 。-->
    <ListView
        android:id="@+id/listView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView1"
   />
</RelativeLayout>

效果图
在这里插入图片描述
分析:布局文件的ListView中第一行代码为它申请了唯一的id标识,第二、三行代码表示它的大小可以自适应内容的大小而变化,第四行体现了相对布局的特点,ListView放在文本textView的下方。ListView中的item的格式在哪里约束呢?同理,为其中的item自然也需要相应的xml文件来进行配置,在layout文件加下新建一个xml文件,如下:
item.xml

<?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="horizontal" >    
    <!-- 下面两个是用来给  activity_main.xml里的ListView赋值,-->
 <TextView
     android:id="@+id/Textviewname"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_weight="1"
       android:text="1"
       android:textSize="30sp"
    />
 <TextView
     android:id="@+id/Textviewage"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
      android:layout_weight="1"
     android:text="2"
     android:textSize="30sp"
    />
</LinearLayout>

效果图
在这里插入图片描述
分析:从以上效果图中可以清晰地看到它对于每个item的格式约束,使得item的内容由两个文本区域组成,他们各占一半的空间。

BaseAdapter(数据适配器)

**BaseAdapter原理:**接下来要解决的问题就是如何在数据源和用户界面的显示之间建立一个联系,如何把数据库中具体的用户信息显示在列表中。这时就需要使用到数据适配器BaseAdapter了,它个作用就是在数据和显示之间建立一个纽带,实现了数据和显示之间的解耦,符合设计模式中松耦合的设计要求。当然,这个过程会遵守上述xml文件的布局要求。代码中,我们使用一个循环生成一些user对象,模拟数据库。BaseAdapter只需要xml的布局配置信息,以及数据信息,就能动态地配置数据的显示,内部是有封装好的显示的代码的。
BaseAdapter的缓存机制:当列表中数据比较多的时候,往往需要下拉才能得到其余的列表信息,这时,如果频繁地创建新的view会造成资源的浪费也会比较低效。BaseAdapter自带缓存的功能,它维护的view包括两个部分,一部分是当前显示的,另一部分是没有被显示的,没有被显示的那个组件就是缓存区的组件。比如当item0离开显示区后,它会被先保存在缓存区,当一个新的item9准备进入显示区时,适配器会先取出那个item0,把它的数据修改为item9的数据,然后从下方开始显示,这样就形成了一种循环,节省了资源。
MainActivity

public class MainActivity extends Activity {
    private TextView tv1;//item.xml里的TextView:Textviewname
    private TextView tv2;//item.xml里的TextView:Textviewage
    private ListView lv;//activity_main.xml里的ListView
    private BaseAdapter adapter;//要实现的类
    private List<User> userList = new ArrayList<User>();//实体类
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);                
        lv = (ListView) findViewById(R.id.listView1);      
        //模拟数据库
        for (int i = 0; i < 20; i++) {
            User ue = new User();//给实体类赋值
            ue.setName("小米"+i);
            ue.setAge("18");
            userList.add(ue);
        }
        //new一个适配器
        adapter = new BaseAdapter() {            
        	/**
        	 * 重写获取元素数目的方法
        	 */
            public int getCount() {
                // TODO Auto-generated method stub
                return userList.size();//数目
            }            
            /**
             * 获取指定位置的item
             * position表示当前要显示的的第几个视图
             * convertView是缓冲区的视图
             * parent是当前显示的视图组
             */
            public View getView(int position, View convertView, ViewGroup parent) {
                LayoutInflater inflater = MainActivity.this.getLayoutInflater();//用它来载入界面
                View view;//组件的视图                 
                if (convertView==null) {    
                    view = inflater.inflate(R.layout.item, null);//缓存区没有就新建一个view
                }else{
                    view=convertView;//缓存区存在就把它作为当前view
                    Log.i("info","有缓存,不需要重新生成"+position);
                }
                tv1 = (TextView) view.findViewById(R.id.Textviewname);//找到Textviewname组件
                tv1.setText(userList.get(position).getName());//通过数据库中的数据配置组件的参数                
                tv2 = (TextView) view.findViewById(R.id.Textviewage);//找到Textviewage组件
                tv2.setText(userList.get(position).getAge());//设置参数
                return view;
            }
            /**
             * 获取id
             */
            public long getItemId(int position) {//取在列表中与指定索引对应的行id
                return 0;    
            }
            /**
             * 获取item对象
             */
            public Object getItem(int position) {//获取数据集中与指定索引对应的数据项
                return null;
            }        
        };   
            lv.setAdapter(adapter);//生效适配器
          //获取当前ListView点击的行数,并且得到该数据
            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                   //
                   public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                       tv1 = (TextView) view.findViewById(R.id.Textviewname);//找到Textviewname
                       String str = tv1.getText().toString();//得到数据
                       Toast.makeText(MainActivity.this, "" + str, Toast.LENGTH_SHORT).show();//显示数据
                       Intent it = new Intent(MainActivity.this, History.class); //创建一个意图对象
                       Bundle b = new Bundle();//创建一个Bundle对象,用于传递数据
                       b.putString("we",str);  //添加数据到Bundle
                       it.putExtras(b);//把Bundle添加到意图对象
                       startActivity(it);//执行这个意图
                   }
               });                        
     }
}

user类(承载数据信息)

class User {
    private String name;
    private String age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }
}              

最终效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值