iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android 天气APP(四)搭建MVP框架与使用
  • 377
分享到

Android 天气APP(四)搭建MVP框架与使用

appAndroid 2022-06-06 13:06:12 377人浏览 薄情痞子
摘要

上一篇:Android 天气APP(三)访问天气api与数据请求 MVP框架搭建与使用4. MVP框架搭建① 创建模块② 配置模块③ 创建Act

上一篇:Android 天气APP(三)访问天气api与数据请求

MVP框架搭建与使用4. MVP框架搭建① 创建模块② 配置模块③ 创建Activity管理④ 创建BaseApplication⑤ 创建KnifeKit⑥ 创建base包(以及包下的类和接口)⑦ 创建mvp包(以及包下的Activity和Fragment)⑧ 创建net包(封装OKHttp,重写CallBack)5. app使用MVP① 创建API管理服务接口ApiService② 订阅接口服务,处理API请求返回数据③ 继承mvplibrary中的BaseApplication④ 配置AndroidManifest.xml文件⑤ 编辑布局文件⑥ 天气查询(使用MVPActivity实现数据请求与数据渲染显示) 4. MVP框架搭建

现在这样固然符合网络请求的标准,结果也得到了,但是这只是一个接口而已,我们用了这么多代码,那假如这个页面上还有好几个接口要请求访问,岂不是多出了很多的重复代码,这一点并不符合现在Android的现状,所以需要封装OKHttp,通过架构或者框架来完成这一步,前期虽然麻烦一些,但是你一旦用习惯了,就停不下来了,接下来我尽量用人话来讲述这个搭建过程。
为了让你有一个清晰的思路,这里创建一个模块,里面搭建MVP框架。

① 创建模块

鼠标右键你的项目名,选择Module
在这里插入图片描述

接下来在AndroidManifest.xml文件中配置
在这里插入图片描述

现在你可以运行一下,看你的项目有没有问题,早出现问题早解决。

现在框架已经搭好了,不过页面布局还没有写好的,所以要写一下页面了。

⑤ 编辑布局文件

activity_main.xml


    
        
        
            
            
                
                
                
                
                

背景图

这样你的布局文件应该就没有报错的红线了。

然后看到MainActivity.java中的这个TextView报错,因为布局文件中已经去掉了这个TextView。

在这里插入图片描述
在这里插入图片描述删除即可

然后再绑定布局中控件

	@BindView(R.id.tv_info)
    TextView tvInfo;//天气状况
    @BindView(R.id.tv_temperature)
    TextView tvTemperature;//温度
    @BindView(R.id.tv_low_height)
    TextView tvLowHeight;//最高温和最低温
    @BindView(R.id.tv_city)
    TextView tvCity;//城市
    @BindView(R.id.tv_old_time)
    TextView tvOldTime;//最近更新时间
⑥ 天气查询(使用MVPActivity实现数据请求与数据渲染显示)

接下来进行使用MVP框架数据请求,删除getTodayWeather()方法。修改后的MainActivity代码如下所示

