68dp
69dp
70dp
71dp
72dp
73dp
74dp
75dp
76dp
77dp
78dp
79dp
80dp
81dp
82dp
83dp
84dp
85dp
86dp
87dp
88dp
89dp
90dp
91dp
92dp
93dp
94dp
95dp
96dp
97dp
98dp
99dp
100dp
101dp
102dp
103dp
104dp
105dp
106dp
107dp
108dp
109dp
110dp
111dp
112dp
113dp
114dp
115dp
116dp
117dp
118dp
119dp
120dp
121dp
122dp
123dp
124dp
125dp
126dp
127dp
128dp
129dp
130dp
131dp
132dp
133dp
134dp
135dp
136dp
137dp
138dp
139dp
140dp
141dp
142dp
143dp
144dp
145dp
146dp
147dp
148dp
149dp
150dp
151dp
152dp
153dp
154dp
155dp
156dp
157dp
158dp
159dp
160dp
161dp
162dp
163dp
164dp
165dp
166dp
167dp
168dp
169dp
170dp
171dp
172dp
173dp
174dp
175dp
176dp
177dp
178dp
179dp
180dp
181dp
182dp
183dp
184dp
185dp
186dp
187dp
188dp
189dp
190dp
191dp
192dp
193dp
194dp
195dp
196dp
197dp
198dp
199dp
200dp
201dp
202dp
203dp
204dp
205dp
206dp
207dp
208dp
209dp
210dp
211dp
212dp
213dp
214dp
215dp
216dp
217dp
218dp
219dp
220dp
221dp
222dp
223dp
224dp
225dp
226dp
227dp
228dp
229dp
230dp
231dp
232dp
233dp
234dp
235dp
236dp
237dp
238dp
239dp
240dp
241dp
242dp
243dp
244dp
245dp
246dp
247dp
248dp
249dp
250dp
251dp
252dp
253dp
254dp
255dp
256dp
257dp
258dp
259dp
260dp
261dp
262dp
263dp
264dp
265dp
266dp
267dp
268dp
269dp
270dp
271dp
272dp
273dp
274dp
275dp
276dp
277dp
278dp
279dp
280dp
281dp
282dp
283dp
284dp
285dp
286dp
287dp
288dp
289dp
290dp
291dp
292dp
293dp
294dp
295dp
296dp
297dp
298dp
299dp
300dp
301dp
302dp
303dp
304dp
305dp
306dp
307dp
308dp
309dp
310dp
311dp
312dp
313dp
314dp
315dp
316dp
317dp
318dp
319dp
320dp
321dp
322dp
323dp
324dp
325dp
326dp
327dp
328dp
329dp
330dp
331dp
332dp
333dp
334dp
335dp
336dp
337dp
338dp
339dp
340dp
341dp
342dp
343dp
344dp
345dp
346dp
347dp
348dp
349dp
350dp
351dp
352dp
353dp
354dp
355dp
356dp
357dp
358dp
359dp
360dp
365dp
370dp
399dp
400dp
410dp
420dp
412dp
422dp
472dp
500dp
520dp
550dp
560dp
600dp
640dp
720dp
6sp
7sp
8sp
9sp
10sp
11sp
12sp
13sp
14sp
15sp
16sp
17sp
18sp
19sp
20sp
21sp
22sp
23sp
24sp
25sp
26sp
27sp
28sp
29sp
30sp
31sp
32sp
33sp
34sp
35sp
36sp
37sp
38sp
40sp
42sp
48sp
12dp
在修改布局之前,先准备好需要的资源,首先是两个图标
在drawable中新建search_et_bg.xml,里面的代码如下:
<?xml version="1.0" encoding="utf-8"?>这是设置输入框的背景
然后再新建一个cursor_style.xml,里面的代码如下:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android=“http://schemas.android.com/apk/res/android”
android:shape=“rectangle”>
这是设置输入框的光标颜色。
下面可以写布局了。
<?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”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:fitsSystemWindows=“true”
android:orientation=“vertical”
tools:context=“.MainActivity”>
<com.google.android.material.appbar.MaterialToolbar
android:id=“@+id/toolbar”
android:layout_width=“match_parent”
android:layout_height=“?attr/actionBarSize”
android:background=“@color/colorPrimaryDark”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center”
android:text=“垃圾分类”
android:textColor=“@color/white”
android:textSize=“18sp” />
</com.google.android.material.appbar.MaterialToolbar>
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:background=“@color/white”>
<RelativeLayout
android:layout_width=“match_parent”
android:layout_height=“36dp”
android:layout_marginStart=“@dimen/sp_16”
android:layout_marginTop=“@dimen/dp_12”
android:layout_marginEnd=“@dimen/dp_16”
android:layout_marginBottom=“@dimen/dp_12”
android:background=“@drawable/search_et_bg”
android:orientation=“horizontal”>
<ImageView
android:id=“@+id/iv_search”
android:layout_width=“@dimen/dp_16”
android:layout_height=“@dimen/dp_16”
android:layout_centerVertical=“true”
android:layout_marginStart=“@dimen/dp_12”
android:layout_marginEnd=“@dimen/dp_8”
app:srcCompat=“@mipmap/icon_search” />
<EditText
android:id=“@+id/et_goods”
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:layout_toStartOf=“@+id/iv_clear”
android:layout_toEndOf=“@+id/iv_search”
android:background=“@null”
android:hint=“请输入物品”
android:imeOptions=“actionSearch”
android:singleLine=“true”
android:textColor=“@color/black”
android:textColorHint=“@color/hint_color”
android:textCursorDrawable=“@drawable/cursor_style”
android:textSize=“@dimen/sp_14” />
<ImageView
android:id=“@+id/iv_clear”
android:layout_width=“@dimen/dp_36”
android:layout_height=“@dimen/dp_36”
android:layout_alignParentEnd=“true”
android:padding=“@dimen/dp_10”
android:src=“@mipmap/icon_clear”
android:visibility=“invisible” />
<androidx.recyclerview.widget.RecyclerView
android:id=“@+id/rv_result”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:overScrollMode=“never”
android:scrollbars=“none” />
下面设置接口的访问地址,打开mvplibrary下的NetworkApi类,修改正式环境的访问地址
mBaseUrl = “http://api.tianapi.com”;
如下图所示
下面回到app模块,在com.llw.goodtrash包下新建NetworkRequiredInfo类,里面代码如下;
package com.llw.goodtrash;
import android.app.Application;
import com.llw.mvplibrary.BuildConfig;
import com.llw.mvplibrary.network.INetworkRequiredInfo;
/**
-
网络访问信息
-
@author llw
*/
public class NetworkRequiredInfo implements INetworkRequiredInfo {
private Application application;
public NetworkRequiredInfo(Application application){
this.application = application;
}
/**
- 版本名
*/
@Override
public String getAppVersionName() {
return BuildConfig.VERSION_NAME;
}
/**
- 版本号
*/
@Override
public String getAppVersionCode() {
return String.valueOf(BuildConfig.VERSION_CODE);
}
/**
- 是否为debug
*/
@Override
public boolean isDebug() {
return BuildConfig.DEBUG;
}
/**
- 应用全局上下文
*/
@Override
public Application getApplicationContext() {
return application;
}
}
之后再新建一个TrashApplication类,代码如下:
package com.llw.goodtrash;
import com.llw.mvplibrary.BaseApplication;
import com.llw.mvplibrary.network.NetworkApi;
/**
- 自定义Application
*/
public class TrashApplication extends BaseApplication {
@Override
public void onCreate() {
super.onCreate();
//初始化网络框架
NetworkApi.init(new NetworkRequiredInfo(this));
}
}
自定义的Application需要到AndroidManifest.xml中去配置才会生效,如下图所示:
现在你就可以访问网络了,这虽然看起来是单独使用Okhttp要麻烦,但实际上是要方便很多的,你可能现在不明白,以后你会懂得。
我在天行API中请求接口使用的KEY,这里我新建了一个全局常量类,放在里面,在com.llw.goodtrash包下新建一个utils包。包下的代码如下:
package com.llw.goodtrash.utils;
/**
-
全局常量
-
@author llw
-
@date 2021/3/30 15:14
*/
public class Constant {
/**
- 垃圾分类的key 请替换为自己的
*/
public static final String KEY = “783da68c7ea7e10fcd259db651cc550b”;
/**
- 请求成功码
*/
public static final int SUCCESS_CODE = 200;
}
之前通过返回的数据可以生成一个返回数据实体,在com.llw.goodtrash包下新建一个model包,包下新建一个TrashResponse类,代码如下:
package com.llw.goodtrash.model;
import java.util.List;
/**
- 垃圾分类返回数据
*/
public class TrashResponse {
/**
-
code : 200
-
msg : success
-
newslist : [{“name”:“羽毛球”,“type”:3,“aipre”:0,“explain”:“干垃圾即其它垃圾,指除可回收物、有害垃圾、厨余垃圾(湿垃圾)以外的其它生活废弃物。”,“contain”:“常见包括砖瓦陶瓷、渣土、卫生间废纸、猫砂、污损塑料、毛发、硬壳、一次性制品、灰土、瓷器碎片等难以回收的废弃物”,“tip”:“尽量沥干水分;难以辨识类别的生活垃圾都可以投入干垃圾容器内”},{“name”:“羽毛球拍”,“type”:0,“aipre”:0,“explain”:“可回收垃圾是指适宜回收、可循环利用的生活废弃物。”,“contain”:“常见包括各类废金属、玻璃瓶、易拉罐、饮料瓶、塑料玩具、书本、报纸、广告单、纸板箱、衣服、床上用品、电子产品等”,“tip”:“轻投轻放;清洁干燥,避免污染,费纸尽量平整;立体包装物请清空内容物,清洁后压扁投放;有尖锐边角的、应包裹后投放”}]
*/
private int code;
private String msg;
private List newslist;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public List getNewslist() {
return newslist;
}
public void setNewslist(List newslist) {
this.newslist = newslist;
}
public static class NewslistBean {
/**
-
name : 羽毛球
-
type : 3
-
aipre : 0
-
explain : 干垃圾即其它垃圾,指除可回收物、有害垃圾、厨余垃圾(湿垃圾)以外的其它生活废弃物。
-
contain : 常见包括砖瓦陶瓷、渣土、卫生间废纸、猫砂、污损塑料、毛发、硬壳、一次性制品、灰土、瓷器碎片等难以回收的废弃物
-
tip : 尽量沥干水分;难以辨识类别的生活垃圾都可以投入干垃圾容器内
*/
private String name;
private int type;
private int aipre;
private String explain;
private String contain;
private String tip;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getAipre() {
return aipre;
}
public void setAipre(int aipre) {
this.aipre = aipre;
}
public String getExplain() {
return explain;
}
public void setExplain(String explain) {
this.explain = explain;
}
public String getContain() {
return contain;
}
public void setContain(String contain) {
this.contain = contain;
}
public String getTip() {
return tip;
}
public void setTip(String tip) {
this.tip = tip;
}
}
}
下面设置api接口,在com.llw.goodtrash包下新建一个api包,包下新建一个ApiService接口。
package com.llw.goodtrash.api;
import com.llw.goodtrash.model.TrashResponse;
import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;
import static com.llw.goodtrash.utils.Constant.KEY;
/**
-
API接口
-
@author llw
-
@date 2021/3/30 15:13
*/
public interface ApiService {
/**
-
垃圾分类
-
@param word 物品名
-
@return TrashResponse 结果实体
*/
@GET(“/txapi/lajifenlei/index?key=” + KEY)
Observable searchGoods(@Query(“word”) String word);
}
这里通过Observable观察TrashResponse,当获取到返回数据时,会解析成TrashResponse,就不需要手动去转了,而searchGoods标识方法名,后面的@Query(“word”) String word表示请求API时会把word作为参数拼接到请求地址后面。
下面构建页面访问网络的订阅类
在com.llw.goodtrash包下新建一个contract包,这个包下新建一个MainContract类。
package com.llw.goodtrash.contract;
import android.annotation.SuppressLint;
import com.llw.goodtrash.api.ApiService;
import com.llw.goodtrash.model.TrashResponse;
import com.llw.mvplibrary.base.BasePresenter;
import com.llw.mvplibrary.base.BaseView;
import com.llw.mvplibrary.network.NetworkApi;
import com.llw.mvplibrary.network.observer.BaseObserver;
/**
- 主页面访问网络
*/
public class MainContract {
public static class MainPresenter extends BasePresenter {
/**
-
搜索物品
-
@param word 物品名
*/
@SuppressLint(“CheckResult”)
public void searchGoods(String word) {
ApiService service = NetworkApi.createService(ApiService.class);
service.searchGoods(word).compose(NetworkApi.applySchedulers(new BaseObserver() {
@Override
public void onSuccess(TrashResponse groupResponse) {
if (getView() != null) {
getView().getSearchResponse(groupResponse);
}
}
@Override
public void onFailure(Throwable e) {
if (getView() != null) {
getView().getSearchResponseFailed(e);
}
}
}));
}
}
public interface MainView extends BaseView {
/**
-
搜索物品返回
-
@param response
*/
void getSearchResponse(TrashResponse response);
/**
-
搜索物品异常返回
-
@param throwable
*/
void getSearchResponseFailed(Throwable throwable);
}
}
下面回到MainActivity,先删掉上一篇添加的代码,然后修改代码如下图所示:
之后你需要重写五个方法。
@Override
public void initData(Bundle savedInstanceState) {
}
@Override
public int getLayoutId() {
return 0;
}
@Override
protected MainContract.MainPresenter createPresenter() {
return null;
}
@Override
public void getSearchResponse(TrashResponse response) {
}
@Override
public void getSearchResponseFailed(Throwable throwable) {
}
下面会一一修改这五个方法。
在上一篇文章中说到返回的是一个可变数组数据,那么是采用列表来显示,有列表,自然要有列表适配器,而列表适配器里面使用了item的布局。在layout下创建item_search_rv.xml,里面的代码如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:id=“@+id/item_search_goods”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginTop=“@dimen/dp_1”
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
实战系列
话不多说,Android实战系列集合都已经系统分类好,由于文章篇幅问题没法过多展示
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
Override
protected MainContract.MainPresenter createPresenter() {
return null;
}
@Override
public void getSearchResponse(TrashResponse response) {
}
@Override
public void getSearchResponseFailed(Throwable throwable) {
}
下面会一一修改这五个方法。
在上一篇文章中说到返回的是一个可变数组数据,那么是采用列表来显示,有列表,自然要有列表适配器,而列表适配器里面使用了item的布局。在layout下创建item_search_rv.xml,里面的代码如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:id=“@+id/item_search_goods”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginTop=“@dimen/dp_1”
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-2RzRTRbK-1713750572376)]
[外链图片转存中…(img-i3dItFUA-1713750572378)]
[外链图片转存中…(img-Zqv7BdWy-1713750572379)]
[外链图片转存中…(img-il2j69Ou-1713750572380)]
[外链图片转存中…(img-t5B11rMw-1713750572381)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
[外链图片转存中…(img-9LochS7t-1713750572382)]
实战系列
话不多说,Android实战系列集合都已经系统分类好,由于文章篇幅问题没法过多展示
[外链图片转存中…(img-xQrdz5m4-1713750572383)]
[外链图片转存中…(img-8mSlWHgj-1713750572384)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!