【问题标题】:listview refresh in android databindingandroid数据绑定中的listview刷新
【发布时间】:2017-05-11 07:17:54
【问题描述】:

我正在使用带有数据绑定概念的 android MVVM 架构的应用程序之一。

问题是当我更新 xml 的 textview 时,整个视图都会更新。所以 listview 会刷新并滚动到顶部位置。我想在 onItem 单击事件发生时限制 listview。

以下 xml 包含列表视图。

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

        <data>

            <variable
                name="kenoservicesVM"
                type="com.naushad.kenocustomer.landing.KenoServicesVM" />
            <variable
                name="kenoservice"
                type="com.naushad.kenocustomer.landing.KenoService" />

        </data>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/nliveo_transparent"
            android:paddingEnd="20sp"
            android:paddingStart="20sp">

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

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:paddingLeft="10dp"
                    android:paddingTop="10dp"
                    android:text="Total"
                    android:textColor="@color/white" />

                <ScrollView
                    android:id="@+id/SCROLLER_ID"
                    android:layout_width="fill_parent"
                    android:layout_height="160sp"
                    android:layout_margin="0sp"
                    android:background="@color/nliveo_transparent"
                    android:fillViewport="true"
                    android:scrollbars="none">

                    <ListView
                        android:id="@+id/lstServices"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
    android:onItemClick="@{kenoservicesVM::onItemClick}"
                        bind:items="@{kenoservicesVM.mList}">

                    </ListView>
                    <!--android:onItemClick="@{kenoservicesVM::onItemClick}"-->
                </ScrollView>
                >

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="horizontal"
                    android:weightSum="2">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:paddingLeft="10dp"
                        android:paddingTop="10dp"
                        android:text="Total"
                        android:textColor="@color/white" />

                    <TextView
                        android:id="@+id/totalCharges"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:gravity="right"
                        android:paddingRight="10dp"
                        android:paddingTop="10dp"

                        android:textColor="@color/white" />
                    <!--android:text="@{kenoservicesVM.totalPrice ?? @string/_0_aed}"-->

                </LinearLayout>

                <RelativeLayout
                    android:id="@+id/your_btn_id"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:id="@+id/bgNext"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_marginBottom="5dip"
                        android:layout_marginTop="15dip"
                        android:alpha="0.5"
                        android:src="@drawable/blue_round_light_bg" />

                    <Button
                        android:id="@+id/btn_add_card"
                        android:layout_width="fill_parent"
                        android:layout_height="40dp"
                        android:layout_marginBottom="5dip"
                        android:layout_marginTop="15dip"
                        android:background="@drawable/blue_next_bg" />
                </RelativeLayout>

            </LinearLayout>
        </FrameLayout>
    </layout>

下面的viewmodel类表示我在xml中使用的viewmodel。

public class KenoServicesVM extends BaseObservable {
    public ObservableArrayList<KenoService> mList = new ObservableArrayList<>();
    private Context mContext;
    @NonNull
    private String mTotalPrice;
    int selectedServiceCharges=0;
    private int bar;

    public ObservableField<String> price;
    Handler handler;

    public KenoServicesVM(List<KenoService> list, Context mContext) {
        mList.addAll(list);
        this.mContext = mContext;
    }

    @NonNull
    public String getTotalPrice() {
        return mTotalPrice;
    }

    public void setTotalPrice(@NonNull String totalPrice) {
        this.mTotalPrice = totalPrice;
//        notifyPropertyChanged(BR.kenoservicesVM);
//        notifyPropertyChanged(BR.totalPrice);
        notifyChange();
//        notifyPropertyChanged(BR.kenoservicesVM);
    }

    @BindingAdapter("bind:items")
    public static void bindList(ListView view, ObservableArrayList<KenoService> list) {
        CustomListAdapter adapter = new CustomListAdapter(list);
        view.setAdapter(adapter);
    }

    public void onItemClick(AdapterView<?> arg0, View arg1,
                            int position, long arg3) {
        if(position == 0) return;
        if(mList.get(position).getSelected())
            mList.get(position).setSelected(false);
        else
            mList.get(position).setSelected(true);


        for (int i=0 ;i<mList.size();i++){
            KenoService keno = mList.get(i);
            if(keno.getSelected())
                selectedServiceCharges +=Integer.parseInt(keno.getKenoServiceCharge());
        }
        /*handler =  new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        price = new ObservableField<>(selectedServiceCharges +" AED");
                    }
                });

            }
        };
        new Thread(runnable).start();*/

        setTotalPrice(selectedServiceCharges  +" AED");
//        dialogueServicesBinding.totalCharges.setText(selectedServiceCharges +" AED");

//        mTotalPrice = selectedServiceCharges +" AED";
//        ModuleManager.startActivity(ModuleManager.DISPATCH_MODULE, DispatchModule.STATE_FORGOTPASSWORD, (Activity) mContext);
    }
}

我是 android 数据绑定概念的新手。当我单击 listview 项并刷新视图时,请帮助我解决此问题。提前致谢。

【问题讨论】:

  • OnitemClickListener 具有 setTotalPrice() 方法,此方法调用 notifyChange()。因此,整个视图将被更新。请检查一次,如果您有任何想法,请告诉我。

标签: android android-layout data-binding android-alertdialog android-databinding


【解决方案1】:

您的属性需要使用Bindable

@NonNull
@Bindable
public String getTotalPrice() {
    return mTotalPrice;
}

这将创建BR.totalPrice 字段,您将可以调用

notifyPropertyChanged(BR.totalPrice);

文本应该随之更新

android:text="@{kenoservicesVM.totalPrice ?? @string/_0_aed}"

另外@NonNull 是一个你可能无法兑现的承诺。考虑添加一个默认值。

【讨论】:

    【解决方案2】:

    抱歉,由于声誉问题,我无法发表评论,但我之前遇到过类似问题之一,您可以在 setTotalPrice 方法中传递 mList 和位置,然后调用 notifyItemChanged 而不是 notifyChange,这样它只会更新列表中指定位置的项目

    public void setTotalPrice(@NonNull String totalPrice, int position, ObservableArrayList<KenoService> mList, TextView totalCharges) {
        this.mTotalPrice = totalPrice;
        mList.notifyItemChanged(position);
        totalCharges.setText(//whatever u need here);
        totalCharges.invalidate(); 
    }
    

    【讨论】:

    • 感谢您给予回复。listview 项目刷新效果很好,但我想在同一个 xml 中更新 listview 之外的 textview,所以当时它也正在更新。我想更新“总费用”textview .
    • 我已经更新了我的答案,希望它能满足你的需要,基本上当你调用 view.invalidate() 时,它会告诉视图用你绑定的新数据重新绘制自己。让我知道这是否有效:)
    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 2010-09-30
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    相关资源
    最近更新 更多