Android的ListView中加入过多的物品 [英] Android ListView adding too many items

查看:233
本文介绍了Android的ListView中加入过多的物品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是循环目前加入TextViews一个ListView元素内的LinearLayout里面,因为TextViews量我要补充在那里是可变的。我加入的项目到列表视图就像你通常做。
问题是,当我滚动项目开始变得越来越多,当我向后滚动起来,我结束了几百个项目。我想这是因为在ListView被重新加载,并通过循环再次循环等每个TextView中多次加入。我可以停止?

我的code:

 公共类ListViewAdapter扩展ArrayAdapter< RowItem> {    私人最终上下文的背景下;    公共ListViewAdapter(上下文的背景下,列表与LT; RowItem>项目){
        超(背景下,R.layout.list,项目);
        this.context =背景;
    }    私有类ViewHolder {
        TextView的称号;
        LinearLayout中的LinearLayout;
    }    公共查看getView(INT位置,查看convertView,父母的ViewGroup){
        ViewHolder持有人;
        RowItem rowItem =的getItem(位置);        LayoutInflater mInflater =(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);        如果(convertView == NULL){
            convertView = mInflater.inflate(R.layout.list_list,NULL);
            持有人=新ViewHolder();
            holder.title =(TextView中)convertView.findViewById(R.id.list_line);
            holder.linearLayout =(的LinearLayout)convertView.findViewById(R.id.list_linear);
            convertView.setTag(保持器);
        }其他{
            支架=(ViewHolder)convertView.getTag();
        }        holder.title.setText(rowItem.getTitle());            字符串数据= rowItem.getData();
            串[] split0 = data.split(=);            Log.e(DATA的数据);
            Log.e(LINE,rowItem.getTitle());            对于(INT J = 0; J< split0.length; J ++){
                的String [] =分割1 split0 [J] .split(:);                的LinearLayout parentLayout =新的LinearLayout(MainActivity.context);
                parentLayout.setLayoutParams(新LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
                parentLayout.setOrientation(LinearLayout.HORIZONTAL);                对于(INT K = 0; K< split1.length; k ++){
                    TextView中的TextView =新的TextView(MainActivity.context);
                    textView.setText(分割1 [K]);
                    textView.setLayoutParams(新LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT,1.0F));
                    textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
                    textView.setTextSize(18);                    parentLayout.addView(TextView的);
                }
                holder.linearLayout.addView(parentLayout);
        }        返回convertView;
    }
}

我的数据sceme看起来像这样的一个条目:

 文本1:文本2 =文字3:文本4

怎么会看就行了:

 文本1文本2
文字3文字4


解决方案

的问题是,一个ArrayAdapter将调用 getView()每一行变为可见的时间。如果该行已成立了previously,它会通过在pviously设立观的 convertView 参数$ P $。

请参阅here了解详情。从<一个href=\"http://The%20old%20view%20to%20reuse,%20if%20possible.%20Note:%20You%20should%20check%20that%20this%20view%20is%20non-null%20and%20of%20an%20appropriate%20type%20before%20using.%20If%20it%20is%20not%20possible%20to%20convert%20this%20view%20to%20display%20the%20correct%20data,%20this%20method%20can%20create%20a%20new%20view.%20Heterogeneous%20lists%20can%20specify%20their%20number%20of%20view%20types,%20so%20that%20this%20View%20is%20always%20of%20the%20right%20type%20(see%20getViewTypeCount()%20and%20getItemViewType(int)).\">the对于文档 convertView


  

老以便如果可能的话再利用。注意:您应该检查这
  视图是使用前非空和适当的类型。如果它不是
  可能这个角度转换,以显示正确的数据,这种方法
  可以创建一个新的观点。异构列表可以指定它们的数量
  视图类型,所以这个视图总是正确的类型(见
  getViewTypeCount()和getItemViewType(INT))。


