我正在开发android studio。我正在使用fragments来制作应用程序工作流程。该应用程序基本上是用于订单接收的。一个客户可以有多个订单。因此,我使用了RecyclerView。下面是我的GUI
"我想做什么"
我想更新我的Total Qty
和Order Value
,这样每当用户输入数量时,edittexts
都应该被更新。例如,在上面的图像中,我搜索了一个产品,它的价格是287.30,当我输入数量5时,然后是Total Qty: 5
和Order Value: 287.30
。在这之后,我选择另一个产品并输入其数量8,然后两个编辑文本都应该更新,如Total Qty: 13
和Order Value: 509.15
,当我删除任何产品时,它应该减去总数量和订单值。Total Qty:
和Order Value:
在我的主片段中。
片段布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/products"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:focusable="true" />
</LinearLayout>
<LinearLayout
android:id="@+id/product_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10sp"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_product">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total Qty:" />
<EditText
android:id="@+id/total_qty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_horizontal"
android:hint=""
android:inputType="number" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Order Value :" />
<EditText
android:id="@+id/order_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_horizontal"
android:hint=""
android:inputType="none" />
</LinearLayout>
</LinearLayout>
片段代码
// created getter setters
public EditText totalQty,totalOrder;
public EditText getTotalQty(){
return totalQty;
}
public void setTotalQty(EditText et){
this.totalQty = et;
}
public EditText getTotalOrder(){return totalOrder;}
public void setTotalOrder(EditText ett){this.totalOrder=ett;}
addProduct.setOnClickListener(v -> {
mProducts.add(new ProductDetail());
mProductsAdapter.setProducts(mProducts);
productsRecyclerView.smoothScrollToPosition(mProducts.size() - 1);
});
产品布局
<AutoCompleteTextView
android:id="@+id/tv_product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10sp"
android:gravity="start"
android:hint="Enter Product"
android:inputType="text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/product_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10sp"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_product">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:orientation="vertical">
<EditText
android:id="@+id/prod_qty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="left"
android:hint="Enter Quantity"
android:inputType="number" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:orientation="vertical">
<EditText
android:id="@+id/prod_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="left"
android:hint="Prod Price"
android:inputType="numberDecimal" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:orientation="vertical">
<EditText
android:id="@+id/prod_specs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="left"
android:hint="Prod Specs"
android:inputType="none" />
</LinearLayout>
</LinearLayout>
<Button
android:id="@+id/btn_rmv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:text="Remove Product"
android:textColor="@color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/product_infos" />
产品适配器
View productView = inflater.inflate(R.layout.product_layout, parent, false);
ProductViewHolder viewHolder = new ProductViewHolder(productView);
viewHolder.tvProduct.setAdapter(prodAdapter);
viewHolder.tvProduct.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
@Override
public void afterTextChanged(Editable s) {
mProductManager = new ProductManager(context);
int position = viewHolder.getAdapterPosition();
if (position != -1) {
ProductDetail productDetail = mProductManager.getProductByPrdName(s.toString());
mProducts.get(position).setProductNameFull(s.toString());
viewHolder.price.setText(productDetail.getPrice());
viewHolder.spec.setText(productDetail.getProductSpec());
viewHolder.pgrp.setText(productDetail.getProductGroup());
viewHolder.ccode.setText(productDetail.getCompanyCode());
viewHolder.cname.setText(productDetail.getCompanyName());
viewHolder.pcode.setText(productDetail.getProductCode());
}
}
});
viewHolder.quantity.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
int position = viewHolder.getAdapterPosition();
if (position != -1) {
Integer val = null;
try {
val = Integer.valueOf(s.toString());
} catch (Exception e) {
}
mProducts.get(position).setQuantity(val);
}
}
});
viewHolder.removeBtn.setOnClickListener(v -> {
int position = viewHolder.getAdapterPosition();
if (position != -1) {
mProducts.remove(position);
notifyItemRemoved(position);
}
});
return viewHolder;
更新1
下面是我的Fragment Class
public class SurveyFormFragment extends Fragment {
.
.
.
.
private final LiveData<Integer> mQuantity = new MutableLiveData<>(0);
private final LiveData<Integer> mOrderValue = new MutableLiveData<>(0);
private ViewModel mViewModel;
private FragmentBinding mBinding;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d("myfragment", "onCreateView");
getActivity().setTitle(getString(R.string.title_new_survey));
mContext = getActivity();
if (view == null) {
view = inflater.inflate(R.layout.new_survey_form_layout, container, false);
mLinearLayout = view.findViewById(R.id.ll_prod);
this.initElements(view);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
this.initListeners(getActivity());
}
Bundle arguments = getArguments();
if (arguments != null && arguments.containsKey("booking_id")) {
isNewSurvey = false;
initSurveyData(arguments.getString("booking_id"));
this.updatingSurveyId = arguments.getString("booking_id");
}
}
Log.d("package", getActivity().getPackageName());
Log.d(TAG, Common.getCarrierName(getActivity()));
return view;
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("myfragment", "onActivityCreated");
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
Log.d("myfragment", "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("myfragment", "onDestroy");
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
//save now
savedInstanceState.putString("faisal_qayyum", consumerNameEditText.getText().toString());
super.onSaveInstanceState(savedInstanceState);
Log.d("myfragment", "onSaveInstanceState saving " + consumerNameEditText.getText().toString());
}
@Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
//restore now
Log.d("myfragment", "onViewStateRestored");
}
.
.
.
.
}
错误
如何添加并更新这些值?
任何帮助都将不胜感激。
5条答案
按热度按时间azpvetkf1#
我会让你失望的不分享代码。我会分享你一个简单的图形,你需要做什么。
Fragment
】:显示您的订单列表。当事件被触发时(用户点击或更改了某些内容),将此事件转发到ViewModel。同时 Observes 用于ViewModel数据state。ViewModel
】:公开了一系列函数来监听用户事件(例如,用户点击了这个订单,或者用户将这个订单的数量更改为NN,等等)。还提供了一个LiveData
(或者Flow
),其中包含了你的Fragment所需要的State和Data。甚至可能会与数据来源的仓库(你在持久化或后端中保存订单的地方)进行对话。相互作用:
当UI修改了 something 时,你告诉viewModel:“这个数据改变了,订单X,现在有一个数量Y”。ViewModel将处理这个,更新屏幕的
State
,并通过Fragment观察到的Livedata/Flow
发送新数据。当Fragment接收到这个新数据时,它将相应地更新UI,因为这是它最重要的工作。这整件事已经大大documented in the official Android recommended architecture guides。我建议你从那里开始,而不是试图打击框架,使你的生活更加复杂。
inb24sb22#
实现适配器和片段之间的接口,就像这样(这只是sodu告诉你必须如何实现东西,你也必须检查它如何实现接口
和适配器类中
像这样你可以减去数量以及对项目的删除
5ssjco0h3#
实际上,它与
LiveData
等交互作用有关。但是,我没有编写大量代码,而是简单地将runnable传递给查尔兹,以便在某些思想发生变化时调用它:)
例如:
gajydyqb4#
您应该使用LiveData和DataBinding
为此,您需要在build.gradle文件中激活它:
然后添加以下代码。
添加ViewModel类:
在您的fragment类中添加以下内容:
将此添加到您的产品布局:
这是你的片段布局:
请注意,在这两个类中,您需要从活动中获取视图模型,而不是从片段本身中获取视图模型,因此您可以为这两个类共享相同的视图模型:
如果您只从UI线程中获取LiveData对象的值(在我的代码中就是这种情况,因为LiveData的onChange和绑定更新总是从UI线程中调用的),您不需要同步ViewModel中的列表。否则,您需要使整个故事线程安全。
tktrz96b5#
很容易理解,当更改文本字段中的值时,您需要采取行动。因此,第一件事是添加一个TextChangeListener或TextWatcher。然后,您必须处理接收到的文本值,以更新其余的依赖项:你的产品清单什么的。
只有一些基本的事情你需要照顾:
1.如果您正在使用片段通信,请通过在片段或Activity的onResume中重新加载来传播更改。或者,您可以使用EventBus或任何其他合适的机制。
1.确保在更改底层数据后通知适配器。我看到在代码mProducts.get(position).setQuantity(瓦尔)后有一个“notify**”调用;产品适配器中缺少。修改基础数据时,必须使用“notify**”调用通知适配器以更新回收程序视图。
1.您在上面发布的MutableLiveData错误可以通过MutableLiveData声明来清除,例如在您的示例中,private final MutableLiveData mutableData = new MutableLiveData(0)。您可以使用一个函数来只返回LiveData,如LiveData getData(){ return mutableData;}