2024年Android最新Android 天气APP(十八)常用城市(2),2024年最新美团三面技术面

最后附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总)

面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验,下面这份PDF是我翻阅了差不多1个月左右一些Android大博主的博客从他们那里取其精华去其糟泊所整理出来的一些Android的核心知识点, 全部都是精华中的精华,我能面试到现在资深开发人员跟我整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。

这份PDF囊括了JVM,Java集合,Java多线程并发,Java基础,生命周期,微服务, 进程,Parcelable 接口,IPC,屏幕适配,线程异步,ART,架构,Jetpack,NDK开发,计算机网络基础,类加载器,Android 开源库源码分析,设计模式汇总,Gradle 知识点汇总…

由于篇幅有限,就不做过多的介绍,大家请自行脑补

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

import org.litepal.crud.LitePalSupport;

public class ResidentCity extends LitePalSupport {

private int id;//编号

private String location;//地区/城市名称

private String parent_city;//该地区/城市的上级城市

private String admin_area;//该地区/城市所属行政区域

private String cnty;//该地区/城市所属国家名称

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getLocation() {

return location;

}

public void setLocation(String location) {

this.location = location;

}

public String getParent_city() {

return parent_city;

}

public void setParent_city(String parent_city) {

this.parent_city = parent_city;

}

public String getAdmin_area() {

return admin_area;

}

public void setAdmin_area(String admin_area) {

this.admin_area = admin_area;

}

public String getCnty() {

return cnty;

}

public void setCnty(String cnty) {

this.cnty = cnty;

}

}

然后在litepal.xml中增加一个mapping

在这里插入图片描述

最后在WeatherApplication中的onCreate方法中初始化,初始化的时候,你的数据库就创建好了,数据库名称是GoodWeather,表名是ResidentCity

在这里插入图片描述

那么这一块的内容就写完了,只需要在实际应用中结合业务逻辑使用就可以了,当然你也可以去自己尝试一下,感兴趣的可以看Android LitePal的简单使用这篇文章。

③ 布局item

通过最上面的效果图可以看到是两个列表,其中一个是已经添加的城市列表,另一个是搜索出来的城市列表,既然两个列表就要有两个item,当然你也可以用一个item来写,只不过用的时候要多写一些代码,首先当然是从布局开始着手了。

在这里插入图片描述

在app中res下的layout中创建两个布局文件

item_commonly_city_list.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout android:orientation=“vertical”

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”>

<com.mcxtzhang.swipemenulib.SwipeMenuLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“@dimen/dp_50”

android:clickable=“true”

android:paddingBottom=“1dp”>

<TextView

android:id=“@+id/tv_city_name”

android:gravity=“center_vertical”

android:paddingLeft=“@dimen/dp_16”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:textColor=“@color/shallow_black”

android:background=“?android:attr/selectableItemBackground”

android:text=“城市”/>

<Button

android:id=“@+id/btn_delete”

android:layout_width=“@dimen/dp_100”

android:layout_height=“match_parent”

android:background=“@color/red”

android:text=“删除”

android:textColor=“@android:color/white”/>

</com.mcxtzhang.swipemenulib.SwipeMenuLayout>

<View

android:background=“@color/line_gray”

android:layout_width=“match_parent”

android:layout_height=“@dimen/dp_1”/>

item_commonly_city_add_list.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:app=“http://schemas.android.com/apk/res-auto”

android:layout_width=“match_parent”

android:id=“@+id/item_add_city”

android:background=“?android:attr/selectableItemBackground”

android:layout_height=“wrap_content”

android:orientation=“vertical”>

<TextView

android:id=“@+id/tv_location”

android:gravity=“center_vertical”

android:layout_width=“match_parent”

android:textSize=“@dimen/sp_16”

android:paddingLeft=“@dimen/dp_16”

android:layout_height=“@dimen/dp_50”

android:textColor=“@color/shallow_black” />

<View

android:layout_width=“match_parent”

android:layout_height=“@dimen/dp_1”

android:background=“@color/line_gray” />

④ 列表适配器

然后创建适配器

在这里插入图片描述

CommonlyCityAdapter.java

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.mvplibrary.bean.ResidentCity;

import java.util.List;

/**

  • 常用城市列表适配器

*/

public class CommonlyCityAdapter extends BaseQuickAdapter<ResidentCity, BaseViewHolder> {

public CommonlyCityAdapter(int layoutResId, @Nullable List data) {

super(layoutResId, data);

}

@Override

protected void convert(BaseViewHolder helper, ResidentCity item) {

helper.setText(R.id.tv_city_name, item.getLocation());

//添加点击事件

helper.addOnClickListener(R.id.tv_city_name)

.addOnClickListener(R.id.btn_delete);

}

}

