Android Room - 汇总值并将其放入 TextView
Android Room - Sum up values and put it in TextView
也许这个问题有点愚蠢,但我就是坚持这个:
我有我的房间数据库 + 实体 + 道。
实体有一个名为 "costs" 的列 - 所以基本上我想总结所有成本(当然在跟踪是否有新输入时,所以检查总和是否已更改 - 如果是,当然更改 value/textview) 然后简单地将带有 .toString() 的值放入 TextView。
我已经有一个带有适配器/ViewModel/存储库的 RecyclerView+CardView Class(他们只将输入的名称放入 CardView)
我只是不知道把成本的东西放在哪里 - 我不认为我需要一个新的 ViewModel/Repository 但是我应该把 Dao 的 sumAllCost() 方法放在哪里
public class SubRepository {
private SubDAO mSubDao;
private LiveData<List<Sub>> mAllSubs;
SubRepository(Application application){
SubDatabase db = SubDatabase.getInstance(application);
mSubDao = db.getsubDAO();
mAllSubs = mSubDao.getAllSubs();
}
public LiveData<List<Sub>> getAllSubs(){
return mAllSubs;
}
public void insert (Sub sub){
new insertAsyncTask(mSubDao).execute(sub);
}
private static class insertAsyncTask extends AsyncTask<Sub, Void, Void> {
private SubDAO mAsyncTaskDao;
insertAsyncTask (SubDAO dao){
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Sub... params){
mAsyncTaskDao.addSub(params[0]);
return null;
}
}
}
public class SubViewModel extends AndroidViewModel {
private SubRepository mRepository;
private LiveData<List<Sub>> mallSubs;
public SubViewModel (Application application) {
super (application);
mRepository = new SubRepository(application);
mallSubs = mRepository.getAllSubs();
}
public LiveData<List<Sub>> getAllSubs(){
return mallSubs;
}
public void insert (Sub sub){
mRepository.insert(sub);
}}
class HomeSubAdapter extends RecyclerView.Adapter<HomeSubAdapter.ViewHolder> {
List<Sub> subList;
Context context;
private final LayoutInflater mInflater;
public static FragmentManager fragmentManager;
HomeSubAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
//Just wanna show the name so only one tv
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView main_cv_dummy;
public ViewHolder(View itemView) {
super(itemView);
main_cv_dummy = itemView.findViewById(R.id.main_cv_dummy);
}
}
@Override
public HomeSubAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View subview = mInflater.inflate(R.layout.snippet_main_cardview, parent, false);
return new ViewHolder(subview);
}
@Override
public void onBindViewHolder (HomeSubAdapter.ViewHolder holder, final int position) {
if (subList!= null){
final Sub current = subList.get(position);
holder.main_cv_dummy.setText(current.getSubName());
holder.main_cv_dummy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Fragment currentFrag = ShowInfoFragment.newInstance(current);
//fragmentManager.beginTransaction().replace(R.id.compLayout, currentFrag).addToBackStack(null).commit();
Log.d("Clicking: ", current.getSubName() + " was clicked - Listener worked");
}
});
}
else {
holder.main_cv_dummy.setText("Create a new Sub!");
}
}
public void setSubs(List<Sub> subs){
this.subList = subs;
notifyDataSetChanged();
}
@Override
public int getItemCount(){
if(subList!=null){
return subList.size();
} else
{
return 0;
}
}
Activity和onCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Log.d(TAG, "onCreate: starting");
middle_vf = (ViewFlipper)findViewById(R.id.middle_vf);
tv_sum = (TextView) findViewById(R.id.tv_sumCosts);
mSubViewModel = ViewModelProviders.of(this).get(SubViewModel.class);
mSubViewModel.getAllSubs().observe(this, new Observer<List<Sub>>() {
@Override
public void onChanged(@Nullable List<Sub> subs) {
mAdapter.setSubs(subs);
}
});
fragmentManager = getSupportFragmentManager();
//Whenever screen is called - call for recycler view
mRecyclerView = (RecyclerView) findViewById(R.id.main_rv);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//give dummy-subs to Adapter to Recycler
mAdapter = new HomeSubAdapter(this);
mRecyclerView.setAdapter(mAdapter);
setupBottomNavigationView();
setupFAB();
}
我真的不确定整个 SUM 的事情
//Get all costs
@Query("SELECT SUM(costs) FROM subscriptions")
void getAllCosts();
//Get all subs
@Query("SELECT * FROM subscriptions")
LiveData<List<Sub>> getAllSubs();
也许有人可以提供帮助 - 我现在觉得很愚蠢抱歉!我已经多次搜索合适的解决方案,但我就是找不到对我有帮助(或我理解的)的东西
您应该为合成列提供一个别名(即使没有它也可以工作,但一般来说,像这样访问域聚合函数结果的列名会更容易):
SELECT SUM(costs) AS value FROM subscriptions
并且当查询预期 return 某些东西 void
(无)不能使用时,那应该是实际的 returned 数据类型;对于货币价值和 LiveData
,尝试 LiveData<BigDecimal>
。 documentation 也有一个相关的例子,可能会更详细地解释它。
也许这个问题有点愚蠢,但我就是坚持这个:
我有我的房间数据库 + 实体 + 道。
实体有一个名为 "costs" 的列 - 所以基本上我想总结所有成本(当然在跟踪是否有新输入时,所以检查总和是否已更改 - 如果是,当然更改 value/textview) 然后简单地将带有 .toString() 的值放入 TextView。
我已经有一个带有适配器/ViewModel/存储库的 RecyclerView+CardView Class(他们只将输入的名称放入 CardView)
我只是不知道把成本的东西放在哪里 - 我不认为我需要一个新的 ViewModel/Repository 但是我应该把 Dao 的 sumAllCost() 方法放在哪里
public class SubRepository {
private SubDAO mSubDao;
private LiveData<List<Sub>> mAllSubs;
SubRepository(Application application){
SubDatabase db = SubDatabase.getInstance(application);
mSubDao = db.getsubDAO();
mAllSubs = mSubDao.getAllSubs();
}
public LiveData<List<Sub>> getAllSubs(){
return mAllSubs;
}
public void insert (Sub sub){
new insertAsyncTask(mSubDao).execute(sub);
}
private static class insertAsyncTask extends AsyncTask<Sub, Void, Void> {
private SubDAO mAsyncTaskDao;
insertAsyncTask (SubDAO dao){
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Sub... params){
mAsyncTaskDao.addSub(params[0]);
return null;
}
}
}
public class SubViewModel extends AndroidViewModel {
private SubRepository mRepository;
private LiveData<List<Sub>> mallSubs;
public SubViewModel (Application application) {
super (application);
mRepository = new SubRepository(application);
mallSubs = mRepository.getAllSubs();
}
public LiveData<List<Sub>> getAllSubs(){
return mallSubs;
}
public void insert (Sub sub){
mRepository.insert(sub);
}}
class HomeSubAdapter extends RecyclerView.Adapter<HomeSubAdapter.ViewHolder> {
List<Sub> subList;
Context context;
private final LayoutInflater mInflater;
public static FragmentManager fragmentManager;
HomeSubAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
//Just wanna show the name so only one tv
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView main_cv_dummy;
public ViewHolder(View itemView) {
super(itemView);
main_cv_dummy = itemView.findViewById(R.id.main_cv_dummy);
}
}
@Override
public HomeSubAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View subview = mInflater.inflate(R.layout.snippet_main_cardview, parent, false);
return new ViewHolder(subview);
}
@Override
public void onBindViewHolder (HomeSubAdapter.ViewHolder holder, final int position) {
if (subList!= null){
final Sub current = subList.get(position);
holder.main_cv_dummy.setText(current.getSubName());
holder.main_cv_dummy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Fragment currentFrag = ShowInfoFragment.newInstance(current);
//fragmentManager.beginTransaction().replace(R.id.compLayout, currentFrag).addToBackStack(null).commit();
Log.d("Clicking: ", current.getSubName() + " was clicked - Listener worked");
}
});
}
else {
holder.main_cv_dummy.setText("Create a new Sub!");
}
}
public void setSubs(List<Sub> subs){
this.subList = subs;
notifyDataSetChanged();
}
@Override
public int getItemCount(){
if(subList!=null){
return subList.size();
} else
{
return 0;
}
}
Activity和onCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Log.d(TAG, "onCreate: starting");
middle_vf = (ViewFlipper)findViewById(R.id.middle_vf);
tv_sum = (TextView) findViewById(R.id.tv_sumCosts);
mSubViewModel = ViewModelProviders.of(this).get(SubViewModel.class);
mSubViewModel.getAllSubs().observe(this, new Observer<List<Sub>>() {
@Override
public void onChanged(@Nullable List<Sub> subs) {
mAdapter.setSubs(subs);
}
});
fragmentManager = getSupportFragmentManager();
//Whenever screen is called - call for recycler view
mRecyclerView = (RecyclerView) findViewById(R.id.main_rv);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//give dummy-subs to Adapter to Recycler
mAdapter = new HomeSubAdapter(this);
mRecyclerView.setAdapter(mAdapter);
setupBottomNavigationView();
setupFAB();
}
我真的不确定整个 SUM 的事情
//Get all costs
@Query("SELECT SUM(costs) FROM subscriptions")
void getAllCosts();
//Get all subs
@Query("SELECT * FROM subscriptions")
LiveData<List<Sub>> getAllSubs();
也许有人可以提供帮助 - 我现在觉得很愚蠢抱歉!我已经多次搜索合适的解决方案,但我就是找不到对我有帮助(或我理解的)的东西
您应该为合成列提供一个别名(即使没有它也可以工作,但一般来说,像这样访问域聚合函数结果的列名会更容易):
SELECT SUM(costs) AS value FROM subscriptions
并且当查询预期 return 某些东西 void
(无)不能使用时,那应该是实际的 returned 数据类型;对于货币价值和 LiveData
,尝试 LiveData<BigDecimal>
。 documentation 也有一个相关的例子,可能会更详细地解释它。