Android数据绑定:属性更改时视图不更新

unftdfkk  于 2023-09-28  发布在  Android
关注(0)|答案(7)|浏览(149)

让我先从展示代码开始:
build.gradle(module):

android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
dataBinding {
    enabled = true
}
defaultConfig {
    applicationId "com.example.oryaa.basecalculator"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.google.android.gms:play-services-appindexing:8.1.0'

activity_main.xml:

<data>
    <import type="android.view.View" />
    <variable
        name="baseCalcModel"
        type="com.example.oryaa.basecalculator.BaseCalcModel">
    </variable>
</data>  <TextView
        android:id="@+id/resultOutput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/resultTextView"
        android:textColor="@color/DarkBlue"
        android:text="@{baseCalcModel.calcResult}"
        android:textSize="32dp" />

网址:MainActicity.java

public class MainActivity extends AppCompatActivity {

EditText userInput = null;
TextView resultTV = null;
Spinner fromBaseSpinner = null;
Spinner toBaseSpinner = null;
ArrayList<String> spinnerArray = new ArrayList<>();
String _allowedChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String _onlyOnceChar = "-+*/";
BaseCalcModel baseCalcModel = new BaseCalcModel();

/**
 * ATTENTION: This was auto-generated to implement the App Indexing API.
 * See https://g.co/AppIndexing/AndroidStudio for more information.
 */
private GoogleApiClient client;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setBaseCalcModel(this.baseCalcModel);
    this.resultTV = (TextView) this.findViewById(R.id.resultOutput);
    this.fromBaseSpinner = (Spinner) findViewById(R.id.fromBaseSpinner);
    this.toBaseSpinner = (Spinner) findViewById(R.id.toBaseSpinner);
    this.userInput = (EditText) findViewById(R.id.userInput);
    SetupUI();
    baseCalcModel.setCalcResult("test");

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}

网址:BaseCalcModel.java

ublic class BaseCalcModel extends BaseObservable {

public String calcResult;
public BaseView firstNumView;
public BaseView secondNumView;
public BaseView resultNumView;
public int firstNumBase;
public int secondNumBase;
public int resultNumBase;
public String error;

@Bindable
String getCalcResult() {
    return calcResult;
}

@Bindable
public BaseView getFirstNumView() {
    return firstNumView;
}

@Bindable
public BaseView getSecondNumView() {
    return secondNumView;
}

@Bindable
public BaseView getResultNumView() {
    return this.resultNumView;
}

@Bindable
public int getFirstNumBase() {
    return this.firstNumBase;
}

@Bindable
public int getSecondNumBase() {
    return this.secondNumBase;
}

@Bindable
public int getResultNumBase() {
    return this.resultNumBase;
}

@Bindable
public String getError() {
    return this.error;
}

public void setCalcResult(String calcResult) {
    this.calcResult = calcResult;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.calcResult);
}

public void setFirstNumView(BaseView firstNumView) {
    this.firstNumView = firstNumView;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.firstNumView);
}

public void setSecondNumView(BaseView secondNumView) {
    this.secondNumView = secondNumView;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.secondNumView);
}

public void setResultNumView(BaseView resultNumView) {
    this.resultNumView = resultNumView;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.resultNumView);
}

public void setFirstNumBase(int firstNumBase) {
    this.firstNumBase = firstNumBase;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.firstNumBase);
}

public void setSecondNumBase(int secondNumBase) {
    this.secondNumBase = secondNumBase;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.secondNumBase);
}

public void setResultNumBase(int resultNumBase) {
    this.resultNumBase = resultNumBase;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.resultNumBase);
}

public void setError(String error) {
    this.error = error;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.error);
}

public BaseCalcModel() {
    firstNumView = new BaseView();
    secondNumView = new BaseView();
    resultNumView = new BaseView();
    firstNumBase = 0;
    secondNumBase = 0;
    resultNumBase = 0;
    calcResult = "";
    error = "";
}

public BaseCalcModel(BaseView firstNumView, BaseView secondNumView, BaseView resultNumView,
                     int firstNumBase, int secondNumBase, int resultNumBase, String clcResult,
                     String error) {
    this.firstNumView = firstNumView;
    this.secondNumView = secondNumView;
    this.resultNumView = resultNumView;
    this.firstNumBase = firstNumBase;
    this.secondNumBase = secondNumBase;
    this.resultNumBase = resultNumBase;
    this.calcResult = clcResult;
    this.error = error;
}

