我试图从LastFm API中获取一些数据,对其进行处理,并在回收器视图中显示。我的问题是,由于我的代码结构方式,我认为我在获取数据之前初始化了我的回收器视图,所以在我重新打开我的片段之前没有任何东西被显示出来,我不知道如何解决这个问题。
这是我的片段代码。
public class TopArtistsFragment extends Fragment {
private RecyclerView recyclerView;
private ArtistRecyclerViewAdapter adapter;
private TopArtistsViewModel mArtistsViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mArtistsViewModel = new ViewModelProvider(this).get(TopArtistsViewModel.class);
mArtistsViewModel.init();
mArtistsViewModel.getArtists().observe(this, new Observer<ArrayList<ArtistData>>() {
@Override
public void onChanged(ArrayList<ArtistData> artistData) {
adapter.notifyDataSetChanged();
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_top_artists, container, false);
recyclerView = view.findViewById(R.id.artistRecyclerView);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initRecyclerView();
}
private void initRecyclerView() {
adapter = new ArtistRecyclerViewAdapter(mArtistsViewModel.getArtists().getValue(), getActivity());
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapter);
}
}
这是我的ViewModel
public class TopArtistsViewModel extends ViewModel {
private MutableLiveData<ArrayList<ArtistData>> mArtists;
private ArtistDataRepository mRepo;
public void init() {
if(mArtists != null)
return;
mRepo = ArtistDataRepository.getInstance();
mArtists = mRepo.getArtists();
}
public LiveData<ArrayList<ArtistData>> getArtists() {
return mArtists;
}
}
这是我的资源库,工作就在这里进行。
public class ArtistDataRepository {
private static ArtistDataRepository instance;
private ArrayList<ArtistData> dataSet = new ArrayList<>();
public static ArtistDataRepository getInstance() {
if(instance == null)
instance = new ArtistDataRepository();
return instance;
}
public MutableLiveData<ArrayList<ArtistData>> getArtists() {
setArtists();
MutableLiveData<ArrayList<ArtistData>> data = new MutableLiveData<>();
data.setValue(dataSet);
return data;
}
private void setArtists () {
fetchData();
}
private void fetchData () {
final String requestUrl = "https://ws.audioscrobbler.com/2.0/?method=chart.gettopartists&api_key=2124b8e156db20ac7a5035fad9c01b8e&format=json";
final OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestUrl).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.d("NETWORK FAILURE", "Artist fetch");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if(response.isSuccessful())
parseData(response.body().string());
else Log.d("OKHTTP", "Response not successful");
}
});
}
private void parseData (String queryResponse) {
try {
JSONArray artistResponse = new JSONObject(queryResponse).getJSONObject("artists").getJSONArray("artist");
for(int i = 0; i < artistResponse.length(); i++) {
JSONObject artist = artistResponse.getJSONObject(i);
dataSet.add(new ArtistData(artist.getString("mbid"), artist.getString("playcount"), artist.getString("listeners"),
artist.getString("name"), artist.getJSONArray("image").getJSONObject(0).getString("#text")));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
我只是个初学者 所以现在我基本上是想把不同教程中的代码合并到一个教程中去 这就是为什么你在这里看到的一些东西可能没有意义,所以请告诉我我可以修正什么。
为了告诉Recycleview数据已经来了,你需要得到Adapter并设置它的数据,然后调用adapter.notifyDataSetChanged()。
mArtistsViewModel.getArtists().observe(this, new Observer<ArrayList<ArtistData>>() {
@Override
public void onChanged(ArrayList<ArtistData> artistData) {
--> adapter.setData(artistData); // Something like that
adapter.notifyDataSetChanged();
}
});
首先尝试学习如何使用retrofit获取数据,你不会解析数据,他们的库GSON和Moshi会完成你所有的工作,你只需要使用POJO。只要通过这个例子
所以回答这个问题,一部分解决方案是像有人建议的那样,在我的适配器中加入adapter.setData()函数,在onChanged()中调用。
mArtistsViewModel.getArtists().observe(this, new Observer<ArrayList<ArtistData>>() {
@Override
public void onChanged(ArrayList<ArtistData> artistData) {
--> adapter.setData(artistData); // Something like that
adapter.notifyDataSetChanged();
}
});
第二部分是在我的repo中的parseData函数中加入data.postValue()。
private void parseData (String queryResponse) {
try {
JSONArray artistResponse = new JSONObject(queryResponse).getJSONObject("artists").getJSONArray("artist");
for(int i = 0; i < artistResponse.length(); i++) {
JSONObject artist = artistResponse.getJSONObject(i);
dataSet.add(new ArtistData(artist.getString("mbid"), artist.getString("playcount"), artist.getString("listeners"),
artist.getString("name"), artist.getJSONArray("image").getJSONObject(0).getString("#text")));
}
data.postValue(dataSet); //THIS WAS ADDED
} catch (JSONException e) {
e.printStackTrace();
}
}
这可能不是我在这里做的最佳解决方案,但它的工作原理是一样的。