我正在开发一个简单的高尔夫计分应用程序,作为针对Android设备的学习练习。输入孔的分数后,我想在主显示屏上以弹出式窗口的形式显示进度分数,该主显示屏在recyclerview中显示每个孔的结果。回收器视图中的数据将按预期更新,但是,当弹出窗口显示时,总数落后一个洞。似乎在对数据库中的总和进行查询之前,已经完成了对具有新分数的数据库更新。
我已经阅读了有关Android开发人员的部分内容,并广泛搜索了类似的问题,并完成了许多教程,但似乎没有一种适合这种情况。我已经看到一个建议,将查询作为事务运行可能会有所帮助,但是我的努力没有任何作用。
在Dao中,存在以下几种查询类型
@Transaction
@Query("SELECT SUM(strokes) AS frontstrokes FROM score_table WHERE hole <= 9")
LiveData<Integer> getStrokesFront();
在ViewModel中,相应的代码为
public LiveData<Integer> getStrokesFront(){return strokesFront;}
存储库包含
public LiveData<Integer> getStrokesFront() {
return strokesFront;
}
在MainActivity的onCreate内
scoringViewModel.getStrokesFront().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
frontstrokes = integer;
}
});
在onActivityResult内部,我们(从得分输入活动返回后)
scoringViewModel.update(scoring);
Toast.makeText(this, "Score added", Toast.LENGTH_LONG).show();
loadData();
showProgress();
在showProgress中,我们有
LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.scoring_header, null);
((TextView) layout.findViewById(R.id.comp_name)).setText(comp);
((TextView) layout.findViewById(R.id.strokes_value)).setText(String.format("%d", frontstrokes));
我认为这是“定时”的原因是,如果我返回得分输入活动并且不进行任何更改,但再次按下保存,则总计更新现在是正确的。
以下内容确实出现在Logcat中
2019-06-05 14:30:13.906 31492-31492/org.ivanhoegc.ivanhoegolfscoringapp E/WindowManager: android.view.WindowLeaked: Activity org.ivanhoegc.ivanhoegolfscoringapp.MainActivity has leaked window android.widget.PopupWindow$PopupDecorView{3e7185f V.E...... R....... 0,0-800,570} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:627)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:377)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1573)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1339)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1305)
at org.ivanhoegc.ivanhoegolfscoringapp.MainActivity$override.showProgress(MainActivity.java:297)
at org.ivanhoegc.ivanhoegolfscoringapp.MainActivity$override.onActivityResult(MainActivity.java:208)
at org.ivanhoegc.ivanhoegolfscoringapp.MainActivity$override.access$dispatch(Unknown Source:92)
at org.ivanhoegc.ivanhoegolfscoringapp.MainActivity.onActivityResult(Unknown Source:39)
at android.app.Activity.dispatchActivityResult(Activity.java:8006)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4638)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4687)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1935)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7116)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:925)
编辑: 我一直在做一些调试工作。
这是我的弹出窗口的代码。
private void showProgress(){
LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.scoring_header, null);
float density = MainActivity.this.getResources().getDisplayMetrics().density;
final PopupWindow pw = new PopupWindow(layout, (int)density * 400, (int)density * 285,true);
pw.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
scoringViewModel = ViewModelProviders.of(this).get(ScoringViewModel.class);
scoringViewModel.getStrokesFront().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
frontstrokes = integer;
}
});
scoringViewModel.getPointsFront().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
frontpoints = integer;
}
});
scoringViewModel.getStrokesBack().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
backstrokes = integer;
}
});
scoringViewModel.getPointsBack().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
backpoints = integer;
}
});
scoringViewModel.getStrokesTotal().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
totalstrokes = integer;
}
});
scoringViewModel.getPointsTotal().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
totalpoints = integer;
}
});
((TextView) layout.findViewById(R.id.comp_name)).setText(comp);
((TextView) layout.findViewById(R.id.strokes_value)).setText(String.format("%d", frontstrokes));
((TextView) layout.findViewById(R.id.points_value)).setText(String.format("%d", frontpoints));
((TextView) layout.findViewById(R.id.bstrokes_value)).setText(String.format("%d", backstrokes));
((TextView) layout.findViewById(R.id.bpoints_value)).setText(String.format("%d", backpoints));
((TextView) layout.findViewById(R.id.rstrokes_value)).setText(String.format("%d", totalstrokes));
((TextView) layout.findViewById(R.id.rpoints_value)).setText(String.format("%d", totalpoints));
pw.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
pw.dismiss();
return true;
}
return false;
}
});
pw.setOutsideTouchable(true);
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
}
查看我要显示的值,直到显示弹出窗口后,它们才会更新。尽管新的个人得分和积分值已在弹出窗口下方的“回收者”视图中清晰显示,但这仍然没有问题。在setTouchInterceptor处的中断显示旧值,而在动作检查“ if语句”处的中断显示新值。重新排列先前代码的顺序不会影响结果。
有什么想法吗?