如何转换 Android SqlBrite 模型 class 以实现 Parcelable
How to convert a Android SqlBrite model class to implement Parcelable
我正在构建一个应用程序,我在其中使用 SQLBrite sql 包装器进行所有数据库操作。此外,我正在使用 Auto Value 来使用 Google AutoValue 库自动处理我所有的 getter 和 setter。
现在,我的问题是处理设备旋转并处理我的 putParcelable() 方法需要两个参数,其中第一个是 KEY,第二个是 Parcelable 类型的值。正如我之前所说,我的 Recipe class(下面的代码)是一个 SQLBrite 实现 class 并且没有实现 Parcelable。我需要一些帮助来将其转换为实现 Parcelable 接口。
@AutoValue
public abstract class Recipe {
public abstract int id();
public abstract String name();
public abstract List<Ingredients> ingredients();
public abstract List<Step> steps();
public abstract int servings();
public abstract String image();
public static Builder builder() {
return new AutoValue_Recipe.Builder();
}
public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
return new AutoValue_Recipe.GsonTypeAdapter(gson);
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder id(int id);
public abstract Builder name(String name);
public abstract Builder ingredients(List<Ingredients> ingredients);
public abstract Builder steps(List<Step> steps);
public abstract Builder servings(int servings);
public abstract Builder image(String image);
public abstract Recipe build();
}
}
现在,我尝试将上面的代码转换为实现 Parcelable 接口,但是,现在我的代码不起作用。请帮我转换这个 class 以实现 Parcelable 接口。
@AutoValue
public abstract class Recipe implements Parcelable {
public static final String ID = "id";
public static final String NAME = "name";
public static final String INGREDIENTS = "ingredients";
public static final String STEPS = "steps";
public static final String SERVINGS = "servings";
public static final String IMAGE = "image";
private int id;
private String name;
private List<Ingredients> ingredients;
private List<Step> steps;
private int servings;
private String image;
public abstract int id();
public abstract String name();
public abstract List<Ingredients> ingredients();
public abstract List<Step> steps();
public abstract int servings();
public abstract String image();
public static Recipe.Builder builder() {
return new AutoValue_Recipe.Builder();
}
public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
return new AutoValue_Recipe.GsonTypeAdapter(gson);
}
public static final class Builder {
private final ContentValues values = new ContentValues();
List<Ingredients> ingredient;
List<Step> step;
public Recipe.Builder id(int id) {
values.put(ID, id);
return this;
}
public Builder name(String name) {
values.put(NAME, name);
return this;
}
public Builder ingredients(List<Ingredients> ingredients) {
*//*for(int i=0; i<ingredients.size(); i++) {
values.put(INGREDIENTS, ingredients.get(i).ingredient());
}*//*
this.ingredient = ingredients;
return this;
}
public Builder steps(List<Step> steps) {
*//*for(int i=0; i<steps.size(); i++) {
values.put(STEPS, steps.get(i));
}*//*
this.step = steps;
return this;
}
public Builder servings(int servings) {
values.put(SERVINGS, servings);
return this;
}
public Builder image(String image) {
values.put(IMAGE, image);
return this;
}
public Recipe build() {
Recipe recipe = null;
recipe.id = (int) values.get(ID);
recipe.name = (String) values.get(NAME);
recipe.ingredients = ingredient;
recipe.steps = step;
recipe.servings = (int) values.get(SERVINGS);
recipe.image = (String) values.get(IMAGE);
return recipe;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeList(ingredients);
dest.writeList(steps);
dest.writeInt(servings);
dest.writeString(image);
}
}
编辑:
我将使用修改后的 class 来处理我的设备旋转,以将我的回收器视图的滚动状态保存在一个片段中。我的 onSaveInstanceState() 方法看起来像这样,
private static final String BUNDLE_RECYCLER_LAYOUT = "BUNDLE_RECYCLER_LAYOUT";
ArrayList<Recipe> mRecipeList = new ArrayList<>(0);
@Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putParcelable(BUNDLE_RECYCLER_LAYOUT,
mRecipeListRecyclerView.getLayoutManager().onSaveInstanceState());
bundle.putParcelableArrayList(BUNDLE_RECYCLER_RECIPE_DATA, mRecipeList);
}
putParcelable里面的第二个参数是Parcelable类型
我的onCreateView()方法如图:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup
container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recipe_list, container, false);
unbinder = ButterKnife.bind(this, view);
if(savedInstanceState != null) {
Parcelable savedRecyclerViewState = savedInstanceState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
mRecipeListRecyclerView.getLayoutManager().onRestoreInstanceState(savedRecyclerViewState);
mRecipeList = savedInstanceState.getParcelableArrayList(BUNDLE_RECYCLER_RECIPE_DATA);
mRecipeListAdapter.refreshRecipes(mRecipeList);
} else {
mRecipeList = getArguments().getParcelableArrayList(BUNDLE_RECYCLER_RECIPE_DATA);
}
mRecipeListAdapter = new RecipeListAdapter(getContext(), mRecipeList, recipeId
-> mRecipeListPresenter.loadRecipeDetails(recipeId));
mRecipeListAdapter.setHasStableIds(true);
gridLayoutManager = new GridLayoutManager(getContext(), mGridColumnCount);
mRecipeListRecyclerView.setLayoutManager(gridLayoutManager);
mRecipeListRecyclerView.setHasFixedSize(true);
mRecipeListRecyclerView.setAdapter(mRecipeListAdapter);
return view;
}
任何帮助都会很棒,因为我在转换 class 以实现 Parcelable 接口时遇到困难。
mRecipeListRecyclerView.getLayoutManager().onRestoreInstanceState(savedRecyclerViewState);
您无需致电 onRestoreInstanceState()
。 Android 系统已经自动调用了它。此外,您不需要自己保存和恢复 ArrayList
。 RecyclerView
已经为您处理好这些细节。
至于保存滚动位置,你应该多做一点研究。例如,我通过快速搜索找到了 ListView jumps to the top on screen orientation change。这个 link 有一个清楚的例子,说明如何做你想做的事。
是关于 ScrollView
但示例代码与您需要的非常相似。
我正在构建一个应用程序,我在其中使用 SQLBrite sql 包装器进行所有数据库操作。此外,我正在使用 Auto Value 来使用 Google AutoValue 库自动处理我所有的 getter 和 setter。
现在,我的问题是处理设备旋转并处理我的 putParcelable() 方法需要两个参数,其中第一个是 KEY,第二个是 Parcelable 类型的值。正如我之前所说,我的 Recipe class(下面的代码)是一个 SQLBrite 实现 class 并且没有实现 Parcelable。我需要一些帮助来将其转换为实现 Parcelable 接口。
@AutoValue
public abstract class Recipe {
public abstract int id();
public abstract String name();
public abstract List<Ingredients> ingredients();
public abstract List<Step> steps();
public abstract int servings();
public abstract String image();
public static Builder builder() {
return new AutoValue_Recipe.Builder();
}
public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
return new AutoValue_Recipe.GsonTypeAdapter(gson);
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder id(int id);
public abstract Builder name(String name);
public abstract Builder ingredients(List<Ingredients> ingredients);
public abstract Builder steps(List<Step> steps);
public abstract Builder servings(int servings);
public abstract Builder image(String image);
public abstract Recipe build();
}
}
现在,我尝试将上面的代码转换为实现 Parcelable 接口,但是,现在我的代码不起作用。请帮我转换这个 class 以实现 Parcelable 接口。
@AutoValue
public abstract class Recipe implements Parcelable {
public static final String ID = "id";
public static final String NAME = "name";
public static final String INGREDIENTS = "ingredients";
public static final String STEPS = "steps";
public static final String SERVINGS = "servings";
public static final String IMAGE = "image";
private int id;
private String name;
private List<Ingredients> ingredients;
private List<Step> steps;
private int servings;
private String image;
public abstract int id();
public abstract String name();
public abstract List<Ingredients> ingredients();
public abstract List<Step> steps();
public abstract int servings();
public abstract String image();
public static Recipe.Builder builder() {
return new AutoValue_Recipe.Builder();
}
public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
return new AutoValue_Recipe.GsonTypeAdapter(gson);
}
public static final class Builder {
private final ContentValues values = new ContentValues();
List<Ingredients> ingredient;
List<Step> step;
public Recipe.Builder id(int id) {
values.put(ID, id);
return this;
}
public Builder name(String name) {
values.put(NAME, name);
return this;
}
public Builder ingredients(List<Ingredients> ingredients) {
*//*for(int i=0; i<ingredients.size(); i++) {
values.put(INGREDIENTS, ingredients.get(i).ingredient());
}*//*
this.ingredient = ingredients;
return this;
}
public Builder steps(List<Step> steps) {
*//*for(int i=0; i<steps.size(); i++) {
values.put(STEPS, steps.get(i));
}*//*
this.step = steps;
return this;
}
public Builder servings(int servings) {
values.put(SERVINGS, servings);
return this;
}
public Builder image(String image) {
values.put(IMAGE, image);
return this;
}
public Recipe build() {
Recipe recipe = null;
recipe.id = (int) values.get(ID);
recipe.name = (String) values.get(NAME);
recipe.ingredients = ingredient;
recipe.steps = step;
recipe.servings = (int) values.get(SERVINGS);
recipe.image = (String) values.get(IMAGE);
return recipe;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeList(ingredients);
dest.writeList(steps);
dest.writeInt(servings);
dest.writeString(image);
}
}
编辑: 我将使用修改后的 class 来处理我的设备旋转,以将我的回收器视图的滚动状态保存在一个片段中。我的 onSaveInstanceState() 方法看起来像这样,
private static final String BUNDLE_RECYCLER_LAYOUT = "BUNDLE_RECYCLER_LAYOUT";
ArrayList<Recipe> mRecipeList = new ArrayList<>(0);
@Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putParcelable(BUNDLE_RECYCLER_LAYOUT,
mRecipeListRecyclerView.getLayoutManager().onSaveInstanceState());
bundle.putParcelableArrayList(BUNDLE_RECYCLER_RECIPE_DATA, mRecipeList);
}
putParcelable里面的第二个参数是Parcelable类型
我的onCreateView()方法如图:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup
container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recipe_list, container, false);
unbinder = ButterKnife.bind(this, view);
if(savedInstanceState != null) {
Parcelable savedRecyclerViewState = savedInstanceState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
mRecipeListRecyclerView.getLayoutManager().onRestoreInstanceState(savedRecyclerViewState);
mRecipeList = savedInstanceState.getParcelableArrayList(BUNDLE_RECYCLER_RECIPE_DATA);
mRecipeListAdapter.refreshRecipes(mRecipeList);
} else {
mRecipeList = getArguments().getParcelableArrayList(BUNDLE_RECYCLER_RECIPE_DATA);
}
mRecipeListAdapter = new RecipeListAdapter(getContext(), mRecipeList, recipeId
-> mRecipeListPresenter.loadRecipeDetails(recipeId));
mRecipeListAdapter.setHasStableIds(true);
gridLayoutManager = new GridLayoutManager(getContext(), mGridColumnCount);
mRecipeListRecyclerView.setLayoutManager(gridLayoutManager);
mRecipeListRecyclerView.setHasFixedSize(true);
mRecipeListRecyclerView.setAdapter(mRecipeListAdapter);
return view;
}
任何帮助都会很棒,因为我在转换 class 以实现 Parcelable 接口时遇到困难。
mRecipeListRecyclerView.getLayoutManager().onRestoreInstanceState(savedRecyclerViewState);
您无需致电 onRestoreInstanceState()
。 Android 系统已经自动调用了它。此外,您不需要自己保存和恢复 ArrayList
。 RecyclerView
已经为您处理好这些细节。
至于保存滚动位置,你应该多做一点研究。例如,我通过快速搜索找到了 ListView jumps to the top on screen orientation change。这个 link 有一个清楚的例子,说明如何做你想做的事。
ScrollView
但示例代码与您需要的非常相似。