android-fragments 如何在android studio中添加数量时更新edittext

6qftjkof  于 2022-11-14  发布在  Android
关注(0)|答案(5)|浏览(185)

我正在开发android studio。我正在使用fragments来制作应用程序工作流程。该应用程序基本上是用于订单接收的。一个客户可以有多个订单。因此,我使用了RecyclerView。下面是我的GUI

"我想做什么"
我想更新我的Total QtyOrder Value,这样每当用户输入数量时,edittexts都应该被更新。例如,在上面的图像中,我搜索了一个产品,它的价格是287.30,当我输入数量5时,然后是Total Qty: 5Order Value: 287.30。在这之后,我选择另一个产品并输入其数量8,然后两个编辑文本都应该更新,如Total Qty: 13Order 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");
}
 .
 .
 .
 .
}

错误

如何添加并更新这些值?
任何帮助都将不胜感激。

azpvetkf

azpvetkf1#

我会让你失望的不分享代码。我会分享你一个简单的图形,你需要做什么。

  • Fragment】:显示您的订单列表。当事件被触发时(用户点击或更改了某些内容),将此事件转发到ViewModel。同时 Observes 用于ViewModel数据state
  • ViewModel】:公开了一系列函数来监听用户事件(例如,用户点击了这个订单,或者用户将这个订单的数量更改为NN,等等)。还提供了一个LiveData(或者Flow),其中包含了你的Fragment所需要的StateData。甚至可能会与数据来源的仓库(你在持久化或后端中保存订单的地方)进行对话。

相互作用:

当UI修改了 something 时,你告诉viewModel:“这个数据改变了,订单X,现在有一个数量Y”。ViewModel将处理这个,更新屏幕的State,并通过Fragment观察到的Livedata/Flow发送新数据。当Fragment接收到这个新数据时,它将相应地更新UI,因为这是它最重要的工作。
这整件事已经大大documented in the official Android recommended architecture guides。我建议你从那里开始,而不是试图打击框架,使你的生活更加复杂。

inb24sb2

inb24sb22#

实现适配器和片段之间的接口,就像这样(这只是sodu告诉你必须如何实现东西,你也必须检查它如何实现接口

public frgment extends Fragment implements GetValueInterface{

in onCreate function{
int totalquantity;

call this after adapter initialization 
adapter.registergetValueInterface(this)

}

 
@Override Void setQuantity(Int _gotquantity){
_gotquantity+=_gotquantity;
totalquantityedittext.setText(_gotquantity,TextView.BufferType.EDITABLE)

}

}

和适配器类中

Adapter class
{

public GetValueInterface instance;

function registergetValueInterface(GetValueInterface obj){

instance=obj;

}

 //and in quantity edittext text watcher 

call instance.setQuantity(quanity)

}

像这样你可以减去数量以及对项目的删除

5ssjco0h

5ssjco0h3#

实际上,它与LiveData等交互作用有关。
但是,我没有编写大量代码,而是简单地将runnable传递给查尔兹,以便在某些思想发生变化时调用它:)
例如:

class Root{
   ...
   public void addItem(){
      ItemController cont = new ItemController(() -> updateSums());
      ...
   }

   public void updateSums(){
      //TODO
   }
}

class ItemController{
   Runnable updater;
   public ItemController(Runnable updater){
      this.updater = updater;
   }
   public void onSomethingChanged(){
      updater.run();
   }
}
gajydyqb

gajydyqb4#

您应该使用LiveDataDataBinding
为此,您需要在build.gradle文件中激活它:

android {
    ...
    buildFeatures {
        dataBinding true
    }
}

然后添加以下代码。
添加ViewModel类:

public class ViewModel extends AndroidViewModel
{
    private final MediatorLiveData<Integer> mTotalQuantity = new MediatorLiveData<>();
    private final MediatorLiveData<Integer> mTotalOrder = new MediatorLiveData<>();
    private final List<LiveData<Integer>> mOrders = new ArrayList<>();
    private final List<LiveData<Integer>> mQuantities = new ArrayList<>();

