ListView仅在方向更改后更新

时间:2015-06-23 16:54:34

标签: android android-listview parcelable

我正在尝试制作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;
    }

}

1 个答案:

答案 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));
    }