I have some adapter which use retrofit to get data right from web api and place it to recyclerview
JavaScript
x
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 This works only when network is enabled
The question is how to set this data right from RecyclerView (or other way) to my Room DataBase when network is enabled by Onclick SaveButton to create other recyclerview and set data there, to get it offline later.
I’m trying to create Entity
JavaScript
@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
JavaScript
@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();
}
and DataBase
JavaScript
@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;
}
}
Which way do I need to create it?
Advertisement
Answer
- Create an
@Entity Notice
which is your data type to be stored in your Room DB. - Create a View Model which is attached to your Activity/Fragment where you need to show this list.
- Use your ViewModel to store the list from API into your Room DB.
- Create a LiveData which observes on the DB and sends the updated list to the other view.
Code for Saving Data in DB. This needs to be run on Background Thread.
JavaScript
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
JavaScript
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 Code where you need to show the saved data
JavaScript
//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
});