this.fxTime = fxTime;
}
public String getPrecip() {
return precip;
}
public void setPrecip(String precip) {
this.precip = precip;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
然后进入到ApiService中,准备添加API接口,这时我发现了一个问题,那就是和风的请求地址都变了
我记得这里之前是heweather。为什么现在改成了qweather。吓得我赶紧去运行一手,看我原来的地址还能不能访问,好在虚惊一场,原来的地址还能够访问,那么和风为什么要改请求地址呢。难道原来的地址会转到这个新的地址吗?我的猜测目前是这样的。
打开ServiceGenerator,而我要改动的也就只有这两处而已。
改成qweather即可。改完之后我运行了一下和之前也没有什么区别,看来这次的更新是很有必要的。不然到时候之前地址访问不了,肯定很多问题会出现的,估计要被叼。
下面在ApiService中添加新的接口。
/**
-
分钟级降水 最近两小时内
-
@param location 经纬度拼接字符串,使用英文逗号分隔,经度在前纬度在后
-
@return
*/
@GET(“/v7/minutely/5m?key=” + API_KEY)
Call getMinutePrec(@Query(“location”) String location);
从上面的API得知想要获取数据,就必须拿到经纬度。而获取经纬度有两种方式:① 通过百度定位获取。② 通过和风天气的城市搜索获取。
这里我们使用第二种方式来获取经纬度,那么就是在搜索城市的返回值中拿到经纬度之后去请求分钟级降水的的接口,获取数据之后显示出来。因此我这里先改变一下activity_main.xml。
增加的布局代码如下:
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginTop=“8dp”
android:paddingLeft=“20dp”
android:paddingRight=“20dp”>
<TextView
android:id=“@+id/tv_precipitation”
android:layout_width=“0dp”
android:layout_weight=“1”
android:layout_height=“wrap_content”
android:drawableLeft=“@mipmap/icon_weather_prec”
android:drawablePadding=“4dp”
android:text=“降水预告”
android:textColor=“@color/white”
android:textSize=“@dimen/sp_12” />
<TextView
android:gravity=“center_vertical”
android:id=“@+id/tv_prec_more”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“查看详情”
android:drawableRight=“@mipmap/icon_more_blue_small”
android:textColor=“@color/blue_more”
android:textSize=“@dimen/sp_12” />
<androidx.recyclerview.widget.RecyclerView
android:visibility=“gone”
android:paddingTop=“@dimen/dp_8”
android:id=“@+id/rv_prec_detail”
android:paddingLeft=“@dimen/dp_12”
android:paddingRight=“@dimen/dp_12”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”/>
<View
android:layout_width=“match_parent”
android:layout_height=“1dp”
android:layout_marginLeft=“20dp”
android:layout_marginTop=“8dp”
android:layout_marginRight=“20dp”
android:alpha=“0.1”
android:background=“@color/white” />
增加位置如下图所示
那么既然有列表自然也要有item了。所以在layout新建一个item_prec_detail_list.xml布局,里面的代码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:gravity=“center_horizontal”
android:paddingLeft=“@dimen/dp_8”
android:paddingRight=“@dimen/dp_8”
android:orientation=“vertical”>
<TextView
android:id=“@+id/tv_time”
android:layout_marginTop=“@dimen/dp_8”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“上午10:00”
android:textColor=“#FFF”
android:textSize=“@dimen/sp_12” />
<TextView
android:id=“@+id/tv_precip_info”
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:layout_marginTop=“@dimen/dp_8”
android:layout_marginBottom=“@dimen/dp_8”
android:gravity=“center”
android:text=“0.1 雨”
android:textColor=“#FFF”
android:textSize=“@dimen/sp_12” />
显示的地方有了下面就是要去MainActivity中实现具体的业务逻辑了。不过在此之前还需要增加一个方法。内容很简单,因为我之后要使用GridLayoutManager,同时也要让RecyclerView横向滚动,因此我设置高度为占满父布局高度。
有布局了,然后就是写列表的适配器了,不然数据怎么填充进去呢?在adapter包下新建一个MinutePrecAdapter,里面的代码如下:
package com.llw.goodweather.adapter;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodweather.R;
import com.llw.goodweather.bean.MinutePrecResponse;
import com.llw.goodweather.utils.DateUtils;
import com.llw.goodweather.utils.WeatherUtil;
import java.util.List;
/**
-
分钟级降水列表适配器
-
@author llw
*/
public class MinutePrecAdapter extends BaseQuickAdapter<MinutePrecResponse.MinutelyBean, BaseViewHolder> {
public MinutePrecAdapter(int layoutResId, @Nullable List<MinutePrecResponse.MinutelyBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, MinutePrecResponse.MinutelyBean item) {
String time = DateUtils.updateTime(item.getFxTime());
//时间
helper.setText(R.id.tv_time, WeatherUtil.showTimeInfo(time) + time);
String type = null;
if(“rain”.equals(item.getType())){
type = “雨”;
}else if(“snow”.equals(item.getType())){
type = “雪”;
}
helper.setText(R.id.tv_precip_info,item.getPrecip()+" "+type);
}
}
现在布局和准备工作都做好了,然后进入WeatherContract,写一个请求接口的方法和回调,在里面增加如下代码
/**
-
分钟级降水
-
@param location 经纬度拼接字符串,使用英文逗号分隔,经度在前纬度在后
*/
public void getMinutePrec(String location) {
ApiService service = ServiceGenerator.createService(ApiService.class, 3);
service.getMinutePrec(location).enqueue(new NetCallBack() {
@Override
public void onSuccess(Call call, Response response) {
if (getView() != null) {
getView().getMinutePrecResult(response);
}
}
@Override
public void onFailed() {
if (getView() != null) {
getView().getWeatherDataFailed();
}
}
});
}
返回的方法
//分钟级降水
void getMinutePrecResult(Response response);
增加的位置如下图所示
然后回到MainActivty,你会发现有报错,先不用管它,先初始化一些数据和类。
@BindView(R.id.tv_precipitation)
TextView tvPrecipitation;//降水预告
@BindView(R.id.tv_prec_more)
TextView tvPrecMore;//降水详情
@BindView(R.id.rv_prec_detail)
RecyclerView rvPrecDetail;//分钟级降水列表
通过butterknife绑定控件,然后
private List<MinutePrecResponse.MinutelyBean> minutelyList = new ArrayList<>();//分钟级降水数据列表
private MinutePrecAdapter mAdapterMinutePrec;//分钟级降水适配器
private boolean state = false;//分钟级降水数据 收缩状态 false 收缩 true 展开
然后在initList方法中,对刚才定义的变量进行实例化。
//分钟级降水
mAdapterMinutePrec = new MinutePrecAdapter(R.layout.item_prec_detail_list,minutelyList);
GridLayoutManager managerMinutePrec = new GridLayoutManager(context,2);
managerMinutePrec.setOrientation(RecyclerView.HORIZONTAL);
rvPrecDetail.setLayoutManager(managerMinutePrec);
rvPrecDetail.setAdapter(mAdapterMinutePrec);
添加位置如下图所示
最后就是在接口返回中进行数据赋值了。
重写getMinutePrecResult方法。
/**
-
分钟级降水返回
-
@param response
*/
@Override
public void getMinutePrecResult(Response response) {
dismissLoadingDialog();//关闭加载弹窗
checkAppVersion();//检查版本信息
if(response.body().getCode().equals(Constant.SUCCESS_CODE)) {
tvPrecipitation.setText(response.body().getSummary());
if(response.body().getMinutely()!=null && response.body().getMinutely().size()>0){
minutelyList.clear();
minutelyList.addAll(response.body().getMinutely());
mAdapterMinutePrec.notifyDataSetChanged();
}else {
ToastUtils.showShortToast(context, “分钟级降水数据为空”);
}
}else {
ToastUtils.showShortToast(context, CodeToStringUtils.WeatherCode(response.body().getCode()));
}
}
现在你的这个MainActivity页面就不会报错了。
不过这个时候你运行你会发现你看不到这个列表,那是因为我隐藏了。既然是隐藏的,那么就需要一个开关了控制它的显示才行,于是可以在onViewClick方法中增加一个id.
这里通过点击的方式来控制这个列表的显示和隐藏了,而很明显这个显示和隐藏我还加了动画效果,否则就会显得很突兀。这里注意这个state的全局变量,它的初始值是false,也就是不显示,当我第一次点击时,它会进行判断,会进入else中。这时候通过动画展开这个布局,展开之后设置为true,而此时你再点击时就会进入if中,然后就会收缩布局,之后又把值设置为false。
OK,这个逻辑就讲清楚了,下面来看看那这个动画的方法吧。
之前在mvplibrary中的utils包下建了一个AnimationUtil动画工具类。那么现在新增加两个方法
/**
-
展开动画
-
@param view 需要展开的View
-
@param textView 修改文本
*/
public static void expand(final View view, final TextView textView) {
//视图测量 传入容器的宽高测量模式
view.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//获取视图的测量高度
final int viewHeight = view.getMeasuredHeight();
//设置布局参数高度
view.getLayoutParams().height = 0;
//视图显示
view.setVisibility(View.VISIBLE);
textView.setText(“收起详情”);
Animation animation = new Animation() {
/**
-
重写动画更新函数
-
@param interpolatedTime 补插时间 计算动画进度
-
@param t
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
//动画已完成
view.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
} else {
//正在进行中
view.getLayoutParams().height = (int) (viewHeight * interpolatedTime);
}
view.requestLayout();
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后,面试前该准备哪些资源复习?
其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
这里再分享一下我面试期间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)
《Android开发七大模块核心知识笔记》
《960全网最全Android开发笔记》
《379页Android开发面试宝典》
历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。
《507页Android开发相关源码解析》
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
这里再分享一下我面试期间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)
《Android开发七大模块核心知识笔记》
[外链图片转存中…(img-yFwK0Hv0-1712769144820)]
[外链图片转存中…(img-RgTjWzYu-1712769144820)]
《960全网最全Android开发笔记》
[外链图片转存中…(img-p6n1ZGtr-1712769144820)]
《379页Android开发面试宝典》
历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。
《507页Android开发相关源码解析》
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-nL1tgU0G-1712769144821)]