android自定义Listview项目混乱

时间:2015-04-29 05:40:42

标签: android listview android-listview

大家好:)我创建自定义Listview,但是如果项目超过某个计数,则listview会变得很奇怪。这些项目混乱不堪。



我添加了这样的项目:

mItems.add(new VenuesListHeader("Barra"));
mItems.add(new VenuesListItem("Olympic gold course"));
mItems.add(new VenuesListItem("Pontal"));
mItems.add(new VenuesListItem("Barra olympic park"));
mItems.add(new VenuesListItem("Riocentro"));

mItems.add(new VenuesListHeader("Copacabana"));
mItems.add(new VenuesListItem("Beach volleyball arena"));
mItems.add(new VenuesListItem("Flamengo park"));
mItems.add(new VenuesListItem("Fort copacabana"));
mItems.add(new VenuesListItem("Lagoa stadium"));
mItems.add(new VenuesListItem("Marina da gloria"));

mItems.add(new VenuesListHeader("Deodora"));
mItems.add(new VenuesListItem("Drodora aquatics centre"));
mItems.add(new VenuesListItem("Drodora stadium"));
mItems.add(new VenuesListItem("Olympic equestrian centre"));
mItems.add(new VenuesListItem("Olympic hockey centre"));
mItems.add(new VenuesListItem("Olympic shooting centre"));
mItems.add(new VenuesListItem("Youth arena"));
mItems.add(new VenuesListItem("X-park"));

mItems.add(new VenuesListHeader("Maracana"));
mItems.add(new VenuesListItem("Olympic stadium"));
mItems.add(new VenuesListItem("Sambodromo"));
mItems.add(new VenuesListItem("Maracana"));

但它从第三个标题项开始混乱。(我尝试了几次尝试,标题的数量并不重要。)

enter image description here



这是我的代码:

View mHeader;
ListView mListView;
ArrayList<Item> mItems;
VenuesListAdapter mAdapter;

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    //listview set list
    mListView = (ListView)rootView.findViewById(R.id.venues_list);
    mHeader = inflater.inflate(R.layout.rio2016_venues_map, mListView, false);
    mItems = new ArrayList<>();

    setList("all");

    mAdapter = new VenuesListAdapter(getActivity(), mItems);

    mListView.addHeaderView(mHeader);
    mListView.setAdapter(mAdapter);
}


void setList(String type){
    switch (type){
        case "barra":
            mItems.clear();
        case "all_barra":
            mItems.add(new VenuesListHeader("Barra"));
            mItems.add(new VenuesListItem("Olympic gold course"));
            mItems.add(new VenuesListItem("Pontal"));
            mItems.add(new VenuesListItem("Barra olympic park"));
            mItems.add(new VenuesListItem("Riocentro"));
            break;

        case "copacabana":
            mItems.clear();
        case "all_copacabana":
            mItems.add(new VenuesListHeader("Copacabana"));
            mItems.add(new VenuesListItem("Beach volleyball arena"));
            mItems.add(new VenuesListItem("Flamengo park"));
            mItems.add(new VenuesListItem("Fort copacabana"));
            mItems.add(new VenuesListItem("Lagoa stadium"));
            mItems.add(new VenuesListItem("Marina da gloria"));
            break;

        case "deodoro":
            mItems.clear();
        case "all_deodoro":
            mItems.add(new VenuesListHeader("Deodora"));
            mItems.add(new VenuesListItem("Drodora aquatics centre"));
            mItems.add(new VenuesListItem("Drodora stadium"));
            mItems.add(new VenuesListItem("Olympic equestrian centre"));
            mItems.add(new VenuesListItem("Olympic hockey centre"));
            mItems.add(new VenuesListItem("Olympic shooting centre"));
            mItems.add(new VenuesListItem("Youth arena"));
            mItems.add(new VenuesListItem("X-park"));
            break;

        case "maracana":
            mItems.clear();
        case "all_maracana":
            mItems.add(new VenuesListHeader("Maracana"));
            mItems.add(new VenuesListItem("Olympic stadium"));
            mItems.add(new VenuesListItem("Sambodromo"));
            mItems.add(new VenuesListItem("Maracana"));
            break;

        case "all":
            mItems.clear();
            setList("all_barra");
            setList("all_copacabana");
            setList("all_copacabana");
            setList("all_maracana");
            break;
    }
}

如果需要,这是自定义适配器

public class VenuesListAdapter extends ArrayAdapter<Item>{

    private static final int TYPE_ITEM = 0;
    private static final int TYPE_HEADER = 1;

    private LayoutInflater mInflater;

    public VenuesListAdapter(Context context, List<Item> items) {
        super(context, 0, items);
        mInflater = LayoutInflater.from(context);
    }

