5

このチュートリアルhttp://android.amberfog.com/?p=296を読んでいます。さまざまな種類の行を持つ Listview を作成したいと思います。アダプターの作成方法は理解できましたが、xml レイアウトはどうでしょうか。したがって、次のような xml レイアウトを定義します。

<ListView/>

<TextView android:id="@+id/id1" />

<TextView android:id="@+id/id2" />

<ImageView android:id="@+id/id3" />

<TextView android:id="@+id/id4" />

ある行がレイアウトの一部の要素 (一部のテキストビューのみ) を使用し、別の行が他の要素を使用している可能性がある場合、(パフォーマンスのために) 問題になりますか? 私の方法がxmlを定義する正しい方法なのか、それとも行のタイプごとに異なるレイアウトを作成する必要があるのか​​ わかりません。

前もって感謝します

編集:今、私はヌルポイントの例外を抱えています。

アダプターからの Java コード:

@Override

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

ViewHolder holder = null;
int type = getItemViewType(position);

if (convertView == null) {
    holder = new ViewHolder();

    convertView = mInflater.inflate(R.layout.listview_main, null);
    holder.textView_title = (TextView)convertView.findViewById(R.id.listview1);

    convertView.setTag(holder);
} else {
    holder = (ViewHolder)convertView.getTag();
}

**holder.textView_title.setText("aaaa");** //NULL POINT EXCEPTION HERE

return convertView;

}

class ViewHolder {
    public TextView textView_title;
}

xml 1:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/main_layout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:gravity="left"
              android:layout_margin="0dp">

    <!-- android:background="#0094ff" -->

    <ListView
            android:id="@id/android:list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:fastScrollEnabled="true"
            android:scrollbarStyle="insideInset"
            android:textFilterEnabled="false"
            android:divider="@null"
            android:layout_margin="0dp"
            android:paddingTop="0dp"
            android:paddingBottom="0dp"
            android:paddingLeft="15dp"
            android:paddingRight="22dp"/>



</LinearLayout>

xml2

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="left"
    android:layout_margin="0dp">

    <TextView
        android:id="@+id/listview1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="7dp"
        android:paddingBottom="0dp"
        android:paddingLeft="0dp"
        android:paddingRight="0dp"
        android:textSize="18sp"
        android:textColor="#000000"
        android:lines="1">
    </TextView>

</LinearLayout>
4

4 に答える 4

3
  • 行ごとに異なるレイアウトを作成するというこの問題を解決しました。
    1. 対応する異なる xml ファイルですべての異なるレイアウトを定義します。
    2. getViewTypeCount() メソッドをオーバーライドし、これから定義されたレイアウトの数を返します。
    3. getItemViewType() メソッドをオーバーライドし、リストビュー内の要素の「位置」と提案された xml レイアウトとの関係に従って条件を定義し、適切な整数値を返します。
    4. getView() メソッドで getItemViewType() メソッドを呼び出すことにより、レイアウトに対応する番号を取得し、対応する xml レイアウトで convertView をインフレートできます。次に、findViewById() を使用して、ViewHolder クラスで定義された TextView クラスのオブジェクトに値を取得し、setText または使用したい任意の操作をさらに実行できます。それと同じくらい簡単です。4 つのタイプのレイアウトと、element1、element2、element3、element4 という名前の 4 つの xml ファイルと、text1、text2 という 2 つの共通のテキストビュー ID があるとします。