编辑:由于原来的code提出了造成问题,它看起来就像你可能无法毕竟使用标准视图座的设计模式。你有唯一的一组镜头,在要在每行中创建的项目的动态量

您也许能够做一些事情,稍微进行了优化,在这里你不必叫膨胀()每个 getView() 电话,但还是重新创建 ViewHolder 每次 getView()被调用,为了填充滚动时正确的数据:

 公共查看getView(INT位置,查看convertView,父母的ViewGroup){
    ViewHolder持有人;
    RowItem rowItem =的getItem(位置);    LayoutInflater mInflater =(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);    如果(convertView == NULL){
        convertView = mInflater.inflate(R.layout.list_list,NULL);    }    持有人=新ViewHolder();
    holder.title =(TextView中)convertView.findViewById(R.id.list_line);
    holder.linearLayout =(的LinearLayout)convertView.findViewById(R.id.list_linear);
    convertView.setTag(保持器);
    holder.title.setText(rowItem.getTitle());        字符串数据= rowItem.getData();
        串[] split0 = data.split(=);        Log.e(DATA的数据);
        Log.e(LINE,rowItem.getTitle());        对于(INT J = 0; J&LT; split0.length; J ++){
            的String [] =分割1 split0 [J] .split(:);            的LinearLayout parentLayout =新的LinearLayout(MainActivity.context);
            parentLayout.setLayoutParams(新LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
            parentLayout.setOrientation(LinearLayout.HORIZONTAL);            对于(INT K = 0; K&LT; split1.length; k ++){
                TextView中的TextView =新的TextView(MainActivity.context);
                textView.setText(分割1 [K]);
                textView.setLayoutParams(新LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT,1.0F));
                textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
                textView.setTextSize(18);                parentLayout.addView(TextView的);
            }
            holder.linearLayout.addView(parentLayout);
        }
    返回convertView;
}

如果不工作,你可以只回到基础知识,只是完全重新创建,以 getView在每次调用视图()

 公共查看getView(INT位置,查看convertView,父母的ViewGroup){
        ViewHolder持有人;
        RowItem rowItem =的getItem(位置);        LayoutInflater mInflater =(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);        //如果(convertView == NULL){
            convertView = mInflater.inflate(R.layout.list_list,NULL);
            持有人=新ViewHolder();
            holder.title =(TextView中)convertView.findViewById(R.id.list_line);
            holder.linearLayout =(的LinearLayout)convertView.findViewById(R.id.list_linear);
            convertView.setTag(保持器);            holder.title.setText(rowItem.getTitle());            字符串数据= rowItem.getData();
            串[] split0 = data.split(=);            Log.e(DATA的数据);
            Log.e(LINE,rowItem.getTitle());            对于(INT J = 0; J&LT; split0.length; J ++){
                的String [] =分割1 split0 [J] .split(:);                的LinearLayout parentLayout =新的LinearLayout(MainActivity.context);
                parentLayout.setLayoutParams(新LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
                parentLayout.setOrientation(LinearLayout.HORIZONTAL);                对于(INT K = 0; K&LT; split1.length; k ++){
                    TextView中的TextView =新的TextView(MainActivity.context);
                    textView.setText(分割1 [K]);
                    textView.setLayoutParams(新LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT,1.0F));
                    textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
                    textView.setTextSize(18);                    parentLayout.addView(TextView的);
                }
                holder.linearLayout.addView(parentLayout);
            }        //}        返回convertView;
    }

I am currently adding TextViews inside a LinearLayout inside a ListView element using a for loop, because the amount of TextViews I have to add in there is variable. I am adding the items to the ListViews like you normally do. The problem is, when I scroll the items start to get more and more and when I scroll back up I end up with hundreds of items. I think it is because the ListView is reloading and cycling through the for loop once again and so adding every TextView multiple times. Can I stop that?

My code:

public class ListViewAdapter extends ArrayAdapter<RowItem> {

    private final Context context;

