Recyclerview与OkHttp请求同步
Recyclerview and OkHttp request synchronisation
我正在尝试从 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);
}
}
这是我的视图模型:
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();
}
}
}
我只是一个初学者,所以现在我基本上是在尝试将来自不同教程的代码合并为一个。这就是为什么你在这里看到的一些东西可能没有意义,所以请告诉我我能解决什么。
首先尝试学习如何使用改造来获取数据,你不会解析数据,它们是一个库 GSON 和 Moshi,它将完成你所有的工作,你只需要使用 POJO。通过这个例子
为了告诉 Recycleview 数据已经到来,您需要获取适配器并设置其数据,然后调用 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();
}
});
所以要回答这个问题,部分解决方案就像有人建议的那样,将 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();
}
}
这可能不是我在这里所做的最佳解决方案,但它按预期工作。
我正在尝试从 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);
}
}
这是我的视图模型:
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();
}
}
}
我只是一个初学者,所以现在我基本上是在尝试将来自不同教程的代码合并为一个。这就是为什么你在这里看到的一些东西可能没有意义,所以请告诉我我能解决什么。
首先尝试学习如何使用改造来获取数据,你不会解析数据,它们是一个库 GSON 和 Moshi,它将完成你所有的工作,你只需要使用 POJO。通过这个例子
为了告诉 Recycleview 数据已经到来,您需要获取适配器并设置其数据,然后调用 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();
}
});
所以要回答这个问题,部分解决方案就像有人建议的那样,将 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();
}
}
这可能不是我在这里所做的最佳解决方案,但它按预期工作。