CommonlyCityAddAdapter.java

package com.llw.goodweather.adapter;

import android.text.SpannableStringBuilder;

import android.text.style.ForegroundColorSpan;

import android.widget.TextView;

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.SearchCityResponse;

import java.util.List;

import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;

/**

  • 添加城市时搜索返回结果列表适配器

*/

public class CommonlyCityAddAdapter extends BaseQuickAdapter<SearchCityResponse.HeWeather6Bean.BasicBean, BaseViewHolder> {

private String edStr;//关键字

public CommonlyCityAddAdapter(int layoutResId, @Nullable List<SearchCityResponse.HeWeather6Bean.BasicBean> data) {

super(layoutResId, data);

}

@Override

protected void convert(BaseViewHolder helper, SearchCityResponse.HeWeather6Bean.BasicBean item) {

TextView textView = helper.getView(R.id.tv_location);

String result = item.getLocation() + " , " + item.getParent_city() + " , " + item.getAdmin_area() + " , " + item.getCnty();

if (edStr != null && edStr.length() > 0) {

textView.setText(matcherSearchText(mContext.getResources().getColor(R.color.shallow_yellow),result,edStr));

} else {

textView.setText(item.getLocation() + " , " +

item.getParent_city() + " , " +

item.getAdmin_area() + " , " +

item.getCnty());

}

helper.addOnClickListener(R.id.item_add_city);

}

/**

  • 改变颜色

  • @param str 输入的文本

*/

public void changTxColor(String str) {

edStr = str;

notifyDataSetChanged();

}

/**

  • 改变一段文本中第一个关键字的文字颜色

  • @param color 要改变文字的颜色

  • @param string 文本字符串

  • @param keyWord 关键字

  • @return

*/

public static CharSequence matcherSearchText(int color, String string, String keyWord) {

SpannableStringBuilder builder = new SpannableStringBuilder(string);

int indexOf = string.indexOf(keyWord);

if (indexOf != -1) {

builder.setSpan(new ForegroundColorSpan(color), indexOf, indexOf + keyWord.length(), SPAN_EXCLUSIVE_EXCLUSIVE);

}

return builder;

}

}

适配器的代码都是比较简单的,其中matcherSearchText方法是根据传入的关键字找到它在一段字符串中的第一次出现的位置,并修改字体颜色。

⑤ 代码整合

打开CommonlyUsedCityActivity.java

在这里插入图片描述

然后会出现五个构造方法,分别是

//数据初始化

@Override

public void initData(Bundle savedInstanceState) {

}

@Override

public int getLayoutId() {

return R.layout.activity_commonly_used_city;

}

@Override

protected SearchCityContract.SearchCityPresenter createPresent() {

return new SearchCityContract.SearchCityPresenter();

}

/**

  • 请求数据返回处理

  • @param response

*/

@Override

public void getSearchCityResult(Response response) {

}

/**

  • 网络异常返回处理

*/

@Override

public void getDataFailed() {

dismissLoadingDialog();//关闭弹窗

ToastUtils.showShortToast(context, “网络异常”);//这里的context是框架中封装好的,等同于this

}

现在你可以把onCreate方法删掉了。

首先初始化控件

@BindView(R.id.edit_query)

EditText editQuery;//输入框

@BindView(R.id.iv_clear_search)

ImageView ivClearSearch;//清除输入框内容的图标

@BindView(R.id.toolbar)

Toolbar toolbar;//标题控件

@BindView(R.id.rv_commonly_used)

RecyclerView rvCommonlyUsed;//常用城市列表

@BindView(R.id.rv_search)

RecyclerView rvSearch;//搜索城市列表

@BindView(R.id.lay_normal)

LinearLayout layNormal;//常用城市为空时展示的布局

CommonlyCityAdapter mAdapter;//常用城市列表适配器

List<SearchCityResponse.HeWeather6Bean.BasicBean> mList = new ArrayList<>();//数据源

CommonlyCityAddAdapter mAdapterAdd;//搜索城市列表适配器

List cityList;//常用城市列表

根据常用城市数据来进行页面控件显示/隐藏

/**

  • 根据常用城市数据来进行页面控件显示/隐藏

*/