    public ListViewAdapter(Context context, List<RowItem> items) {
        super(context,  R.layout.list, items);
        this.context = context;
    }

    private class ViewHolder {
        TextView title;
        LinearLayout linearLayout;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        RowItem rowItem = getItem(position);

        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_list, null);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.list_line);
            holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.list_linear);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.title.setText(rowItem.getTitle());

            String data = rowItem.getData();
            String[] split0 = data.split("=");

            Log.e("DATA", data);
            Log.e("LINE", rowItem.getTitle());

            for (int j = 0; j < split0.length; j++) {
                String[] split1 = split0[j].split(":");

                LinearLayout parentLayout = new LinearLayout(MainActivity.context);
                parentLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                parentLayout.setOrientation(LinearLayout.HORIZONTAL);

                for (int k = 0; k < split1.length; k++) {
                    TextView textView = new TextView(MainActivity.context);
                    textView.setText(split1[k]);
                    textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f));
                    textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
                    textView.setTextSize(18);

                    parentLayout.addView(textView);
                }
                holder.linearLayout.addView(parentLayout);
        }

        return convertView;
    }
}

My data sceme looks like this for one entry:

text1:text2=text3:text4

How it will look on the list:

text1    text2
text3    text4

解决方案

The problem is that the ArrayAdapter will call getView() each time the row becomes visible. If the row has been set up previously, it will pass in the previously set up View in the convertView parameter.

See here for details. From the documentation for convertView:

The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).

Edit: Since the original code proposed was causing problems, it looks like you might not be able to use the standard view holder design pattern after all. You have a unique set-up, where you are creating a dynamic amount of items in each row.

You might be able to do something that is slightly optimized, where you don't have to call inflate() on each getView() call, but still re-create the ViewHolder each time getView() is called, in order to populate the correct data when scrolling:

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    RowItem rowItem = getItem(position);

    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_list, null);

    } 

    holder = new ViewHolder();
    holder.title = (TextView) convertView.findViewById(R.id.list_line);
    holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.list_linear);
    convertView.setTag(holder);


    holder.title.setText(rowItem.getTitle());

        String data = rowItem.getData();
        String[] split0 = data.split("=");

        Log.e("DATA", data);
        Log.e("LINE", rowItem.getTitle());

        for (int j = 0; j < split0.length; j++) {
            String[] split1 = split0[j].split(":");

            LinearLayout parentLayout = new LinearLayout(MainActivity.context);
            parentLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            parentLayout.setOrientation(LinearLayout.HORIZONTAL);

            for (int k = 0; k < split1.length; k++) {
                TextView textView = new TextView(MainActivity.context);
                textView.setText(split1[k]);
                textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f));
                textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
                textView.setTextSize(18);

                parentLayout.addView(textView);
            }
            holder.linearLayout.addView(parentLayout);
        }


    return convertView;
}

If that doesn't work, you could just go back to the basics, and just completely re-create the view on each call to getView():

public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        RowItem rowItem = getItem(position);

        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        //if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_list, null);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.list_line);
            holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.list_linear);
            convertView.setTag(holder);

            holder.title.setText(rowItem.getTitle());

            String data = rowItem.getData();
            String[] split0 = data.split("=");

            Log.e("DATA", data);
            Log.e("LINE", rowItem.getTitle());

            for (int j = 0; j < split0.length; j++) {
                String[] split1 = split0[j].split(":");

                LinearLayout parentLayout = new LinearLayout(MainActivity.context);
                parentLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                parentLayout.setOrientation(LinearLayout.HORIZONTAL);

                for (int k = 0; k < split1.length; k++) {
                    TextView textView = new TextView(MainActivity.context);
                    textView.setText(split1[k]);
                    textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f));
                    textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
                    textView.setTextSize(18);

                    parentLayout.addView(textView);
                }
                holder.linearLayout.addView(parentLayout);
            }     

        //} 

        return convertView;
    }

这篇关于Android的ListView中加入过多的物品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