package com.llw.Goodweather;
import android.Manifest;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.alibaba.fastJSON.jsON;
import com.alibaba.fastjson.TypeReference;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.llw.goodweather.bean.TodayResponse;
import com.llw.goodweather.contract.WeatherContract;
import com.llw.goodweather.utils.ToastUtils;
import com.llw.mvplibrary.mvp.MvpActivity;
import com.tbruyelle.rxpermissions2.RxPermissions;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Response;
public class MainActivity extends MvpActivity implements WeatherContract.IWeatherView {
    @BindView(R.id.tv_info)
    TextView tvInfo;//天气状况
    @BindView(R.id.tv_temperature)
    TextView tvTemperature;//温度
    @BindView(R.id.tv_low_height)
    TextView tvLowHeight;//最高温和最低温
    @BindView(R.id.tv_city)
    TextView tvCity;//城市
    @BindView(R.id.tv_old_time)
    TextView tvOldTime;//最近更新时间
    private RxPermissions rxPermissions;//权限请求框架
    //定位器
    public LocationClient mLocationClient = null;
    private MyLocationListener myListener = new MyLocationListener();
    //数据初始化  主线程,onCreate方法可以删除了,把里面的代码移动这个initData下面
    @Override
    public void initData(Bundle savedInstanceState) {
        //因为这个框架里面已经放入了绑定,所以这行代码可以注释掉了。
        //ButterKnife.bind(this);
        rxPermissions = new RxPermissions(this);//实例化这个权限请求框架,否则会报错
        permissionVersion();//权限判断
    }
    //绑定布局文件
    @Override
    public int getLayoutId() {
        return R.layout.activity_main;
    }
    //绑定Presenter ,这里不绑定会报错
    @Override
    protected WeatherContract.WeatherPresenter createPresent() {
        return new WeatherContract.WeatherPresenter();
    }
    //权限判断
    private void permissionVersion() {
        if (Build.VERSION.SDK_INT >= 23) {//6.0或6.0以上
            //动态权限申请
            permissionsRequest();
        } else {//6.0以下
            //发现只要权限在AndroidManifest.xml中注册过,均会认为该权限granted  提示一下即可
            ToastUtils.showShortToast(this, "你的版本在Android6.0以下,不需要动态申请权限。");
        }
    }
    //动态权限申请
    private void permissionsRequest() {//使用这个框架需要制定jdk版本,建议用1.8
        rxPermissions.request(Manifest.permission.ACCESS_FINE_LOCATION)
                .subscribe(granted -> {
                    if (granted) {//申请成功
                        //得到权限之后开始定位
                        startLocation();
                    } else {//申请失败
                        ToastUtils.showShortToast(this, "权限未开启");
                    }
                });
    }
    //定位
    private void startLocation() {
        //声明LocationClient类
        mLocationClient = new LocationClient(this);
        //注册监听函数
        mLocationClient.reGISterLocationListener(myListener);
        LocationClientOption option = new LocationClientOption();
        //如果开发者需要获得当前点的地址信息,此处必须为true
        option.setIsNeedAddress(true);
        //可选,设置是否需要最新版本的地址信息。默认不需要,即参数为false
        option.setNeedNewVersionRGC(true);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
        mLocationClient.setLocOption(option);
        //启动定位
        mLocationClient.start();
    }
    
    private class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //获取区/县
            String district = location.getDistrict();
            //获取今天的天气数据
            mPresent.todayWeather(context,district);
        }
    }
    //查询当天天气,请求成功后的数据返回
    @Override
    public void getTodayWeatherResult(Response response) {
        //数据返回后关闭定位
        mLocationClient.stop();
        if (response.body().getHeWeather6().get(0).getBasic() != null) {//得到数据不为空则进行数据显示
            //数据渲染显示出来
            tvTemperature.setText(response.body().getHeWeather6().get(0).getNow().getTmp());//温度
            tvCity.setText(response.body().getHeWeather6().get(0).getBasic().getLocation());//城市
            tvInfo.setText(response.body().getHeWeather6().get(0).getNow().getCond_txt());//天气状况
            tvOldTime.setText("上次更新时间:" + response.body().getHeWeather6().get(0).getUpdate().getLoc());
        } else {
            ToastUtils.showShortToast(context, response.body().getHeWeather6().get(0).getStatus());
        }
    }
    //数据请求失败返回
    @Override
    public void getDataFailed() {
        ToastUtils.showShortToast(context,"网络异常");//这里的context是框架中封装好的,等同于this
    }
}

写完之后就可以直接运行了,运行效果图如下:
在这里插入图片描述
可以看到,已经得到天气数据了,只不过美中不足,上面的状态栏是原生的颜色,原谅绿,这个颜色不吉利啊。我们换一下。这个时候就可以用到透明状态栏,这种东西了,在utils包下新建一个StatusBarUtil工具
在这里插入图片描述
工具类代码如下:

package com.llw.goodweather.utils;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class StatusBarUtil {
    
    @TargetApi(19)
    public static void transparencyBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }
    
    public static void setStatusBarColor(Activity activity, int colorId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
//      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(activity.getResources().getColor(colorId));
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //使用SystemBarTint库使4.4版本状态栏变色,需要先将状态栏设置为透明
            transparencyBar(activity);
            SystemBarTintManager tintManager = new SystemBarTintManager(activity);
            tintManager.setStatusBarTintEnabled(true);
            tintManager.setStatusBarTintResource(colorId);
        }
    }
    
    public static int StatusBarLightMode(Activity activity) {
        int result = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (MIUISetStatusBarLightMode(activity, true)) {
                result = 1;
            } else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {
                result = 2;
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                result = 3;
            }
        }
        return result;
    }
    
    public static void StatusBarLightMode(Activity activity, int type) {
        if (type == 1) {
            MIUISetStatusBarLightMode(activity, true);
        } else if (type == 2) {
            FlymeSetStatusBarLightMode(activity.getWindow(), true);
        } else if (type == 3) {
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    }
    
    public static void StatusBarDarkMode(Activity activity, int type) {
        if (type == 1) {
            MIUISetStatusBarLightMode(activity, false);
        } else if (type == 2) {
            FlymeSetStatusBarLightMode(activity.getWindow(), false);
        } else if (type == 3) {
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
        }
    }
    
    public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
        boolean result = false;
        if (window != null) {
            try {
                WindowManager.LayoutParams lp = window.getAttributes();
                Field darkFlag = WindowManager.LayoutParams.class
                        .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class
                        .getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(lp);
                if (dark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                window.setAttributes(lp);
                result = true;
            } catch (Exception e) {
            }
        }
        return result;
    }
    
    public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
        boolean result = false;
        Window window = activity.getWindow();
        if (window != null) {
            Class clazz = window.getClass();
            try {
                int darkModeFlag = 0;
                Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if (dark) {
                    extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
                } else {
                    extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
                }
                result = true;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    //开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
                    if (dark) {
                        activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                    } else {
                        activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                    }
                }
            } catch (Exception e) {
            }
        }
        return result;
    }
}

接下来,在MainActivity.java中调用即可
在这里插入图片描述

StatusBarUtil.transparencyBar(context);//透明状态栏

然后再运行一下
在这里插入图片描述
不管怎么说,都比原谅绿好看。
现在查询当天的天气是可以了,但是都说是天气预报了,当然也要有啊,否则不就是骗人了吗?OK

下一篇:Android 天气APP(五)天气预报、生活指数的数据请求与渲染


作者:初学者-Study


--结束END--

本文标题: Android 天气APP(四)搭建MVP框架与使用

