滚动我的自定义组件时,GC应用滞后 [英] GC Lagging app when scrolling my custom component

查看:243
本文介绍了滚动我的自定义组件时,GC应用滞后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要创建一个自定义组件(我不能使用GridView控件或dataTable中),这与6列和x行(无图像)的表。下图显示了它的工作:

I had to create a custom component (I could not use gridview or dataTable), which is a table with 6 columns and X rows (no images). The image below shows it working:

当我向上或向下滚动该表出现问题。有时它正确地滚动,在别人需要一个滞后。在logcat中,我意识到滞后发生GC时踢

The problem occurs when I scroll up or down on that table. Sometimes it scrolls correctly, in others it takes a lag. In the logcat, I realized that the lag occurs when the GC kicks in.

我一直在寻找一种方式来优化我的组件,但是,我是新来的Java。我读了有关优化视图和对象重用宽度getView。下面是我目前的getView code:

I was looking for a way to optimize my component, however I am new to Java. I read about optimizing Views, and reuse of objects width getView. Below is my current getView code:

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

                if (null == this.parent)
                    this.parent = (ListViewOT) parent;

                if (this.parent.isInEditMode()) {
                    super.getView(position, convertView, parent);
                }

                mActivity = (MainActivity) parent.getContext();
                this.c = this.getCursor();
                c.moveToPosition(position);

                if (null == convertView) {

                    view = (LinearLayout) LinearLayout.inflate(
                            this.context, R.layout.item_lvacoes, null);

                    row = (LinearLayout) view.getChildAt(1);
                    headerRow = (TableRow) this.parent.getHeader().getChildAt(0);
                    for (int j = 0; j < this.c.getColumnCount(); j++) {
                        columnName = c.getColumnName(j);

                        if (columnName.startsWith("Status")) {
                            continue;
                        }

                        headerCell = (CelulasLV) headerRow.getChildAt(j);
                        current_width = headerCell.getWidth();
                        headerCell.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);

                        cell_width = AdapterLVAcoes.CalculateTextSize(headerCell.getPaint(), c.getColumnName(j));
                        column_width = this.parent.getColumnWidthAt(j);

                        if (column_width == 0)
                            headerCell.setWidth(0);
                        else if (cell_width <= column_width)
                        {
                            if (current_width != column_width)
                                headerCell.setWidth(column_width);
                        } else
                        {
                            this.changedWidth = true;
                            this.parent.setColumnWidthAt(j, cell_width);
                        }

                        column = new CelulasLV(this.context,(ListViewOT) parent);
                        if (columnName.equals("No"))
                            column.setText("" + (position + 1));
                        else
                            column.setText(c.getString(j));

                        column.setIndexColumn(j);
                        column.setIndexRow(position);
                        column.setEPC(c.getString(c.getColumnIndex("_id")));

                        int status = c.getInt(c.getColumnIndex("Status"));
                        if (status == 0)
                            column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cell));
                        else if (status == 1)
                            column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellachado));
                        else if (status == 2)
                            column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellextraviado));
                        else if (status == 3)
                            column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellinexistente));
                        else if (status == 4)
                            column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellpreachado));

                        activity.registerForContextMenu(column);
                        cell_width = AdapterLVAcoes.CalculateTextSize(column.getPaint(), column.getText().toString());
                        column_width = this.parent.getColumnWidthAt(j);

                        if (column_width == 0)
                            column.setWidth(0);
                        else if (cell_width <= column_width)
                            column.setWidth(column_width);
                        else
                        {
                            this.changedWidth = true;
                            this.parent.setColumnWidthAt(j, cell_width);
                        }
                        row.addView(column);
                    }
                    return view;
                }
                else 
                {
                    view = (LinearLayout) convertView;
                    row = (LinearLayout) view.getChildAt(1);
                    int i = 0;
                    headerRow = (TableRow) this.parent.getHeader().getChildAt(0);
                    {
                        for (int j = 0; j < this.c.getColumnCount(); j++)
                        {
                            columnName = c.getColumnName(j);

                            if (columnName.startsWith("Status")) {
                                continue;
                            }

                            headerCell = (CelulasLV) headerRow.getChildAt(j);
                            current_width = headerCell.getWidth();
                            headerCell.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
                            cell_width = AdapterLVAcoes.CalculateTextSize(headerCell.getPaint(), c.getColumnName(j));
                            column_width = this.parent.getColumnWidthAt(j);

                            if (column_width == 0)
                                headerCell.setWidth(0);
                            else if (cell_width <= column_width)
                                if (current_width != column_width)
                                    headerCell.setWidth(column_width);
                            else
                            {
                                this.changedWidth = true;
                                this.parent.setColumnWidthAt(j, cell_width);
                            }
                            column = (CelulasLV) row.getChildAt(i);

                            if (columnName.equals("No"))
                                column.setText("" + (position + 1));
                            else
                                column.setText(c.getString(j));

                            column.setIndexColumn(j);
                            column.setIndexRow(position);
                            column.setRealIndex(c.getLong(c.getColumnIndex("No")));
                            column.setEPC(c.getString(c.getColumnIndex("_id")));

                            status = c.getInt(c.getColumnIndex("Status"));
                            if (status == 0)
                                column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cell));
                            else if (status == 1)
                                column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellachado));
                            else if (status == 2)
                                column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellextraviado));
                            else if (status == 3)
                                column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellinexistente));
                            else if (status == 4)
                                column.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.cellpreachado));

                            activity.registerForContextMenu(column);
                            column.setOnClickListener(this.cellClick);
                            cell_width = AdapterLVAcoes.CalculateTextSize(column.getPaint(), column.getText().toString());
                            column_width = this.parent.getColumnWidthAt(j);

                            if (column_width == 0)
                                column.setWidth(0);
                            else if (cell_width <= column_width)
                                column.setWidth(column_width);
                            else 
                            {
                                this.changedWidth = true;
                                this.parent.setColumnWidthAt(j, cell_width);
                            }
                            i++;
                        }
                    }
                    return convertView;
                }
            }