@Override public int getItemViewType(int position) { if (position % 4 == 0) { return 0; } else if (position % 4 == 1) { return 1; } else if (position % 4 == 2) { return 2; } return 3; }

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

    ViewHolder holder = null;

    int type = getItemViewType(position);
    if (convertView == null) {
        switch (type) {
        case 0: {
            convertView = mInflater.inflate(R.layout.element1, null);
            break;
        }
        case 1: {
            convertView = mInflater.inflate(R.layout.element2, null);
            break;
        }
        case 2: {
            convertView = mInflater.inflate(R.layout.element3, null);
            break;
        }
        case 3: {
            convertView = mInflater.inflate(R.layout.element4, null);
            break;
        }
        }
        holder = new ViewHolder();
        holder.txt1 = (TextView) convertView.findViewById(R.id.text1);
        holder.txt2 = (TextView) convertView.findViewById(R.id.text2);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    String rowItem = null;
    rowItem = rowItems[position];
    holder.txt1.setText(rowItem);
    rowItem = rowItems[position+1];
    holder.txt1.setText(rowItem);
    return convertView;
}



private class ViewHolder {
    TextView txt1, txt2;
}
于 2014-08-23T03:40:25.767 に答える
2

これは間違った方法である可能性があります。ListView にコンポーネントが 1 つしかない場合は、単純なアダプターを使用します。それ以外の場合は、リスト行に別の XML を持つカスタム アダプターを使用します。

サンプルコード:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listhistory);
        initcomponents();

        ArrayList<HashMap<String, String>> alist = new ArrayList<HashMap<String, String>>();

        for (int i = 1; i < 20; i++) {
            HashMap<String, String> hmap = new HashMap<String, String>();
            hmap.put("date", "" + i + "/13");
            hmap.put("restaurant", "Restaurant" + i);
            hmap.put("distance", "" + (i * 100) + "kms");
            alist.add(hmap);

        }

        final CustomListAdapter adapter = new CustomListAdapter(this,
                R.layout.listitemhistory, alist);

        list.setAdapter(adapter);

    }

    private void initcomponents() {
        list = (ListView) findViewById(R.id.history_lst_list);

    }

    public void backButtonClick(View v) {
        finish();
    }

    class CustomListAdapter extends ArrayAdapter<HashMap<String, String>> {
        Context context;
        int textViewResourceId;
        ArrayList<HashMap<String, String>> alist;

        public CustomListAdapter(Context context, int textViewResourceId,
                ArrayList<HashMap<String, String>> alist) {
            super(context, textViewResourceId);
            this.context = context;
            this.alist = alist;
            this.textViewResourceId = textViewResourceId;

        }

        public int getCount() {

            return alist.size();
        }

        public View getView(int pos, View convertView, ViewGroup parent) {
            Holder holder = null;

                LayoutInflater inflater = ((Activity) context)
                        .getLayoutInflater();
                convertView = inflater.inflate(R.layout.listitemhistory,
                        parent, false);
                holder = new Holder();
                holder.date = (TextView) convertView
                        .findViewById(R.id.listitemhistory_txt_date);
                holder.restaurant = (TextView) convertView
                        .findViewById(R.id.listitemhistory_txt_restaurant);
                holder.distance = (TextView) convertView
                        .findViewById(R.id.listitemhistory_txt_distance);
                holder.lin_background = (LinearLayout) convertView
                        .findViewById(R.id.history_lin_background);
                convertView.setTag(holder);



            holder = (Holder) convertView.getTag();

            holder.date.setText(alist.get(pos).get("date"));
            holder.restaurant.setText(alist.get(pos).get("restaurant"));
            holder.distance.setText(alist.get(pos).get("distance"));

            return convertView;

        }

        class Holder {
            TextView date, restaurant, distance;
            LinearLayout lin_background;
        }
    }
于 2013-09-18T10:39:08.933 に答える
0

問題になることはありません。しかし、あなたはチュートリアルを間違っていると思います。

行のレイアウトを定義する必要があります。

行にテキストまたは画像を含めることができるようにする場合は、両方のビューをレイアウトに追加する必要があります。

アダプターでは、リストに入力する場所で、設定する項目を決定します。

2 つの文字列と 1 つの画像があるとします。

したがって、最初の 2 行にテキストを設定し、3 行目に画像を追加します。すべての行を事前に定義する必要はありません。それがあなたがやろうとしていることだと思います。

于 2013-09-18T09:19:09.023 に答える