Android自定义适配器挂起,直到我向下滚动

时间:2017-08-06 01:58:49

标签: java android debugging mobile

我正在尝试使用Android填充列表视图,而且我对此非常新...还没有在这里找到问题的确切解决方案。问题似乎出现在我的自定义适配器中的getView(...)方法中。当我运行应用程序时,它会立即崩溃。当我调试时,列表会很好地填充,直到它到达视图的底部 - 然后它会挂起,直到我物理向下滚动,并再次填充直到它到达底部...重复该过程直到完全填充。即使这个问题似乎已在这里得到解决,但在这种情况下,没有一个解决方案可以解决。任何Android大师都有任何建议吗?

这是ListView xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.heytow.challenge.heycontacts.ContactsActivity">

<ListView
    android:layout_width="368dp"
    android:layout_height="495dp"
    android:id="@+id/customListView"
    tools:layout_editor_absoluteY="8dp"
    tools:layout_editor_absoluteX="8dp">
</ListView>

和项目布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:paddingTop="10dp"
                android:paddingBottom="10dp">

    <ImageView
        android:id="@+id/contact_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginRight="10dp"
        android:contentDescription="Property Image" />

    <LinearLayout
        android:id="@+id/contact_info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/image"
        android:orientation="vertical">

        <TextView
            android:id="@+id/contact_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Street Address"
            android:textSize="18sp"/>

        <TextView
            android:id="@+id/contact_company"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Description"
            android:textSize="15sp"/>
    </LinearLayout>

</RelativeLayout>

我的自定义适配器:

public class ContactAdapter extends ArrayAdapter<Contact> {
    private final String TAG = ContactAdapter.class.getSimpleName();

    private Context mContext;
    private List<Contact> mContactList;


    //constructor, call on creation
    public ContactAdapter(Context context, int resource, ArrayList<Contact> objects) {
        super(context, resource, objects);

        this.mContext = context;
        this.mContactList = objects;
    }

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


    //called when rendering the list
    public View getView(int position, View convertView, ViewGroup parent) {

        //get the property we are displaying
        Contact contact = mContactList.get(position);

        //get the inflater and inflate the XML layout for each item
        LayoutInflater inflater;
         View view = convertView;
        if(view == null) {
            ViewHolder holder = new ViewHolder();
            if (contact.isFavorite() == true) {
                inflater = ((Activity)mContext).getLayoutInflater();
                view = inflater.inflate(R.layout.favorite_contact_layout, null);
            } else {
                inflater = ((Activity)mContext).getLayoutInflater();
                view = inflater.inflate(R.layout.contact_layout, null);
            }
        }
        TextView name = (TextView) view.findViewById(R.id.contact_name);
        TextView company = (TextView) view.findViewById(R.id.contact_company);
        ImageView image = (ImageView) view.findViewById(R.id.contact_image);

        //set address and description
        if(contact.getName() != null) {
            name.setText(contact.getName());
        }

        if(contact.getCompanyName() != null) {
            company.setText(contact.getCompanyName());
        }


        //get the image associated with this contact
        ImageParser parser = new ImageParser();
        AsyncTask<String, Void, Bitmap> urlImage = parser.execute(contact.getSmallImageURL());
        try {
            image.setImageBitmap(urlImage.get());
        } catch (InterruptedException e) {
            Log.e(TAG, "Error accessing image URL: " + e.getMessage());
        } catch (ExecutionException e) {
            Log.e(TAG, "Error accessing image URL: " + e.getMessage());
        }
        return view;

    }
}

我的MainActivity类中的调用onCreate。

ArrayAdapter<Contact> adapter = new ContactAdapter(ContactsActivity.this, 0, mContacts);
ListView listView = (ListView) findViewById(R.id.customListView);
listView.setAdapter(adapter);

我只是尝试从arrayList填充ListView。任何帮助,将不胜感激。谢谢!

*编辑*

这是新的getView - 相同的效果 - 它挂起......当数据不在视图中时,它表示“应用程序正在运行”并且getView在我滚动之前不会继续:

public View getView(int position, View convertView, ViewGroup parent) {
    //get the property we are displaying
    Contact contact = mContactList.get(position);
    ViewHolder viewHolder;
    //get the inflater and inflate the XML layout for each item
    LayoutInflater inflater;
    if(convertView == null) {
        viewHolder = new ViewHolder();
        if (contact.isFavorite() == true) {
            inflater = ((Activity)mContext).getLayoutInflater();
            convertView = inflater.inflate(R.layout.favorite_contact_layout, parent, false);
        } else {
            inflater = ((Activity)mContext).getLayoutInflater();
            convertView = inflater.inflate(R.layout.contact_layout, parent, false);
        }
        viewHolder.contactName = (TextView) convertView.findViewById(R.id.contact_name);
        viewHolder.contactCompany = (TextView) convertView.findViewById(R.id.contact_company);
        viewHolder.contactImage = (ImageView) convertView.findViewById(R.id.contact_image);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }


    //set address and description
    if(contact.getName() != null) {
        viewHolder.contactName.setText(contact.getName());
    }

    if(contact.getCompanyName() != null) {
        viewHolder.contactCompany.setText(contact.getCompanyName());
    }


    //get the image associated with this contact
    ImageParser parser = new ImageParser();
    AsyncTask<String, Void, Bitmap> urlImage = parser.execute(contact.getSmallImageURL());
    try {
        viewHolder.contactImage.setImageBitmap(urlImage.get());
    } catch (InterruptedException e) {
        Log.e(TAG, "Error accessing image URL: " + e.getMessage());
    } catch (ExecutionException e) {
        Log.e(TAG, "Error accessing image URL: " + e.getMessage());
    }
    return convertView;
}

2 个答案:

答案 0 :(得分:0)

ListView重用视图。您似乎正在为视图夸大两种不同的布局。尝试通过合并两者来使用相同的布局,并仅为必要的部分设置可见性。

答案 1 :(得分:0)

  

我建议您关注:a)将所有这些视图声明移到其中   静态类(您的视图):

static class ViewHolder{
        public TextView name;
        public TextView company;
        public ImageView image;
}
  

b)在下面的块中分配ViewHolder的视图:(对于   可重用)

  View view= convertView;
  if(view == null) {

        if (contact.isFavorite() == true) {
            inflater = ((Activity)mContext).getLayoutInflater();
            view = inflater.inflate(R.layout.favorite_contact_layout, null);
        } else {
            inflater = ((Activity)mContext).getLayoutInflater();
            view = inflater.inflate(R.layout.contact_layout, null);
        }

        ViewHolder holder= new ViewHolder();

        holder.name = (TextView) view.findViewById(R.id.contact_name);
        holder.company = (TextView) view.findViewById(R.id.contact_company);
        holder.image = (ImageView) view.findViewById(R.id.contact_image);

        view.setTag(viewHolder);
    }

    ViewHolder holder = (ViewHolder) view.getTag();
    //below do the proper assignments:

    //set address and description
    if(contact.getName() != null) {
        holder.name.setText(contact.getName());
    }

    if(contact.getCompanyName() != null) {
        holder.company.setText(contact.getCompanyName());
    }

//用picasso设置imageview:

  

1)首先添加对gradle文件的依赖:

compile 'com.squareup.picasso:picasso:2.5.2'
  

2)用毕加索设置图像视图:

Picasso.with(context).load(contact.getSmallImageURL()).into(holder.image);