ウェブアプリケーション,インジェクション,コマンドインジェクション

Androidアプリ開発 画像とアイテムのリストを表示していく

TextViewを追加してさらに改良

Further Custominzing Each Row With Additional TextViews

改良型ListViewを作るで、
様々なViewとともにListView内のそれぞれの行を
どのように改良するかを示しました。
ここでは、さらなるViewでさらに改良する方法を示します。

解決策 1 追加のTextViewを加える

追加のTextViewらをそれぞれの行に加えることで、
それぞれの行のコンテンツをさらに改良します。
他のXMLドキュメントレイアウトをres/layoutフォルダに
加える必要がでてきます。
lvrowlayout2.xmlファイルのコンテンツを以下の様に設定します。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal" >

  <ImageView
   android:id="@+id/icon"
   android:layout_width="60dp"
   android:layout_height="60dp"
   android:layout_marginBottom="5dp"
   android:layout_marginLeft="5dp"
   android:layout_marginRight="5dp"
   android:layout_marginTop="5dp"
   src="@drawable/ic_launcher" />

  <LinearLayout
   android:layout_width="fill_parent"
   android:layout_height="90dp"
   android:orientation="vertical" >

  TextView
   android:id="@+id/txtosName"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:textSize="25dp" />

  TextView
   android:id="@+id/txtDescription"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:textSize="15dp" />
  <LinearLayout>
<LinearLayout>

上のコードにあるレイアウトは、ImageViewとTextViewを持っています。
この新しく作ったレイアウトを使ってそれぞれの行を設定するには、
新しいcustom array adapterを作る必要があります。
作るためには、新しいjavaクラスをプロジェクトに加え、
CustomArrayAdapter.javaと名づけます。
CustomArrayAdapter.javaファイルの設定は以下のようにします。

package android.app.Activity;

import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class CustomArrayAdapter extends ArrayAdapter<String>{
  private final Activity context;
  private final String[] os;
  private final Integet[] imageIds;

  public CustomArrayAdapter(Activity context,
  String[] os,Integer[] imageIds){
   super(context, R.layout.lvrowlayout2, os);
   this.context = context;
   this.os = os;
   this.imageIds = imageIds;
  }


  @Override
  public View getView(int position, View view, ViewGroup parent){
   //---print the index of the row to examine---
   Log.d("CustomArrayAdapter", String.valueOf(position));

   LayoutIflater inflater = context.getLayoutInflater();
   View rowView = inflater.inflate(R.layout.lvrowlayout2, null, true);
   //---get a reference to all the views on the xml layout---
   TextView txtTitle = (TextView) rowView.findViewById(R.id.txtosName);
   TextView txtDescription = (TextView) rowView.findViewById
        (R.id.txtDescription);
   ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);

   //---customize the content of each row based on position ---
   txtTitle.setText(os[position]);
   txtDescription.setText(os[position] + "...Some descriptions here...");
   imageView.setImageResource(imageIds[position]);
   return rowView;
  }
}

CustomArrayAdapterクラスはArrayAdapter基底クラスを拡張してます。
このCustomArrayAdapterクラスは作ったばかりの新しいレイアウトに
表をバインドするために必要になるでしょう。
CustomArrayAdapterクラスのコンストラクタが3つの引数を
とることに注意してください。
アプリケーションのコンテキスト、OSの名前を含んでいる表、
それぞれのOSの写真のIDを含んでいる数字の表の3つです。
新しいレイアウトを使ってListViewを表示するためには、
以下のコードをMainActivity.javaファイルに加えます。

package net.learn2develop.customlistview;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class mainActivity extends ListActivity{
  String[] os = {          "Linux",
         "Free BSD",
         "OS_X",
         "Windows"
       };

  Integer[] imageIDs = {
         R.drawable.pic1
         R.drawable.pic2
         R.drawable.pic3
         R.drawable.pic4
       };

  @Override
  public void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   /*
   this.setListAdapter(new ArrayAdapter<String>(
          this,
          R.layout.lvrowlayout,
          R.id.txtosName,
          os));
   */

   //---using custom array adapter---
   CustomArrayAdapter adapter = new
     CustomArrayAdapter(this, os, imageIDs);
   setListAdapter(adapter);
  }
}

解決法 2 それぞれの行をリサイクルする