本文链接: https://www.lsjlt.com/news/29398.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android用kotlin搭建MVVM框架(一)
    Android用kotlin搭建MVVM框架(一) 什么是MVVM搭建MVVM框架 什么是MVVM Android的项目框架,大家应该都不陌生吧。而目前的项目框架有MVC,MVP,MVVM...
    99+
    2023-10-11
    android kotlin android studio
  • 安卓大作业:使用Android Studio开发天气预报APP(使用sqlite数据库)
    使用Android Studio开发天气预报APP 今天我来分享一下如何使用Android Studio开发一个天气预报APP。在文中,我们将使用第三方接口获取实时天气数据,并显示在APP界面上。 步...
    99+
    2023-09-27
    数据库 android studio sqlite python
  • hibernate框架怎么搭建和使用
    搭建和使用Hibernate框架可以按照以下步骤进行: 添加Hibernate依赖:在项目的构建文件中(如Maven的pom.x...
    99+
    2023-10-23
    hibernate
  • 如何使用Python3+mysql8.0搭建Django框架
    小编给大家分享一下如何使用Python3+mysql8.0搭建Django框架,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、安装python基础环境:cent...
    99+
    2023-06-15
  • 怎么用开源框架Matrix-Dendrite搭建聊天服务器
    这篇“怎么用开源框架Matrix-Dendrite搭建聊天服务器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用开源框架...
    99+
    2023-06-29
  • 持久层ORM框架Hibernate框架的使用及搭建方式
    目录前言一、Hibernate的优点?二、Hibernate的缺点三、搭建Hibernate项目架构四、Hibernate核心接口的介绍五、封装Hibernate的工具类六、常用的C...
    99+
    2024-04-02
  • 如何使用seajs库和Bootstrap框架搭建通用前端框架
    这篇文章主要介绍如何使用seajs库和Bootstrap框架搭建通用前端框架,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前端框架主要研究了四点1、 研究Web框架的动态加载技术针对...
    99+
    2024-04-02
  • 如何使用Maven搭建SpringMVC+Spring+MyBatis框架
    这篇文章主要介绍如何使用Maven搭建SpringMVC+Spring+MyBatis框架,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级...
    99+
    2023-05-30
    springmvc spring mybatis
  • Python - 【FastAPI】框架配置搭建基本使用
    一. 前言 之前在面试的时候面试官有提到过这个框架,但是个人在之前的项目中没有用到过,只是有听过,并没有实际的应用,因此,个人自己研究了一下,这是个新型的框架,使用起来相对挺简单。FastAPI是一个...
    99+
    2023-09-11
    python fastapi 数据库
  • java工作流框架怎么搭建及使用
    要搭建和使用Java工作流框架,可以按照以下步骤进行操作:1. 确定需求:首先,确定您的应用程序需要哪些工作流功能,例如流程定义、任...
    99+
    2023-10-19
    java
  • 如何使用SpringCloud搭建一个微服务框架
    这篇文章将为大家详细讲解有关如何使用SpringCloud搭建一个微服务框架,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Spring Cloud是一个基于Spring Boot实现的云应用...
    99+
    2023-05-30
    springcloud
  • 如何使用eclipse+maven一步步搭建SSM框架
    这篇文章将为大家详细讲解有关如何使用eclipse+maven一步步搭建SSM框架,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。SSM (SSM 框架集)SSM(Spring+SpringMVC+MyBa...
    99+
    2023-05-30
    eclipse maven ssm
  • C++ 函数指针与 Qt 框架:搭建灵活的 GUI 应用
    函数指针在 c++++ 和 qt 框架中的应用:函数指针允许将函数作为变量传递。qt 框架使用信号和槽机制,允许将函数指针分配给事件处理程序。可通过 connect() 函数将槽函数分配...
    99+
    2024-04-29
    c++ qt 点击事件
  • 使用gin框架搭建简易服务的实现方法
    go语言web框架挺多的,各有各的特点和风格。我之所以在项目中使用gin框架,是因为项目一开始是用的martini,一个设计得很好的框架,但是存在一个比较严重的问题,就是大量使用反射...
    99+
    2024-04-02
  • 如何使用Cmake来搭建跨平台的应用程序框架
    这篇文章主要介绍“如何使用Cmake来搭建跨平台的应用程序框架”,在日常操作中,相信很多人在如何使用Cmake来搭建跨平台的应用程序框架问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用Cmake来搭建跨...
    99+
    2023-06-15
  • .Net Core3.0 WebApi 项目框架搭建之使用Serilog替换掉Log4j
    为什么使用Serilog Serilog 是一个用于.NET应用程序的日志记录开源库,配置简单,接口干净,并可运行在最新的.NET平台上,与其他日志库不同, Serilog 是以功能...
    99+
    2024-04-02
  • 使用SpringMVC和MyBatis框架如何搭建一个开发环境
    本篇文章给大家分享的是有关使用SpringMVC和MyBatis框架如何搭建一个开发环境,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。下载SpringMVC框架架包,点击打开地...
    99+
    2023-05-31
    springmvc sprinmybatis 环境搭建
  • C++中如何使用Cmake来搭建跨平台的应用程序框架
    这篇文章主要介绍了C++中如何使用Cmake来搭建跨平台的应用程序框架,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。示例代码说明1. 功能描...
    99+
    2024-04-02
  • 你知道如何使用 ASP 搭建自然语言处理框架吗?
    ASP 是一种常见的网页编程语言,它可以用来搭建各种网站和应用程序。除此之外,ASP 还可以用于构建自然语言处理框架。本文将介绍如何使用 ASP 搭建自然语言处理框架,并且会穿插一些演示代码以方便读者理解。 一、什么是自然语言处理? 在介绍...
    99+
    2023-10-21
    自然语言处理 框架 索引
  • 如何使用 Laravel 框架搭建一个高效的大数据处理平台?
    Laravel是一种流行的PHP框架,它提供了一种高效的方式来构建Web应用程序。但是,Laravel不仅仅是一个Web框架。它还可以用于搭建大规模的数据处理平台。本文将介绍如何使用Laravel框架搭建一个高效的大数据处理平台。 一、安装...
    99+
    2023-09-09
    ide 大数据 laravel
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作