Android 天气APP(三十二)快捷切换常用城市

简介: Android 天气APP(三十二)快捷切换常用城市

快捷切换常用城市及每日弹窗优化


前言


 在2021年正式到来之前再更新几篇天气APP的文章,说实话现在对于这个APP的更新速度是比较缓慢的,一方面我有工作在进行,同时在写其他的文章,其次我正在使用Kotlin语言重写天气APP,还有一个原因就是功能的迭代问题,因为作为天气APP该满足用户的其实都已经满足了,我本来还有好多的想法打算加进去,又怕这个变得不伦不类,因此有些东西就搁置了,而这篇文章就是在对于用户的体验上做提升,嗯,来看看吧。


正文


 快捷切换城市自然要在App的主页面进行了,那么首先修改一下布局文件activity_main.xml。


            <!--切换城市-->
                        <!--常用城市快捷切换-->
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:animateLayoutChanges="true">
                            <androidx.recyclerview.widget.RecyclerView
                                android:id="@+id/rv_change_city"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:padding="12dp"
                                android:visibility="gone" />
                        </LinearLayout>


放置的位置就在城市的下方,只不过是隐藏的列表,所以你还看不见的。


20210204100932235.png


然后在MainActivity绑定控件

  @BindView(R.id.rv_change_city)
    RecyclerView rvChangeCity;//点击切换常用城市


再创建两个变量用于控制是否显示和是否展开常用城市列表

  private boolean changeCityState = false;//常用城市列表  收缩状态  false 收缩  true 展开
    private boolean isChangeCity = false;//是否可以展开,如果没有添加常用城市,自然不能展开


一、创建适配器


  既然有列表自然就有适配器。然后在layout中创建一个item_main_city_change.xml


<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_city"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/selected_bg_color"
    android:paddingStart="@dimen/dp_16"
    android:paddingTop="@dimen/dp_4"
    android:paddingEnd="@dimen/dp_16"
    android:paddingBottom="@dimen/dp_4"
    android:text="常用城市"
    android:textColor="@drawable/selected_text_color"
    android:textSize="@dimen/sp_18" />


这里我改变了触摸item时的背景样式和文字颜色样式,样式都放在drawable下。


selected_bg_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/selected_bg_radius"/>
</selector>


selected_bg_radius.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white_4"/>
    <corners android:radius="@dimen/dp_12"/>
</shape>


selected_text_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/white"/>
    <item android:state_pressed="false" android:color="@color/white_8"/>
</selector>


item写完了,下面到适配器了。

在adapter包下新建一个MainChangeCommonlyCityAdapter类,代码如下:

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;
/**
 * 主页面左右滑动切换常用城市列表适配器
 *
 * @author llw
 */
public class MainChangeCommonlyCityAdapter extends BaseQuickAdapter<ResidentCity, BaseViewHolder> {
    public MainChangeCommonlyCityAdapter(int layoutResId, @Nullable List<ResidentCity> data) {
        super(layoutResId, data);
    }
    @Override
    protected void convert(BaseViewHolder helper, ResidentCity item) {
        helper.setText(R.id.tv_city, item.getLocation())
                .addOnClickListener(R.id.tv_city);
    }
}



二、配置列表加载常用城市数据


刚才适配器写好了,然后进入到MainActivity中,再创建两个变量


  //主页面切换城市列表适配器
    private MainChangeCommonlyCityAdapter changeCityAdapter;
    //常用城市切换列表
    private List<ResidentCity> residentCityList = new ArrayList<>();


