我有一個使用自定義ArrayAdapter的列表視圖。 ListView的項目是RelativeLayouts。存儲在「Track」對象的「lightsOnThisTrack」列表中的「Light」視圖隨後被添加到其相應的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 I don不知道什麼對你的用例最好,但是我認爲如果你打算讓這些燈可以拖動,那麼'ListView'會讓你的生活變得非常困難。對於觸摸交互控制,「ListView」相當沉重。如果您可以切換到使用'RecyclerView',那會更好。 – Karakuri