它根据发现的最宽列基本上重绘列。

It basically redraws the columns according to the widest column found.

如何优化我的组件,所以这些滞后不要在GC时发生付诸行动?

How to optimize my component, so these lags do not occur when the GC into action?

在此先感谢和抱歉不好英语。

Thanks in advance and sorry for bad english.

推荐答案

老兄,我畏缩只是看着这个和你的其他职位。让我们试着与你有什么工作。你有一些pretty复杂的算法在确定的宽度,但在我们解决这一问题,我们绝对可以加快速度。我会画画的你应该做的更高的概况。你必须翻译成的code,因为这是一个复杂的问题。

Dude, I'm cringing just looking at this and your other post. Lets try to work with what you have. You have some pretty complicated algorithms in determining width but before we address that, we can definitely speed things up. I will paint a higher overview of what you should do. You'll have to translate that into the code as this is a complex problem.

您需要创建一个特定的位置和列#将存储测量宽度的缓存。总是先检查你的缓存,如果有什么发现,只有测量。在 getView()方法可以被调用,每个位置的3-4倍。所以这应该产生一个巨大的进步。

You'll need to create a cache which given a position and a column # will store the measured width. Always check your cache first and only measure if there's nothing found. The getView() method can be invoked 3-4 times per position. So this should yield a huge improvement.

这一种替代,如果你有很多动态文本或重复的文字......你可以创建基于文本,而不是一个缓存。因此,对于一个给定的字符串,你缓存测量宽度是什么。

An alternative to this, if you have a lot of dynamic text or repetitive text...you can create a cache based on text instead. So for a given String, you cache what the measured width is.

假设你永远只能显示的列文,有可能会更快的替代测量解决方案。只需使用TextView中的 getPaint()。measureText(字符串)方法。它会返回像素文本的宽度。你可能需要扔在一些绒毛像一个额外的4-8 DP但可能会更快,那么你在做什么。

Assuming you are only ever showing text in the columns, there's an alternative measuring solution which may be quicker. Just use the TextView's getPaint().measureText(String) method. It'll return the width of the text in pixels. You'll probably need to throw on some fluff like an additional 4-8 dp but that may be quicker then what you are doing.

缓存示例:

在适配器的构造函数,这样做:

In the constructor of the adapter, do something like:

Map<String, Float> mWidthCache = new HashMap<String, Float>();

然后内循环内 getView()做这样的事情:

String key = String.valueOf(position) + c.getColumnName(j);
Float measuredWidth = mWidthCache.get(key);
if (width == null) {
    //Calculate measuredWidth
    mWidthCache.put(key, measuredWidth); //Then place back in cache
}

//Adjust width of layout based on measureWidth

这篇关于滚动我的自定义组件时,GC应用滞后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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