ListView的用法

一、ListView的简单介绍

1. ListView 概念:

  ListView是Android中最重要的组件之一,几乎每个Android应用中都会使用ListView。它以垂直列表的方式列出所需的列表项。

2. ListView的两个职责:

(1)将数据填充到布局;
(2)处理用户的选择点击等操作。

3. 列表的显示需要三个元素

(1)ListVeiw:用来展示列表的View;
(2)适配器: 用来把数据映射到ListView上的中介;
(3)数据源: 具体的将被映射的字符串,图片,或者基本组件。

4. 什么是适配器?

  适配器是一个连接数据和AdapterView的桥梁,通过它能有效地实现数据与AdapterView的分离设置,使AdapterView与数据的绑定更加简便,修改更加方便。

  Android开发中的适配器一共可分为:
  ArrayAdapter,
  BaseAdapter,
  CursorAdapter,
  HeaderViewListAdapter,
  ResourceCursorAdapter,
  SimpleAdapter,
  SimpleCursorAdapter,
  WrapperListAdapter
  其中,ArrayAdapter和SimpleAdapter最为常见。

ArrayAdapter最为简单,只能展示一行字;
SimpleAdapter有最好的扩充性,可以自定义各种各样的布局,除了文本外,还可以放ImageView(图片)、Button(按钮)、CheckBox(复选框)等等;
但是实际工作中,常用自定义适配器。即继承于BaseAdapter的自定义适配器类。

5. ListView的常用UI属性:

  android:divider
  android:dividerHeight

二、ListView的创建与使用

1. ArrayAdapter适配器

先看下面代码:

package com.danny_jiang.day08_listview_introduce;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 1 初始化ListView
        ListView listView = (ListView) findViewById(R.id.list_Main);

        // 2 初始化数据源
        String[] data = getResources().getStringArray(R.array.arr);

        // 3 初始化适配器
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, data);

        // 4 将适配器设置到ListView控件中
        listView.setAdapter(adapter);

        // 设置ListView的单击事件
        listView.setOnItemClickListener(new OnItemClickListener() {

            /**
             * @param parent
             *            ListView
             * @param view
             *            所点击的item视图,也就是TextView
             * @param position
             *            所点击item的位置
             * @param id
             *            所点击item的id
             */
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                if (view instanceof TextView) {
                    TextView textView = (TextView) view;
                    String content = textView.getText().toString();

                    Toast.makeText(MainActivity.this, "点击了 " + content,
                            Toast.LENGTH_SHORT).show();
                }
            }
        });

        // 设置ListView的长按事件
        listView.setOnItemLongClickListener(new OnItemLongClickListener() {

            /**
             * @param parent
             *            ListView
             * @param view
             *            所点击的item视图,也就是TextView
             * @param position
             *            所点击item的位置
             * @param id
             *            所点击item的id
             */
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view,
                    int position, long id) {
                if (view instanceof TextView) {
                    TextView textView = (TextView) view;
                    String content = textView.getText().toString();

                    Toast.makeText(MainActivity.this, "长按了 " + content,
                            Toast.LENGTH_SHORT).show();
                }
                // 返回true,表示将单击事件进行拦截
                return true;
            }
        });
    }
}

布局文件:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <!--
        通过ListView标签可以声明列表视图
        android:divider="#FF0000"   设置ListView间隙之间的颜色,必须指定dividerHeight后才会生效
        android:dividerHeight="2dp"     设置ListView间隙之间的间隔
    -->

    <ListView
        android:id="@+id/list_Main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="#FF0000"
        android:dividerHeight="2dp" >
    </ListView>

</RelativeLayout>

strings.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Day08_ListView_Introduce</string>
    <string name="hello_world">Hello world!</string>

    <string-array name="arr">
        <item>西游记</item>
        <item>红楼梦</item>
        <item>李尔王</item>
        <item>麦克白</item>
        <item>西游记</item>
        <item>红楼梦</item>
        <item>李尔王</item>
        <item>麦克白</item>
        <item>西游记</item>
        <item>红楼梦</item>
        <item>李尔王</item>
        <item>麦克白</item>
        <item>西游记</item>
        <item>红楼梦</item>
        <item>李尔王</item>
        <item>麦克白</item>
    </string-array>

</resources>

效果图如下:
这里写图片描述

2. SimpleAdapter适配器

2.1 使用系统自带item布局
先看下面代码:

package com.danny_jiang.day08_listview_simpleadapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化ListView控件
        listView = (ListView) findViewById(R.id.list_Main);

        // 初始化数据源
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        for (int i = 0; i < 10; i++) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("name", "Android-" + i);
            map.put("age", "age-" + i);
            map.put("gender", "male");

            list.add(map);
        }

        // 初始化item的布局文件(使用系统自带布局)
        int itemLayout = android.R.layout.simple_list_item_2;

        /**
         * 初始化SimpleAdapter适配器
         * 
         * @param this 
         *                上下文
         * @param list
         *            数据源 List<Map>
         * @param itemLayout
         *            item的布局文件ID,使用此item来显示ListVirw中的每一个item
         * @param new String[] { "gender", "age" }
         *            是一系列String,key的数组,key是Map中put时所使用的key值
         * @param new int[] { android.R.id.text1, android.R.id.text2 } 
         *            一些列id的int数组,id的顺序决定了数据源中item的摆放顺序
         *        
         */
        SimpleAdapter adapter = new SimpleAdapter(this, list, itemLayout,
                new String[] { "gender", "age" },
                new int[] { android.R.id.text1, android.R.id.text2 });


        // ListView设置适配器
        listView.setAdapter(adapter);
    }
}

布局文件:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/list_Main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</RelativeLayout>

效果图如下:
这里写图片描述

2.2 自定义item布局文件

代码如下:

package com.danny_jiang.day08_listview_iconitem;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

    private ListView listView;

    // 声明需要显示到ListView上的图片资源ID
    private int[] iconId = new int[] { R.drawable.tv01, R.drawable.tv02,
            R.drawable.tv03, R.drawable.tv04, R.drawable.tv05,
            R.drawable.tv06, R.drawable.tv07, R.drawable.tv08, 
            R.drawable.tv09, R.drawable.tv10, R.drawable.tv01,};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化ListView控件
        listView = (ListView) findViewById(R.id.list_main);

        // 初始化数据源
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < iconId.length; i++) {
            Map<String, Object> map = new HashMap<String, Object>();

            map.put("name", "Android-" + i);
            map.put("icon", iconId[i]);

            list.add(map);
        }

        // 初始化item布局
        int itemLayout = R.layout.list_item;

        // 初始化适配器SimpleAdapter
        SimpleAdapter adapter = new SimpleAdapter(this, list, itemLayout,
                new String[] { "icon", "name" }, new int[] { R.id.image,
                        R.id.name });

        // ListView设置适配器
        listView.setAdapter(adapter);
    }
}

布局文件:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/list_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

item布局文件:

<?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:gravity="center_vertical"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="TEXT" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="120dp"
        android:layout_marginLeft="50dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

效果图如下:
这里写图片描述

3. BaseAdapter适配器

代码如下:

package com.danny_jiang.day08_listview_baseadapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {

    private ListView listView;

    private List<Map<String, String>> list = new ArrayList<Map<String,String>>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.list_Main);

        for(int i = 0; i < 50; i++) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("key", "value" + i);
            map.put("asd", "asd" + i);

            list.add(map);
        }

        MyBaseAdapter adapter = new MyBaseAdapter(this, list);

        listView.setAdapter(adapter);
    }
}

自定义适配器 MyBaseAdapter:

package com.danny_jiang.day08_listview_baseadapter;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyBaseAdapter extends BaseAdapter{

    // 在自定义Adapter中声明全局的数据源对象
    private List<Map<String, String>> list;

    private Context context;

    // 声明布局填充器,通过它可以填充xml布局文件并返回View对象
    private LayoutInflater inflater;

    public MyBaseAdapter(Context context, List<Map<String, String>> list) {
        this.context = context;
        inflater = LayoutInflater.from(context);
        this.list = list;
    }

    /**
     * 返回ListView需要显示条数
     * 一般情况下需要返回数据源的长度
     */
    @Override
    public int getCount() {
        // 如果数据源是null,则返回0,否则返回数据源的长度
        return list == null ? 0 : list.size();
    }

    /**
     * 返回某位置上的item对象
     * 当调用ListView.getItemAtPosition(0/1)
     * 应当返回数据源中position对应的对象
     */
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    /**
     * 返回position对应item的id,一般返回position
     */
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 返回ListView中position所对应的item需要显示的视图对象
     * position从0开始
     * 
     * @param position      需要填充视图的视图位置,从0开始
     * @param convertView   ListView的优化机制,Android系统对getView返回视图的一个复用机制
     * @param parent            将item视图填充到的AdapterView,也就是ListView本身
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;

        if (convertView == null) {

            // 通过LayoutInflater填充xml布局文件,将获取到的convertView对象返回
            convertView = inflater.inflate(R.layout.list_item, null);

            // 初始化holder,并为其属性赋值
            holder = new ViewHolder();
            holder.text1 = (TextView) convertView.findViewById(R.id.text1);
            holder.text2 = (TextView) convertView.findViewById(R.id.text2);

            // 给convertView添加标签holder
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        // 获取当前位置中数据源的元素
        Map<String, String> map = list.get(position);
        String value = map.get("key");
        String asd = map.get("asd");

        // 为每个item中的所有UI控件设置属性值
        holder.text1.setText(value);
        holder.text2.setText(asd);
        return convertView;
    }

    class ViewHolder{
        TextView text1;
        TextView text2;
    }

}

