Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog

编程入门 行业动态 更新时间:2024-10-26 18:25:25

Android MVVM<a href=https://www.elefans.com/category/jswz/34/1770644.html style=框架搭建(八)高德地图定位、天气查询、BottomSheetDialog"/>

Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog

Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog

  • 前言
  • 正文
    • 一、集成SDK
    • 二、基础配置
      • ① 权限配置
      • ② 配置Key
    • 三、显示地图
      • ① MapFragment
      • ② Navigation绑定
      • ③ Fragment中地图生命周期绑定
    • 四、显示当前所在地
      • ① 定位动态权限申请
      • ② 地图定位当前所在地
    • 五、获取详细的地址信息
    • 六、获取天气数据
    • 七、显示天气数据
      • ① 实时天气数据
      • ② 天气弹窗布局
      • ③ BottomSheetDialog使用
    • 八、源码

前言

  在上一篇文章中完成了对个人用户信息的修改,同时讲述了对弹窗数据的处理,权限的使用,本文将在App中接入一个地图SDK,同时完成天气的查询,完成后的效果如下图所示:

正文

  实际上地图和天气我在之前的好天气App上都写过了,那个上面写的就比较多了,也比较复杂了,在这里第一个是为了丰富MVVM的使用场景,同时满足在Fragment中使用地图的需要,第三个就是底部弹窗与MVVM的结合。

可以扫描二维码下载体验一下:

一、集成SDK

  本文中将会使用地图,这里我选择使用高德地图,需要去集成SDK,首先需要登录高德开放平台去注册,创建应用,获取key,由于之前写过这样的文章,因此不用再重复了,不了解的可以看看Android 高德地图API,看完步骤一,拿到了key就可以了,没有问题再回来本文。

点击提交就会有一个key了。

点击下载SDK,对SDK进行选择,如下图所示:

点击下载,到本地之后解压,如下图所示:

将这些文件复制到你的项目的libs下,如下图所示:

现在这个SDK还没有集成的,你只是放到了项目中,打开app模块下的build.gradle,在android{}闭包下添加如下代码:

	defaultConfig {ndk {//设置支持的SO库架构abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"}}sourceSets {main {jniLibs.srcDirs = ['libs']}}

如下图所示:

然后在dependencies{}闭包下添加如下代码:

	//加载lib下的jar文件implementation fileTree(include: '*.jar', dir: 'libs')

添加位置如下:这行代码老版本的AS是自带的,后面新版本的没有了。

然后点击右上角的Sync Now,进行依赖库下载配置同步,此时你的jar包可以展开了,就说明SDK集成成功了。

二、基础配置

  SDK已经引入,要使用还需要进行一些配置,首先是权限配置。

① 权限配置

在AndroidManifest.xml下新增如下权限:

	<!--允许获取粗略位置--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!--允许获取精准位置--><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><!--允许获取wifi状态改变,用于网络定位--><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

其他的所需权限,在之前写相应功能的时候都已经添加好了,因此就不用重复添加了,添加位置如下图所示:

下面配置Key

② 配置Key

然后配置高德地图Key,在application标签内

		<!--高德地图Key--><meta-dataandroid:name="com.amap.api.v2.apikey"android:value="597d296d723c5adb7165b732bc6f831e"/>

添加位置如下图所示:

现在来说,前期的准备工作就差不多了,下面就要去实现地图显示和定位了。

三、显示地图

  我们让地图显示在HomeActivity上,因此我们需要创建一个MapFragment去加载地图,一些读者只看到我用Activity加载过地图,换到Fragment上就不会用了,我很心痛啊。痛定思痛之后,我决定在Fragment上演示一下地图怎么操作,当然这是很简单的,我也会慢慢提高难度,你准备好了吗?

① MapFragment

首先在fragment包下新建一个MapFragment,对应的布局是map_fragment.xml,布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android=""xmlns:tools=""><FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ui.fragment.MapFragment"><com.amap.api.maps.MapViewandroid:id="@+id/map_view"android:layout_width="match_parent"android:layout_height="match_parent"/></FrameLayout>
</layout>

很简单,就一个地图。下面回到MapFragment,里面的代码如下:

public class MapFragment extends BaseFragment {private MapFragmentBinding binding;public static MapFragment newInstance() {return new MapFragment();}@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {binding = DataBindingUtil.inflate(inflater,R.layout.map_fragment,container,false);return binding.getRoot();}@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);// TODO: Use the ViewModel}}

这里只是简单的继承了一下BaseFragment,然后就是DataBinding的绑定。

② Navigation绑定

然后我们需要在nav_graph.xml中添加这个布局。

	<!--地图--><fragmentandroid:id="@+id/map_fragment"android:name="com.llw.mvvm.ui.fragment.MapFragment"android:label="map_fragment"tools:layout="@layout/map_fragment" />

  这里配置了,那么底部的菜单同样要配置,毕竟我们是通过菜单去控制Fragment的切换的,打开navigation_menu.xml,在里面添加一个item,代码如下:

	<itemandroid:id="@+id/map_fragment"android:icon="@mipmap/ic_map"android:title="地图" />

这个图标可以去我的源码里面去找,或者自己去网上找一个也行。

下面进入到HomeActivity中去配置,配置切换菜单时的Fragment布局改变,如下图所示:

③ Fragment中地图生命周期绑定

要显示地图需要将地图的生命周期与Fragment的生命周期绑定起来,如下图所示:

如果你是线上的项目你需要在隐私政策中引入高德SDK的说明,然后在MapFragment中绑定地图的生命周期。

	@Overridepublic void onSaveInstanceState(@NonNull @NotNull Bundle outState) {super.onSaveInstanceState(outState);binding.mapView.onSaveInstanceState(outState);}@Overridepublic void onResume() {super.onResume();binding.mapView.onResume();}@Overridepublic void onPause() {super.onPause();binding.mapView.onPause();}@Overridepublic void onDestroy() {super.onDestroy();binding.mapView.onDestroy();}

下面运行一下:


现在只是显示了地图,但是并没有定位到我当前所在地,这当然是不行的。

四、显示当前所在地

  显示当前所在地则需要定位权限,之前在AndroidManifest.xml中已经配置好了,下面则需要在代码中动态请求。

① 定位动态权限申请

在上一篇文章中写过一个PermissionUtils类,这里给这个类再加一点东西进去,在PermissionUtils中增加如下代码:

	public static final String LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;public static final int REQUEST_LOCATION_CODE = 1003;

然后在getPermissionRequestCode方法中增加一个case,如下图所示:

下面就是在HomeActivity中请求动态权限了,在HomeActivity中新增如下方法:

	/*** 请求定位权限*/private void requestLocation() {if (isAndroid6()) {if (!hasPermission(PermissionUtils.LOCATION)) {requestPermission(PermissionUtils.LOCATION);}} else {showMsg("您无需动态请求权限");}}

然后在initView方法中调用它,如下图所示:

② 地图定位当前所在地

下面回到MapFragment,新增如下代码:

	private static final String TAG = MapFragment.class.getSimpleName();/*** 初始化地图*/private void initMap() {//初始化地图控制器对象AMap aMap = binding.mapView.getMap();// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是falseaMap.setMyLocationEnabled(true);MyLocationStyle style = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。style.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且将视角移动到地图中心点。aMap.setMyLocationStyle(style);//设置定位蓝点的StyleaMap.getUiSettings().setMyLocationButtonEnabled(true);//设置默认定位按钮是否显示,非必需设置。aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。//设置SDK 自带定位消息监听aMap.setOnMyLocationChangeListener(this);}@Overridepublic void onMyLocationChange(Location location) {// 定位回调监听if(location != null) {Log.e(TAG, "onMyLocationChange 定位成功, lat: " + location.getLatitude() + " lon: " + location.getLongitude());} else {Log.e(TAG, "定位失败");}}

实现位置监听

调用initMap()

运行一下

五、获取详细的地址信息

  通过地图定位的方式定位在了当前所在地,但是onMyLocationChange的location中只有当前所在地的经纬度,如果我们需要拿到详细的地址信息要怎么做呢?通过SearchSDK实现,通过逆地理编码来将坐标转换成详细的地址。依然是在MapFragment,继承GeocodeSearch.OnGeocodeSearchListener,实现两个回调方法。代码如下:

	/*** 坐标转地址*/@Overridepublic void onRegeocodeSearched(RegeocodeResult regeocodeResult, int rCode) {}/*** 地址转坐标*/@Overridepublic void onGeocodeSearched(GeocodeResult geocodeResult, int rCode) {}

然后这个也需要初始化,代码如下:

	//解析成功标识码private static final int PARSE_SUCCESS_CODE = 1000;private GeocodeSearch geocoderSearch = null;private String district = null;// 区/县

下面写一个方法初始化搜索

	/*** 初始化搜索*/private void initSearch() {try {geocoderSearch = new GeocodeSearch(requireActivity());geocoderSearch.setOnGeocodeSearchListener(this);} catch (AMapException e) {e.printStackTrace();}}

调用的地方如下图:

当收位置信息改变时,进行坐标的搜索,在onMyLocationChange中添加如下代码:

			//创建一个经纬度点,参数一是纬度,参数二是经度LatLonPoint latLonPoint = new LatLonPoint(location.getLatitude(), location.getLongitude());// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 20, GeocodeSearch.AMAP);//通过经纬度获取地址信息geocoderSearch.getFromLocationAsyn(query);

添加位置如下:

  然后就会触发onRegeocodeSearched的回调,在onRegeocodeSearched中则对所在地的信息进行打印和简单的区/县赋值,在onRegeocodeSearched方法中添加如下代码:

		//解析result获取地址描述信息if (rCode == PARSE_SUCCESS_CODE) {RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();//显示解析后的地址Log.e(TAG, "地址: " + regeocodeAddress.getFormatAddress());district = regeocodeAddress.getDistrict();Log.e(TAG, "区: " + district);} else {showMsg("获取地址失败");}

添加位置如下:

下面运行一下:

这样就拿到了详细的位置信息。

六、获取天气数据

  高德是自带了天气数据接口的,可以用,只不过数据不是很多,如果需要更多的数据的话可以自己去对接天气API,例如和风、彩云。
在MapFragment创建变量

	private LocalWeatherLive liveResult;private LocalWeatherForecast forecastResult;

然后MapFragment继承WeatherSearch.OnWeatherSearchListener,实现两个方法。

	/*** 实时天气返回*/@Overridepublic void onWeatherLiveSearched(LocalWeatherLiveResult localWeatherLiveResult, int code) {liveResult = localWeatherLiveResult.getLiveResult();if (liveResult != null) {Log.e(TAG, "onWeatherLiveSearched: " + new Gson().toJson(liveResult));} else {showMsg("实时天气数据为空");}}/*** 天气预报返回*/@Overridepublic void onWeatherForecastSearched(LocalWeatherForecastResult localWeatherForecastResult, int code) {forecastResult = localWeatherForecastResult.getForecastResult();if (forecastResult != null) {Log.e(TAG, "onWeatherForecastSearched: " + new Gson().toJson(forecastResult));} else {showMsg("天气预报数据为空");}}

在方法回调中打印一下返回的数据,然后写一个搜索天气的方法,根据传入不同的天气类型,进行不同的天气数据搜索,代码如下:

	/*** 搜索天气** @param type WEATHER_TYPE_LIVE 实时天气   WEATHER_TYPE_FORECAST  预报天气*/private void searchWeather(int type) {WeatherSearchQuery weatherSearchQuery = new WeatherSearchQuery(district, type);try {WeatherSearch weatherSearch = new WeatherSearch(requireActivity());weatherSearch.setOnWeatherSearchListener(this);weatherSearch.setQuery(weatherSearchQuery);weatherSearch.searchWeatherAsyn(); //异步搜索} catch (AMapException e) {e.printStackTrace();}}

最后在onRegeocodeSearched中,拿到地址信息时调用searchWeather方法,代码如下:

			//搜索天气  实时天气和预报天气searchWeather(WeatherSearchQuery.WEATHER_TYPE_LIVE);searchWeather(WeatherSearchQuery.WEATHER_TYPE_FORECAST);

添加位置如下:


下面运行一下,查看日志,天气的数据就有了

七、显示天气数据

  有了天气数据之后就是显示天气数据了,这里我们可以这么做,就是在MapFragment中添加一个浮动按钮,点击之后从屏幕底部弹出一个,先来修改一下map_fragment中的代码,我们增加一个浮动按钮。

	<com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:id="@+id/fab_weather"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="end|bottom"android:layout_margin="20dp"android:visibility="gone"android:contentDescription="天气"android:src="@mipmap/ic_weather"app:backgroundTint="@color/white"app:fabSize="auto"tools:ignore="UsingOnClickInXml" />

添加的位置就如下图所示:

  这里我先把这个按钮给隐藏了,当地图上获取了当前的位置,查询到了天气之后再显示这个按钮。下面回到MapFragment中,在initMap方法中增加一行代码,

		//修改放大缩小按钮的位置aMap.getUiSettings().setZoomPosition(AMapOptions.ZOOM_POSITION_RIGHT_CENTER);

这样做就是让我们的浮动按钮不至于挡住这个地图的放大缩小按钮。

在MapFragment中添加一个变量

	//天气预报列表private List<LocalDayWeatherForecast> weatherForecast;

然后在onWeatherForecastSearched回调中对找个变量赋值,这才是实际的天气数据

查询到天气预报数据后,显示这个按钮。

① 实时天气数据

  现在已经可以看到所在地的天气了,当需要显示出来的时候你会发现找个数据里面是没有所在地的区/县的,只有省和市。因此在model包下新建一个LiveWeather,把我们在通过你地理编码返回时的区/县的值放进去,代码如下:

public class LiveWeather {private String district;private LocalWeatherLive localWeatherLive;public LiveWeather(String district, LocalWeatherLive localWeatherLive) {this.district = district;this.localWeatherLive = localWeatherLive;}public String getDistrict() {return district;}public void setDistrict(String district) {this.district = district;}public LocalWeatherLive getLocalWeatherLive() {return localWeatherLive;}public void setLocalWeatherLive(LocalWeatherLive localWeatherLive) {this.localWeatherLive = localWeatherLive;}
}

这个数据将会绑定到我们的天气弹窗,现在来创建这个弹窗的布局。

② 天气弹窗布局

  弹窗布局分为两个环节,一个是实时天气,一个是预报天气。首先colors.xml创建一个颜色值,如下:

	<color name="translucent">#90000000</color>

然后在drawable下创建一个shape_translucent_radius_12.xml样式文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android=""><corners android:radius="12dp"/><solid android:color="@color/translucent"/>
</shape>

下面创建弹窗的布局,在layout下新建一个dialog_weather.xml,里面的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android=""><data><variablename="liveWeather"type="com.llw.mvvm.model.LiveWeather" /></data><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#00000000"android:orientation="vertical"android:paddingStart="12dp"android:paddingEnd="12dp"android:paddingBottom="?attr/actionBarSize"><TextViewandroid:id="@+id/tv_city"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="12dp"android:background="@drawable/shape_translucent_radius_12"android:gravity="center"android:padding="12dp"android:text="@{liveWeather.district}"android:textColor="@color/white"android:textSize="28sp" /><TextViewandroid:id="@+id/tv_weather"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@+id/tv_report_time"android:layout_below="@+id/tv_city"android:layout_alignParentStart="true"android:layout_marginEnd="12dp"android:layout_marginBottom="12dp"android:background="@drawable/shape_translucent_radius_12"android:gravity="center"android:padding="12dp"android:text="@{liveWeather.localWeatherLive.weather}"android:textColor="@color/white"android:textSize="24sp" /><LinearLayoutandroid:id="@+id/wind_lay"android:layout_width="wrap_content"android:layout_height="44dp"android:layout_below="@+id/tv_city"android:layout_toStartOf="@+id/tv_temp"android:layout_toEndOf="@+id/tv_weather"android:background="@drawable/shape_translucent_radius_12"android:gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_wind_direction"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="12dp"android:text="@{liveWeather.localWeatherLive.windDirection+`风`}"android:textColor="@color/white" /><TextViewandroid:id="@+id/tv_wind_power"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="12dp"android:text="@{liveWeather.localWeatherLive.windPower+`级`}"android:textColor="@color/white" /></LinearLayout><LinearLayoutandroid:id="@+id/humidity_lay"android:layout_width="wrap_content"android:layout_height="44dp"android:layout_below="@+id/wind_lay"android:layout_marginTop="12dp"android:layout_toStartOf="@+id/tv_temp"android:layout_toEndOf="@+id/tv_weather"android:background="@drawable/shape_translucent_radius_12"android:gravity="center"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="24dp"android:text="湿度"android:textColor="@color/white" /><TextViewandroid:id="@+id/tv_humidity"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{liveWeather.localWeatherLive.humidity+`%`}"android:textColor="@color/white" /></LinearLayout><TextViewandroid:id="@+id/tv_temp"android:layout_width="100dp"android:layout_height="100dp"android:layout_below="@+id/tv_city"android:layout_alignParentEnd="true"android:layout_marginStart="12dp"android:layout_marginBottom="12dp"android:background="@drawable/shape_translucent_radius_12"android:gravity="center"android:padding="12dp"android:text="@{liveWeather.localWeatherLive.temperature+`℃`}"android:textColor="@color/white"android:textSize="32sp" /><TextViewandroid:id="@+id/tv_report_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/tv_temp"android:background="@drawable/shape_translucent_radius_12"android:gravity="center"android:padding="12dp"android:text="@{liveWeather.localWeatherLive.reportTime+`发布`}"android:textColor="@color/white" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_forecast"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/tv_report_time"android:layout_marginTop="12dp" /></RelativeLayout>
</layout>

有列表就有对应的item布局,在layout下创建item_forecast.xml布局,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android=""><data><variablename="forecast"type="com.amap.api.services.weather.LocalDayWeatherForecast" /><!--引入一个工具类--><import type="com.llw.mvvm.utils.EasyDate" /></data><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="12dp"android:background="@drawable/shape_translucent_radius_12"android:padding="12dp"><TextViewandroid:id="@+id/tv_date"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{forecast.date}"android:textColor="@color/white" /><TextViewandroid:id="@+id/tv_week"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="12dp"android:layout_toEndOf="@+id/tv_date"android:text="@{EasyDate.getWeek(forecast.date)}"android:textColor="@color/white" /><TextViewandroid:id="@+id/tv_temp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentEnd="true"android:text="@{forecast.dayTemp+`° /`+ forecast.nightTemp+`°`}"android:textColor="@color/white" /></RelativeLayout>
</layout>

  这里我引入的数据源是高德的,同时我还插入了一个工具类,这个工具类用于对日期进行处理,可以直接在xml中调用,例如将2021-12-22,转换成星期三。

布局都写好了,下面在themes.xml中增加一个样式,代码如下:

	<style name="BottomSheetDialogStyle_Light" parent="Theme.Design.BottomSheetDialog"><item name="android:windowFrame">@null</item><item name="android:windowIsFloating">true</item><item name="android:windowIsTranslucent">true</item><item name="android:background">@android:color/transparent</item><item name="android:backgroundDimEnabled">false</item></style>

这表示底部弹窗出现是不会使我们的屏幕变暗。

③ BottomSheetDialog使用

在写之前,我们先写一个ForecastAdapter,这是天气预报的列表适配器,在adapter包下创建它,代码如下:

public class ForecastAdapter extends BaseQuickAdapter<LocalDayWeatherForecast, BaseDataBindingHolder<ItemForecastBinding>> {public ForecastAdapter(@Nullable List<LocalDayWeatherForecast> data) {super(R.layout.item_forecast, data);}@Overrideprotected void convert(@NotNull BaseDataBindingHolder<ItemForecastBinding> bindingHolder, LocalDayWeatherForecast localDayWeatherForecast) {ItemForecastBinding binding = bindingHolder.getDataBinding();if (binding != null) {binding.setForecast(localDayWeatherForecast);binding.executePendingBindings();}}
}

下面在MapFragment中添加一个方法,代码如下:

	/*** 显示天气弹窗*/private void showWeatherDialog() {//隐藏浮动按钮binding.fabWeather.hide();BottomSheetDialog dialog = new BottomSheetDialog(requireActivity(), R.style.BottomSheetDialogStyle_Light);DialogWeatherBinding weatherBinding = DataBindingUtil.inflate(LayoutInflater.from(requireActivity()), R.layout.dialog_weather, null, false);//设置数据源weatherBinding.setLiveWeather(new LiveWeather(district,liveResult));//配置天气预报列表ForecastAdapter forecastAdapter = new ForecastAdapter(weatherForecast);weatherBinding.rvForecast.setLayoutManager(new LinearLayoutManager(requireActivity()));weatherBinding.rvForecast.setAdapter(forecastAdapter);dialog.setContentView(weatherBinding.getRoot());dialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundColor(Color.TRANSPARENT);//弹窗关闭时显示浮动按钮dialog.setOnDismissListener(dialog1 -> binding.fabWeather.show());dialog.show();}

  当点击浮动按钮的时候就会出现这个弹窗,出现弹窗后就隐藏浮动按钮,然后我们对弹窗的样式进行了修改,同时绑定数据,设置数据到xml中,在再配置列表数据和适配器,最后是设置背景透明,以及弹窗消失时显示浮动按钮。

最后在onActivityCreated的方法中进行浮动按钮的点击事件处理,代码如下:

		//点击按钮显示天气弹窗binding.fabWeather.setOnClickListener(v -> showWeatherDialog());


下面来运行一下:

效果就是这个样子,应该是比较的明显了。

八、源码

GitHub:MVVM-Demo
CSDN: MVVMDemo_8.rar

更多推荐

Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog

本文发布于:2023-07-03 14:18:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1007567.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:框架   天气   地图   Android   MVVM

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!