接着《ArcGIS for Android 例子Offline Editor (BETA)(四)》,要实现编辑状态下,长按屏幕,会显示在长按处一定范围内所有feature的popup信息,并且还可以进行修改。为了偷懒,我把其中的一个功能给去掉了,还有个功能,不知道怎么回事老出问题,希望能有人帮我解决下,谢谢。
去掉的功能:对相连表的编辑和更新。
出问题的功能:在对每个要素判断是否包含有Attachment 时,都返回没有(照抄例子中的方法也是一样),所以就无法完成增加Attachment 这个功能。
1 新建一个类:PopupForEditOffline,并声明相关变量,和构造函数:
private Activity mianActivity;
private MapView mapView;
private PopupContainer container;//保存popup的容器
private PopupDialog popupDialog;//显示的Popup的对话框
private ProgressDialog dialog;
private LinearLayout editorBarLocal;//编辑工具条的布局
private int count;//记录查询图层的个数
private int popupCount;//记录popup的个数
public PopupForEditOffline(Activity mianActivity, MapView mapView) {
this.mianActivity = mianActivity;
this.mapView = mapView;
}
2 其中的PopupDialog,为显示一个Dialog,用来显示所有的popup信息。跟现在FeatureLayer例子中的一样,定义如下:
//显示的Popup的对话框
class PopupDialog extends Dialog{
private PopupContainer container;
private Context context;
public PopupDialog(Context context,PopupContainer container) {
super(context);
this.container=container;
this.context=context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
LinearLayout line=new LinearLayout(context);
line.addView(container.getPopupContainerView(),
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
setContentView(line);
super.onCreate(savedInstanceState);
}
}
3 声明一个显示popup信息的方法:showDia,这个方法主要显示根据长按处一定范围内所有feature的popup信息,并显示编辑工具条。
/**
* 显示popupDialog
* @param x 长按处的x坐标
* @param y 长按处的y坐标
* @param tolerance 查询的容限
*/
public void showDia(float x,float y, int tolerance){
if(!mapView.isLoaded()){
return;
}
container=new PopupContainer(mapView);
count=0;
popupCount=0;
popupDialog=null;
if(dialog==null|| !dialog.isShowing()){
dialog=new ProgressDialog(mianActivity);
dialog.setMessage("正在查询。。。。");
dialog.show();
}
//得到所有图层
Layer[] layers= mapView.getLayers();
for(Layer layer :layers){
if (!layer.isInitialized() || !layer.isVisible()){
continue;//如果图层没有初始化,或者不可见,就跳过
}
if(layer instanceof FeatureLayer){
FeatureLayer fLayer=(FeatureLayer) layer;
//该图层具有popup信息
if(fLayer.getPopupInfos()!=null){
count++;
//进行查询
new RunQueryLocalFeatureLayerTask(x, y, tolerance)
.execute(fLayer);
}
}
}
}
4 其中RunQueryLocalFeatureLayerTask为一个异步方法,其作用为从每个图层中查询在长按处一定范围内的Feature。并将它们的popup加入到一个PopupContainer中,供显示。
要复写其中的doInBackground和onPostExecute方法。定义变量和构造函数如下:
private float x;
private float y;
private int tolerance;
private FeatureLayer localFeatureLayer;
public RunQueryLocalFeatureLayerTask(float x, float y, int tolerance) {
super();
this.x = x;
this.y = y;
this.tolerance = tolerance;
}
doInBackground 方法主要用来查询一个FeatureLayer中的在一定范围内所有的Feature,闭放到一个集合中,返回给onPostExecute方法,的代码如下:
@Override
protected List<Feature> doInBackground(FeatureLayer... params) {
for (FeatureLayer featureLayer : params) {
this.localFeatureLayer = featureLayer;
long[] ids = featureLayer.getFeatureIDs(x, y, tolerance);
if (ids != null && ids.length > 0) {
List<Feature> features = new ArrayList<Feature>();
for (long id : ids) {
Feature f = featureLayer.getFeature(id);
if (f == null)
continue;
features.add(f);
}
return features;
}
}
return null;
}
onPostExecute的方法,除了要显示所有的popup信息之外,还需要建立一个包含有取消,增加Attachment,保存,编辑,删除这个几个按钮的工具条,分别用来删除当前的选中的Feature,或者更新它们的属性信息。要素popup可以编辑,必须现将对应的popup设置可编辑,在编辑时,要设置成编辑状态才能编辑,对应的方法如下:
要素的删除,和要素的属性的更新,可以使用FeatureTable的如下方法:
onPostExecute的代码如下(其中在编辑按钮的事件中 判断当前feature是否包含Attachment,都返回不包含,不知道是什么原因,求各位大神解释啊!!!)
@Override
protected void onPostExecute(List<Feature> result) {
count--;
if(result==null || result.size()==0){
if(count==0&& dialog!=null && dialog.isShowing()){
dialog.dismiss();
}
return ;
}
for(Feature feature :result){
//得到这个Feature对应得Popup
Popup popup=localFeatureLayer.createPopup(mapView, 0, feature);
//将Popup加入到PopupContainer中
container.addPopup(popup);
popupCount++;
//当第一个popup被加入时,就开始构建编辑工具条
if(popupCount==1){
editorBarLocal=new LinearLayout(mianActivity);
//取消按钮
Button canclebtn= new Button(mianActivity);
canclebtn.setText("取消");
canclebtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(popupDialog!=null&& popupDialog.isShowing()){
popupDialog.dismiss();
}
}
});
editorBarLocal.addView(canclebtn);
//增加Attachment按钮
final Button addAchbtn=new Button(mianActivity);
addAchbtn.setText("添加Att");
addAchbtn.setEnabled(false);
addAchbtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent it=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
mianActivity.startActivityForResult(it, 0);
}
});
editorBarLocal.addView(addAchbtn);
//添加保存按钮
final Button savebtn=new Button(mianActivity);
savebtn.setText("保存");
savebtn.setEnabled(false);
savebtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//得到当前的Popup
Popup currentPopup= container.getCurrentPopup();
//得到对应的Feature
Feature f= currentPopup.getFeature();
//得到这个Feature的属性
Map<String, Object> atts= ((GdbFeature)f).getAttributes();
//得到被更新的书信
Map<String, Object> updateAtts=currentPopup.getUpdatedAttributes();
//移除Feature的属性中更新的记录的标记
for(String key :atts.keySet()){
//System.out.println(key+"::"+atts.get(key));
Field field= ((GdbFeature)f).getTable().getField(key);
if(!field.isEditable()){
if (key.equals("CREATED_USER")
|| key.equals("CREATED_DATE")
|| key.equals("LAST_EDITED_USER")
|| key.equals("LAST_EDITED_DATE")) {
atts.remove(key);
}
}
}
//进行属性的更新
for(Entry<String, Object> upEnt: updateAtts.entrySet()){
atts.put(upEnt.getKey(), upEnt.getValue());
}
Graphic g=new Graphic(f.getGeometry(), null, atts);
//进行更新
try {
//得到被更新Feature的ID
long updateID=f.getId();
((GdbFeature)f).getTable().updateFeature(updateID, g);
} catch (Exception e) {
e.printStackTrace();
}
if(popupDialog.isShowing()){
popupDialog.dismiss();
}
}
});
editorBarLocal.addView(savebtn);
//删除按钮
final Button delBtn=new Button(mianActivity);
delBtn.setText("删除");
delBtn.setEnabled(false);
delBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//得到要被删除Feature的ID
long delid= container.getCurrentPopup().getFeature().getId();
try {
((GdbFeature) container.getCurrentPopup().getFeature()).getTable().deleteFeature(delid);
} catch (TableException e) {
e.printStackTrace();
}
if(popupDialog.isShowing()){
popupDialog.dismiss();
}
}
});
editorBarLocal.addView(delBtn);
//编辑按钮
Button editbtn=new Button(mianActivity);
editbtn.setText("编辑");
editbtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//设置为编辑状态
container.getCurrentPopup().setEditMode(true);
//设置各个按钮的状态
savebtn.setEnabled(true);
delBtn.setEnabled(true);
//得到是否包含Attachment
GdbFeature f=(GdbFeature)container.getCurrentPopup().getFeature();
boolean exitAtt= ((GdbFeatureTable)f.getTable()).hasAttachments();
//为何这里exitAtt的值都为false,及时在有Attachments的Feature上,求解释!!!
addAchbtn.setEnabled(exitAtt);
}
});
editorBarLocal.addView(editbtn);
//将editorBarLocal加入到PopupContainer所包含的View中
container.getPopupContainerView().addView(editorBarLocal,0);
}
}
if(count==0 &&dialog!=null &&dialog.isShowing()){
dialog.dismiss();
popupDialog=new PopupDialog(mianActivity, container);
popupDialog.show();
}
}
5 完成1到4之后,就可以在OfflineEditorActivity中的MyTouchListener中重写长按事件的方法:
@Override
public void onLongPress(MotionEvent point) {
PopupForEditOffline popup=new PopupForEditOffline(OfflineEditorActivity.this, mMapView);
popup.showDia(point.getX(), point.getY(), 25);
}
6 运行结果如下: