gpt4 book ai didi

Android MVVM 架构组件 : How do I update a single data entity from a list fragment?

转载 作者:行者123 更新时间:2023-11-29 15:36:31 25 4
gpt4 key购买 nike

我一直在尝试学习新的 Android 架构组件。我的应用程序一直基于此示例:Basic Sample

我可以正常使用,但我对如何插入、更新或删除 Room 数据库中的数据感到困惑。在示例中,它没有为这些提供示例。

从提供的示例开始,我正在尝试弄清楚如何从 ProductListFragment 对每个产品进行更改。在我的应用程序中,我没有使用产品,而是使用了定义的区域。因此,例如在列表中我想要一个按钮,按下该按钮将删除该区域。或者可以更新区域属性的按钮,例如区域具有 Activity 属性。单击该 CardView 上的按钮时,它将更新区域的 Activity 属性。

区域列表 fragment

public class ZoneListFragment extends android.support.v4.app.Fragment {

public static final String TAG = "ZoneListViewModel";
private ZoneAdapter mZoneAdapter;
private FragmentZoneListBinding mBinding;
private ZoneListViewModel viewModel;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_zone_list, container, false);

mZoneAdapter = new ZoneAdapter(mZoneClickCallback, mZoneDirectionClickCallback);
mBinding.zonesList.setAdapter(mZoneAdapter);

return mBinding.getRoot();
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(this).get(ZoneListViewModel.class);
subscribeUi(viewModel);
}

private void subscribeUi(ZoneListViewModel viewModel) {
// Update the list when the data changes
viewModel.getZones().observe(this, new Observer<List<ZoneEntity>>() {
@Override
public void onChanged(@Nullable List<ZoneEntity> myZones) {
if (myZones != null) {
mBinding.setIsLoading(false);
mZoneAdapter.setZoneList(myZones);
} else {
mBinding.setIsLoading(true);
}
mBinding.executePendingBindings();
}
});
}

private final ZoneClickCallback mZoneClickCallback = new ZoneClickCallback() {
@Override
public void onClick(Zone zone) {

}
};

private final ZoneDirectionClickCallback mZoneDirectionClickCallback = new ZoneDirectionClickCallback() {
@Override
public void onClick(Zone zone) {
zone.setDirection(zone.isDirection() ? false : true);
viewModel.updateZone(zone);
}
};
}

区域 ListView 模型

public class ZoneListViewModel extends AndroidViewModel {
private final MediatorLiveData<List<ZoneEntity>> mObservableZones;
private DataRepository repository;

public ZoneListViewModel(Application application) {
super(application);

mObservableZones = new MediatorLiveData<>();
// set by default null, until we get data from the database.
mObservableZones.setValue(null);

LiveData<List<ZoneEntity>> zones = ((Zoneify) application).getRepository()
.getZones();

// observe the changes of the zones from the database and forward them
mObservableZones.addSource(zones, mObservableZones::setValue);
}

public LiveData<List<ZoneEntity>> getZones() {
return mObservableZones;
}
}

区域适配器

public class ZoneAdapter extends RecyclerView.Adapter<ZoneAdapter.ZoneViewHolder> {

List<? extends Zone> mZoneList;

@Nullable
private final ZoneClickCallback mZoneClickCallback;
@Nullable
private final ZoneDirectionClickCallback mZoneDirectionClickCallback;

public ZoneAdapter(@Nullable ZoneClickCallback zoneClickCallback,
@Nullable ZoneDirectionClickCallback zoneDirectionClickCallback) {
mZoneClickCallback = zoneClickCallback;
mZoneDirectionClickCallback = zoneDirectionClickCallback;
}

public void setZoneList(final List<? extends Zone> zoneList) {
if (mZoneList == null) {
mZoneList = zoneList;
notifyItemRangeInserted(0, zoneList.size());
} else {
DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return mZoneList.size();
}

@Override
public int getNewListSize() {
return zoneList.size();
}

@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return mZoneList.get(oldItemPosition).getId() ==
zoneList.get(newItemPosition).getId();
}

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
Zone newZone = zoneList.get(newItemPosition);
Zone oldZone = mZoneList.get(oldItemPosition);
return newZone.getId() == oldZone.getId()
&& Objects.equals(newZone.getName(), oldZone.getName())
&& Objects.equals(newZone.getAddress(), oldZone.getAddress())
&& newZone.isActive() == oldZone.isActive()
&& newZone.isDirection() == oldZone.isDirection()
&& Objects.equals(newZone.getLatLng(), oldZone.getLatLng())
&& Objects.equals(newZone.getNotification(), oldZone.getNotification());
}
});
mZoneList = zoneList;
result.dispatchUpdatesTo(this);
}
}

