使用自定义适配器的 Android ListView 示例教程

在本教程中,我们将使用一个CustomAdapter 来填充** Android ListView** 的自定义行,其中包含一个ArrayList。此外,为了增强用户体验,我们将在滚动时设置ListView的动画。

Android ListView自定义适配器概述

从ArrayList填充视图的最简单的Adapter是ArrayAdapter。这就是我们将在本教程中实现的。还有其他适配器,例如CursorAdapter,它直接绑定到本地SQLite Database]的结果集,并使用游标作为其数据源。

回收行

因为实例化了ListView并且填充了行,从而填充了列表的整个高度。此后,不会在存储器中创建新的行项。当用户滚动列表时,离开屏幕的项目将保留在内存中以供以后使用,然后进入屏幕的每个新行都会重复使用内存中保留的较旧的行。

创建视图模板

让我们创建一个XML布局,以定制的方式显示一行中的项。row_item.xml

 1<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 2    android:layout_width="match_parent"
 3    android:layout_height="wrap_content"
 4    android:orientation="vertical"
 5    android:padding="10dp">
 6
 7    <TextView
 8        android:id="@+id/name"
 9        android:layout_width="wrap_content"
10        android:layout_height="wrap_content"
11        android:layout_alignParentTop="true"
12        android:text="Marshmallow"
13        android:textAppearance="?android:attr/textAppearanceSmall"
14        android:textColor="@android:color/black" />
15
16    <TextView
17        android:id="@+id/type"
18        android:layout_width="wrap_content"
19        android:layout_height="wrap_content"
20        android:layout_below="@+id/name"
21        android:layout_marginTop="5dp"
22        android:text="Android 6.0"
23        android:textColor="@android:color/black" />
24
25    <ImageView
26        android:id="@+id/item_info"
27        android:layout_width="wrap_content"
28        android:layout_height="wrap_content"
29        android:layout_alignParentEnd="true"
30        android:layout_alignParentRight="true"
31        android:layout_centerVertical="true"
32        android:src="@android:drawable/ic_dialog_info" />
33
34    <LinearLayout
35        android:layout_width="wrap_content"
36        android:layout_height="wrap_content"
37        android:layout_centerInParent="true">
38
39        <TextView
40            android:id="@+id/version_heading"
41            android:layout_width="wrap_content"
42            android:layout_height="wrap_content"
43            android:text="API: "
44            android:textColor="@android:color/black"
45            android:textStyle="bold" />
46
47        <TextView
48            android:id="@+id/version_number"
49            android:layout_width="wrap_content"
50            android:layout_height="wrap_content"
51            android:text="23"
52            android:textAppearance="?android:attr/textAppearanceButton"
53            android:textColor="@android:color/black"
54            android:textStyle="bold" />
55
56    </LinearLayout>
57
58</RelativeLayout>

在本教程中,我们将构建一个由显示文本描述和信息图标的行列表组成的应用程序。单击行将显示带有该行文本元素的Snackbar。单击该信息将显示一个SnackBar,其中包含特定于该行的信息。

项目结构

Android自定义列表视图示例,android中的自定义适配器

代码

我们通过将ArrayAdapter子类化并将DataModel 作为对象来创建的自定义ListView。** getView()** 是返回在ListView中特定位置作为一行使用的实际视图的方法。content_main.xml包含ListView,如下所示。Content_main.xml

 1<?xml version="1.0" encoding="utf-8"?>
 2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    xmlns:tools="https://schemas.android.com/tools"
 4    android:layout_width="match_parent"
 5    android:layout_height="match_parent"
 6    xmlns:app="https://schemas.android.com/apk/res-auto"
 7    tools:context="com.journaldev.customlistview.MainActivity"
 8    app:layout_behavior="@string/appbar_scrolling_view_behavior"
 9    tools:showIn="@layout/activity_main">
10
11    <ListView
12        android:id="@+id/list"
13        android:layout_width="wrap_content"
14        android:layout_height="wrap_content"
15        />
16
17</RelativeLayout>

