Я хочу динамически добавлять список элементов из XML-макетов в LinearLayout в ScrollView. Это включает в себя многократный вызов findViewById по каждому пункту, который, как мне сказали, стоит очень дорого. Как я могу переработать свои взгляды, чтобы этого избежать?

Я бы использовал ListView, за исключением того, что каждый элемент может иметь любое количество элементов контента и комментариев внутри, и мне было сказано в Google I / O 2010 - мир ListView, который ListView не должен быть чрезмерно сложным.

Вот мой код для соответствующего метода:

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());

    }

Параметр quoteNodeList - это org.w3c.dom.NodeList. XmlUtilities - это вспомогательный класс, который я написал сам, но его методы не требуют пояснений.

Любая помощь очень ценится.

2
William Carter 18 Фев 2013 в 20:39

1 ответ

Лучший ответ

Это включает в себя вызов findViewById несколько раз для каждого элемента, что, как мне сказали, очень дорого.

Не так дорого, как сама инфляция. Если у вас 10 000 комментариев, вы увеличите размер 10 000 строк, что подвергнет вас риску нехватки места в куче и / или слишком долгого замораживания вашего пользовательского интерфейса.

Как я могу переработать свои взгляды, чтобы этого избежать?

Вы не можете, учитывая вашу структуру.

Я бы использовал ListView, за исключением того, что каждый элемент может иметь любое количество элементов контента и комментариев внутри, и мне сказали в Google I / O 2010 - мире ListView, что ListViews не должны быть чрезмерно сложными.

Поскольку предлагаемое вами решение будет значительно более "чрезмерно сложным" - на два или три порядка, используйте ListView.

4
CommonsWare 18 Фев 2013 в 20:45
Это, как обычно, сильный ответ, но он не касается: «за исключением того, что каждый элемент может иметь любое количество элементов содержимого и комментариев внутри него». Судя по вложенному циклу, возможно, ExpandableListView является лучший выбор?
 – 
Sam
18 Фев 2013 в 21:07
@Sam: "но он не адресует:", за исключением того, что каждый элемент может иметь любое количество элементов содержимого и комментариев внутри него "" - это просто вопрос использования правильного макета строки для позиции, ее соответствующего заполнения и переопределение getViewTypeCount() и getItemViewType() в вашем Adapter. «Судя по вложенному циклу, возможно, ExpandableListView - лучший выбор?» - с довольно специфическим интерфейсом. Если вам нужен именно такой интерфейс, обязательно сделайте это.
 – 
CommonsWare
18 Фев 2013 в 21:33