私はいくつかのリストを持っている Android アプリを開発しています。ここで説明するよりも複雑ですが、投稿しているシナリオも予期しない動作をします。
Stack Overflow でいくつかの質問を参照してきましたが、この問題を解決できるものは見つかりませんでした。
したがって、質問のために、このシナリオを作成しました。次のように、文字列の配列を持つアクティビティがあります。
public class TestViewlazyloadActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] items = { "lorem", "ipsum", "dolor", "sit", "amet" };
ListView list = (ListView) findViewById(R.id.testListView);
TestAdapter adapter = new TestAdapter(this, R.layout.list_item, items);
list.setAdapter(adapter);
}
}
このように私の2つのレイアウトであること:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/testListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
そしてこのように:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/testTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
ものすごく単純。次に、ViewHolder のアイデアを使用して ArrayAdapter クラスを実装しました。この getView() メソッドは次のとおりです。
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
String item = this.getItem(position);
if(convertView == null) {
LayoutInflater inflater = ((Activity) this.getContext()).getLayoutInflater();
convertView = inflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.textView = (TextView) convertView.findViewById(R.id.testTextView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ViewHolder auxHolder = holder;
LoadingService.capitalizeItemWithDelay(item, new LoadedCallback() {
public void onItemLoaded(String item) {
auxHolder.textView.setText(item);
}
});
return convertView;
}
ただLoadedCallback
のインターフェースであることonItemLoaded
。そしてLoadingService.capitalizeItemWithDelay()
、(遅延ロードをシミュレートするために)ランダムな時間スリープするスレッドを開始し、このコールバックを大文字の文字列で呼び出します。
通常の動作は、ユーザーが 5 つの空白行を含むリストを表示することです。しばらくすると、ランダムなスリープタイマーが与えられたランダムな順序であっても、アイテムがそれぞれの行にスポーンし始めます。
実際に起こることは、項目が最初の行に 1 つずつロードされ、最終的にそれらのいくつかが実際の場所に設定されるということです。auxHolder
それは奇妙なことですが、最初の要素への参照を TextView に保持するようなものです。ビューがリサイクルされているためか、存在していることが原因であると理解してauxHolder
いfinal
ます。
何か案は?前もって感謝します。