然而,另一个ListView自定义适配器getView被称为方式太多次了

时间:2013-07-22 17:03:00

标签: android listview

我有一个自定义适配器,getView在位置0被调用了很多次。我已经阅读了一堆类似的问题,其中大多数都指向将ListView的高度设置为“wrap_content”作为罪魁祸首。我的ListView和行都设置为fill_parent或match_parent,它们都没有设置为wrap_content。

虽然我知道可以以任何顺序和任意次数调用getView,但似乎我必须做错了才能为位置0产生这么多调用(参见下面的日志)。 getView被多次调用的其他一些可能原因是什么?

07-22 11:48:03.032: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 5
07-22 11:48:03.082: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.092: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.102: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.112: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.152: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.162: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.192: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.202: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.332: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 6
07-22 11:48:03.392: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.402: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.412: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.422: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.472: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.482: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.492: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.492: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.542: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.552: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.562: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:03.562: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.602: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 7
07-22 11:48:05.642: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.652: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.662: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.672: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view  for position 0
07-22 11:48:05.692: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.712: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.712: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.722: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.862: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 8
07-22 11:48:05.922: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.952: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.962: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:05.972: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.012: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.012: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.022: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.032: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.062: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.102: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.102: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.112: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.412: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 9
07-22 11:48:06.442: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.452: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.452: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.462: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.492: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.492: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.502: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.502: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.702: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 10
07-22 11:48:06.762: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.772: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.782: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.792: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.822: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.832: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.862: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.872: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.892: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.902: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0
07-22 11:48:06.912: INFO/com.thisclicks.appdataroom(28989): Masonry adapter fetching view for position 0

这是我的ListView:

<ListView android:id="@id/android:list"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:background="@color/categorylist_divider"
          android:headerDividersEnabled="false"
          android:drawSelectorOnTop="false" android:choiceMode="singleChoice"
          android:clickable="false" android:divider="@color/categorylist_divider" android:dividerHeight="10.0sp"
          android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_below="@+id/header" />

行:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:background="#eeeeee">
<ImageView
        android:layout_width="fill_parent"
        android:layout_height="20dp"
        android:id="@+id/ivHeader" android:background="@color/categorylist_divider"
        android:layout_alignParentTop="true"/>

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent" android:useDefaultMargins="true" android:clipChildren="false"
                android:layout_height="match_parent" android:id="@+id/masonryrow_layout" android:columnCount="3"
                android:rowCount="2" android:background="#eeeeee" android:layout_below="@+id/ivHeader">
</GridLayout>
</RelativeLayout>

以下是getView的代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    Log.i(TAG, String.format("Masonry adapter fetching view for position %d", position));
    View vi=convertView;
    int rowType = determineRowType(position);
    ViewHolder holder;
    if(convertView==null)
    {
        Log.i(TAG, String.format("Masonry adapter building view for position %d", position));
        vi = buildView(parent, rowType);
    }

    holder = (ViewHolder) vi.getTag();
    int columnWidth = (parent.getWidth()-20)/holder.layout.getColumnCount();
    if(holder.columnWidth != columnWidth)
    {
        Log.i(TAG, "Column width mismatch, rebuilding view");
        vi = buildView(parent, rowType);
        holder = (ViewHolder) vi.getTag();
    }


    //hide header and footer spacing
    if(position != 0)
    {
        if(holder.ivHeader != null)
            holder.ivHeader.setVisibility(View.GONE);
    }
    else
    {
        if(holder.ivHeader != null)
            holder.ivHeader.setVisibility(View.VISIBLE);
    }



    int rowCapacity = calculateRowCapacity(rowType);


    for(int i = 1; i <= rowCapacity; i++)
    {
        CellHolder cellHolder = holder.cells.get(i-1);
        int realPosition = calculatePosition(position, i);
        if(realPosition < data.size())
        {
            cellHolder.ivMediaTileThumbnail.setVisibility(View.VISIBLE);
            cellHolder.tvMediaName.setVisibility(View.VISIBLE);
            cellHolder.ivMediaTileCorner.setVisibility(View.VISIBLE);
            Media media = data.get(realPosition);

            hydrateMediaTileView(realPosition, media, cellHolder);

        }
        else
        {

            cellHolder.ivMediaTileThumbnail.setVisibility(View.GONE);
            cellHolder.tvMediaName.setVisibility(View.GONE);
            cellHolder.ivMediaTileCorner.setVisibility(View.GONE);
        }
    }

    return vi;
}