我试图做简单的数据绑定,但我的看法不更新后,proparty是改变。正如你在图片中看到的,我的代码到达:

notifyPropertyChanged(com.example.oryaa.basecalculator.BR.calcResult);

但只有当应用程序启动时,或者当我将手机从垂直旋转到水平时,视图才会更新,反之亦然。
我的问题在哪里?
多谢了,还是雅各布

xuo3flqw

xuo3flqw1#

如果您在使用LiveData时遇到此问题,您可能忘记设置绑定的生命周期所有者; binding.setLifecycleOwner(lifecycleOwner)

mrphzbgm

mrphzbgm2#

当我需要在事件后刷新视图时,我遇到了类似的问题,我的变量对象不可观察,所以我添加了这个:

binding?.invalidateAll()

我希望能帮上忙。

1szpjjfi

1szpjjfi3#

你需要调用executePendingBindings()来立即更新视图中的绑定值:
当变量或可观察变化时,绑定将被调度为在下一帧之前改变。但是,有时绑定必须立即执行。要强制执行,请使用executePendingBindings()方法。
有关详细信息,请参阅Advanced Binding章节

yzckvree

yzckvree4#

我也有同样的问题。显然,这是一个单一的线,一直造成的问题。您所要做的就是将licycleowner设置为binding

binding.lifecycleOwner = this
bprjcwpo

bprjcwpo5#

在我的情况下,我忘记了setContentView(binding.root)。我使用ResultReceiver作为Activity类的子类。在安装documentation之后,我最终得到了这个:

class MyActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener, ServiceConnection {

    lateinit var txtV     : TextView
    lateinit var binding  : MyActivityBinding
    lateinit var receiver : MyResultReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = MyActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)                           // <--
        receiver = MyResultReceiver(Handler(), binding)
        ...
    }

    class MyResultReceiver(handler: Handler?, binding : MyActivityBinding) : ResultReceiver(handler) {
        private var mBinding = binding
        override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
            mBinding.txtV.append("\n${resultData?.getString("theTag")}")
        }
    }
}
gxwragnw

gxwragnw6#

  • 将模型类字段设置为私有。
  • 更改getCalcResult()应该是公共的。
  • BaseView应扩展BaseObservable
  • 如果不动态更改模型值。然后你不需要让每个访问器都是@Bindable。你可以把它去掉。并删除notifyPropertyChanged()。相反,如果您需要动态更改模型值,则使用@Bindable属性。

你可以走了。

public class BaseCalcModel extends BaseObservable {
    private String calcResult;
    private BaseView firstNumView;
    private BaseView secondNumView;
    private BaseView resultNumView;
    private int firstNumBase;
    private int secondNumBase;
    private int resultNumBase;
    private String error;

    public String getCalcResult() {
        return calcResult;
    }

    public void setCalcResult(String calcResult) {
        this.calcResult = calcResult;
    }

    public BaseView getFirstNumView() {
        return firstNumView;
    }

    public void setFirstNumView(BaseView firstNumView) {
        this.firstNumView = firstNumView;
    }

    public BaseView getSecondNumView() {
        return secondNumView;
    }

    public void setSecondNumView(BaseView secondNumView) {
        this.secondNumView = secondNumView;
    }

    public BaseView getResultNumView() {
        return resultNumView;
    }

    public void setResultNumView(BaseView resultNumView) {
        this.resultNumView = resultNumView;
    }

    public int getFirstNumBase() {
        return firstNumBase;
    }

    public void setFirstNumBase(int firstNumBase) {
        this.firstNumBase = firstNumBase;
    }

    public int getSecondNumBase() {
        return secondNumBase;
    }

    public void setSecondNumBase(int secondNumBase) {
        this.secondNumBase = secondNumBase;
    }

    public int getResultNumBase() {
        return resultNumBase;
    }

    public void setResultNumBase(int resultNumBase) {
        this.resultNumBase = resultNumBase;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }
}
vkc1a9a2

vkc1a9a27#

请确保在数据绑定不起作用时更新the same object fieldThe object's instance必须相同才能更新UI。也许我的回答对某些人有帮助,享受编码!

相关问题