    public enum RowType {
        LIST_ITEM, HEADER_ITEM
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).getViewType();
    }

    @Override
    public int getViewTypeCount() {
        return RowType.values().length;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        int rowType = getItemViewType(position);

        if(convertView == null){
            holder = new ViewHolder();

            switch (rowType){
                case TYPE_ITEM :
                    convertView = mInflater.inflate(R.layout.rio2016_venues_item, null);
                    holder.View = getItem(position).getView(mInflater, convertView);
                    break;
                case TYPE_HEADER :
                    convertView = mInflater.inflate(R.layout.rio2016_venues_header, null);
                    holder.View = getItem(position).getView(mInflater, convertView);
                    break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        return convertView;
    }

    public static class ViewHolder {
        public  View View;
    }
}

(即使没有使用递归函数,也会出现同样的问题。)



Xml:

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

    <ListView
        android:id="@+id/venues_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

项目适配器

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="10dp"
    android:background="@color/white"
    android:padding="15dp">


    <TextView
        android:id="@+id/venues_list_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        android:layout_centerVertical="true"/>

</RelativeLayout>

标头适配器:

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

    <TextView
        android:id="@+id/venues_list_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:layout_centerVertical="true"/>

</RelativeLayout>



这种现象是它发生的原因吗?我该怎么做才能解决这个问题?

3 个答案:

答案 0 :(得分:2)

更改您的代码并尝试以下操作:

 public class VenuesListAdapter extends ArrayAdapter<Item>{

            private static final int TYPE_ITEM = 0;
            private static final int TYPE_HEADER = 1;

            private LayoutInflater mInflater;

            public VenuesListAdapter(Context context, List<Item> items) {
                super(context, 0, items);
                mInflater = LayoutInflater.from(context);
            }

            public enum RowType {
                LIST_ITEM, HEADER_ITEM
            }
        @Override
            public int getViewTypeCount() {
                // TODO Auto-generated method stub
                return 2;
            }

        @Override
            public int getItemViewType(int position) {
                // TODO Auto-generated method stub


                if(position == TYPE_ITEM)
                 {return 1;}
                 else{return 0;}


          }

            @Override
            public int getViewTypeCount() {
                return RowType.values().length;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder = null;


                if(convertView == null){
                    holder = new ViewHolder();
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }

 int type=getItemViewType(position);
            if(type==1){
                  convertView = mInflater.inflate(R.layout.rio2016_venues_item, null);
       holder.View =  getItem(position).getView(mInflater, convertView);
             }else{
      convertView = mInflater.inflate(R.layout.rio2016_venues_header, null);
       holder.View = getItem(position).getView(mInflater, convertView);
    }
                return convertView;
            }

            public static class ViewHolder {
                public  View View;
            }
        }

这是长列表视图的常见问题可以解决使用:

@Override
    public int getViewTypeCount() {
        // TODO Auto-generated method stub
        return integer(number of different cases in your list);
    }



    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub

    }

答案 1 :(得分:1)

getView()中,您似乎正在缓存View对象,而该对象无法可靠地运行。我的代码风格与您的代码风格完全不同,因为我喜欢使用custom adapter来控制ListView中的所有数据。不过,我相信,如果您拨打setText方法填写ListView,您的代码风格也会有效。

请查看代码示例@ Using an ArrayAdapter with ListView

注意:

  1. usersAdapter 的搜索文字扩展了ArrayAdapter。
  2. getView()中,代码User user = getItem(position)获取对象。在您的情况下,对象的类型为
  3. tvName.setText(user.name)。在您的情况下,也许setText(getItem(position).getText()
  4. 我希望这有点清楚。

答案 2 :(得分:1)

我soveld自,和它&#39; S非常容易(因此,我&#39; M生气我...)我修改CustomAdapter

之前:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    int rowType = getItemViewType(position);

    if(convertView == null){
        holder = new ViewHolder();

        switch (rowType){
            case TYPE_ITEM :
                convertView = mInflater.inflate(R.layout.rio2016_venues_item, null);
                holder.View = getItem(position).getView(mInflater, convertView);
                break;
            case TYPE_HEADER :
                convertView = mInflater.inflate(R.layout.rio2016_venues_header, null);
                holder.View = getItem(position).getView(mInflater, convertView);
                break;
        }

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    return convertView;
}

之后:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    int rowType = getItemViewType(position);

    if(convertView == null){
        holder = new ViewHolder();

        switch (rowType){
            case TYPE_ITEM :
                convertView = mInflater.inflate(R.layout.rio2016_venues_item, null);
                break;
            case TYPE_HEADER :
                convertView = mInflater.inflate(R.layout.rio2016_venues_header, null);
                break;
        }

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.View = getItem(position).getView(mInflater, convertView);

    return convertView;
}

我只将holder.View = getItem(position).getView(mInflater, convertView);移到if(convertView == null)内的if(convertView == null)外侧。

谢谢你给了我很多帮助:)!