当我用 LiveData 观察 dataList 时,通过服务 RecyclerView 调用 API 出现故障
on calling API through a service RecyclerView glitches when i observe dataList with LiveData
我要实时显示数据。所以我创建了一个服务并添加了一个计时器。我每 1 分钟按一次 Rest API 并将数据存储在 room-Bb 中。
问题:每隔一分钟调用一次服务后,我的适配器就会重置,我的 recyclerView 每隔一分钟就会一次又一次地闪烁,即使我滚动了一个列表,我也会到达列表的顶部。
在我的 activity 片段基础中,我调用了 MySimpleService 。在这项服务中,我使用了一个计时器,每隔一分钟就会给我的 API 打电话,以检查我是否有新的预订。每当我的 API 被调用时,我的列表就会更新,并且由于适配器中 setBookingData 方法中的 notifydatasetchanged(),我的 Recyclerview 适配器会被重置。所以我的 recyclerView 每隔一分钟就会继续闪烁。
这是我的代码
MySimpleService
public class MySimpleService extends Service {
private static final String TAG = "MyTag";
private Timer mTimer;
private Handler mHandler = new Handler();
private static final int TIMER_INTERVAL = 10000; // 1 Minute
private static final int TIMER_DELAY = 0;
private MyDatabase appDatabase;
@Override
public void onCreate() {
super.onCreate();
appDatabase = MyDatabase.getInstance(getApplicationContext());
Log.d(TAG, "MySimpleService onCreate: ");
if (mTimer != null)
mTimer = null;
// Create new Timer
mTimer = new Timer();
// Required to Schedule DisplayToastTimerTask for repeated execution with an interval of `1 min`
mTimer.scheduleAtFixedRate(new DisplayToastTimerTask(), TIMER_DELAY, TIMER_INTERVAL);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "MySimpleService onStartCommand: ");
return Service.START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "My Service onDestroy: ");
// Cancel timer
mTimer.cancel();
}
private class DisplayToastTimerTask extends TimerTask {
@Override
public void run() {
mHandler.post(() -> {
if (Utils.getConnectivityStatus(getApplicationContext()) == 0) {
Utils.showOkAlert(getApplicationContext(), getString(R.string.info), "Please check your internet connection", false);
} else {
new Thread(() -> callApbookingList()).start();
new Thread(() -> callApiAssignList()).start();
new Thread(() -> callApiBookingActivitiesList()).start();
}
});
}
}
private void callApbookingList() {
RetrofitApiInterface apiInterface = RetrofitClient.getClient().create(RetrofitApiInterface.class);
Call<BookingDataResponse> call = apiInterface.getAllData(new PostContData(PreferenceData.getLong(getApplicationContext(), "cont_id")));
call.enqueue(new Callback<BookingDataResponse>() {
@Override
public void onResponse(Call<BookingDataResponse> call, Response<BookingDataResponse> response) {
if (response.isSuccessful()) {
BookingDataResponse body = response.body();
appDatabase.myDao().deleteBookingList();
if (body.getStatus() == 0) {
Log.d(TAG, "onResponse: " + body.getMessage());
new Thread(() -> {
try {
appDatabase.myDao().insertBooking(body.getBookingList());
} catch (Exception e) {
}
}).start();
}
}
}
@Override
public void onFailure(Call<BookingDataResponse> call, Throwable t) {
Log.e(TAG, "onFailure: " + t);
}
});
}
我的片段
public class BookingAssignFragment extends Fragment {
private BookingViewModel bookingViewModel;
private BookingListAdepter bookingListAdepter;
public BookingAssignFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_booking_assign, container, false);
bookingListAdepter = new BookingListAdepter(getActivity());
RecyclerView recyclerView = view.findViewById(R.id.rev_booking_list);
TextView errorMessasge = view.findViewById(R.id.error_message);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(bookingListAdepter);
bookingViewModel = new ViewModelProvider(getActivity()).get(BookingViewModel.class);
bookingViewModel.getBooking().observe(getActivity(), bookingLists -> {
if (bookingLists.isEmpty()) {
if (errorMessasge.getVisibility() == View.GONE)
errorMessasge.setVisibility(View.VISIBLE);
} else {
if (errorMessasge.getVisibility() == View.VISIBLE)
errorMessasge.setVisibility(View.GONE);
// bookingListAdepter.setBookingData(bookingLists);
}
bookingListAdepter.setBookingData(bookingLists);
});
return view;
}
}
我的适配器
public class BookingListAdepter extends RecyclerView.Adapter<BookingListAdepter.BookingViewHolder> {
private List<BookingList> bookingLists;
private LayoutInflater mInflater;
private Context mContext;
public BookingListAdepter(Context context) {
mInflater = LayoutInflater.from(context);
mContext =context;
}
@NonNull
@Override
public BookingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.item_view_booking_list, parent, false);
return new BookingViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BookingViewHolder holder, int position) {
BookingList li = bookingLists.get(position);
if(li.getPlanType().equalsIgnoreCase("Both Way")){
if (holder.numberOfDay.getVisibility()==View.GONE) {
holder.numberOfDay.setVisibility(View.VISIBLE);
holder.numberOfDay.setText(String.valueOf(li.getBookingDays()));
}
}else {
if (holder.numberOfDay.getVisibility()==View.VISIBLE)
holder.numberOfDay.setVisibility(View.GONE);
}
if (li.getPlanType().equals(li.getTerrifType())){
if (holder.palanTyupe.getVisibility()==View.VISIBLE)
holder.palanTyupe.setVisibility(View.GONE);
}else { if (holder.palanTyupe.getVisibility()==View.GONE)
holder.palanTyupe.setVisibility(View.VISIBLE);}
holder.packageName.setText(li.getPlanType());
holder.cabCategory.setText(li.getCabCategory());
holder.dateTime.setText(li.getDatetime());
holder.formLocation.setText(li.getFromLocation());
holder.toLocation.setText(li.getToLocation());
holder.amount.setText(String.valueOf(li.getTotalAmount()));
holder.paidWalletAmount.setText(String.valueOf(li.getPaidWalletAmount()));
holder.assignBooking.setOnClickListener(v -> {
if (Utils.getConnectivityStatus(mContext) == 0) {
Utils.showOkAlert(mContext,mContext.getString(R.string.info), "Please check your internet connection", false);
}else {
BookingAssignDialogFragment updateDriver = BookingAssignDialogFragment.newInstance(li.getBookingId(), PreferenceData.getLong(mContext,"cont_id"),0,"");
updateDriver.show((Activity) mContext);
}
});
}
@Override
public int getItemCount() {
if (bookingLists!=null)
return bookingLists.size();
else return 0;
}
public void setBookingData(List<BookingList> bookingData) {
bookingLists = bookingData;
Log.d("UpdatedBooking", String.valueOf(bookingLists.size()));
notifyDataSetChanged();
}
class BookingViewHolder extends RecyclerView.ViewHolder{
TextView packageName,palanTyupe,cabCategory,amount,formLocation,toLocation,dateTime,numberOfDay,paidWalletAmount;
ImageView assignBooking,acceptBooking;
public BookingViewHolder(@NonNull View itemView) {
super(itemView);
packageName = itemView.findViewById(R.id.package_name);
palanTyupe = itemView.findViewById(R.id.plan_type);
cabCategory = itemView.findViewById(R.id.cab_category);
amount = itemView.findViewById(R.id.amount);
formLocation = itemView.findViewById(R.id.from_location);
toLocation = itemView.findViewById(R.id.to_location);
dateTime = itemView.findViewById(R.id.date_and_time);
numberOfDay = itemView.findViewById(R.id.no_of_day);
assignBooking = itemView.findViewById(R.id.assign_booking);
paidWalletAmount = itemView.findViewById(R.id.paid_wallet_amount);
acceptBooking =itemView.findViewById(R.id.accept_booking);
}
}
}
我的视图模型
public class BookingActivitiesListViewModel extends AndroidViewModel {
private BookingActivitiesListRepository bookingActivitiesListRepository;
private LiveData<List<BookingActivitiesList>> mLiveData;
public BookingActivitiesListViewModel(@NonNull Application application) {
super(application);
bookingActivitiesListRepository = new BookingActivitiesListRepository(application);
mLiveData = bookingActivitiesListRepository.getBookingActivitiesList();
}
public LiveData<List<BookingActivitiesList>> getBookingActivitiesList()
{
return mLiveData;
}
}
我的存储库
public class BookingRepository {
private MyDao myDao;
private LiveData<List<BookingList>> mBookingList;
BookingRepository(Application application){
MyDatabase db = MyDatabase.getInstance(application);
myDao = db.myDao();
mBookingList = myDao.getBookingList();
}
LiveData<List<BookingList>> getBooking(){return mBookingList;}
我的item_view_booking_list
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
android:elevation="5dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
style="@style/ItemViewStyle"
android:weightSum="1">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight=".85">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_location_form_24dp"
android:drawablePadding="@dimen/dp5"
android:padding="5dp"
android:layout_weight="1"
android:id="@+id/from_location"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_location_to_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/to_location"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:padding="5dp"
android:gravity="left|center"
android:drawableLeft="@drawable/ic_car"
android:drawablePadding="@dimen/dp5"
android:id="@+id/cab_category"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_work_black_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:gravity="center|left"
android:padding="5dp"
android:id="@+id/package_name"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2560"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_rupee_indian"
android:drawablePadding="@dimen/dp5"
android:padding="5dp"
android:gravity="left|center"
android:id="@+id/amount"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center|left"
android:drawableLeft="@drawable/wallet"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/paid_wallet_amount"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:padding="5dp"
android:layout_weight="1"
android:layout_gravity="center"
android:textStyle="bold"
android:drawableLeft="@drawable/ic_access_time_black_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_height="wrap_content"
android:id="@+id/date_and_time"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_date_range_black_24dp"
android:layout_gravity="center"
android:drawablePadding="@dimen/dp5"
android:visibility="gone"
android:padding="5dp"
android:id="@+id/no_of_day"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="plan type"
android:layout_gravity="center"
android:gravity="center|left"
android:drawableLeft="@drawable/ic_work_black_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/plan_type"/>
</LinearLayout>
<ImageView
android:layout_width="0dp"
android:layout_weight=".15"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_send_black_24dp"
android:id="@+id/assign_booking"
android:visibility="visible"
android:scaleType="centerInside"/>
<ImageView
android:layout_width="0dp"
android:layout_weight=".15"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/check_black"
android:visibility="gone"
android:id="@+id/accept_booking"
android:scaleType="centerInside"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
我的fragment_booking_assignxml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.booking.assigned.UnassignedBooking.BookingAssignFragment">
<!-- TODO: Update blank fragment layout -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rev_booking_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_marginBottom="@dimen/dp20"
android:scrollbarSize="@dimen/dp15"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/data_not_available"
android:id="@+id/error_message"
android:visibility="gone"
android:layout_centerInParent="true"
android:textColor="@color/red"
android:textSize="@dimen/dimen_26dp"/>
</RelativeLayout>
更新
在本地尝试代码后,我无法重现您的问题,唯一不同的是我模拟了数据并且没有使用该服务。所以我再次检查了您的服务 class,我想我找到了问题所在。在您的服务 class 中,成功请求新数据后,您可以:
appDatabase.myDao().deleteBookingList();
由于您的 mBookingList
liveData 由 myDao
更新(如您在存储库中声明的那样),这将导致 mBookingList
更新为空列表,因此 recyclerView 重置为空一会儿==眨眼。紧接着,你用新数据填充你的 DAO,即用新数据更新你的 mBookingList
,导致用新数据填充当前空的 recyclerView == 看似滚动到顶部(但实际上发生的事情只是从空开始到完整数据)。
因此,为了解决您的问题,提出更新数据库而不是清除它并重新填充的实现,或者如果传入数据集为空,请避免为您的 recyclerView 设置数据。
我要实时显示数据。所以我创建了一个服务并添加了一个计时器。我每 1 分钟按一次 Rest API 并将数据存储在 room-Bb 中。
问题:每隔一分钟调用一次服务后,我的适配器就会重置,我的 recyclerView 每隔一分钟就会一次又一次地闪烁,即使我滚动了一个列表,我也会到达列表的顶部。
在我的 activity 片段基础中,我调用了 MySimpleService 。在这项服务中,我使用了一个计时器,每隔一分钟就会给我的 API 打电话,以检查我是否有新的预订。每当我的 API 被调用时,我的列表就会更新,并且由于适配器中 setBookingData 方法中的 notifydatasetchanged(),我的 Recyclerview 适配器会被重置。所以我的 recyclerView 每隔一分钟就会继续闪烁。
这是我的代码
MySimpleService
public class MySimpleService extends Service {
private static final String TAG = "MyTag";
private Timer mTimer;
private Handler mHandler = new Handler();
private static final int TIMER_INTERVAL = 10000; // 1 Minute
private static final int TIMER_DELAY = 0;
private MyDatabase appDatabase;
@Override
public void onCreate() {
super.onCreate();
appDatabase = MyDatabase.getInstance(getApplicationContext());
Log.d(TAG, "MySimpleService onCreate: ");
if (mTimer != null)
mTimer = null;
// Create new Timer
mTimer = new Timer();
// Required to Schedule DisplayToastTimerTask for repeated execution with an interval of `1 min`
mTimer.scheduleAtFixedRate(new DisplayToastTimerTask(), TIMER_DELAY, TIMER_INTERVAL);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "MySimpleService onStartCommand: ");
return Service.START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "My Service onDestroy: ");
// Cancel timer
mTimer.cancel();
}
private class DisplayToastTimerTask extends TimerTask {
@Override
public void run() {
mHandler.post(() -> {
if (Utils.getConnectivityStatus(getApplicationContext()) == 0) {
Utils.showOkAlert(getApplicationContext(), getString(R.string.info), "Please check your internet connection", false);
} else {
new Thread(() -> callApbookingList()).start();
new Thread(() -> callApiAssignList()).start();
new Thread(() -> callApiBookingActivitiesList()).start();
}
});
}
}
private void callApbookingList() {
RetrofitApiInterface apiInterface = RetrofitClient.getClient().create(RetrofitApiInterface.class);
Call<BookingDataResponse> call = apiInterface.getAllData(new PostContData(PreferenceData.getLong(getApplicationContext(), "cont_id")));
call.enqueue(new Callback<BookingDataResponse>() {
@Override
public void onResponse(Call<BookingDataResponse> call, Response<BookingDataResponse> response) {
if (response.isSuccessful()) {
BookingDataResponse body = response.body();
appDatabase.myDao().deleteBookingList();
if (body.getStatus() == 0) {
Log.d(TAG, "onResponse: " + body.getMessage());
new Thread(() -> {
try {
appDatabase.myDao().insertBooking(body.getBookingList());
} catch (Exception e) {
}
}).start();
}
}
}
@Override
public void onFailure(Call<BookingDataResponse> call, Throwable t) {
Log.e(TAG, "onFailure: " + t);
}
});
}
我的片段
public class BookingAssignFragment extends Fragment {
private BookingViewModel bookingViewModel;
private BookingListAdepter bookingListAdepter;
public BookingAssignFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_booking_assign, container, false);
bookingListAdepter = new BookingListAdepter(getActivity());
RecyclerView recyclerView = view.findViewById(R.id.rev_booking_list);
TextView errorMessasge = view.findViewById(R.id.error_message);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(bookingListAdepter);
bookingViewModel = new ViewModelProvider(getActivity()).get(BookingViewModel.class);
bookingViewModel.getBooking().observe(getActivity(), bookingLists -> {
if (bookingLists.isEmpty()) {
if (errorMessasge.getVisibility() == View.GONE)
errorMessasge.setVisibility(View.VISIBLE);
} else {
if (errorMessasge.getVisibility() == View.VISIBLE)
errorMessasge.setVisibility(View.GONE);
// bookingListAdepter.setBookingData(bookingLists);
}
bookingListAdepter.setBookingData(bookingLists);
});
return view;
}
}
我的适配器
public class BookingListAdepter extends RecyclerView.Adapter<BookingListAdepter.BookingViewHolder> {
private List<BookingList> bookingLists;
private LayoutInflater mInflater;
private Context mContext;
public BookingListAdepter(Context context) {
mInflater = LayoutInflater.from(context);
mContext =context;
}
@NonNull
@Override
public BookingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.item_view_booking_list, parent, false);
return new BookingViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BookingViewHolder holder, int position) {
BookingList li = bookingLists.get(position);
if(li.getPlanType().equalsIgnoreCase("Both Way")){
if (holder.numberOfDay.getVisibility()==View.GONE) {
holder.numberOfDay.setVisibility(View.VISIBLE);
holder.numberOfDay.setText(String.valueOf(li.getBookingDays()));
}
}else {
if (holder.numberOfDay.getVisibility()==View.VISIBLE)
holder.numberOfDay.setVisibility(View.GONE);
}
if (li.getPlanType().equals(li.getTerrifType())){
if (holder.palanTyupe.getVisibility()==View.VISIBLE)
holder.palanTyupe.setVisibility(View.GONE);
}else { if (holder.palanTyupe.getVisibility()==View.GONE)
holder.palanTyupe.setVisibility(View.VISIBLE);}
holder.packageName.setText(li.getPlanType());
holder.cabCategory.setText(li.getCabCategory());
holder.dateTime.setText(li.getDatetime());
holder.formLocation.setText(li.getFromLocation());
holder.toLocation.setText(li.getToLocation());
holder.amount.setText(String.valueOf(li.getTotalAmount()));
holder.paidWalletAmount.setText(String.valueOf(li.getPaidWalletAmount()));
holder.assignBooking.setOnClickListener(v -> {
if (Utils.getConnectivityStatus(mContext) == 0) {
Utils.showOkAlert(mContext,mContext.getString(R.string.info), "Please check your internet connection", false);
}else {
BookingAssignDialogFragment updateDriver = BookingAssignDialogFragment.newInstance(li.getBookingId(), PreferenceData.getLong(mContext,"cont_id"),0,"");
updateDriver.show((Activity) mContext);
}
});
}
@Override
public int getItemCount() {
if (bookingLists!=null)
return bookingLists.size();
else return 0;
}
public void setBookingData(List<BookingList> bookingData) {
bookingLists = bookingData;
Log.d("UpdatedBooking", String.valueOf(bookingLists.size()));
notifyDataSetChanged();
}
class BookingViewHolder extends RecyclerView.ViewHolder{
TextView packageName,palanTyupe,cabCategory,amount,formLocation,toLocation,dateTime,numberOfDay,paidWalletAmount;
ImageView assignBooking,acceptBooking;
public BookingViewHolder(@NonNull View itemView) {
super(itemView);
packageName = itemView.findViewById(R.id.package_name);
palanTyupe = itemView.findViewById(R.id.plan_type);
cabCategory = itemView.findViewById(R.id.cab_category);
amount = itemView.findViewById(R.id.amount);
formLocation = itemView.findViewById(R.id.from_location);
toLocation = itemView.findViewById(R.id.to_location);
dateTime = itemView.findViewById(R.id.date_and_time);
numberOfDay = itemView.findViewById(R.id.no_of_day);
assignBooking = itemView.findViewById(R.id.assign_booking);
paidWalletAmount = itemView.findViewById(R.id.paid_wallet_amount);
acceptBooking =itemView.findViewById(R.id.accept_booking);
}
}
}
我的视图模型
public class BookingActivitiesListViewModel extends AndroidViewModel {
private BookingActivitiesListRepository bookingActivitiesListRepository;
private LiveData<List<BookingActivitiesList>> mLiveData;
public BookingActivitiesListViewModel(@NonNull Application application) {
super(application);
bookingActivitiesListRepository = new BookingActivitiesListRepository(application);
mLiveData = bookingActivitiesListRepository.getBookingActivitiesList();
}
public LiveData<List<BookingActivitiesList>> getBookingActivitiesList()
{
return mLiveData;
}
}
我的存储库
public class BookingRepository {
private MyDao myDao;
private LiveData<List<BookingList>> mBookingList;
BookingRepository(Application application){
MyDatabase db = MyDatabase.getInstance(application);
myDao = db.myDao();
mBookingList = myDao.getBookingList();
}
LiveData<List<BookingList>> getBooking(){return mBookingList;}
我的item_view_booking_list
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
android:elevation="5dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
style="@style/ItemViewStyle"
android:weightSum="1">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight=".85">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_location_form_24dp"
android:drawablePadding="@dimen/dp5"
android:padding="5dp"
android:layout_weight="1"
android:id="@+id/from_location"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_location_to_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/to_location"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:padding="5dp"
android:gravity="left|center"
android:drawableLeft="@drawable/ic_car"
android:drawablePadding="@dimen/dp5"
android:id="@+id/cab_category"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_work_black_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:gravity="center|left"
android:padding="5dp"
android:id="@+id/package_name"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2560"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_rupee_indian"
android:drawablePadding="@dimen/dp5"
android:padding="5dp"
android:gravity="left|center"
android:id="@+id/amount"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center|left"
android:drawableLeft="@drawable/wallet"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/paid_wallet_amount"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:padding="5dp"
android:layout_weight="1"
android:layout_gravity="center"
android:textStyle="bold"
android:drawableLeft="@drawable/ic_access_time_black_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_height="wrap_content"
android:id="@+id/date_and_time"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_date_range_black_24dp"
android:layout_gravity="center"
android:drawablePadding="@dimen/dp5"
android:visibility="gone"
android:padding="5dp"
android:id="@+id/no_of_day"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="plan type"
android:layout_gravity="center"
android:gravity="center|left"
android:drawableLeft="@drawable/ic_work_black_24dp"
android:drawablePadding="@dimen/dp5"
android:layout_weight="1"
android:padding="5dp"
android:id="@+id/plan_type"/>
</LinearLayout>
<ImageView
android:layout_width="0dp"
android:layout_weight=".15"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_send_black_24dp"
android:id="@+id/assign_booking"
android:visibility="visible"
android:scaleType="centerInside"/>
<ImageView
android:layout_width="0dp"
android:layout_weight=".15"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/check_black"
android:visibility="gone"
android:id="@+id/accept_booking"
android:scaleType="centerInside"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
我的fragment_booking_assignxml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.booking.assigned.UnassignedBooking.BookingAssignFragment">
<!-- TODO: Update blank fragment layout -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rev_booking_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_marginBottom="@dimen/dp20"
android:scrollbarSize="@dimen/dp15"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/data_not_available"
android:id="@+id/error_message"
android:visibility="gone"
android:layout_centerInParent="true"
android:textColor="@color/red"
android:textSize="@dimen/dimen_26dp"/>
</RelativeLayout>
更新
在本地尝试代码后,我无法重现您的问题,唯一不同的是我模拟了数据并且没有使用该服务。所以我再次检查了您的服务 class,我想我找到了问题所在。在您的服务 class 中,成功请求新数据后,您可以:
appDatabase.myDao().deleteBookingList();
由于您的 mBookingList
liveData 由 myDao
更新(如您在存储库中声明的那样),这将导致 mBookingList
更新为空列表,因此 recyclerView 重置为空一会儿==眨眼。紧接着,你用新数据填充你的 DAO,即用新数据更新你的 mBookingList
,导致用新数据填充当前空的 recyclerView == 看似滚动到顶部(但实际上发生的事情只是从空开始到完整数据)。
因此,为了解决您的问题,提出更新数据库而不是清除它并重新填充的实现,或者如果传入数据集为空,请避免为您的 recyclerView 设置数据。