ArrayList中包含的数据模型如下所示。DataModel.java

 1public class DataModel {
 2
 3    String name;
 4    String type;
 5    String version_number;
 6    String feature;
 7
 8    public DataModel(String name, String type, String version_number, String feature ) {
 9        this.name=name;
10        this.type=type;
11        this.version_number=version_number;
12        this.feature=feature;
13
14    }
15
16    public String getName() {
17        return name;
18    }
19
20    public String getType() {
21        return type;
22    }
23
24    public String getVersion_number() {
25        return version_number;
26    }
27
28    public String getFeature() {
29        return feature;
30    }
31
32}

将DataModel填充到ListView中的CustomAdapter如下所示。CustomAdapter.java

 1public class CustomAdapter extends ArrayAdapter<DataModel> implements View.OnClickListener{
 2
 3    private ArrayList<DataModel> dataSet;
 4    Context mContext;
 5
 6    // View lookup cache
 7    private static class ViewHolder {
 8        TextView txtName;
 9        TextView txtType;
10        TextView txtVersion;
11        ImageView info;
12    }
13
14    public CustomAdapter(ArrayList<DataModel> data, Context context) {
15        super(context, R.layout.row_item, data);
16        this.dataSet = data;
17        this.mContext=context;
18
19    }
20
21    @Override
22    public void onClick(View v) {
23
24        int position=(Integer) v.getTag();
25        Object object= getItem(position);
26        DataModel dataModel=(DataModel)object;
27
28        switch (v.getId())
29        {
30            case R.id.item_info:
31                Snackbar.make(v, "Release date " +dataModel.getFeature(), Snackbar.LENGTH_LONG)
32                        .setAction("No action", null).show();
33                break;
34        }
35    }
36
37    private int lastPosition = -1;
38
39    @Override
40    public View getView(int position, View convertView, ViewGroup parent) {
41        // Get the data item for this position
42        DataModel dataModel = getItem(position);
43        // Check if an existing view is being reused, otherwise inflate the view
44        ViewHolder viewHolder; // view lookup cache stored in tag
45
46        final View result;
47
48        if (convertView == null) {
49
50            viewHolder = new ViewHolder();
51            LayoutInflater inflater = LayoutInflater.from(getContext());
52            convertView = inflater.inflate(R.layout.row_item, parent, false);
53            viewHolder.txtName = (TextView) convertView.findViewById(R.id.name);
54            viewHolder.txtType = (TextView) convertView.findViewById(R.id.type);
55            viewHolder.txtVersion = (TextView) convertView.findViewById(R.id.version_number);
56            viewHolder.info = (ImageView) convertView.findViewById(R.id.item_info);
57
58            result=convertView;
59
60            convertView.setTag(viewHolder);
61        } else {
62            viewHolder = (ViewHolder) convertView.getTag();
63            result=convertView;
64        }
65
66        Animation animation = AnimationUtils.loadAnimation(mContext, (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
67        result.startAnimation(animation);
68        lastPosition = position;
69
70        viewHolder.txtName.setText(dataModel.getName());
71        viewHolder.txtType.setText(dataModel.getType());
72        viewHolder.txtVersion.setText(dataModel.getVersion_number());
73        viewHolder.info.setOnClickListener(this);
74        viewHolder.info.setTag(position);
75        // Return the completed view to render on screen
76        return convertView;
77    }
78}

在上面的代码中,我们向ImageView 添加了一个onClickListener,当单击它时会显示Snackbar,并显示相应行的描述。此外,滚动列表行时还会显示动画。下面给出了两个动画XML资源文件。Down_from_top.xml

1<?xml version="1.0" encoding="utf-8"?>
2<set xmlns:android="https://schemas.android.com/apk/res/android"
3    android:shareInterpolator="@android:anim/decelerate_interpolator">
4    <translate
5        android:fromXDelta="0%" android:toXDelta="0%"
6        android:fromYDelta="-100%" android:toYDelta="0%"
7        android:duration="400" />
8</set>

up_from_bottom.xml

1<?xml version="1.0" encoding="utf-8"?>
2<set xmlns:android="https://schemas.android.com/apk/res/android"
3    android:shareInterpolator="@android:anim/decelerate_interpolator">
4    <translate
5        android:fromXDelta="0%" android:toXDelta="0%"
6        android:fromYDelta="100%" android:toYDelta="0%"
7        android:duration="400" />
8</set>

将CustomAdapter设置为ListView的MainActivity.java定义如下。此外,还填充了DataModel对象的随机ArrayList。MainActivity.java

 1public class MainActivity extends AppCompatActivity {
 2
 3    ArrayList<DataModel> dataModels;
 4    ListView listView;
 5    private static CustomAdapter adapter;
 6
 7    @Override
 8    protected void onCreate(Bundle savedInstanceState) {
 9        super.onCreate(savedInstanceState);
10        setContentView(R.layout.activity_main);
11        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
12        setSupportActionBar(toolbar);
13
14        listView=(ListView)findViewById(R.id.list);
15
16        dataModels= new ArrayList<>();
17
18        dataModels.add(new DataModel("Apple Pie", "Android 1.0", "1","September 23, 2008"));
19        dataModels.add(new DataModel("Banana Bread", "Android 1.1", "2","February 9, 2009"));
20        dataModels.add(new DataModel("Cupcake", "Android 1.5", "3","April 27, 2009"));
21        dataModels.add(new DataModel("Donut","Android 1.6","4","September 15, 2009"));
22        dataModels.add(new DataModel("Eclair", "Android 2.0", "5","October 26, 2009"));
23        dataModels.add(new DataModel("Froyo", "Android 2.2", "8","May 20, 2010"));
24        dataModels.add(new DataModel("Gingerbread", "Android 2.3", "9","December 6, 2010"));
25        dataModels.add(new DataModel("Honeycomb","Android 3.0","11","February 22, 2011"));
26        dataModels.add(new DataModel("Ice Cream Sandwich", "Android 4.0", "14","October 18, 2011"));
27        dataModels.add(new DataModel("Jelly Bean", "Android 4.2", "16","July 9, 2012"));
28        dataModels.add(new DataModel("Kitkat", "Android 4.4", "19","October 31, 2013"));
29        dataModels.add(new DataModel("Lollipop","Android 5.0","21","November 12, 2014"));
30        dataModels.add(new DataModel("Marshmallow", "Android 6.0", "23","October 5, 2015"));
31
32        adapter= new CustomAdapter(dataModels,getApplicationContext());
33
34        listView.setAdapter(adapter);
35        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
36            @Override
37            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
38
39                DataModel dataModel= dataModels.get(position);
40
41                Snackbar.make(view, dataModel.getName()+"\n"+dataModel.getType()+" API: "+dataModel.getVersion_number(), Snackbar.LENGTH_LONG)
42                        .setAction("No action", null).show();
43            }
44        });
45    }
46
47    @Override
48    public boolean onCreateOptionsMenu(Menu menu) {
49        // Inflate the menu; this adds items to the action bar if it is present.
50        getMenuInflater().inflate(R.menu.menu_main, menu);
51        return true;
52    }
53
54    @Override
55    public boolean onOptionsItemSelected(MenuItem item) {
56        // Handle action bar item clicks here. The action bar will
57        // automatically handle clicks on the Home/Up button, so long
58        // as you specify a parent activity in AndroidManifest.xml.
59        int id = item.getItemId();
60
61        //noinspection SimplifiableIfStatement
62        if (id == R.id.action_settings) {
63            return true;
64        }
65
66        return super.onOptionsItemSelected(item);
67    }
68}

运行中的应用程序的输出如下所示。Android Listview示例,android中的自定义Listview这将结束本教程。您可以通过下面的链接下载最终的Android ListView自定义适配器项目

下载安卓Listview定制适配器Project

参考:API指南列表视图

Published At
Categories with 技术
Tagged with
comments powered by Disqus