一个适配器一个数据列表,然后下面新增一个方法用于加载适配器数据并且渲染,还有点击事件。这里先查询数据,然后判断数据,之后渲染数据,最后是点击item之后搜索城市,然后查找天气数据。


  /**
     * 加载常用城市数据
     */
    private void loadingCommonlyUsedCity() {
        residentCityList = LitePal.findAll(ResidentCity.class);
        //先判断是否有常用城市
        if (residentCityList != null && residentCityList.size() > 0) {
            isChangeCity = true;
        } else {
            isChangeCity = false;
        }
        //配置适配器
        changeCityAdapter = new MainChangeCommonlyCityAdapter(R.layout.item_main_city_change, residentCityList);
        LinearLayoutManager manager = new LinearLayoutManager(context);
        manager.setOrientation(RecyclerView.HORIZONTAL);
        rvChangeCity.setLayoutManager(manager);
        rvChangeCity.setAdapter(changeCityAdapter);
        //常用城市点击
        changeCityAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            showLoadingDialog();
            district = residentCityList.get(position).getLocation();
            mPresent.newSearchCity(district);
            flag = false;
            //隐藏列表
            rvChangeCity.setVisibility(View.GONE);
            changeCityState = false;
        });
    }


三、添加到常用城市列表


这里我判断了一下是否为定位城市的返回,是的话我就添加到数据库中,当然也不能重复添加数据,因此还需要判断一下。


  /**
     * 添加到常用城市列表
     *
     * @param locationBean
     */
    private void addCommonlyUsedCity(NewSearchCityResponse.LocationBean locationBean) {
        if (flag) {//定位到的城市
            List<ResidentCity> residentCityList = LitePal.findAll(ResidentCity.class);
            if (residentCityList != null && residentCityList.size() > 0) {
                //查询要添加的城市是否已经存在
                List<ResidentCity> residentCities = LitePal
                        .where("location = ? and parent_city = ?", locationBean.getName(), locationBean.getAdm2())
                        .find(ResidentCity.class);
                if (residentCities.size() == 0) {
                    ResidentCity residentCity = new ResidentCity();
                    residentCity.setLocation(locationBean.getName());//地区/城市名称
                    residentCity.setParent_city(locationBean.getAdm2());//该地区/城市的上级城市
                    residentCity.setAdmin_area(locationBean.getAdm1());//该地区/城市所属行政区域
                    residentCity.setCnty(locationBean.getCountry());//该地区/城市所属国家名称
                    residentCity.save();//保存数据到数据库中
                }
            } else {
                ResidentCity residentCity = new ResidentCity();
                residentCity.setLocation(locationBean.getName());//地区/城市名称
                residentCity.setParent_city(locationBean.getAdm2());//该地区/城市的上级城市
                residentCity.setAdmin_area(locationBean.getAdm1());//该地区/城市所属行政区域
                residentCity.setCnty(locationBean.getCountry());//该地区/城市所属国家名称
                residentCity.save();//保存数据到数据库中
            }
        }
        //加载常用城市数据
        loadingCommonlyUsedCity();
    }

image.png



然后你还需要在initData中调用loadingCommonlyUsedCity方法。


20210204165343327.png


其次就是在接收事件的时候再加载一次数据,因为我在常用城市中添加数据之后会发起事件,然后关闭常用城市页面,回到主页面,此时需要把数据加载一下,后面会演示一下。


20210204165459295.png


四、修改UI


  因为我是点击城市触发常用城市列表的判断处理,因此之前的代码需要修改一下,有两处,在initData中

20210204170055223.png


在onReceiveLocation方法中


20210204170140228.png


最后在tv_city的点击事件中先判断当前城市是否定位到,定位到则判断有无数据,有数据则可以判断点击后不同的控件样式。

20210204170342372.png


那么下面就可以运行一下了。

20210204172706949.gif


文末


  这篇文章比较的简洁,那么也到这里了,山高水长,后会有期~





相关文章
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
118 0
安卓项目:app注册/登录界面设计
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
107 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
2月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
123 2
|
2月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
85 3
|
1月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
169 0
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
67 10
|
2月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
存储 缓存 安全
Android14 适配之——现有 App 安装到 Android14 手机上需要注意些什么?
Android14 适配之——现有 App 安装到 Android14 手机上需要注意些什么?
511 0
|
6月前
|
传感器 物联网 Android开发
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
192 1
|
6月前
|
Android开发 网络架构
【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)
【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)
871 1