编辑:这是包含listview的完整布局(它是一个ListFragment):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent" android:clipChildren="true"
                android:layout_height="match_parent" android:background="@color/categorylist_divider">
    <RelativeLayout
            android:layout_width="fill_parent" android:clipChildren="true"
            android:layout_height="wrap_content" android:id="@+id/header" android:background="#ca4f37"
            android:paddingRight="10dp">
        <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/ivBack" android:src="@drawable/category_title_bar_backarrow"
                android:paddingTop="10dp" android:paddingBottom="10dp" android:paddingLeft="15dp"/>
        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="New Text"
                android:id="@+id/tvHeaderText" android:textColor="@color/categorylist_headertext"
                android:layout_toRightOf="@+id/ivBack" android:layout_centerVertical="true"
                android:paddingLeft="15dp" android:textSize="@dimen/categoryList_headertext" android:paddingTop="10dp"
                android:paddingBottom="10dp"/>
        <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/ivHeaderPlus" android:layout_alignParentRight="true"
                android:layout_alignTop="@+id/ivBack" android:src="@drawable/title_bar_plus"
                android:layout_centerVertical="true" android:paddingTop="10dp"
                android:paddingBottom="10dp" android:layout_marginLeft="25dp"/>
        <Button
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:text="Clear"
                android:id="@+id/btnLeft" android:layout_centerVertical="true" android:layout_alignParentRight="false"
                android:background="@drawable/header_button_background" android:layout_toLeftOf="@+id/btnRight"
                android:textSize="@dimen/headerButton_textSize"
                android:textColor="@color/categorylist_headertext"/>
        <Button
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:text="Send"
                android:id="@+id/btnRight" android:layout_centerVertical="true" android:layout_alignParentRight="true"
                android:background="@drawable/header_button_background"
                android:textSize="@dimen/headerButton_textSize"
                android:textColor="@color/categorylist_headertext" android:layout_marginLeft="25dp"
                android:layout_marginRight="25dp" android:paddingLeft="10dp"
                android:paddingRight="10dp"/>
    </RelativeLayout>
    <ListView android:id="@id/android:list"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@color/categorylist_divider"
              android:headerDividersEnabled="false"
              android:drawSelectorOnTop="false" android:choiceMode="singleChoice"
              android:clickable="false" android:divider="@color/categorylist_divider" android:dividerHeight="10.0sp"
              android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_below="@+id/header" />
    <WebView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/webView" android:layout_below="@+id/header" android:layout_marginTop="40dp"
            android:layout_marginLeft="40dp" android:layout_marginRight="40dp" android:padding="20dp"
            android:background="@android:color/background_dark"/>
</RelativeLayout>

3 个答案:

答案 0 :(得分:1)

既然你的问题是,列表视图调用getView的次数太多的原因是什么,前三个是:

1.-调用notifyDataSetChanged();不断强制适配器重绘。

2.-调用ListView.setAdapter(yourAdapter);反复尝试每次都分配一个新的适配器,从而渲染它。

3.-对持有视图的布局进行修改,导致子项重绘,使当前视图状态无效

希望这有帮助。

问候!

答案 1 :(得分:0)

我也遇到过在我的适配器中多次调用getView()的问题。我正在使用一个带有基础列表的ListFragment。我做了很多研究,以弄清楚如何更改基础列表的布局。最后我在文档中偶然发现了这个:https://developer.android.com/reference/android/app/ListFragment.html

我认为我的问题是底层列表布局没有layout_width =&#34; match_parent&#34;和layout_height =&#34; match_parent&#34;。我试着在我的java代码中设置它,但我从来没有真正使用它。相反,我尝试了另一条路线,我想在布局xml文件中为ListFragment中的基础列表设置布局。这工作得更好!它在上面的链接的顶部有点解释。

我的布局文件(listview_listfragment_activity_main.xml):

<?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">

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@id/android:list"/>

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@id/android:empty"/>

然后我像我这样覆盖了MainActivityListFragment的onCreateView()方法,以便在创建ListFragment时返回正确的布局:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.listview_listfragment_activity_main, container,  false);
}

在适配器的getView()方法中,我添加了这一行来检查调用方法的次数,最后只为每个列表项调用一次:)

Log.i("DEBUG", "Entered getView - position: " + position);

答案 2 :(得分:-2)

原来,罪魁祸首是在ListFragment onCreate中。将ListFragment的根LinearLayout动态设置为宽度为0会导致问题。对此进行评论修复了适配器问题。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);

    inflater.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ViewGroup mRootView = (ViewGroup) inflater.inflate(R.layout.masonry_list, container, false);



    if(model != null && model.getFragmentWeight() != 0)
    {
        mRootView.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, model.getFragmentWeight()));
    }

    return mRootView;
}