@Override
public ZoneViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ZoneItemBinding binding = DataBindingUtil
.inflate(LayoutInflater.from(parent.getContext()), R.layout.zone_item,
parent, false);
binding.setZoneClickcallback(mZoneClickCallback);
binding.setZoneDirectionClickCallback(mZoneDirectionClickCallback);
return new ZoneViewHolder(binding);
}

@Override
public void onBindViewHolder(ZoneViewHolder holder, int position) {
holder.binding.setZone(mZoneList.get(position));
holder.binding.executePendingBindings();
}

@Override
public int getItemCount() {
return mZoneList == null ? 0 : mZoneList.size();
}

static class ZoneViewHolder extends RecyclerView.ViewHolder {

final ZoneItemBinding binding;

public ZoneViewHolder(ZoneItemBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

区域项目.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:map="http://schemas.android.com/tools">
<data>
<variable name="zone"
type="com.davidh.zoneify.data.model.Zone"/>
<variable name="zoneClickcallback"
type="com.davidh.zoneify.view.ZoneClickCallback"/>
<variable name="zoneDirectionClickCallback"
type="com.davidh.zoneify.view.ZoneDirectionClickCallback"/>
</data>

<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
android:onClick="@{() -> callback.onClick(zone)}"
android:orientation="horizontal"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:cardUseCompatPadding="true">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="125dp"
android:orientation="horizontal"
android:background="@color/colorPrimary">

<com.google.android.gms.maps.MapView
android:id="@+id/map"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
map:cameraZoom="15"
map:mapType="normal"
map:liteMode="true"
app:initMap="@{zone.latLng}"/>

<LinearLayout
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="@{zone.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Title.Inverse"/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="@{zone.notification}"
android:textAppearance="@style/TextAppearance.AppCompat.Small.Inverse"/>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_gravity="center|bottom">

<Button
android:layout_width="0dp"
android:layout_height="@dimen/imageButtonCardView"
android:layout_weight="1"
android:layout_gravity="center_horizontal|center|center_vertical"
android:background="@color/colorPrimary"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.Button.Inverse"
style="?android:attr/borderlessButtonStyle"
android:id="@+id/btn_zone_direction"
android:drawableTop="@{zone.direction ? @drawable/ic_leaving_24 : @drawable/ic_entering_24}"
android:text="@{zone.direction ? @string/leaving : @string/entering}"
android:onClick="@{() -> directionCallback.onClick(zone)}"/>

<Button
android:layout_width="0dp"
android:layout_height="@dimen/imageButtonCardView"
android:layout_weight="1"
android:layout_gravity="center_horizontal|center|center_vertical"
android:background="@color/colorPrimary"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.Button.Inverse"
style="?android:attr/borderlessButtonStyle"
android:id="@+id/btn_zone_active"
android:drawableTop="@{zone.active ? @drawable/ic_alarm_on_24 : @drawable/ic_alarm_off_24}"
android:text="@{zone.active ? @string/on : @string/off}"/>

<Button
android:layout_width="0dp"
android:layout_height="@dimen/imageButtonCardView"
android:layout_weight="1"
android:layout_gravity="center_horizontal|center|center_vertical"
android:background="@color/colorPrimary"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.Button.Inverse"
style="?android:attr/borderlessButtonStyle"
android:id="@+id/btn_zone_edit"
android:drawableTop="@drawable/ic_edit_24"
android:text="@string/edit"
android:padding="@dimen/buttonCardViewPadding"/>

<Button
android:layout_width="0dp"
android:layout_height="@dimen/imageButtonCardView"
android:layout_weight="1"
android:layout_gravity="center_horizontal|center|center_vertical"
android:background="@color/colorPrimary"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.Button.Inverse"
style="?android:attr/borderlessButtonStyle"
android:padding="@dimen/buttonCardViewPadding"
android:id="@+id/btn_zone_delete"
android:drawableTop="@drawable/ic_delete_24"
android:text="@string/delete"/>

</LinearLayout>

</LinearLayout>

</LinearLayout>

</android.support.v7.widget.CardView>
</layout>

其余设置与基本示例中的设置相同。只是停留在如何从列表中更新区域。

最佳答案

点击删除/更新时,您需要更新您的模型(您的存储库)。存储库将发出一个新的 LiveData 项目,适配器将被更新并且 DiffUtils 将完成它的工作。它将删除或更新项目。

例如删除操作:

  • 为“删除”按钮设置点击监听器
  • 从监听器调用 viewModel.deleteItem(id)(这是您的 ZoneListViewModel)
  • ViewModel 中调用 repository.deleteItem(id)
  • 在存储库中使用 Room 删除项目
  • Room 将使用更新后的列表发出一个新值(不包括已删除的项目)。
  • 适配器观察此列表并与 DiffUtils 一起删除该项目。

这是来自 android-architecture-blueprints 的示例

关于Android MVVM 架构组件 : How do I update a single data entity from a list fragment?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48671257/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com