移动一张图专题分析
简介
[专题模块为整个项目中的重要组成部分,也是不可或缺之一。用户可通过专题信息查看其主要层级结构和内部构造划分。对主要层级可进行收藏展示,便于直观查看。可手动点击某一层级结构打开对应图层,查看详细信息。]
列表主要分为两种结构,一种为树状结构、一种为层级结构。以相同的数据模型展示不同的列表结构,便于用户选择。
逻辑
列表项包括三角号小图标、收藏按钮和点击开关的按钮。根据不同情境分别设置相应的展示状态。
- 当为树状结构时:首先初始化专题列表,通过Id展示最新列表。当点击Item项时,我们会记录专题的id,通过id找到子集列表数据,查看子集的type类型是否为“catalog”,如果是该类型,则会继续打开。直到我们点击Item项为“group”类型时,这时图层状态则不显示下一级别。 当我们点击开关状态时,获取子结点数据,将当前状态设置为打开,设置专题是否可见,根据id判断找到父级与子级,并更新整个专题的数据。当开关状态点击到“group”级别时,下一级别则是“layer”级别,图层状态则不显示下一级别。直接在图层上加载layer级别的数据。关闭时如果点击group级别的数据,则会直接关闭当前对应级别数据,父级状态为半开状态,如果关闭“catalog级则会将子级数据共同关闭,直到点击状态为“catalog”级别,对应“parentLayerId”=-1时,这时所有子级数据将全部关闭。
- 当为层级结构时:当我们点击开关状态时,记录当前id,并通过id找到对应子级的信息,清空当前数据,将最新数据更新到列表上。关闭时当”parentLayerId!=-1”时,列表下方有一个按钮提示返回上一级,当点击按钮时会找到上一级别数据,将当前级别数据清空,并将父级数据展示到列表上,更新适配器。
Windows平台/AndroidStudio开发环境
重要代码实现
1. 通过ID获取列表,projectId刚开始传入-1.显示根目录列表:
1 | public void replaceAndShowListById(Context context, String projectId, boolean isOnlyShow) { |
2. 列表Item的点击事件:
1 | public synchronized void clickItemResponse(Context context, int position) throws Exception { |
3. 开关按钮的点击事件:
public static void projectSwitch(Context context, Handler handler, List<ThemeInfo> themeInfoList, ThemeInfo info, TopicAdapter.ViewHolder finalHolder, boolean isGradedData) {
List<ThemeInfo> parents = new ArrayList<>();
TopicUtil.getAllParent(info, parents, themeInfoList, false);
List<ThemeInfo> childrens = new ArrayList<>();
TopicUtil.getAllChildren(info, childrens, themeInfoList, false);
String openStatus = info.getOpenStatus();
if (!openStatus.equals(Constants.TOPIC_STATUS_OFF)) {
finalHolder.isOpen.setImageResource(R.mipmap.topic_off);
info.setOpenStatus(Constants.TOPIC_STATUS_OFF);
TopicUtil.closeCurrentNode(info, themeInfoList, false);
} else {
finalHolder.isOpen.setImageResource(R.mipmap.topic_on);
info.setOpenStatus(Constants.TOPIC_STATUS_ON);
for (ThemeInfo node : childrens) {
node.setOpenStatus(Constants.TOPIC_STATUS_ON);
}
for (ThemeInfo node : parents) {
node.setOpenStatus(Constants.TOPIC_STATUS_ON);
}
}
if (JudgeNullUtil.ObjIsNull(info)) {
return;
}
TopicUtil.topicSwitchVisible(context, info, handler, isGradedData);
}
4.通过图层id显示专题图层:
/**
* 通过图层id显示专题图层。
*
* @param context 上下文
* @param visibleInfos 当前需要显示的图层
*/
public static void setLayerVisible(Context context, List<ThemeInfo> visibleInfos, String currentStatus) throws Exception {
if (JudgeNullUtil.ObjIsNull(visibleInfos)) {
return;
}
boolean isOpenLayer = false;
if (!currentStatus.equals(Constants.TOPIC_STATUS_OFF)) {
isOpenLayer = true;
}
if(App.isOnLineData){
onlineVisibleLayer(context, visibleInfos, isOpenLayer);
}else{
offlineVisibleLayer(visibleInfos,isOpenLayer);
}
}
5.更新专题数据:
/**
* 更新专题某一层级数据或整个专题数据源
*/
public static void updateThemeList(Context context, List<ThemeInfo> themeList) throws Exception {
App appCtx = (App) context.getApplicationContext();
appCtx.getDataSource().setTheme(themeList);
}
/**
* 更新子级目录专题数据
*/
public static List<ThemeInfo> updateSubData(ThemeInfo subThemeInfo, List<ThemeInfo> themeList) throws Exception {
if (subThemeInfo == null) {
return themeList;
}
String currentId = subThemeInfo.getId();
if (currentId == null || JudgeNullUtil.ObjIsNull(themeList)) {
return themeList;
}
List<String> subLayerIds = getSubLayerIds(currentId, themeList);
if (JudgeNullUtil.ObjIsNull(subLayerIds)) {
return themeList;
}
assert subLayerIds != null;
for (int i = 0; i < subLayerIds.size(); i++) {
String subId = subLayerIds.get(i);
subThemeInfo.setId(subId);
String type = getThemeType(subThemeInfo, themeList);
updateCurrentData(subThemeInfo, themeList);
if (type == null) {
continue;
}
if (type.equals(Constants.TYPE_CATLOG)) {
updateSubData(subThemeInfo, themeList);
}
}
return themeList;
}
6. 更新layer数据:
/**
* 设置layer显示状态
* @param layer专题图层
* @param visibleIds 图层id
*/
public static void updateLayerVisible(Layer layer, int[] visibleIds, boolean isOpenLayer) throws Exception {
if (layer == null) {
return;
}
if (layer instanceof ArcGISDynamicMapServiceLayer) {
ArcGISDynamicMapServiceLayer dynamicLayer = (ArcGISDynamicMapServiceLayer) layer;
refreshDynamicLayer(visibleIds, dynamicLayer, isOpenLayer);
} else {
layer.setVisible(isOpenLayer);
}
}
/**
* 根据visibleIds 更新DymicLayer
* @param visibleIds layer Ids
* @param dynamicLayer 当前需要刷新的图层
*/
private static void refreshDynamicLayer(int[] visibleIds, ArcGISDynamicMapServiceLayer dynamicLayer, boolean isOpenLayer) throws Exception {
if (dynamicLayer == null) {
return;
}
ArcGISLayerInfo[] arcGISLayerInfos = dynamicLayer.getAllLayers();
if (visibleIds.length > arcGISLayerInfos.length) {
return;
}
ArcGISLayerInfo layerInfo;
for (int index : visibleIds) {
if (index < 0) {
continue;
}
layerInfo = arcGISLayerInfos[index];
if (layerInfo == null) {
continue;
}
boolean isVisible = layerInfo.isVisible();
ArcGISLayerInfo layerParentInfo = layerInfo.getParentLayer();
if (layerParentInfo != null) {
boolean parentVisible = layerParentInfo.isVisible();
if (isOpenLayer) {
if (!parentVisible) {
layerParentInfo.setVisible(true);
}
} else {
if (parentVisible) {
layerParentInfo.setVisible(false);
}
}
}
if (isOpenLayer) {
if (!isVisible) {
layerInfo.setVisible(true);
}
} else {
if (isVisible) {
layerInfo.setVisible(false);
}
}
}
if (!dynamicLayer.isVisible()) {
dynamicLayer.setVisible(true);
}
dynamicLayer.refresh();
}
结语
专题模块的开发提高了项目的灵活性和通透性,大大缩短了用户点击搜索的时间,保证了多层级结构加载时层与层之间的联系不冲突,确保它们之间稳定性。查询时可通过坐标点查询多个图层所对应信息,大大缩短了查询效率,确保项目的顺利进行。为后期新功能迭代打下坚实基础,提高用户体验。