IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 简易的安卓天气app(四)——搜索城市、完善页面 -> 正文阅读

[移动开发]简易的安卓天气app(四)——搜索城市、完善页面

?简易的安卓天气app(一)——解析Json数据、数据类封装
?简易的安卓天气app(二)——适配器、每小时数据展示
?简易的安卓天气app(三)——城市管理、数据库操作
📌简易的安卓天气app(四)——搜索城市、完善页面

需求🏷?

前三篇重要的功能已经实现的差不多了,完成了api获取数据,封装数据,展示数据,和一些数据库操作,接着就是按照自己的意愿,搜索城市,查看此城市天气,并决定将此城市加入数据库操作,方法是尽可能地简化的,本次项目共涉及三个页面之间的跳转,逻辑清晰,条理明朗,后续更多复杂化操作,和更多重复性操作有待探索,本质上都是已有代码的延申。
先获取到全国各个城市的信息,展示在搜索城市页面,方便查找。
实现步骤:

  1. AutoCompleteTextView输入提示文本框
  2. 实现读取全部城市展示
  3. 搜索框搜索指定城市

实现效果:
gif

涉及内容

  • AutoCompleteTextView输入提示文本框
  • 文件读取,Json数据封装,RecyclerView数据展示
  • 根据城市名称刷新天气

项目结构

2此文为项目开发第四篇文章,故前面文章已经讲完一部分内容,想了解详细步骤移步页首,每一篇文章都已经给出独立源码,可自行根据需要模拟;;

界面设计

搜索页面设计:
4大概就是三层的线性布局:
第一层TextView接受主页面传进来的当前天气的城市名称。
第二层就是一个搜索框,使用到的是AutoCompleteTextView,带有提示信息的输入框,EditView也可以,右边搜索图标设置点击监听事件。
第三层就是一个RecyclerView展示全部城市名称,也可以设置点击事件监听,或者输入框输入,此处作为提示出现,都是可行方案

搜索城市页面输入框代码:
输入框AutoCompleteTextView此次用到的属性:

android:completionThreshold="1" //输入一个字符就给出提示
android:dropDownHorizontalOffset://提示菜单与文本起始的水平间距
android:dropDownHeight://设置提示框的高度,太小可能会遮盖部分提示,不过可以上下滚动显示
android:dropDownWidth://设置提示框的宽度,太小可能会遮盖部分提示
android:imeOptions="actionSearch" //键盘点击搜索事件
	<LinearLayout
        android:layout_width="380dp"
        android:layout_height="40dp"
        android:gravity="center_vertical"
        android:layout_gravity="center"
        android:background="@drawable/blackground">
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_marginRight="12dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:paddingLeft="12dp"
            android:paddingRight="12dp">
            <!--输入框-->
            <AutoCompleteTextView
                android:id="@+id/edit_query"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@null"
                android:completionThreshold="1"
                android:dropDownHorizontalOffset="5dp"
                android:dropDownWidth="200dp"
                android:hint="请输入城市名称"
                android:imeOptions="actionSearch"
                android:paddingLeft="8dp"
                android:paddingRight="4dp"
				android:textColor="@color/white"
                android:singleLine="true"
                android:textSize="18sp" />
            <!--搜索图标-->
            <ImageView
                android:layout_width="26dp"
                android:layout_height="26dp"
                android:id="@+id/iv_search"
                android:src="@mipmap/icon_search" />
        </LinearLayout>
    </LinearLayout>

输入城市显示提示文本:
5

省、城市数据类封装