上のセクションでは、異なる画像とテキストを表示している行で、
どのようにListViewを作るかを紹介しました。
しかし、これでは適切ではなく、それぞれの行は一定の画像とテキストを
保存するためのメモリ量が必要になってきます。
そのため、長いアイテムのリストは開発するアプリケーションの
動作に必ず衝撃を与え、長いアイテムのリストは、
大きなメモリ量を消費する原因となります。
まるで現れないユーザに使う行によって消費されるメモリを
再利用する方が良いでしょう。これ以下では、どのようにListViewの
メモリを効率良く使用できるようにするかを示します。
他のjavaクラスをプロジェクトに加え、
AdvancedCustomArrayAdapter.javaファイルと名づけます。
AdvancedCustomArrayAdapter.javaファイルの中身は以下になります。

package net.learn2develop.customlistview;

import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class AdvanceCustomArrayAdapter extends ArrayAdapter<Sting>{
  private final Activity context;
  private final String[] os;
  private final Integet[] imageIds;

  public AdvancedCustomArrayAdapter(
  Activity context, String[] os, Integet[] imageIds){
   super(context, R.layout.lvrowlayout2, os);
   this.context = context;
   this.os = os;
   this.imageIds = imageIds;
  }

  @Override
  public View getView(int position, View view, ViewGroup parent){
   ViewContainer viewContainer;
   View rowView = view;

   //---print the index of the row to examine---
   Log.d("CustomArrayAdapter", String.valueOf(position));

   //---if the row is dispalyed for the first time---
   if (rowView == null){

    Log.d("CustomArrayAdapter", "New");
    LayoutInflater inflater ~ contet.getLayoutInflater();
    rowView = inflater.inflate(R.layout.ivrowlayout2, null, true);

    //---create a view container object---
    viewContainer = new ViewContainer();

    //get the references to all the views in the row---
    viewContainer.txtTitle = (TextView)
        rowView.findViewById(R.id.txtosName);
    viewContainer.txtDescription = (TextView)
        rowView.findViewById(R.id.txtDescription);
    viewContainer.imageView = (ImageView)
        rowView.findViewById(R.id.icon);

    //---assign the view container to the rowView---
    rowView.setTag(viewContainer);
   }else{
    //---view was previously created; can recycle---
    Log.d("CustomArrayAdapter", "Recycling");
    //---retrieve the previouslyassigned tag to get
    //a reference to all the views; bypass the findViewByID() process,
    //which is computationally expensive---
    viewContainer = (ViewContainer) rowView.getTag();
   }

   //---customize the content of each row based on position---
   viewContainer.txtTitle.setText(os[position]);
   viewContainer.txtDescription.setText(os[position]) +
       "...Some descriptions here...");
   viewContainer.imageView.setImageResource(imageIds[position]);
   return rowView;
  }
}

上のコードは解決法 1のセクションで紹介したものと
とても似通っていることに気がつくでしょう。
ViewContainerオブジェクトを使うようになっている事を除いては。
このViewContainerオブジェクトはImageViewを1つと、
TextViewを2つ定義されたものです。
ViewContainerオブジェクトはListViewにある個々の行を
保存するために使われます。それぞれの行が表示されるように、
ViewContainerオブジェクトが
以前に作られたかどうかをチェックします。
もし違ったら、行を保存するためにViewContainerオブジェクトを
新しく作ります。
ViewContainerオブジェクトが以前に作られていたら、
保存されたViewContainerオブジェクトを検索し、
オブジェクトを再利用します。
この新しいcustom adaptorを使うためには、
以下のようなステートメントをMainActivity.javaファイルに
加えます。

@Override
public void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  /*
  //---using custom layout---
  this.setListAdapter(new ArrayAdapter<String>(
        this,
        R.layout.lvrowlayout,
        R.id.txtosName,
        os));
  */

  /*
  //---using custom array adapter---
  CustomArrayAdapter adapter = new CustomArrayAdapter(this, os);
  setListAdapter(adapter);
  */

  //---using custom array adapter(with recycling)---
  AdvancedCustomArrayAdapter adapter =
      new AdvancedCustomArrayAdapter(this, os, imageIDs);
  setListener(adapter);

}

もし、Eclipseを使ってこのアプリケーションをデバッグした場合、
最初の数行が表示されます。
最初に現れる数行は新しく作られたものです。
(LogCatウィンドウ内の出力されたものを見てください。)
リストを上にスクロールさせると、さらなる行が表示されます。
この後で現れる行がリサイクルされたものになります。

ホーム
便利堂ロゴ
ページ内メニュー

解決法 1
解決法 2

inserted by FC2 system