私はカスタムArrayAdapterを使用するリストビューを持っています。 ListViewのアイテムはRelativeLayoutsです。 「トラック」オブジェクトの「lightsOnThisTrack」リストに格納されている「ライト」ビューは、その後、対応するRelativeLayoutsに追加されます。ListView内のRelativeLayoutにビューを追加すると、繰り返しのアイテムが返されます
ListViewにアイテムを追加すると、以前にrelativeLayoutsに追加されたビューが新しく追加されたアイテムで繰り返されるようになります。一方、この例のように、TextViewの "trackText"は繰り返されていません。私が他の投稿を読んだので、ViewHolderパターンの実装方法に関連する問題だとわかっていますが、どこに問題があるのか分かりません。
public class TrackListAdapter extends ArrayAdapter<Track> {
private static final String TAG = "TrackListAdapter";
private LayoutInflater layoutInflater;
public ArrayList<Track> trackArrayList;
Context mContext;
RelativeLayout relativeLayout;
public TrackListAdapter(Context context, ArrayList<Track> trackArrayList) {
super(context, 0, trackArrayList);
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mContext = context;
this.trackArrayList = trackArrayList;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder viewHolder;
if (rowView == null) {
rowView = layoutInflater.inflate(R.layout.track_list_item, null);
viewHolder = new ViewHolder();
viewHolder.relativeLayout = (RelativeLayout) rowView.findViewById(R.id.relativeLayout);
viewHolder.trackText = new TextView(mContext);
viewHolder.trackText.setTextColor(Color.GRAY);
viewHolder.trackText.setX(100);
viewHolder.trackText.setY(20);
viewHolder.trackText.setTextSize(18);
viewHolder.relativeLayout.addView(viewHolder.trackText);
rowView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) rowView.getTag();
}
viewHolder.track = trackArrayList.get(position);
if (viewHolder.track.getName() == null)
viewHolder.trackText.setText(" NUMBER " + position);
else
viewHolder.trackText.setText(viewHolder.track.getName());
for (int i = 0; i < viewHolder.track.getNumberOfLights(); i++) {
Light light = viewHolder.track.lightsOnThisTrackList.get(i);
if (light.getParent() != null) {
if (!light.getParent().equals(viewHolder.relativeLayout)) {
ViewGroup viewGroup = (ViewGroup) light.getParent();
if (viewGroup != null) viewGroup.removeView(light);
viewHolder.relativeLayout.addView(light);
}
} else {
viewHolder.relativeLayout.addView(light);
}
}
notifyDataSetInvalidated();
notifyDataSetChanged();
return rowView;
}
public static class ViewHolder {
Track track;
TextView trackText;
RelativeLayout relativeLayout;
}
public View getViewByPosition(int pos, ListView listView) {
final int firstListItemPosition = listView.getFirstVisiblePosition();
final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;
if (pos < firstListItemPosition || pos > lastListItemPosition) {
return listView.getAdapter().getView(pos, null, listView);
} else {
final int childIndex = pos - firstListItemPosition;
return listView.getChildAt(childIndex);
}
}
}
RelativeLayoutで以前のビューを削除していただきありがとうございました。また、 'notifyDataSetInvalidated()'と 'notifyDataSetChanged()'は、あなたが想像しているように、データセットを変更しているコード部分に配置するだけで、不要なgetView()内であることが判明しました。 – gotramaval
最後に、これらのビューをlistView内で使用しています。ビューのスクロールをコーディングせずにスクロールできるようにしたいのです。あなたはそれをどのように提案しますか?(私は実際には 'Track'にある' Light'の最大数を予測することはできませんし、トラック上でドラッグすることができるので、特定の場所はありません) – gotramaval
@gotramaval私はドンあなたのユースケースに最適なものは分かっていませんが、ListViewはあなたがそれらのライトをドラッグ可能にすることを計画するならあなたの人生を非常に困難にすると思います。 ListViewは、タッチ操作のコントロールについてかなり重いです。代わりに 'RecyclerView'を使用するように切り替えることができれば、それは良いでしょう。 – Karakuri