Android自定义ArrayAdapter:滚动时“不幸的是,应用程序已停止”

Posted

技术标签:

【中文标题】Android自定义ArrayAdapter:滚动时“不幸的是,应用程序已停止”【英文标题】:Android custom ArrayAdapter : "unfortunately, app has stopped" while scrolling 【发布时间】:2019-02-04 15:03:39 【问题描述】:

我不明白为什么这段代码会导致“不幸的是,android3 已停止”

我在网上找了很多解决方案,但似乎没有一个有效,我不知道原因,请有人帮助我。

这是我的 activity_main.xml 文件

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity"
    android:orientation="vertical">
    <ListView
        android:layout_
        android:layout_
        android:id="@+id/theListView">
    </ListView>
</LinearLayout>

这是我的 MainActivity.java 文件

MainActivity.java

package  com.snoott.android3;


import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

import java.util.ArrayList;

public  class MainActivity extends AppCompatActivity 

    ListView listView;

    public void onCreate(Bundle savedInstanceState)
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String names[] = "Dustin Moskovitz" , "Elon Musk" , "Bill Gates" , "Mark Zuckerberg" , "Larry Page" ,
                "Sergey Brin" , "Steve Jobs" , "Tim Cook";
        final Integer[] images = R.drawable.dustin , R.drawable.elon , R.drawable.gate , R.drawable.mark , R.drawable.page ,
                R.drawable.sergey , R.drawable.steve , R.drawable.tim;



        final String descriptions [] = "Co-founder of Facebook" , "CEO Tesla" , "Founder Microsoft" , "Co-founder , CEO of Facebook" ,
                "Chairman Alphabet Inc." , "President Alphabet Inc." , "Founder Apple" , "CEO Apple";

        ArrayList<Profile> profiles = new ArrayList<Profile>();

        for(int i = 0; i < descriptions.length; ++i)
            profiles.add(new Profile(names[i] , images[i] , descriptions[i]));

        






        ArrayAdapter<Profile> listAdapter = new CustomAdapter(this , profiles);
        listView = (ListView)findViewById(R.id.theListView);
        listView.setAdapter(listAdapter);



    


这是我的 Profile.java 文件

Profile.java:

package com.snoott.android3;

public class Profile 

    public String name;
    public Integer profileImage;
    public String description;


    public  Profile()

    public Profile(String name , Integer profile , String description)
        this.name = name;
        this.profileImage = profile;
        this.description = description;
    


这是我的 CustomAdapter 文件:

CustomAdapter.java:

package com.snoott.android3;


import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomAdapter extends ArrayAdapter<Profile>


    public CustomAdapter(@NonNull Context context, ArrayList<Profile> resource) 
        super(context, R.layout.custom_listview , resource);
    


    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) 
        ViewHolder viewHolder;

        Profile currentProfile = (Profile)getItem(position);

        if(convertView == null)
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_listview , parent , false);
            viewHolder.nameTextView = (TextView)convertView.findViewById(R.id.profileName);
            viewHolder.profileImage = (ImageView)convertView.findViewById(R.id.profile_image);
            viewHolder.descriptionTextView = (TextView)convertView.findViewById(R.id.profileDescription);
            convertView.setTag(viewHolder);
        

        else 

            viewHolder = (ViewHolder)convertView.getTag();

        

        viewHolder.nameTextView.setText(currentProfile.name);
        viewHolder.profileImage.setImageResource(currentProfile.profileImage);
        viewHolder.descriptionTextView.setText(currentProfile.description);

        return  convertView;

    

    static class ViewHolder 

        TextView nameTextView;
        TextView descriptionTextView;
        ImageView profileImage;

    

custom_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_
    android:layout_

    >

    <de.hdodenhof.circleimageview.CircleImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/profile_image"
        android:layout_
        android:layout_
        android:src="@drawable/mark"
        app:civ_border_
        app:civ_border_color="#FF000000"
        android:layout_marginRight="30dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        />
    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="vertical"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="-20dp">

        <TextView
            android:layout_
            android:layout_
            android:text="Mark Zuckerberg"
            android:textFontWeight="bold"
            android:fontFamily="sans-serif-condensed"
            android:textStyle="bold"
            android:id="@+id/profileName"
            />
        <TextView
            android:layout_
            android:layout_
            android:layout_marginTop="10dp"
            android:text="CEO of Facebook"
            android:id="@+id/profileDescription"/>

    </LinearLayout>


</LinearLayout>

build.gradle

apply plugin: 'com.android.application'

android 
    compileSdkVersion 28
    defaultConfig 
        applicationId "com.snoott.android3"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
    


dependencies 
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    implementation 'de.hdodenhof:circleimageview:2.2.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

【问题讨论】:

如果您的应用停止运行,则有相应的 Logcat 条目 - 请将其添加到您的问题中 如果您的应用程序在您向下滚动一点后停止运行,可能是因为图像太大,并且所有图像都在同时加载,系统内存不足并且强制它停止 尝试从您的列表视图中删除图像并检查它是否仍然崩溃,如果它仍然几乎可以肯定正在加载的图像是什么导致它崩溃。您需要降低分辨率并正确管理它们 在日志中发布错误。 分享 custom_listview.xml 布局 【参考方案1】:

它必须抛出ArrayIndexOutOfBoundsException,因为数组namesimages 长度为8,但description 数组长度为9。只需保持所有数组项大小相等即可。

【讨论】:

刚刚数了一下,长度一样 @KosiEric 只要确保你已经在 app gradle 中添加了这个依赖implementation 'de.hdodenhof:circleimageview:2.2.0'

以上是关于Android自定义ArrayAdapter:滚动时“不幸的是,应用程序已停止”的主要内容,如果未能解决你的问题,请参考以下文章

android中自定义ArrayAdapter中的自定义getFilter

Android自定义Arrayadapter不显示数据

Android - ListView 中的 EditTexts 绑定到自定义 ArrayAdapter - 跟踪更改

Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)

在android中使用arrayadapter类自定义listview

Android零基础入门第40节:自定义ArrayAdapter