布局文件:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/list_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

自定义item布局文件:

<?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:gravity="center_vertical"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="TEXT" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="120dp"
        android:layout_marginLeft="50dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

效果图如下:
这里写图片描述

三、convertView原理:

  Adapter的作用就是ListView界面与数据之间的桥梁,当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View。

  如果在我们的列表有上千项时会是什么样的?是不是会占用极大的系统资源?

  Android中有个叫做Recycler的构件,如果你有100个item,其中只有可见的项目存在内存中,其他的在Recycler中。ListView先请求一个type1视图(getView),然后请求其他可见的item,convertView在getView中是空(null)的。
当item1滚出屏幕,并且一个新的item从屏幕底端上来时,ListView再请求一个type1视图,convertView此时不是空值了,它的值是item1。你只需设定新的数据,然后返回convertView,不必重新创建一个视图。

四、什么是listview点击的灵异事件?

  项目中的ListView不仅仅是简单的文字,常常需要自己定义ListView,如果自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件,此时这些子控件会将焦点获取到,所以当点击item中的子控件时有变化,而item本身的点击没有响应。
  解决方案的关键是:android:descendantFocusability

  当一个view获取焦点时,定义ViewGroup及其子控件之间的关系。
  属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

  通常我们用到的是第三种,即在Item布局的根布局加android:descendantFocusability=”blocksDescendants”的属性(阻塞子控件抢夺焦点,让Item具有焦点。这样ListView的onItemClick就能被正确触发,同时item上的button等控件在被点击时照样可以触发自身的点击事件)就好了,至此ListView点击的灵异事件告一段落。

五、ListView优化中的细节问题:

1、android:layout_height属性:
  必须将ListView的布局高度属性设置为非“wrap_content“,(可以是match_parent/fill parent/400dp等绝对数值),如果ListView的布局高度为“wrap_content”,那么getView()就会重复调用。一般来说,一个item会被调用三次左右。
2、ViewHolder:
  利用ViewHolder内部类,将item布局文件中需要展示的控件定义为属性(其实ViewHolder就是一个自定义的模型类)。这样就把item中散在的多个控件合成一个整体,这样可以有效地避免图片错位。
3、convertView:
  ListView的加载是一个item一个item的加载,这样就会每次都inflate一个item布局,然后findViewById一遍该布局上的所有控件。当数据量大的时候,是不可想象的。而利用Recycle回收利用就可以解决问题。所以要善于重复利用convertView,这样可以减少填充布局的过程,减少ViewHolder对象实例化的次数。减少内存开销,提高性能。
4、convertView的setTag():
  利用setTag()方法将ViewHolder对象作为标签附加到convertView上,当convertView被重复利用的时候,因为上面有ViewHolder对象,所以convertView就具有了ViewHolder中的几个属性,这样就节省了findViewById()这个过程。如果一个item有三个控件,如果有100条item,那么在加载数据过程中,就就相当于节省了几百次findViewById(),节约了执行findViewById()的时间,提升了加载速度,节省了性能的开销。
5、LayoutInflater对象的inflate()方法:
  inflate()方法一般接收两个参数,第一个参数就是要加载的布局id,第二个参数是指给该布局的外部再嵌套一层父布局,如果不需要就直接传null。

  inflate()方法还有个接收三个参数的方法重载
  1.如果root为null,attachToRoot将失去作用,设置任何值都没有意义。
  2.如果root不为null,attachToRoot设为true,则会在加载的布局文件的最外层再嵌套一层root布局。
  3.如果root不为null,attachToRoot设为false,则root参数失去作用。
  4.在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。
  所以在使用LayoutInflater填充布局的时候,要注意inflate()方法的参数。如果是两个参数,则第二个参数可以采用null;如果使用三个参数的方法,则要注意参数之间的搭配。

