簡體   English   中英

我可以直接從 RecyclerView 實體房間數據並將其保存到房間數據庫嗎?

[英]Can I Entity Room data right from RecyclerView and Save it to Room Database?

我有一些適配器使用改造從 web 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);
        }
    }

這是我的 recyclerview這僅在啟用網絡時有效

問題是當通過 Onclick SaveButton 啟用網絡以創建其他 recyclerview 並在那里設置數據時,如何將這些數據從 RecyclerView(或其他方式)設置到我的 Room 數據庫,以便稍后使其脫機。

我正在嘗試創建實體

  @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;
            }
        }

我需要以哪種方式創建它?

  1. 創建一個@Entity Notice ,它是您要存儲在Room DB 中的數據類型。
  2. 創建一個附加到您的活動/片段的視圖模型,您需要在其中顯示此列表。
  3. 使用您的 ViewModel 將來自 API 的列表存儲到您的 Room DB 中。
  4. 創建一個 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); 
        });

視圖模型

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;
    }
}

您需要在其中顯示已保存數據的活動代碼

//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

            });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM