Android ListView+ArrayAdapter简单用法
ListView+ArrayAdapter可以几行代码实现一个简单的列表,不用再写一个复杂的继承BaseAdapter的Adapter
最简单的示例
直接用android自带的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">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
public class MainActivity3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
final ListView listView = findViewById(R.id.list_view);
String[] items = new String[100];
for (int i = 0; i < items.length; i++) {
items[i] = "item" + i;
}
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));
}
}
List数据源
上面示例的数据源为数组,ArrayAdapter也支持List数据源
public class MainActivity3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
final ListView listView = findViewById(R.id.list_view);
List<String> items = new ArrayList<>();
for (int i = 0; i < 100; i++) {
items.add("item" + i);
}
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));
}
}
支持自定义对象
上面的数据都是String类型,其实ArrayList也支持自定义的数据类型,显示的内容是改对象toString的内容,所有可以重写对象的toString()方法显示要显示的内容
public class MainActivity3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
final ListView listView = findViewById(R.id.list_view);
List<Student> items = new ArrayList<>();
for (int i = 0; i < 100; i++) {
items.add(new Student("Student" + i, i));
}
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));
}
private class Student {
public String name;
public int age;
public Student() {}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + "今年" + age + "岁啦";
}
}
}
支持自定义Layout
我们上面item的布局用的是android自带的布局android.R.layout.simple_list_item_1,其实我们也可以自定义布局
先看下android.R.layout.simple_list_item_1的源码
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
然后模仿android.R.layout.simple_list_item_1的布局文件,自定义一个布局文件item.xml
这种只有一个TextView的情况下可以不设置TextView的id
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18sp"
android:textColor="#0000ff" />
然后在在创建ArrayAdapter时传入R.layout.item即可
listView.setAdapter(new ArrayAdapter<>(this, R.layout.item, items));
需要注意的是如果是如果是一个复杂的布局,一定要指定一个android:id="@android:id/text1"的TextView来显示数据内容,否则ArrayList会默认把最外层的控件转化成TextView,导致类型转化错误,会报如下错误
2019-09-04 15:10:42.838 3838-3838/com.him.hisapp E/ArrayAdapter: You must supply a resource ID for a TextView
--------- beginning of crash
2019-09-04 15:10:42.843 3838-3838/com.him.hisapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.him.hisapp, PID: 3838
java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:401)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:371)
at android.widget.AbsListView.obtainView(AbsListView.java:2413)
at android.widget.ListView.makeAndAddView(ListView.java:1986)
at android.widget.ListView.fillDown(ListView.java:709)
at android.widget.ListView.fillFromTop(ListView.java:770)
at android.widget.ListView.layoutChildren(ListView.java:1749)
at android.widget.AbsListView.onLayout(AbsListView.java:2212)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1766)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1755)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1521)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:444)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1766)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1610)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1519)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:774)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2519)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2234)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1372)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6782)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:933)
at android.view.Choreographer.doCallbacks(Choreographer.java:742)
at android.view.Choreographer.doFrame(Choreographer.java:674)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:919)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6623)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
Caused by: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.TextView
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:388)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:371)
at android.widget.AbsListView.obtainView(AbsListView.java:2413)
at android.widget.ListView.makeAndAddView(ListView.java:1986)
at android.widget.ListView.fillDown(ListView.java:709)
at android.widget.ListView.fillFromTop(ListView.java:770)
at android.widget.ListView.layoutChildren(ListView.java:1749)
at android.widget.AbsListView.onLayout(AbsListView.java:2212)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1766)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1755)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1521)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:444)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1766)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1610)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1519)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:774)
at android.view.View.layout(View.java:17708)
at android.view.ViewGroup.layout(ViewGroup.java:5631)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2519)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2234)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1372)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6782)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:933)
at android.view.Choreographer.doCallbacks(Choreographer.java:742)
at android.view.Choreographer.doFrame(Choreographer.java:674)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:919)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6623)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)