我正在尝试制作Parcelable模式,以便在方向更改时保存和恢复ListView数据。
问题是,ListView只会在我更改方向后更新。否则不会更新。它曾经工作得很好,直到我开始实现Parcelable。
非常感谢所有帮助!
我的片段类在下面复制,但也可以访问here on GitHub:
public class TrackActivityFragment extends Fragment {
private IconicAdapter trackResultListViewAdapter = null;
private String artistId = null;
private final String LOG_TAG = TrackActivityFragment.class.getSimpleName();
public TrackActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ArrayList<TrackParcelable> trackParcelables = null;
View rootView = inflater.inflate(R.layout.fragment_track, container, false);
Intent intent = getActivity().getIntent();
if(intent != null && intent.hasExtra(Intent.EXTRA_SHORTCUT_NAME)) {
artistId = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
}
if(savedInstanceState == null || !savedInstanceState.containsKey("tracks_key")) {
trackParcelables = new ArrayList<TrackParcelable>();
performSearch(artistId);
}
else {
trackParcelables = savedInstanceState.getParcelableArrayList("tracks_key");
}
ListView listView = (ListView) rootView.findViewById(R.id.listViewOfTopTracks);
trackResultListViewAdapter = new IconicAdapter(trackParcelables,
getTrackNamesFromParcelables(trackParcelables));
listView.setAdapter(trackResultListViewAdapter);
return rootView;
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("tracks_key",
trackResultListViewAdapter.getTrackParcelables());
super.onSaveInstanceState(outState);
}
private ArrayList<String> getTrackNamesFromParcelables(ArrayList<TrackParcelable>
trackParcelables){
ArrayList<String> trackNames = new ArrayList<>();
for(TrackParcelable element : trackParcelables){
trackNames.add(element.name);
}
return trackNames;
}
private void performSearch(String artistId) {
SpotifyApi api = new SpotifyApi();
SpotifyService spotify = api.getService();
Map<String, Object> options = new HashMap<>();
options.put("country", "US");
spotify.getArtistTopTrack(artistId, options, new Callback<Tracks>() {
@Override
public void success(Tracks tracks, Response response) {
final ArrayList<TrackParcelable> trackParcelables =
new ArrayList<TrackParcelable>();
for (Track track : tracks.tracks) {
trackParcelables.add(new TrackParcelable(track.name,track.album.name,
track.album.images.get(0).url,track.preview_url));
}
trackResultListViewAdapter.swapItems(trackParcelables);
Log.d(LOG_TAG,trackParcelables.toString());
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if(trackParcelables.size()==0){
Toast.makeText(getActivity(),
getString(R.string.no_tracks_found_toast),
Toast.LENGTH_SHORT).show();
}
trackResultListViewAdapter.notifyDataSetChanged();
}
});
}
@Override
public void failure(RetrofitError error) {
}
});
}
//This ViewHolder Pattern is from Busy Android Coder's Guide page 274 of book version 6.7
class ViewHolder {
ImageView icon=null;
TextView trackName=null;
TextView trackAlbum=null;
ViewHolder(View row) {
this.icon = (ImageView)row.findViewById(R.id.imageViewAlbum);
this.trackName = (TextView)row.findViewById(R.id.textViewTrackTitle);
this.trackAlbum = (TextView)row.findViewById(R.id.textViewTrackAlbum);
}
}
//This IconicAdapter Pattern is from Busy Android Coder's Guide page 272 of book version 6.7
class IconicAdapter extends ArrayAdapter<String> {
private ArrayList<TrackParcelable> trackParcelables;
public IconicAdapter(ArrayList<TrackParcelable> trackParcelables,
ArrayList<String> trackNames) {
super(getActivity(), R.layout.list_item_top_tracks, R.id.textViewTrackTitle
, trackNames);
this.trackParcelables = trackParcelables;
}
public void swapItems(ArrayList<TrackParcelable> trackParcelables) {
this.trackParcelables = trackParcelables;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder)row.getTag();
if (holder==null) {
holder=new ViewHolder(row);
row.setTag(holder);
}
Picasso.with(getActivity()).load(trackParcelables.get(position).albumImageUrl)
.into(holder.icon);
TextView trackAlbumTextView = (TextView)row.findViewById(R.id.textViewTrackAlbum);
trackAlbumTextView.setText(trackParcelables.get(position).albumName);
return row;
}
public ArrayList<TrackParcelable> getTrackParcelables(){
return trackParcelables;
}
}
答案 0 :(得分:0)
问题是IconicAdapter仅跟踪trackNames中的更改,而不是ArrayList <TrackParcelable> trackParcelables
中的更改。
为了解决这个问题,我在我的IconicAdapter中为trackNames添加了一个成员变量,并在构造函数中设置它,如下所示:
private ArrayList<TrackParcelable> trackParcelables;
private ArrayList <String> trackNames;
public IconicAdapter(ArrayList<TrackParcelable> trackParcelables,
ArrayList<String> trackNames) {
super(getActivity(), R.layout.list_item_top_tracks, R.id.textViewTrackTitle
, trackNames);
this.trackNames = trackNames;
this.trackParcelables = trackParcelables;
}
然后,我编辑了我的swapItems来更新我的ListView数据,如下所示:
public void swapItems(ArrayList<TrackParcelable> trackParcelables) {
this.trackParcelables = trackParcelables;
trackNames.clear();
trackNames.addAll(getTrackNamesFromParcelables(trackParcelables));
}