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) 

 

posted @ 2019-09-04 15:21  野猿新一  阅读(45)  评论(0编辑  收藏  举报