我的应用程序是一个基本的新闻应用程序,它从Guardian API提供的JSON中获取数据。我使用原始java代码解析JSON中的值(不使用改装(。
然后我在NewsFeedViewModel类中获得LiveData,该类扩展为AndroidViewModel。
然后在片段中,我将列表提交给适配器。
以下是我面临的问题:1( 首先,如果要显示的文章设置为10,然后如果我转到设置并将其更改为2,则最后8篇文章正在消失,但空白/间隙不会消失。我仍然可以在空白处滚动。2( 如果我不断地更改文章数的值,那么应用程序就会变得不可滚动。
我还有一些疑问,当swipeToRefresh发生时,如何手动刷新数据?
这是我的项目github链接:https://github.com/sdzshn3/News24-7-RV
应用程序中发生的问题的视频示例:https://drive.google.com/file/d/1gr_fabS2rqREuyecvGSG3IQ_jXOowlW7/view?usp=drivesdk
在kotlin风格中:
class RefreshableLiveData<T>(
private val source: () -> LiveData<T>
) : MediatorLiveData<T>() {
private var liveData = source()
init {
this.addSource(liveData, ::observer)
}
private fun observer(data: T) {
value = data
}
fun refresh() {
this.removeSource(liveData)
liveData = source()
this.addSource(liveData, ::observer)
}
}
示例:
class MainActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.goals.observe(this) { result ->
// update UI
}
// refresh
viewModel.refresh()
}
}
class MyViewModel(useCase: MyUseCase): ViewModel() {
private val _goals = RefreshableLiveData {
useCase.getGoals()
}
val goals: LiveData<Result<List<GoalItem>>>
get() = _goals.map(GoalItem::fromEntity)
fun refresh() {
_goals.refresh()
}
}
class MyUseCase {...}
...
你需要做我在这篇Reddit帖子中做的事情:
public class RefreshLiveData<T> extends MutableLiveData<T> {
public interface RefreshAction<T> {
private interface Callback<T> {
void onDataLoaded(T t);
}
void loadData(Callback<T> callback);
}
private final RefreshAction<T> refreshAction;
private final Callback<T> callback = new RefreshAction.Callback<T>() {
@Override
public void onDataLoaded(T t) {
postValue(t);
}
};
public RefreshLiveData(RefreshAction<T> refreshAction) {
this.refreshAction = refreshAction;
}
public final void refresh() {
refreshAction.loadData(callback);
}
}
然后你可以做
public class YourViewModel extends ViewModel {
private final GithubRepository githubRepository;
public YourViewModel(GithubRepository githubRepository, SavedStateHandle savedStateHandle) {
this.githubRepository = githubRepository;
}
private final LiveData<String> userId = savedStateHandle.getLiveData("userId"); // from args
private final RefreshLiveData<List<Project>> refreshLiveData = Transformations.switchMap(userId, (uId) -> {
return githubRepository.getProjectList(uId);
});
public void refreshData() {
refreshLiveData.refresh();
}
public LiveData<List<Project>> getProjects() {
return refreshLiveData;
}
}
然后存储库可以做到:
public RefreshLiveData<List<Project>> getProjectList(String userId) {
final RefreshLiveData<List<Project>> liveData = new RefreshLiveData<>((callback) -> {
githubService.getProjectList(userId).enqueue(new Callback<List<Project>>() {
@Override
public void onResponse(Call<List<Project>> call, Response<List<Project>> response) {
callback.onDataLoaded(response.body());
}
@Override
public void onFailure(Call<List<Project>> call, Throwable t) {
}
});
});
return liveData;
}