六、ListView分页的实现

1. 目的:
  Android 应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过 分页的形式来展示数据,这样会有更好的用户体验。因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑 动至列表底端时自动加载下一页数据,也可能在底部放置一个”查看更多”按钮,用户点击后,加载下一页数据。
2. 核心技术点:
  a. 借助 ListView组件的OnScrollListener监听事件,去判断何时该加载新数据;
  b.往服务器get传递表示页码的参数:page。而该page会每加载一屏数据后自动加一;
  c.利用addAll()方法不断往list集合末端添加新数据,使得适配器的数据源每新加载一屏数据就发生变化;
   d.利用适配器对象的notifyDataSetChanged()方法。该方法的作用是通知适配器自己及与该数据有关的view,数据已经发生变动,要刷新自己、更新数据。

案例演示:

package com.danny_jiang.day09_listview_scroll;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView.LayoutParams;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView;

public class MainActivity extends Activity {

    private ListView listView;

    private boolean isLastShown;

    private List<String> data = new ArrayList<String>();

    private ArrayAdapter<String> adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.list_Main);

        for(int i = 0; i < 20; i++) {
            data.add("Android-" + i);
        }

        adapter = new ArrayAdapter<String>(this, 
                android.R.layout.simple_list_item_1, data);

        listView.setAdapter(adapter);

        /**
         * 通过ListView.addHeaderView方法可以给ListView添加一个头视图View
         */
        ImageView header = new ImageView(this);

        /**
         * 当需要动态修改UI控件的宽高,需要使用LayoutParams参数对象,
         * 指定宽高,并将此LayoutParams设置到相应的UI控件上
         */
        //初始化LayoutParams时,需要指定宽高
        LayoutParams param = new LayoutParams(LayoutParams.MATCH_PARENT, 200);

        //将LayoutParams设置到UI控件上
        header.setLayoutParams(param);

        //设置ImageView宽高都填充父视图
        header.setScaleType(ScaleType.FIT_XY);

        header.setImageResource(R.drawable.food);

        listView.addHeaderView(header);

        /**
         * 通过ListView.addFooterView方法可以给ListView添加一个底部视图View
         */
        View footer = getLayoutInflater().inflate(R.layout.footer_loading, null);

        listView.addFooterView(footer);

        /**
         * ListView的分页实现
         * 通过setOnScrollListener可以给ListView设置滑动监听
         * 1 滑动状态的改变
         * 2 滑动时,item的位置信息
         * 通过此OnScrollListener可以判断出ListView是否已经滑动到屏幕底部,并且滑动停止
         */
        listView.setOnScrollListener(new OnScrollListener() {

            /**
             * 当ListView的滑动状态发送改变时,此方法被调用
             * @param view  指ListView本身
             * @param scrollState   表示当前ListView所处于的状态
             *      SCROLL_STATE_FLING--2 抛掷状态--手指离开屏幕前,用力滑了一下,屏幕产生惯性滑动
             *      SCROLL_STATE_IDLE--0    停止状态
             *      SCROLL_STATE_TOUCH_SCROLL--1    手指触摸屏幕触发ListView滚动状态
             */
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                android.util.Log.e("TAG", "onScrollStateChanged");
                // 说明ListView已经滑动到底部,并且停止状态
                if (isLastShown && scrollState == SCROLL_STATE_IDLE) {
                    int dataSize = data.size();
                    for(int i = dataSize; i < dataSize + 20; i++) {
                        data.add("Andorid-" + i);
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 通知适配器数据源已经发生改变
                    adapter.notifyDataSetChanged();
                }
            }

            /**
             * 只要ListView处于滑动状态,此方法会被一直调用
             * @param view  指ListView本身
             * @param firstVisibleItem  屏幕当前第一个可见Item的位置,从0开始
             * @param visibleItemCount  屏幕当前可见item的个数
             * @param totalItemCount        ListView中总的item的个数
             */
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, 
                    int visibleItemCount, int totalItemCount) {
                android.util.Log.e("TAG", "onScroll");
                // 通过方法参数可以判断出最后一条是否已经显示到屏幕上
                isLastShown = firstVisibleItem + visibleItemCount == totalItemCount;
            }
        });
    }
}

布局文件:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/list_Main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</RelativeLayout>

底部视图布局文件:footer_loading.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:gravity="center"
    android:orientation="horizontal" >

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="Loading..." />

</LinearLayout>
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值