2

現在、大学でリスト ビューを使用しています。私の講師は、メール メッセージをリストに表示する簡単なアプリケーションを提供してくれました。ユーザーがリストを選択すると、メッセージの内容が新しいアクティビティに表示されます。何が起こっているかはほとんど理解していますが、クリアしたい灰色の領域がいくつかあります。

基本的に、コードのこのセクションが何をするのか疑問に思っていますか?

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

    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.inbox_row, null);
    }

このメソッドは、ArrayAdapter を拡張するクラス内にあります。ある種のリサイクルと考えてよろしいでしょうか? ビューが画面に出入りするのはいつですか?...

どんな助けでも大歓迎です。ありがとう。

4

1 に答える 1

4

それはまさにあなたが言ったこと、リサイクルの一形態です。

レイアウトのインフレートには多くのメモリと時間がかかるため、効率のために、システムは画面から消えたばかりのテキストと画像をユーザーに渡し、ユーザーはそのテキストと画像を更新して UI に戻すことができます。

たとえば、リスト ビューのリストに 6 つの項目が表示されている場合 (その高さのために)、6 つの項目のみが膨張し、スクロール中はそれらをリサイクルし続けます。

使用する必要がある追加の最適化のトリックがいくつかあります。コメント投稿者が投稿したビデオリンクでそれらが説明されると確信しています.

編集

その例は Store アイテムの ArrayAdapter ですが、必要なものは何でも作成できます。アダプターは、UI とデータの間の一致レイヤーと分離レイヤーを実行します。

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

    if (convertView == null)
    convertView = newView();

    // Store is the type of this ArrayAdapter
    Store store = getItem(position);
    Holder h = (Holder) convertView.getTag();

    // And here I get the data and address them to the UI
    // as you can see, if the convertView is not null,
    // I'm not creating a new one, I'm just changing text, images, etc
    h.storeName.setText(store.getStoreName());
    h.address.setText(store.getAddressLine1());
    h.postcode.setText(store.getPostCode());
    h.distance.setText(store.getDistance());

    return convertView;
}

// I like to separate in a different method when the convertView is null
// but that's me being organisation obsessive
// but it also makes easy to see which methods are only being called the 1st time
private View newView() {
    LayoutInflater inf = LayoutInflater.from(getContext());
    View v = inf.inflate(R.layout.map_result_list, null);
    Holder h = new Holder();
    // here we store that holder inside the view itself
    v.setTag(h);

    // and only call those findById on this first start
    h.storeName = (TextView) v.findViewById(R.id.txtLine1);
    h.address = (TextView) v.findViewById(R.id.txtLine2);
    h.postcode = (TextView) v.findViewById(R.id.txtLine3);
    h.distance = (TextView) v.findViewById(R.id.txtDistance);

    return v;
}

// this class is here just to hold reference to the UI elements
// findViewById is a lengthy operation so this is one of the optimisations
private class Holder {
    TextView storeName;
    TextView address;
    TextView postcode;
    TextView distance;
}
于 2012-11-07T15:56:05.943 に答える