既然需求中需要输入一个字就给出相关城市提示信息,那么就要有全部城市数据,才能以此为根据提示城市名称,由于获取全国全部城市的API太难找,而且免费版的还有使用上限,所以此处直接根据文件读取,并封装。前几篇文章由于网络请求api封装用到的是Gson第三方工具,也提到了使用JsonObject等封装,所以此文会使用JsonArray,JsonObject来进行Json数据封装。
给出的City.txt文件放在main文件夹下的assets文件夹(res同级)下6里面给出的就是全国省份,各省下辖市,以及市下的区和县。
例如:

	[{
 		"pname": "北京市",
 		"city": [{
 			"name": "北京市",
 			"area": [
 				"东城区",
 				"西城区",
 				.........
 			]
 		}]
 	},
 	{
 		"pname": "天津市",
 		"city": [{
 			"name": "天津市",
 			"area": [
 				"和平区",
 				"河东区",
 				.........
 			]
 		}]
 	},
 	{
 		"pname": "河北省",
 		"city": [{
 				"name": "石家庄市",
 				"area": [
 					"长安区",
 					"桥西区",
 					.........
 				]
 			},
 			{
 				"name": "唐山市",
 				"area": [
 					"路北区",
 					"路南区",
 					.........
 				]
 			},
 			{
 				"name": "秦皇岛市",
 				"area": [
 					"海港区",
 					"山海关区",
 					.........
 				]
 			},
 			.........

前往下面地址自取(永久有效):
1.百度网盘:City.txt

  • 提取码:mnmp

2.阿里云盘:City.txt

  • 提取码:su08

前往json在线解析网站观察此文件结构

  1. 先观察省,此处就以北京和天津为例,前面文章也提到了观察法,先是一个中括号"[“括住了全部省份,每个省份都是一个Object对象(大括号”{"阔了起来)。
  2. 再观察市,每个省里面的city属性名表示此省下辖的市,也是"["包裹起来,表示是个数组,里面包含了省下全部市的信息(包括name市名称,area数组:区/县),这里就解析到各个城市,因为套法一样。
    6接着就是封装(连带着省份也一起封装吧),需要两个数据类,因为只封装到各个省下的城市。
    7
    ProvinceBean封装省份名称pname和市city,市是集合List
public class ProvinceBean {//省
    private String pname;
    private List<CityBean> city;
	//set、get、toString、构造。。。。。。
}

CityBean封装市名称name和区/县area,县是数组String[]

public class CityBean {
    private String name;
    private String[] area;//县/区
    private String tem;//方便数据库操作
    private String updateTime;//方便数据库操作
    //set、get、toString、构造。。。。。。

Json数据解析

接着就是从文件City.txt读取信息
下面是读取方法

InputStream inputStream = getResources().getAssets().open("City.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String lines = bufferedReader.readLine();
while (lines != null) {
	sb.append(lines);
	lines = bufferedReader.readLine();
}
String resultCity = sb.toString();
Log.d("SelectCity", "resultCity>>>>>>>>>" + resultCity);

控制台显示(原txt有空格和换行,这样的格式很正常):7然后得到了一个字符串resultCity ,接着就是根据resultCity 进行数据封装

JSONArray ja= new JSONArray(resultCity);
//获取省,封装
for (int i = 0; i < ja.length(); i++) {//这个长度就是省的个数
	JSONObject provinceJsonObject = ja.getJSONObject(i);
	String provinceName = provinceJsonObject.getString("pname");
	ProvinceBean provinceBean = new ProvinceBean();
	provinceBean.setPname(provinceName);
	mProvinceBeanList.add(provinceBean);
	//添加市,也可以用省里封装的List<CityBean>,直接set,以后不免用到CityBean,就1并封装了
	JSONArray cityArray = provinceJsonObject.getJSONArray("city");
	for (int j = 0; j < cityArray.length(); j++) {
		JSONObject cityObj = cityArray.getJSONObject(j);
		String cityName = cityObj.getString("name");
		CityBean cityBean = new CityBean();
		cityBean.setName(cityName);
		mCityBeanList.add(cityBean);
		}
		// 添加区/县待拓展。。。。。。。。。
	}
	Log.d("SelectCity", "mCityBeanList>>>>>>>>>" + mCityBeanList.toString());

到此省和市的数据就已经封装好了,可以查看控制台,发现area=null,因为用不到此数据,就没有对area进行封装,需要封装直接cityBean.set完事,没有难度。

数据解析封装好,就是设置适配器,既然用到RecyclerView展示城市,那么城市的适配器就得写,毕竟封装好的城市数据不是String数组,是一个集合,为了规范(凑复杂度)直接写适配器吧(List转成String数组就可以不用写适配器,直接用ArrayAdapter)。

CityAdapter适配器:

前面文章提到过,略过过了就,,

指路==>适配器写法:
简易的安卓天气app(二)——适配器、每小时数据展示
根据目录适配器HourWeatherAdapter索引

/**也可以在此适配器添加点击事件,拿到天气,此方法前面文章(根据目录适配器AddCityAdapter索引)也提到过,此处略过/

SelectCityActivity.java

搜索框

搜索城市页面首先我们来设计搜索框输入文字提示框,首先,我们已经在xml布局中运用了AutoCompleteTextView,会自动根据输入的一个字匹配传入的值,有就显示提示,如下,这个弹出提示框其实是可以自定义样式的,这里就用默认了。后续会更新,适配器也是安卓提供的ArrayAdapter,传入的是全国所有市的String[]数组。
8
现在,先在SelectCityActivity.java中定义AutoCompleteTextView;
private AutoCompleteTextView query;
然后绑定组件

query = (AutoCompleteTextView) findViewById(R.id.edit_query);

接着就是设置一个ArrayAdapter适配器,里面设置样式为android.R.layout.simple_list_item_1安卓提供的样式,就是简单的白框, 然后传入城市的数组;
在此之前,这个城市数组还得定义好,前面Json数据解析我们已经知道,从City.txt文件已经拿到了全部城市,并成功传值给mCityBeanList
72然后我们把这个List转成String数组,放在适配器ArrayAdapter中;

	String[] cityArray = new String[mCityBeanList.size()];
        for (int i = 0; i < mCityBeanList.size(); i++) {
        //城市名称定义为一个数组
            cityArray[i] = mCityBeanList.get(i).getName().substring(0, mCityBeanList.get(i).getName().length() - 1);
        }

这里带了substring方法,主要是由于我们的天气api查询城市时传入的城市名称不能带市,只能北京,天津,上海,不可北京市,上海市。
然后适配器就可以传参了,如下:

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, cityArray);
query.setAdapter(adapter);//

然后添加输入框右面的搜索图标的点击事件,输入框的城市名就传到了主页并显示天气

	ivSearch = (ImageView) findViewById(R.id.iv_search);
        ivSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            //拿到输入框的值
                String cityName = query.getText().toString();
//                ToastUtil.showLongToast(SelectCityActivity.this, cityName);
                Intent intent = new Intent(SelectCityActivity.this, MainActivity.class);
                intent.putExtra("inputCity", cityName);
                setResult(200, intent);
                finish();
            }
        });

城市显示

用到RecyclerView,只要把此类中已经封装好的全部城市集合传进去就行了,前面文章已经讲述过RecyclerView的用法,同时,也可以实现点击item跳转到主页获取天气的操作,前面文章也已经提到,不想过多赘述了;

若是嫌弃城市列表太多,都显示在一个页面还得滑动屏幕一个个找;
那么,二级RecyclerView不妨考虑一下:先显示全部省,点击省时,弹出市;
亦或者Spinner、两个RecyclerView联动,等等方法;(源码已给,自行探索)

9>实现上图的效果,用到了左右两个RecyclerView,点击左面,就对应显示有点数据,把数据解析那一步改改就行,省和市完整封装在一起,省不止要serPname了,还要把此省的全部市封装一下provinceBean.setCity(mCityBeanList);
下面是封装部分的源码,都是ArrayList,查询速度快。
为了保证搜索框还有提示功能,重新定义actureCityBeanList,传入集合actureCityBeanList转的数组;;

final JSONArray Data = new JSONArray(resultCity);
            //获取省,封装
            for (int i = 0; i < Data.length(); i++) {
                JSONObject provinceJsonObject = Data.getJSONObject(i);
                String provinceName = provinceJsonObject.getString("pname");
                ProvinceBean provinceBean = new ProvinceBean();
                provinceBean.setPname(provinceName);
                mCityBeanList = new ArrayList<>();
                //添加市
                final JSONArray cityArray = provinceJsonObject.getJSONArray("city");
                for (int j = 0; j < cityArray.length(); j++) {
                    JSONObject cityObj = cityArray.getJSONObject(j);
                    String cityName = cityObj.getString("name");
                    CityBean cityBean = new CityBean();
                    cityBean.setName(cityName);
//                    mCityNameList.add(cityName);
                    mCityBeanList.add(cityBean);
                    actureCityBeanList.add(cityBean);
                }
                provinceBean.setCity(mCityBeanList);
                mProvinceBeanList.add(provinceBean);

                // 添加县待拓展。。。。。。。。。
            }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 19:12:58  更:2022-06-29 19:14:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 3:58:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码