private void initHideOrShow() {

ivClearSearch.setVisibility(View.GONE);//隐藏清除输入框内容的图标

rvSearch.setVisibility(View.GONE);//隐藏搜索结果列表

if (cityList != null && cityList.size() > 0) {//有数据

rvCommonlyUsed.setVisibility(View.VISIBLE);//显示常用城市列表

layNormal.setVisibility(View.GONE);//隐藏没有数据时的布局

} else {//没数据

rvCommonlyUsed.setVisibility(View.GONE);//隐藏常用城市列表

layNormal.setVisibility(View.VISIBLE);//显示没有数据时的布局

}

}

初始化常用城市列表数据

这个方法主要是查询表中的所有数据,有数据就渲染出来,没有数据就更换为相应的表示布局,其中对item中的点击事件做了处理,分别item的点击和侧滑菜单的点击。

/**

  • 初始化常用城市列表数据

*/

private void initCityList() {

//查询ResidentCity表中所有数据

cityList = LitePal.findAll(ResidentCity.class);

if (cityList.size() > 0 && cityList != null) {

mAdapter = new CommonlyCityAdapter(R.layout.item_commonly_city_list, cityList);

rvCommonlyUsed.setLayoutManager(new LinearLayoutManager(context));

rvCommonlyUsed.setAdapter(mAdapter);

mAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {

@Override

public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {

switch (view.getId()) {

case R.id.tv_city_name:

SPUtils.putString(Constant.LOCATION, cityList.get(position).getLocation(), context);

//发送消息

EventBus.getDefault().post(new SearchCityEvent(cityList.get(position).getLocation(),

cityList.get(position).getParent_city()));

finish();

break;

case R.id.btn_delete://删除

LitePal.delete(ResidentCity.class, cityList.get(position).getId());//删除指定id

initCityList();

//删除数据后判断一下显示和隐藏的控件

initHideOrShow();

break;

}

}

});

mAdapter.notifyDataSetChanged();

} else {

rvCommonlyUsed.setVisibility(View.GONE);

layNormal.setVisibility(View.VISIBLE);

}

}

添加城市列表item,点击保存数据并发送事件

/**

  • 添加城市列表item,点击保存数据并发送事件

  • @param position

*/

private void QueryWeather(int position) {

ResidentCity residentCity = new ResidentCity();

residentCity.setLocation(mList.get(position).getLocation());//地区/城市名称

residentCity.setParent_city(mList.get(position).getParent_city());//该地区/城市的上级城市

residentCity.setAdmin_area(mList.get(position).getAdmin_area());//该地区/城市所属行政区域

residentCity.setCnty(mList.get(position).getCnty());//该地区/城市所属国家名称

residentCity.save();//保存数据到数据库中

if (residentCity.save()) {//保存成功

//然后使用之前在搜索城市天气中写好的代码

SPUtils.putString(Constant.LOCATION, mList.get(position).getLocation(), context);

//发送消息

EventBus.getDefault().post(new SearchCityEvent(mList.get(position).getLocation(),

mList.get(position).getParent_city()));

finish();

} else {//保存失败

ToastUtils.showShortToast(context, “添加城市失败”);

}

}

初始化搜索要添加的城市列表

/**

  • 初始化搜索要添加的城市列表

*/

private void initQueryAddList() {

最后:学习总结——Android框架体系架构知识脑图(纯手绘xmind文档)

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。

下方即为我手绘的Android框架体系架构知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的Android框架体系架构知识脑图原件(包括上方的面试解析xmind文档)

除此之外,前文所提及的Alibaba珍藏版 Android框架体系架构 手写文档以及一本 《大话数据结构》 书籍等等相关的学习笔记文档,也皆可分享给认可的朋友!

——感谢大家伙的认可支持,请注意:点赞+点赞+点赞!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

nt_city()));

finish();

} else {//保存失败

ToastUtils.showShortToast(context, “添加城市失败”);

}

}

初始化搜索要添加的城市列表

/**

  • 初始化搜索要添加的城市列表

*/

private void initQueryAddList() {

最后:学习总结——Android框架体系架构知识脑图(纯手绘xmind文档)

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。

下方即为我手绘的Android框架体系架构知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的Android框架体系架构知识脑图原件(包括上方的面试解析xmind文档)
[外链图片转存中…(img-FvL4Auow-1715649377484)]

除此之外,前文所提及的Alibaba珍藏版 Android框架体系架构 手写文档以及一本 《大话数据结构》 书籍等等相关的学习笔记文档,也皆可分享给认可的朋友!

——感谢大家伙的认可支持,请注意:点赞+点赞+点赞!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值