    public ViewModel(@NonNull Application application)
    {
        super(application);
        mTotalOrder.setValue(0);
        mTotalQuantity.setValue(0);
    }

    public LiveData<Integer> getTotal()
    {
        return mTotalOrder;
    }

    public LiveData<Integer> getQuantity()
    {
        return mTotalQuantity;
    }

    public void attachQuantity(LiveData<Integer> quantity)
    {
        mQuantities.add(quantity);
        mTotalQuantity.addSource(quantity, (q) -> calculateQuantities());
    }

    public void detachQuantity(LiveData<Integer> quantity)
    {
        mQuantities.remove(quantity);
        mTotalQuantity.removeSource(quantity);
        calculateQuantities();
    }

    private void calculateQuantities()
    {
        int total = 0;
        for (LiveData<Integer> quantity : mQuantities)
        {
            Integer value = quantity.getValue();
            if (value != null)
            {
                total += value;
            }
        }
        mTotalQuantity.setValue(total);
    }

    public void attachTotal(LiveData<Integer> total)
    {
        mOrders.add(total);
        mTotalOrder.addSource(total, (q) -> calculateOrders());
    }

    public void detachTotal(LiveData<Integer> total)
    {
        mOrders.remove(total);
        mTotalOrder.removeSource(total);
        calculateOrders();
    }

    private void calculateOrders()
    {
        int total = 0;
        for (LiveData<Integer> order : mOrders)
        {
            Integer value = order.getValue();
            if (value != null)
            {
                total += value;
            }
        }
        mTotalOrder.setValue(total);
    }
}

在您的fragment类中添加以下内容:

private LiveData<Integer> mQuantity = new MutableLiveData<>(0);
private LiveData<Integer> mOrderValue = new MutableLiveData<>(0);
private ViewModel mViewModel;
private FragmentBinding mBinding;

@Override
public void onCreate(@Nullable Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    mViewModel = new ViewModelProvider(requireActivity()).get(ViewModel.class);
    mViewModel.attachQuantity(mQuantity);
    mViewModel.attachTotal(mOrderValue);
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
    mBinding = DataBindingUtil.setContentView(this, R.layout.fragment);
    mBinding.quantity = mQuantity;
    mBinding.order_value = mOrderValue;
}

@Override
public void onDestroy()
{
    super.onDestroy();
    mViewModel.detachQuantity(mQuantity);
    mViewModel.detachTotal(mOrderValue);
}

将此添加到您的产品布局:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>

        <variable
            name="quantity"
            type="android.arch.lifecycle.MutableLiveData&lt;Integer&gt;" />

        <variable
            name="order_value"
            type="android.arch.lifecycle.MutableLiveData&lt;Integer&gt;" />
    </data>
            ...

            <EditText
                android:id="@+id/prod_qty"
                
                // This does the magic
                android:text="@{quantity}" />
            ...

            <EditText
                android:id="@+id/prod_price"
                
                // And this of course...
                android:text="@{order_value}" />
            ...
</layout>

这是你的片段布局:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>

        <variable
            name="viewmodel"
            type="yourpackage.ViewModel" />
    </data>
            ...

            <EditText
                android:id="@+id/total_qty"
                
                // This does the magic
                android:text="@{viewmodel.quantity}" />
            ...

            <EditText
                android:id="@+id/order_value"
                
                // And this of course..
                android:text="@{viewmodel.total}" />
            ...
</layout>

请注意,在这两个类中,您需要从活动中获取视图模型,而不是从片段本身中获取视图模型,因此您可以为这两个类共享相同的视图模型:

ViewModelProvider(requireActivity()).get(ViewModel.class);

如果您只从UI线程中获取LiveData对象的值(在我的代码中就是这种情况,因为LiveData的onChange和绑定更新总是从UI线程中调用的),您不需要同步ViewModel中的列表。否则,您需要使整个故事线程安全。

tktrz96b

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

相关问题