【问题标题】:How to recycle views in a LinearLayout, to avoid multiple calls to findViewById()?如何在 LinearLayout 中回收视图,以避免多次调用 findViewById()?
【发布时间】:2013-02-03 03:56:44
【问题描述】:

我想动态添加从布局 XML 扩展的项目列表到 ScrollView 内的 LinearLayout。这涉及为每个项目多次调用findViewById,我被告知这是非常昂贵的。如何回收我的视图以避免这种情况?

我会使用ListView,除了每个项目可以包含任意数量的内容和评论元素,Google I/O 2010 - The world of ListView 告诉我ListViews 不应该过于复杂。

这是我的相关方法的代码:

private void addQuotes(NodeList quoteNodeList){

    LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    for(int i = 0; i < quoteNodeList.getLength(); i++){

        Log.i(getClass().getSimpleName(), "Adding quote number " + i);

        Node quoteNode = quoteNodeList.item(i);
        // Inflate view to hold multiple content items, single additional content TextView, and multiple comment items
        LinearLayout quote = (LinearLayout) layoutInflater.inflate(R.layout.quote, null);
        LinearLayout contentList = (LinearLayout) quote.findViewById(R.id.dialog_list);
        TextView additionalContent = (TextView) quote.findViewById(R.id.additional_content);
        LinearLayout commentList = (LinearLayout) quote.findViewById(R.id.comment_list);

        // Get data for content items and add to contentList
        NodeList contentNodeList =
                XmlUtilities.getChildWithTagName(quoteNode, NetworkHelper.XML_TAG_QUOTE_CONTENT).getChildNodes();
        for(int contentIndex = 0; contentIndex < contentNodeList.getLength(); contentIndex++){

            Log.i(getClass().getSimpleName(), "Adding content number " + contentIndex + " to quote number " + i);

            Node contentItemNode = contentNodeList.item(contentIndex);
            // Inflate view to hold name and dialog TextViews
            LinearLayout contentItem = (LinearLayout) layoutInflater.inflate(R.layout.dialog_item, null);
            TextView nameView = (TextView) contentItem.findViewById(R.id.speaker);
            TextView dialogView = (TextView) contentItem.findViewById(R.id.dialog);
            // Get data and insert into views
            String nameString = XmlUtilities.getChildTextValue(contentItemNode, NetworkHelper.XML_TAG_QUOTE_CONTENT_ITEM_NAME);
            String dialogString = XmlUtilities.getChildTextValue(contentItemNode, NetworkHelper.XML_TAG_QUOTE_CONTENT_ITEM_DIALOG);
            nameView.setText(nameString + ":");
            dialogView.setText("\"" + dialogString + "\"");
            // Add to parent view
            contentList.addView(contentItem);
        }

        // Get additional content data and add
        String additionalContentString = XmlUtilities.getChildTextValue(
                quoteNode, NetworkHelper.XML_TAG_QUOTE_ADDITIONAL_CONTENT);
        Log.d(getClass().getSimpleName(), "additionalContentString: " + additionalContentString);
        additionalContent.setText(additionalContentString);

        // TODO: Get comment data and add

        // Add everything to ScrollView
        mQuoteList.addView(quote);
        Log.d(getClass().getSimpleName(), "additionalContent: " + additionalContent.getText());

    }

参数quoteNodeListorg.w3c.dom.NodeListXmlUtilities 是我自己编写的辅助类,但方法应该是不言自明的。

非常感谢任何帮助。

【问题讨论】:

    标签: java android android-layout optimization


    【解决方案1】:

    这涉及为每个项目多次调用 findViewById,我被告知这是非常昂贵的。

    并不像通货膨胀本身那么昂贵。如果您有 10,000 个 cmets,您将膨胀 10,000 行,这会使您面临堆空间不足和/或 UI 完全冻结太久的风险。

    如何回收我的视图以避免这种情况?

    鉴于你的结构,你不能。

    我会使用 ListView,除了每个项目中可以包含任意数量的内容和评论元素,而且我在 Google I/O 2010 - ListView 世界中被告知,ListViews 不应该过于复杂。

    由于您提出的解决方案将明显更加“过于复杂”——两到三个数量级——使用ListView

    【讨论】:

    • 像往常一样,这是一个强有力的答案,但它没有解决:“除了每个项目可以包含任意数量的内容和评论元素”。从嵌套循环来看,ExpandableListView 可能是更好的选择?
    • @Sam:“但它没有解决:“除了每个项目可以包含任意数量的内容和评论元素””——这只是使用正确的行布局的问题该位置,相应地填充它,并在您的Adapter 中覆盖getViewTypeCount()getItemViewType()。 “从嵌套循环来看,也许 ExpandableListView 是更好的选择?” ——它有一个相当具体的用户界面。如果那是你想要的 UI,一定要去做。
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2018-10-31
    • 2019-05-24
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多