Android ListView控件

1. ListView类

ListView的主要属性

  • stackFromBottom,设置为true时,内容将从底部开始显示
  • cacheColorHint,设置为#00000000透明时,可以避免拖动时背景显示黑色的问题
  • divider,设置分割线,#00000000@null分割线被隐藏
  • fadingEdge,设置为none,去除上边和下边的阴影
  • scrollbars,设置为none,隐藏滚动条

2. ListView添加数据

ListView通过setAdapter(ListAdapter)方法设置数据,Adapter需要继承ListAdapter

2.1 ArrayAdapter类

ArrayAdapter继承BaseAdapter类,其构造函数内,定义界面的resourcetextViewResourceId,以及数据。

public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull T[] objects) {
    this(context, resource, 0, Arrays.asList(objects));
}

public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
        @NonNull List<T> objects) {
    this(context, resource, 0, objects);
}

public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
        @IdRes int textViewResourceId, @NonNull List<T> objects) {
    this(context, resource, textViewResourceId, objects, false);
}

getView(int, View, ViewGroup)返回界面,如果mFieldId(也就是textViewResourceId)为0时,convertView必须是TextView,否则根据mFieldId来查找TextView

public @NonNull View getView(int position, @Nullable View convertView,
        @NonNull ViewGroup parent) {
    return createViewFromResource(mInflater, position, convertView, parent, mResource);
}

private @NonNull View createViewFromResource(@NonNull LayoutInflater inflater, int position,
        @Nullable View convertView, @NonNull ViewGroup parent, int resource) {
    final View view;
    final TextView text;

    if (convertView == null) {
        view = inflater.inflate(resource, parent, false);
    } else {
        view = convertView;
    }

    try {
        if (mFieldId == 0) {
            //  If no custom field is assigned, assume the whole resource is a TextView
            text = (TextView) view;
        } else {
            //  Otherwise, find the TextView field within the layout
            text = view.findViewById(mFieldId);

            if (text == null) {
                throw new RuntimeException("Failed to find view with ID "
                        + mContext.getResources().getResourceName(mFieldId)
                        + " in item layout");
            }
        }
    } catch (ClassCastException e) {
        Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
        throw new IllegalStateException(
                "ArrayAdapter requires the resource ID to be a TextView", e);
    }

    final T item = getItem(position);
    if (item instanceof CharSequence) {
        text.setText((CharSequence) item);
    } else {
        text.setText(item.toString());
    }

    return view;
}

代码调用

ListView listView = findViewById(R.id.list_view);
String[] data = new String[]{"Peter", "Lily", "Jack", "Mike"};
listView.setAdapter(new ArrayAdapter<>(this,
        R.layout.list_view_item, R.id.tv_name, data));

list_view_item.xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="#ffa6a5aa">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="15dp"
        android:textSize="16sp"
        android:textColor="#ffffffff" />

    <TextView
        android:id="@+id/tv_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="15dp"
        android:textSize="16sp"
        android:textColor="#ffcccccc" />

</RelativeLayout>

效果如下
在这里插入图片描述

2.2 SimpleAdapter类

SimpleAdapter同样继承BaseAdapter类,其构造函数内,同样定义了界面resourcefrom表示data中数据keyto则是界面对应的id

public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,
        @LayoutRes int resource, String[] from, @IdRes int[] to) {
    mData = data;
    mResource = mDropDownResource = resource;
    mFrom = from;
    mTo = to;
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

data包含两种数据,分别以nameaddress为关键字表示,对应到界面。

List<Map<String, String>> data = new ArrayList<>();
Map<String, String> item = new HashMap<>();
item.put("name", "Peter");
item.put("address", "ShangHai");
data.add(item);

item = new HashMap<>();
item.put("name", "Lily");
item.put("address", "BeiJing");
data.add(item);

item = new HashMap<>();
item.put("name", "Jack");
item.put("address", "GuangZhou");
data.add(item);

item = new HashMap<>();
item.put("name", "Mike");
item.put("address", "ShengZhen");
data.add(item);

ListView listView = findViewById(R.id.list_view);
listView.setAdapter(new SimpleAdapter(this, data, R.layout.list_view_item,
    new String[]{"name", "address"}, new int[]{R.id.tv_name, R.id.tv_address}));

效果如下
在这里插入图片描述

2.3 自定义CustomAdapter

CustomAdapter同样继承BaseAdapter,并且实现了getCount()getItem(int)getItemId(int)getView(int, View, ViewGroup)方法。使用ViewHolder可以减少内存。

public class CustomAdapter extends BaseAdapter {

    private Context mContext;
    List<Person> mData;

    public CustomAdapter(Context context, List<Person> data) {
        this.mContext = context;
        this.mData = data;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.tvName = convertView.findViewById(R.id.tv_name);
            viewHolder.tvAddress = convertView.findViewById(R.id.tv_address);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        Person person = mData.get(position);
        viewHolder.tvName.setText(person.name);
        viewHolder.tvAddress.setText(person.address);

        return convertView;
    }

    private static class ViewHolder {
        TextView tvName;
        TextView tvAddress;
    }
}

数据类

class Person {
    public String name;
    public String address;

    public Person(String name, String address) {
        this.name = name;
        this.address = address;
    }
}

代码调用

ListView listView = findViewById(R.id.list_view);
listView.setAdapter(new CustomAdapter(this, Arrays.asList(new People[]{
        new People("Peter", "ShangHai"),
        new People("Lily", "BeiJing"),
        new People("Jack", "GuangZhou"),
        new People("Mike", "ShengZhen")})));

3. 监听事件

setOnItemClickListener(OnItemClickListener)监听列表选择事件。

public interface OnItemClickListener {
    void onItemClick(AdapterView<?> parent, View view, int position, long id);
}

setOnScrollListener(OnScrollListener)监听列表滚动事件。

public interface OnScrollListener {
    public void onScrollStateChanged(AbsListView view, int scrollState);
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount);
}

4. HeaderView和FooterView

列表有时需要添加一些表头和表尾,可以addHeaderView()addFootView()来添加。

注意点就是这些方法需要在setAdapter(ListAdapter)之前调用,而有了HeaderViewFooterView以后,列表长度也会相应增加。如添加了HeaderViewHeaderViewposition为0,列表中的数据相应加一。

addHeaderView(View v)
addHeaderView(View v, Object data, boolean isSelectable)
addFooterView(View v)
addFooterView(View v, Object data, boolean isSelectable)

如果需要动态显示和隐藏HeaderView,不能直接设置HeaderView.setVisibility(View.GONE),那样会留下一片空白。也不能直接removeHeaderView(View v),因为不能再添加了。需要在HeaderView外层添加HeaderParentView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/header_view"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:gravity="center_vertical">

    </LinearLayout>

</LinearLayout>

需要隐藏HeadView时,调用header_viewsetVisibility(View.GONE)方法

ListView listView = findViewById(R.id.list_view);
View headerParentView = getLayoutInflater().inflate(
        R.layout.list_view_header_view, listView, false);
final View headerView = headerParentView.findViewById(R.id.header_view);
listView.addHeaderView(headerParentView, null, false);

headerView.setVisibility(View.GONE)

5. 去除ListView头部和尾部荧光效果

ListView上拉到头部,下拉到尾部,继续拉会出现荧光效果。去除这种效果,设置overScrollMode属性。

android:fadingEdge="none"
android:overScrollMode="never"

相关文章
Android ListView控件
Android ListView滚动条
Android 自定义下拉刷新列表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值