在Android开发中,如果需要实现导航功能,我们可能会用到百度地图或者高德地图提供的API,百度地图导航界面大致是这样:
界面上方是导航路线信息,中间是导航地图,底部是导航的菜单栏,包括关闭导航的按钮,旁边还有路况条。
但是有的时候这个默认的界面与我们的APP风格会有差异,或者我们可能需要自定义一个开关导航的按钮,有的控件可能不需要。这个时候我们就需要把原来的关闭按钮或者菜单栏都隐藏掉。但是百度地图并没有提供相关的API,所以这就需要我们自己解决了。
我的解决办法:
百度的导航界面是通过BNRouteGuideManager的onCreate()方法创建一个获取百度导航过程View对象,然后将这个View加入应用布局中即可显示导航过程。也就是说整个导航的显示界面就是靠这个View来显示。我们看到的所有控件都是这个View里面的。所以我们可以通过这个View来控制其中的控件是否显示。
简单的说就是得到我们需要隐藏的控件,然后再把其visible属性设置为false就OK了。
首先我们要得到这个View,这个很简单,在创建View的时候就可以获取。然后就是通过这个View去获取我们需要隐藏的控件。但是这些类都是封装在jar包里面的,百度也没有将这些控件放出来,并没有提供直接的办法让我们去访问。
不过我们可以通过View的getChildAt(int index)方法去访问它的子控件。所以只有我们知道控件的index,我们就能获取该控件,也就能控制它是否显示。但是问题来了,貌似我们看不到这些源码,也就不能直接找到控件的位置。不过我们可以试试通过反编译,看看能不能得到源码。
但是我觉得这个还是太麻烦了,所以想了一个办法,就是调试程序。
在调试的时候,我们是可以观察到变量的信息的,包括属性值。
比如像这样子:
mChildren是控件的名称,下面有12个子控件,包含ProgressBar、TextView等等。
不过其实我们也不知道具体哪个是我们需要隐藏的控件,所以我们需要找到疑似对象然后去验证,验证的方法就是得到这个控件,将它的visible设置为false,看看是否有效果。不过我们并不需要每一个都去尝试,比如说我们需要隐藏一个显示那个关闭按钮,那么它一般不可能是一个TextView,所以TextView就排除了。
下面是我测试的代码:
1. 先获取导航界面的View
FrameLayout mBDNavView = (FrameLayout) BNRouteGuideManager.getInstance().onCreate(this, new OnNavigationListener(){...}});
呃。。。为什么是定义的FrameLayout 呢?
因为调试的时候发现其实创建的这个导航的View是一个FrameLayout。
2. 找到对应的控件并隐藏
try {
ViewGroup viewGroup = (ViewGroup) mBDNavView.getChildAt(1);
ViewGroup vg = (ViewGroup) viewGroup.getChildAt(4);
ViewGroup vg2 = (ViewGroup) vg.getChildAt(1);
vg2.setVisibility(View.GONE);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
效果图:
原本的菜单栏神奇的消失了。。。
终于写完了,希望对大家有帮助。。。
等会再来一个高德地图。。。