我可以直接从 RecyclerView 获取实体房间数据并将其保存到房间数据库吗?
Can I Entity Room data right from RecyclerView and Save it to Room Database?
我有一些适配器使用改装从网络上获取数据 api 并将其放置到 recyclerview
public class NoticeAdapter extends RecyclerView.Adapter<NoticeAdapter.EmployeeViewHolder> {
private Wind wind;
private ArrayList<Notice> dataList;
private Main main;
private Date currentTime = Calendar.getInstance().getTime();
private RecyclerItemClickListener recyclerItemClickListener;
public NoticeAdapter(ArrayList<Notice> dataList, Main main, Wind wind, RecyclerItemClickListener recyclerItemClickListener) {
this.dataList = dataList;
this.main = main;
this.wind = wind;
this.recyclerItemClickListener = recyclerItemClickListener;
}
@Override
public EmployeeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.single_view_row, parent, false);
return new EmployeeViewHolder(view);
}
@Override
public void onBindViewHolder(EmployeeViewHolder holder, @SuppressLint("RecyclerView") final int position) {
if(getAddressMap()!=null){holder.txtNoticeAddress.setText("Loc: "+getAddressMap());}else{holder.txtNoticeAddress.setText("Loc: Unknown location");}
holder.imageIcon.setImageURI(Uri.parse("android.resource://com.locweather/drawable/i"+dataList.get(position).getIcon()));
holder.txtNoticeWind.setText("Wind: "+roundUp(+wind.getSpeed(),1)+"m/s, "+arrow());
holder.txtNoticeTempMain.setText(roundUp(+main.getTemp(),1)+"°C");
holder.txtNoticeWeather.setText(dataList.get(position).getWeather()+" : "+dataList.get(position).getInfo());
holder.txtNoticeTemp.setText("Feels: "+roundUp(+main.getFeelsLike(),1)+"°C ");
holder.txtNoticeTime.setText(currentTime.toString());
holder.txtNoticeHumidity.setText("Humidity: "+main.getHumidity()+"%");
holder.txtNoticePressure.setText("Pressure: "+main.getPressure()+"hPa");
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
recyclerItemClickListener.onItemClick(dataList.get(position));
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
class EmployeeViewHolder extends RecyclerView.ViewHolder {
ImageView imageIcon;
TextView txtNoticeWeather, txtNoticeTempMain,txtNoticeTemp, txtNoticeHumidity,txtNoticeAddress,txtNoticePressure,txtNoticeWind,txtNoticeTime;
EmployeeViewHolder(View itemView) {
super(itemView);
imageIcon=itemView.findViewById(R.id.image_icon);
txtNoticeTime= itemView.findViewById(R.id.txt_time);
txtNoticeWind= itemView.findViewById(R.id.txt_notice_wind);
txtNoticeAddress= itemView.findViewById(R.id.txt_notice_title);
txtNoticeWeather = itemView.findViewById(R.id.txt_notice_weather);
txtNoticeTemp = itemView.findViewById(R.id.txt_notice_temp);
txtNoticeHumidity = itemView.findViewById(R.id.txt_notice_humidity);
txtNoticePressure = itemView.findViewById(R.id.txt_notice_pressure);
txtNoticeTempMain = itemView.findViewById(R.id.txt_notice_temp_main);
}
}
This is my recyclerview
这仅在启用网络时有效
问题是当 Onclick SaveButton 启用网络以创建其他 recyclerview 并在那里设置数据,以便稍后将其离线时,如何将此数据从 RecyclerView(或其他方式)设置到我的房间数据库。
我正在尝试创建实体
@Entity
public class WeatherData {
@PrimaryKey(autoGenerate = true)
private long id;
private String address;
private Double windSpeed;
private Integer windDegree;
private String datalistIcon;
private String datalistInfo;
private String datalistWeather;
private Double mainTemp;
private Double mainFeel;
private Integer mainHumidity;
private Integer mainPressure;
private String time;
private Double locLat;
private Double locLon;
public WeatherData(){}
@Ignore
public WeatherData(String address, Double windSpeed, Integer windDegree, String datalistIcon,String datalistInfo,String datalistWeather, Double mainTemp,Double mainFeel,Integer mainHumidity,Integer mainPressure,String time,LatLng currentLocation,Double locLat,Double locLon) {
this.address = address;
this.windSpeed = windSpeed;
this.windDegree = windDegree;
this.datalistIcon=datalistIcon;
this.datalistInfo=datalistInfo;
this.datalistWeather=datalistWeather;
this.mainTemp=mainTemp;
this.mainFeel=mainFeel;
this.mainHumidity=mainHumidity;
this.mainPressure=mainPressure;
this.time=time;
this.locLat=locLat;
this.locLon=locLon;
}
道
@Dao
public interface WeatherDataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void saveAll(List<WeatherData> weathers);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void save(WeatherData weather);
@Update
void update(WeatherData weather);
@Delete
void delete(WeatherData weather);
@Query("SELECT * FROM WeatherData")
LiveData<List<WeatherData>> findAll();
}
和数据库
@Database(entities = {WeatherData.class}, version = 1)
public abstract class WeatherDatabase extends RoomDatabase {
public static WeatherDatabase INSTANCE;
public abstract WeatherDataDao weatherDao();
private static final Object sLock = new Object();
public static WeatherDatabase getInstance(Context context) {
synchronized (sLock) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WeatherDatabase.class, "Weathers.db")
.allowMainThreadQueries()
.build();
}
return INSTANCE;
}
}
我需要用什么方式创建它?
- 创建一个
@Entity Notice
这是您要存储在 Room DB 中的数据类型。
- 创建一个附加到您的 Activity/Fragment 的视图模型,您需要在其中显示此列表。
- 使用您的 ViewModel 将 API 中的列表存储到您的 Room 数据库中。
- 创建一个在数据库上观察并将更新列表发送到另一个视图的 LiveData。
在数据库中保存数据的代码。这需要在后台线程上 运行。
public static void saveNoticeList(Context context, List<Notice> noticeList) {
if (context != null && noticeList != null) {
RoomDatabaseCreator.getInstance(context)
.getDatabase()
.noticeDao()
.saveNotices(noticeList);
}
}
// For Saving in background you can use RxJava, I am using a new thread for simplification
backgroundHandler.post(() -> {
saveNoticeList(getActivity(), dataList);
});
ViewModel
public class NoticeViewModel extends AndroidViewModel {
public MutableLiveData<List<Notice>> mNoticesLiveData = new MutableLiveData<>();
private Context mContext;
public NoticeViewModel(final Application application) {
super(application);
mContext = application.getApplicationContext();
mNoticesLiveData = Transformations.switchMap(databaseCreated,
(Function<Boolean, LiveData<List<Notice>>) isDbCreated -> {
if (!Boolean.TRUE.equals(isDbCreated)) { // Not needed here, but watch out for null
//noinspection unchecked
return ABSENT;
} else {
return databaseCreator.getDatabase()
.noticedao()
.getSavedNotices();
}
}
});
public LiveData<List<Notice> getNoticeLiveData() {
return mNoticesLiveData;
}
}
Activity 需要显示保存数据的代码
//1. Initialize the viewModel
NoticeViewModel viewModel = ViewModelProviders.of(this).get(NoticeViewModel.class);
//2. Subscribe to the saved notices live-data to get updates in your view
viewModel.getNoticeLiveData().observe(this
list -> {
if (list.isEmpty()) {
return;
}
// Add the list in your adapter
});
我有一些适配器使用改装从网络上获取数据 api 并将其放置到 recyclerview
public class NoticeAdapter extends RecyclerView.Adapter<NoticeAdapter.EmployeeViewHolder> {
private Wind wind;
private ArrayList<Notice> dataList;
private Main main;
private Date currentTime = Calendar.getInstance().getTime();
private RecyclerItemClickListener recyclerItemClickListener;
public NoticeAdapter(ArrayList<Notice> dataList, Main main, Wind wind, RecyclerItemClickListener recyclerItemClickListener) {
this.dataList = dataList;
this.main = main;
this.wind = wind;
this.recyclerItemClickListener = recyclerItemClickListener;
}
@Override
public EmployeeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.single_view_row, parent, false);
return new EmployeeViewHolder(view);
}
@Override
public void onBindViewHolder(EmployeeViewHolder holder, @SuppressLint("RecyclerView") final int position) {
if(getAddressMap()!=null){holder.txtNoticeAddress.setText("Loc: "+getAddressMap());}else{holder.txtNoticeAddress.setText("Loc: Unknown location");}
holder.imageIcon.setImageURI(Uri.parse("android.resource://com.locweather/drawable/i"+dataList.get(position).getIcon()));
holder.txtNoticeWind.setText("Wind: "+roundUp(+wind.getSpeed(),1)+"m/s, "+arrow());
holder.txtNoticeTempMain.setText(roundUp(+main.getTemp(),1)+"°C");
holder.txtNoticeWeather.setText(dataList.get(position).getWeather()+" : "+dataList.get(position).getInfo());
holder.txtNoticeTemp.setText("Feels: "+roundUp(+main.getFeelsLike(),1)+"°C ");
holder.txtNoticeTime.setText(currentTime.toString());
holder.txtNoticeHumidity.setText("Humidity: "+main.getHumidity()+"%");
holder.txtNoticePressure.setText("Pressure: "+main.getPressure()+"hPa");
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
recyclerItemClickListener.onItemClick(dataList.get(position));
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
class EmployeeViewHolder extends RecyclerView.ViewHolder {
ImageView imageIcon;
TextView txtNoticeWeather, txtNoticeTempMain,txtNoticeTemp, txtNoticeHumidity,txtNoticeAddress,txtNoticePressure,txtNoticeWind,txtNoticeTime;
EmployeeViewHolder(View itemView) {
super(itemView);
imageIcon=itemView.findViewById(R.id.image_icon);
txtNoticeTime= itemView.findViewById(R.id.txt_time);
txtNoticeWind= itemView.findViewById(R.id.txt_notice_wind);
txtNoticeAddress= itemView.findViewById(R.id.txt_notice_title);
txtNoticeWeather = itemView.findViewById(R.id.txt_notice_weather);
txtNoticeTemp = itemView.findViewById(R.id.txt_notice_temp);
txtNoticeHumidity = itemView.findViewById(R.id.txt_notice_humidity);
txtNoticePressure = itemView.findViewById(R.id.txt_notice_pressure);
txtNoticeTempMain = itemView.findViewById(R.id.txt_notice_temp_main);
}
}
This is my recyclerview 这仅在启用网络时有效
问题是当 Onclick SaveButton 启用网络以创建其他 recyclerview 并在那里设置数据,以便稍后将其离线时,如何将此数据从 RecyclerView(或其他方式)设置到我的房间数据库。
我正在尝试创建实体
@Entity
public class WeatherData {
@PrimaryKey(autoGenerate = true)
private long id;
private String address;
private Double windSpeed;
private Integer windDegree;
private String datalistIcon;
private String datalistInfo;
private String datalistWeather;
private Double mainTemp;
private Double mainFeel;
private Integer mainHumidity;
private Integer mainPressure;
private String time;
private Double locLat;
private Double locLon;
public WeatherData(){}
@Ignore
public WeatherData(String address, Double windSpeed, Integer windDegree, String datalistIcon,String datalistInfo,String datalistWeather, Double mainTemp,Double mainFeel,Integer mainHumidity,Integer mainPressure,String time,LatLng currentLocation,Double locLat,Double locLon) {
this.address = address;
this.windSpeed = windSpeed;
this.windDegree = windDegree;
this.datalistIcon=datalistIcon;
this.datalistInfo=datalistInfo;
this.datalistWeather=datalistWeather;
this.mainTemp=mainTemp;
this.mainFeel=mainFeel;
this.mainHumidity=mainHumidity;
this.mainPressure=mainPressure;
this.time=time;
this.locLat=locLat;
this.locLon=locLon;
}
道
@Dao
public interface WeatherDataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void saveAll(List<WeatherData> weathers);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void save(WeatherData weather);
@Update
void update(WeatherData weather);
@Delete
void delete(WeatherData weather);
@Query("SELECT * FROM WeatherData")
LiveData<List<WeatherData>> findAll();
}
和数据库
@Database(entities = {WeatherData.class}, version = 1)
public abstract class WeatherDatabase extends RoomDatabase {
public static WeatherDatabase INSTANCE;
public abstract WeatherDataDao weatherDao();
private static final Object sLock = new Object();
public static WeatherDatabase getInstance(Context context) {
synchronized (sLock) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WeatherDatabase.class, "Weathers.db")
.allowMainThreadQueries()
.build();
}
return INSTANCE;
}
}
我需要用什么方式创建它?
- 创建一个
@Entity Notice
这是您要存储在 Room DB 中的数据类型。 - 创建一个附加到您的 Activity/Fragment 的视图模型,您需要在其中显示此列表。
- 使用您的 ViewModel 将 API 中的列表存储到您的 Room 数据库中。
- 创建一个在数据库上观察并将更新列表发送到另一个视图的 LiveData。
在数据库中保存数据的代码。这需要在后台线程上 运行。
public static void saveNoticeList(Context context, List<Notice> noticeList) {
if (context != null && noticeList != null) {
RoomDatabaseCreator.getInstance(context)
.getDatabase()
.noticeDao()
.saveNotices(noticeList);
}
}
// For Saving in background you can use RxJava, I am using a new thread for simplification
backgroundHandler.post(() -> {
saveNoticeList(getActivity(), dataList);
});
ViewModel
public class NoticeViewModel extends AndroidViewModel {
public MutableLiveData<List<Notice>> mNoticesLiveData = new MutableLiveData<>();
private Context mContext;
public NoticeViewModel(final Application application) {
super(application);
mContext = application.getApplicationContext();
mNoticesLiveData = Transformations.switchMap(databaseCreated,
(Function<Boolean, LiveData<List<Notice>>) isDbCreated -> {
if (!Boolean.TRUE.equals(isDbCreated)) { // Not needed here, but watch out for null
//noinspection unchecked
return ABSENT;
} else {
return databaseCreator.getDatabase()
.noticedao()
.getSavedNotices();
}
}
});
public LiveData<List<Notice> getNoticeLiveData() {
return mNoticesLiveData;
}
}
Activity 需要显示保存数据的代码
//1. Initialize the viewModel
NoticeViewModel viewModel = ViewModelProviders.of(this).get(NoticeViewModel.class);
//2. Subscribe to the saved notices live-data to get updates in your view
viewModel.getNoticeLiveData().observe(this
list -> {
if (list.isEmpty()) {
return;
}
// Add the list in your adapter
});