我正在建造一个使用两张桌子的健身追踪器。一个是Workout_Container,可以有多个动作。接下来是Movements表,其中包含实际移动(名称,重量,百分比等)。每个表都作为唯一键字段(_id),但Movement有一个Workout_Container的_id字段,因为这是一个关系数据库。因此,对于Workout Container的一个记录,它可以在Movement表中有多个条目。
架构是:
Main(_id INTEGER PRIMARY KEY AUTOINCREMENT, Workout_Date TEXT)
Workout_Container (_id INTEGER PRIMARY KEY AUTOINCREMENT, Date_ID INTEGER, AMRAP INTEGER, Rounds INTEGER, Finish_Time TEXT, Rounds_Finished INTEGER, IsWeight_Workout TEXT, Workout_Name TEXT, Comments TEXT).
Movement_Template (_id INTEGER PRIMARY KEY AUTOINCREMENT, Workout_Container_ID INTEGER, Sets INTEGER, Reps INTEGER, Movement TEXT, Time_of_Movement TEXT, Length INTEGER, Weight INTEGER, Percentage INTEGER, Comments TEXT).
主要是 Workout_Container 的父级,他是锻炼模板的父级。我只关心最后两张表作为第一张(虽然看似多余)在其他地方用于显示日历,我想要一张较小的表格,以便我查询某一天是否存在锻炼。
在视觉上,这看起来类似于List适配器,但是以分层方式,因为Workout Container将是其下面列出的任何Movements的父级。 Workout容器在视觉上与Movements ....不同......看起来像这样......这意味着getView需要知道要加载的特定.xml格式。
Workout Container (_id = 45)
===============
*Movement 1 (movement with Container_id = 45)*
*Movement 2 (movement with Container_id = 45)*
*Movement 3 (movement with Container_id = 45)*
Workout Container (_id = 46)
==============
*Movement 1 (movement with Container_id = 46)*
*Movement 2 (movement with Container_id = 46)*
View
(Adapter
或CursorAdapter
)给出的每一行都是MergeAdapter
。用户可以选择这些行并对其进行编辑或删除。是的,我将有一个添加行的功能,但尚未到达那里。现在,我在Cursor
查询中合并两个表,抓取当天Workout_Container中的所有行,以及Movement中与通过JOIN在Workout_Container中抓取的行对应的所有行。但这让我合并了两个表并且在一个CursorAdapter
中,我无法分辨我是否应该显示一个Workout_Container .xml或一个Movement .xml,因为我不知道过去的那一行我在getView中显示行时显示。上面的示例将在查询中返回5行,其中Workout Container _id = 45在Cursor
中被复制3次,而Workout_Container _id = 46信息在Cursor
中重复2次。
我的问题是:我将如何展示这个?
选项1:我应该将两个表合并到一个光标视图中吗?如果是这样,那么我如何知道要输出哪个视图,因为可以为多个记录复制锻炼容器信息,我不能回头查看该行以确定是否必须显示新的锻炼容器? CursorAdapter
每行需要一个唯一的ID号,并且我可能不会拥有它,因为这两个表的每个_id都是独立的。
选项2:使用合并适配器,抓取当天锻炼容器的单行,并将每行放在自己的光标中。然后获取与给定Workout Container _id相对应的每个Movement的一行,并将其移动到其自己的Cursor中。将每个Cursor作为自己的MergeAdapter
加入CursorAdapter
。我基本上会有一个CursorAdapters
数组,只有一行。基本上是通过一个嵌套的循环,它会在它穿过时抓住游标。这会是一次重大的性能打击,因为我可能会在CursorAdapters
内打开一些MergeAdapter
吗?
选项3:创建一个复制每个表的类,并将一行倒入一个类数组中,然后生成一组类,然后将这些类发送到MergeAdapter
。这似乎是最困难的,因为我必须覆盖CursorAdapter
已经处理过的更多项目。
现在,我在一个片段中的AsyncTask
内的AsyncTask
内一次性抓取Workout_Container和Movements中所有相关行,隐藏其唯一的工作是Activity
项目。并将其交回AsyncTask
。我是否需要将每行{{1}}移到适配器上,一次创建一个视图,而不是整行光标并通过它?
我希望这一切都有意义,因为我一直在绞尽脑汁,唯一似乎很容易的事情就是选项2 ....我搜索并没有发现任何有助于这种特定情况的东西。
答案 0 :(得分:2)
我将如何显示此内容?
我会使用选项#2,#3或#4。
选项#4:使用ExpandableListView
,它似乎具有您想要的UI,增加了用户扩展和折叠的能力,是否显示特定锻炼的动作。
由于我可能在MergeAdapter中打开了许多CursorAdapter,这会对性能造成重大影响吗?
不是从显示的角度来看。加载数据会有点昂贵,因为你要进行N + 1个查询:一个用于锻炼,一个用于锻炼的每组动作。
您可以通过创建覆盖CursorWindowAdapter
,getCount()
以及其他内容的moveToPosition()
来改善这一点,以使其“适应”Cursor
的子集(开始位置和行数#)。然后你只需要两个查询:一个用于锻炼,一个用于所有动作,后者通过锻炼排序。然后,您将浏览一下Cursor
移动,为每个锻炼的一组动作构建CursorWindowAdapter
个实例。我不知道创建一个可靠的CursorWindowAdapter
是多么容易或多么困难。而且,如果您的数据集较小,您可能会在没有它的情况下逃脱。
这似乎是最困难的,因为我必须覆盖CursorAdapter已经处理的更多项目。
更大的问题是:您打算如何处理超越在此列表中显示的数据?如果您的整体预期用途更适合应用于POJO而不是Cursor
条目,那么将您的数据集转换为合适的POJO树可能是值得的。不要孤立地考虑显示列表问题。
我是否需要将AsyncTask的每一行都移交给适配器,一次创建一个视图,而不是整行的Cursor并通过它?
这是MergeAdapter
方案的另一种方式:您必须等到所有查询完成,然后在{{{{}}中构建MergeAdapter
1}}。 onPostExecute()
的一大限制是,一旦将其附加到MergeAdapter
,就无法为其添加更多适配器/视图。