16

LinearLayoutすでにいくつかの要素を含むビューがあります。プログラムで、さらに多くのビューを追加したいと考えています。これは 内にあるためScrollView、すべてがスクロールされます。

したがって、リストを調べて、カスタム ビューの新しいインスタンスをリストに追加します。そのカスタム ビューは XML レイアウトを拡張し、いくつかのメソッドを追加します。

このアプローチはうまく機能します。問題は、クレイジーなコードがなくても非常に遅いことです... 10 個のアイテムを含むリストをインスタンス化するのに約 500 ミリ秒かかります。ユーザー エクスペリエンスの観点からすると、これは受け入れがたいものです。

私の質問は、これは正しい/最善のアプローチですか? 「R.layout.my_list_item」は非常にシンプルですが、Android ではレイアウトの拡張に時間がかかるようです。「膨張した」レイアウトを追加のビューに再利用して、より複雑な解析をキャッシュする方法があるのだろうか?

ListView(およびアダプターとラッパー)を使用してこれを実行しようとしましたが、はるかに高速であるようです。ListView問題は、単純な;を使用できないことです。私のレイアウトは単純なリストよりも複雑です (LinearLayoutそれ自体に追加のカスタム アイコンが含まれており、 でラップされる前にさらに多くのビューを持つ別の親がありますScrollView)。

しかし、LinearLayout にアダプタを使用する方法はありますか? 自分でビューを追加しようとするよりも速いでしょうか?

どんな助けでも大歓迎です。これをもっと速くしたいです。

コードは次のとおりです。

主な活動:

// The LinearLayout that will contain everything
lineList = (LinearLayout) findViewById(R.id.lineList);

// Add a lot of items for testing
for (int i = 0; i < 10; i++) {
    addListItem("Item number " + i);
}

protected void addListItem(String __title) {
    MyListItem li;
    li = new MyListItem(this);
    li.setTitle(__title);
    lineList.addView(li);       
}

マイリスト項目:

public class MyListItem extends RelativeLayout {

    protected TextView textTitle;

    public MyListItem(Context __context) {
        super(__context);
        init();
    }

    public MyListItem(Context __context, AttributeSet __attrs) {
        super(__context, __attrs);
        init();
    }

    public MyListItem(Context __context, AttributeSet __attrs, int __attrsdefStyle) {
        super(__context, __attrs, __attrsdefStyle);
        init();
    }

    protected void init() {
        // Inflate the XML layout
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_list_item, this);

        // Create references
        textTitle = (TextView)findViewById(R.id.textTitle);
    }

    public void setTitle(String __text) {
        textTitle.setText(__text);
    }
}

私が達成しようとしているのはこれです。次のレイアウトを検討してください。

基本レイアウト

このレイアウトは、 (灰色)、(上部の内側の長方形)、および(下部の内側の長方形FrameLayout) を含む (外側のボックス)です。この四角形は、いくつかのアイテムを動的に取り込んでいる四角形です。ImageViewTextViewLinearLayoutLinearLayout

データを入力した後、最終結果を次のようにしたいと思います (すべての新しい四角形が新しいMyListItemインスタンスになります)。

配置されたレイアウト

つまり、すべてがスクロール可能です (たとえば、背景画像が上に配置されます)。はLinearLayoutそれ自体ではスクロールできません(他のすべてが続きます)。したがって、ListView私が知っていることから、私の場合は a がうまく機能しないのはなぜですか。

4

3 に答える 3

7

3 オプション:

  1. すべてを ListView に置き換え、その他の親アイコンとカスタム アイコンを ListView のヘッダー ビューとして置き換えます。ListView は、必要なときにのみビューを作成するため、より高速です。

  2. 膨張させるのではなく、プログラムで my_list_item のコンテンツを作成すると、より速くなる可能性があります

  3. ViewStubsを使用すると、ビューをオンデマンドでロードできる場合があります。

  4. ビューではなくデータをロードしているのかもしれません。その場合、バックグラウンド スレッドでデータを準備します。

于 2011-12-16T22:20:01.360 に答える
2

AListViewは行く方法です。

レイアウトが複雑すぎるとあなたは言います。しかし、子供の頃に複雑なレイアウトを膨らませてもまったく問題ありません。たとえば、テキストとアイコンを含むレイアウト:

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

次のようにアダプターで膨らませることができます。

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    LinearLayout root = null;
    ImageView editImageView;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        root = (LinearLayout)inflater.inflate(R.layout.item, null);
    } else {
        root = (LinearLayout)convertView;
    }
}

ヘッダーをサポートするために、もう少し賢くなることもできます。インデックスがルートであるかどうかのチェックを追加して、別のビューを膨らませるだけです。ヘッダーだけが異なるため、再利用可能な他のすべての行を引き続き利用できます。ヘッダーを事前に膨張させて保存し、それを再利用して膨張を完全に取り除くこともできます.

于 2011-12-16T23:02:33.720 に答える
1

ListViewを使用するだけです!

セットアップと保守が最も簡単です。List-RowのXMLレイアウトと、リスト全体を保持するビューのXMLレイアウトを定義します。ListAdapterが残りの作業を行います。

作成するだけです:

List<HashMap<String, String>> services = new ArrayList<HashMap<String, String>>();

...データをループして、マップに必要な数のアイテムを追加します。次に、このマップをListAdapterに設定します。10アイテムでも100アイテムでも、ListAdapterはその数のアイテムを含むリストを作成します。

例:

    public void updateProductList(String searchTerm) {
        createOrOpenDB(this);
        Cursor cursor = (searchTerm!=null)? dbAdapter.fetchWhere(TBL_NAME, KEY_NAME+" LIKE '%"+searchTerm+"%'")
                : dbAdapter.fetchAll(TBL_NAME);
        int rows = cursor.getCount();
        if (rows<=0) return;
        services.clear(); //clear current list
        for (int i=0; i<rows; i++) {
            HashMap<String, String> map = new HashMap<String, String>();
            cursor.moveToPosition(i);
            map.put(KEY_NAME, "" + cursor.getString(cursor.getColumnIndex(KEY_NAME)));
            map.put(KEY_DESC, "" + cursor.getString(cursor.getColumnIndex(KEY_DESC)));
            map.put(KEY_COST, "" + cursor.getDouble(cursor.getColumnIndex(KEY_COST)));
            services.add(map);
        }
        cursor.close();
        closeDB();

        ListAdapter adapter = new SimpleAdapter(this, services, R.layout.products_view_row,
                new String[] {KEY_NAME, KEY_DESC, KEY_COST},
                new int[] {R.id.listViewText1, R.id.listViewText2, R.id.listViewText3});
        setListAdapter(adapter);
    }
于 2011-12-16T22:42:34.790 に答える