RecyclerView布局

RecyclerView获得行布局下标的两种方式

一.创建事件处理接口

1
2
3
4
5
public interface OnClickRecycler {

public void clickRecycler(int position);
public void longClickRecycler(int position);
}

二.创建适配器

说明:本篇文章主要说明获得行布局控件下标的两种方式,如果还有其他方式大家可以留言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {

private List<Bean.T1348647853363Bean> beans;
private Context context;
private OnClickRecycler clickListener;

public RecyclerViewAdapter(Context context, List<Bean.T1348647853363Bean> beans){
this.beans = beans;
this.context = context;
}

public void setListener(OnClickRecycler clickListener){
this.clickListener = clickListener;
}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.itemlayout,viewGroup,false);

MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, final int i) {
Bean.T1348647853363Bean info = beans.get(i);
Glide.with(context).load(info.getImgsrc()).into(myViewHolder.imageView);
myViewHolder.textView.setText(info.getTitle());
myViewHolder.itemView.setTag(i);

//方式一:绑定时处理事件
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.clickRecycler(i);
}
});

myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
clickListener.longClickRecycler(i);
return true;
}
});
}

@Override
public int getItemCount() {
return beans.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder{

private TextView textView;
private ImageView imageView;

public MyViewHolder(@NonNull final View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.txt_item);
imageView = itemView.findViewById(R.id.img_item);

//方式二:ViewHolder类中实现事件处理,使用getTag()获得下标
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//itemView.getTag()返回绑定的下标
clickListener.clickRecycler((Integer) itemView.getTag());
}
});

itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
clickListener.longClickRecycler((Integer) itemView.getTag());
return true;
}
});
}
}
}

okgo使用

一.返回值接口

1
2
3
public interface IOKgoResult<T> {
public void getResult(T something);
}

二.定义下载工具类

封装支持所有数据类型的下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class OKGoUtils {

private static OKGoUtils OK_GO_UTILS = null;
private IOKgoResult ioKgoResult;

public static OKGoUtils getInstance(){
if(OK_GO_UTILS == null)
OK_GO_UTILS = new OKGoUtils();
return OK_GO_UTILS;
}

private OKGoUtils(){

}

/**
* 此方法必须调用
* @param ioKgoResult
*/
public void setOKResult(IOKgoResult ioKgoResult){
this.ioKgoResult = ioKgoResult;
}

/**
* callback说明
* StringCallback:操作字符串
* BitmapCallback:操作图片
*/
public void stringGet(){
OkGo.<String>get(Strings.URL_STR).execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
ioKgoResult.<String>getResult(response.body().toString());
}
});
}

public void bitmapGet(){
OkGo.<Bitmap>get(Strings.URL_STR).execute(new BitmapCallback() {
@Override
public void onSuccess(Response<Bitmap> response) {
//自行做处理
}
});
}

/**
* 封装返回任意类型的方法
* 说明:先执行convertResponse()将该方法的返回值返给onSuccess()
*/
public void test(){

OkGo.<Bean> get(Strings.URL_STR).execute(new AbsOkgoUtils<Bean>() {
@Override
public void onSuccess(Response<Bean> response) {
//使用回调函数
Bean result = response.body();
ioKgoResult.<Bean>getResult(result);
}

/**
* 这个方法主要负责解析
* @param response
* @return
*/
@Override
public Bean convertResponse(okhttp3.Response response) {
ResponseBody bean = response.body();

try {
String json_str = bean.string();
Gson gson = new Gson();
Bean bean1 = gson.fromJson(json_str,Bean.class);
return bean1;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
});
}
}

retrofit的初步使用

本篇文章从一个角度说明为什么retrofit会搭配rxjava一起使用

一.定义请求接口

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 使用get请求
* @Get(网址)方法参数:网址中需要的参数
*/
public interface IRetrofitResult {

@GET("/nc/article/headline/T1348647853363/0-40.html")
Call<ResponseBody> getInfo();

//观察者
@GET("/nc/article/headline/T1348647853363/0-40.html")
Observable<Bean> getBean();
}

二.封装retrofit工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* 使用retrofit框架下载数据
*/
public class RetrofitUtils {

IOKgoResult<Response<ResponseBody>> result;
IOKgoResult<Bean> result2;

public void setResult(IOKgoResult<Response<ResponseBody>> result){
this.result = result;
}

public void setResult2(IOKgoResult<Bean> result2){
this.result2 = result2;
}

/**
* retrofit底层封装了OKHttp框架,真正的下载还是由OKHttp来实现
* 说明:使用enqueue()实现异步下载
*/
public void getStr(){

OkHttpClient client = new OkHttpClient.Builder().build();

Retrofit rbuilder = new Retrofit.Builder()
.baseUrl(Strings.BASE_URL)
.client(client).build();

IRetrofitResult retrofitResult = rbuilder.create(IRetrofitResult.class);
Call<ResponseBody> info = retrofitResult.getInfo();
info.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
result.getResult(response);
}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {

}
});
}

/**
* 使用retrofit执行下载,调用execute()执行同步请求
* 没有rxjava的时候,如果使用retrofit同步方式下载会报错
* 解决方式:1.new Thread
* 2.使用Rxjava
*/
public void getStr_tongbu(){

OkHttpClient client = new OkHttpClient.Builder().build();

Retrofit retrofit = new Retrofit.Builder().
client(client)
.baseUrl(Strings.BASE_URL)
.build();

IRetrofitResult retrofitResult = retrofit.create(IRetrofitResult.class);

Response<ResponseBody> bodyResponse;

try {
bodyResponse = retrofitResult.getInfo().execute();
result.getResult(bodyResponse);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 使用retrofit同步+rxjava
*/
public void rxjavaTest(){

OkHttpClient client = new OkHttpClient.Builder().build();

Retrofit retrofit = new Retrofit.Builder().
client(client)
.baseUrl(Strings.BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();

IRetrofitResult retrofitResult = retrofit.create(IRetrofitResult.class);

//被观察者
Observable<Bean> observable = retrofitResult.getBean();
//被观察者订阅观察者(Observer是观察者)
/**
* 观察者创建的两种方式
* 方式一:new Observer
* 方式二:new Subscriber
* 区别:底层是将方式一转换为方式二执行,并且方式二新增onStart()方法
*/
// observable.subscribe(new Observer<ResponseBody>() {
// @Override
// public void onCompleted() {
//
// }
//
// @Override
// public void onError(Throwable e) {
//
// }
//
// @Override
// public void onNext(ResponseBody responseBody) {
//
// }
// });

// observable
// .observeOn(AndroidSchedulers.mainThread())
// .subscribeOn(Schedulers.io())
// .subscribe(new Subscriber<Bean>() {
// @Override
// public void onCompleted() {
//
// }
//
// @Override
// public void onError(Throwable e) {
//
// }
//
// @Override
// public void onNext(Bean responseBody) {
// result2.getResult(responseBody);
// }
// });

/**
* 观察者中的方法可以使用Action对象来单独处理
* subscribe()
*/
//处理next方法
Action1<Bean> onNext = new Action1<Bean>() {
@Override
public void call(Bean bean) {
result2.getResult(bean);
}
};

//处理异常的对象
Action1<Throwable> error = new Action1<Throwable>() {
@Override
public void call(Throwable e) {
Log.d("amy",e.getMessage());
}
};

observable
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(onNext,error);
}
}

okhttp使用

异步、同步下载

一.返回结果接口

public interface IDownloadResult {

    public void success(String str);
    public void  error(String str);
}

二.工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class OKHttp {

private static OKHttp okhttp = null;
private OkHttpClient client;

private OKHttp(){

}

public static OKHttp getInstance(){
if(okhttp == null){
synchronized (OKHttp.class){
if(okhttp == null)
okhttp = new OKHttp();
}
}
return okhttp;
}

IDownloadResult result;

public void setResult(IDownloadResult result){
this.result = result;
}

//返回Client对象
private OkHttpClient getClient(){
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5000, TimeUnit.MILLISECONDS)
.readTimeout(2000,TimeUnit.MILLISECONDS)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
/**
* 返回response,先获得request再通过调用proceed方法得到response
*/
Request request = chain.request();

Log.d("amy", String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);

return response;
}
})
.build();
return client;
}

/**
* 异步下载
*/
public void downLoadJsonStr(){

client = getClient();

final Request request = new Request.Builder().get().
url(Strings.URL_STR).build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
result.error(e.getMessage());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
result.success(response.body().string());
}
});
}

//同步下载(调用时需要创建线程)
public void downLoadJsonStr_tongbu(){
client = getClient();

Request request = new Request.Builder().url(Strings.URL_STR).build();

try {
Response response = client.newCall(request).execute();
result.success(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}

AndroidStudio搭建

@TOC

                        凉州词

        葡萄美酒夜光杯,欲饮琵琶马上催。

        醉卧沙场君莫笑,古来征战几人回? 


酒筵上甘醇的葡萄美酒盛满在精美的夜光杯之中,歌伎们弹奏起急促欢快的琵琶声助兴催饮,想到即将跨马奔赴沙场杀敌报国,战士们个个豪情满怀。今日一定要一醉方休,即使醉倒在战场上又何妨?此次出征为国效力,本来就打算马革裹尸,没有准备活着回来。俗话说工欲善其事必先利其器,想要成为Android大神,首先我们需要有一把锋利的武器,那么我们就开始组装武器吧!!

安装须知

一. 首先把组装武器的材料准备好,去我的百度网盘下载吧
https://pan.baidu.com/s/1xbVlZSO7gwCVmN_vGeDp3A
提取密码 asat

  1. AndroidStudio
    是一个Android集成开发工具,基于IntelliJ IDEA.。
    类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试。
  2. SDK (software development kit)软件开发工具包。
  3. gradle4.4 Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。

    安装AndroidStudio

    双击android-studio-ide-173.4670197-windows
    一直next
    直到如下界面
    在这里插入图片描述
    点击ok
    会出现如下界面
    在这里插入图片描述
    选择calcel
    之后会出现如下界面
    在这里插入图片描述
    点击next
    出现如下界面
    在这里插入图片描述
    选择Custom,之后一路next
    直到出现如下界面
    在这里插入图片描述
    将Android SDK Location改为你的SDK所在的位置
    比如我的SDK路径为 D:\Android\AndroidSDK\SDK\AndroidStudioSDK
    那么我就应该修改Android SDK Location如下图所示
    在这里插入图片描述
    一路next直到finish, 解压安装SDK比较耗时
    接着会出现如下界面
    在这里插入图片描述
    选择Start a new Android Studio project
    一路next直到finish
    会进入到如下页面
    在这里插入图片描述
    此时会去网络下载gradle,比较耗时,那么我们就需要注销系统,并将刚刚下载的gradle-4.4-all压缩包放到指定的目录下

C:\Users\Administrator.gradle\wrapper\dists\gradle-4.4-all\9br9xq1tocpiv8o6njlyu5op1目录下面

接下来重新启动AndroidStudio
在同步的过程中还会报缺少sdk 26的错误,那么我们就下载一个sdk26
在这里插入图片描述
点击红色箭头进行SDK的下载

进入到如下界面
在这里插入图片描述
选中红色部分进行下载就可以了
下载完后再回到刚刚报错的工程,点击try again进行工程的同步!!!

至此AndroidStudio工具的安装就成功了!!!!!!

配置环境变量

类似于我们学习java需要配置环境变量,Android同样需要配置环境变量
1.打开环境变量配置窗口
属性–>高级系统设置–>环境变量

2.添加android系统环境变量(变量值为SDK中的platform-tools跟SDK中tools的目录)
变量名:android
变量值:D:\AndroidStudio\AndroidStudioSDK\platform-tools;D:\AndroidStudio\AndroidStudioSDK\tools

3.将android变量添加到path中
添加到最后 ;%android%

4.重启AndroidStudio即可
至此环境变量我们也已经配置完毕
当我们在cmd命令窗口 输入adb命令出现下面的图示 即表示环境变量配置成功

在这里插入图片描述

安装夜神模拟器

我们可以使用系统自带的模拟器,也可以使用市场上主流的模拟器. 我的电脑卡的要死,所以我就不用Android Studio自带的模拟器了,我倾向于使用夜神模拟器,下面我们一起来安装,并学习使用方法

安装包下载地址

https://pan.baidu.com/s/1sSrSMBIXihC_beZhllycwQ
提取密码 x2t5
在这里插入图片描述
启动完后将夜神模拟器设置成手机模式

在这里插入图片描述

AndroidStudio连接夜神模拟器

首先需要将夜神加入到系统环境变量中

1.将夜神bin文件路径加入到path环境变量中
D:\Program Files\Nox\bin添加到path环境变量中
添加过后如下图所示

在这里插入图片描述
2.在命令行执行如下命令进入到夜神目录
cd D:\program Files\Nox
3.在命令行执行如下命令链接AndroidStudio
nox_adb.exe connect 127.0.0.1:62001
在这里插入图片描述
验证是否链接成功
在这里插入图片描述
至此我们的环境就安装成功呢!!!!
在这里插入图片描述

RecyclerView适配器的封装及实现

一.封装万能适配器BaseAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* 支持传任意布局和任意实体类
* 支持增删改查
* 支持长按、点击事件
* //public abstract class A<T,VH extends A.ViewHolderJava<T>> extends RecyclerView.Adapter<VH>
*/
public abstract class BaseRecyclerAdapter<T,VH extends BaseRecyclerAdapter.BaseHolder>
extends RecyclerView.Adapter<VH>{

private List<T> datas = null;
private Context context;
protected int itemlayoutid; //行布局id


public BaseRecyclerAdapter(List<T> datas,Context context){
this.datas = datas;
this.context = context;
}
public BaseRecyclerAdapter(List<T> datas){
this.datas = datas;
}

@NonNull
@Override
public abstract VH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i);

@Override
public void onBindViewHolder(@NonNull VH baseHolder, int i) {

bindView_Holder(baseHolder,i);
}

@Override
public int getItemCount() {
return datas.size();
}

public abstract int setItemLayout();

public abstract void bindView_Holder(BaseRecyclerAdapter.BaseHolder baseHolder,int position);


/**
* 内部类holder
*/
public abstract class BaseHolder extends RecyclerView.ViewHolder{

public BaseHolder(@NonNull View itemView) {
super(itemView);
bindItem(itemView);
}
public abstract void bindItem(View view);
}

}

二.实现Adapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
public class SubAdapter extends BaseRecyclerAdapter{

ArrayList<Bean.T1348647853363Bean> datas;
Context context;
OnClickRecycler clickRecycler;

public SubAdapter(ArrayList<Bean.T1348647853363Bean> datas, Context context,OnClickRecycler onClickRecycler){
super(datas,context);
this.datas = datas;
this.context = context;
this.clickRecycler = onClickRecycler;
}

public SubAdapter(ArrayList<Bean.T1348647853363Bean> datas){
super(datas);
this.datas = datas;

}

public void setContext(Context context){
this.context = context;
}

public void setOnClickRecycler(OnClickRecycler onClickRecycler){
this.clickRecycler = onClickRecycler;
}

@NonNull
@Override
public BaseHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(setItemLayout(),viewGroup,false);
SubAdapter.SubHolder subHolder = new SubAdapter.SubHolder(view);

return subHolder;
}


@Override
public int setItemLayout() {
return R.layout.itemlayout;
}

@Override
public void bindView_Holder(BaseHolder baseHolder, final int position) {
SubAdapter.SubHolder subHolder = (SubAdapter.SubHolder)baseHolder;
Glide.with(context).load(datas.get(position).getImgsrc()).into(subHolder.imageView);

//修改行布局高度
ViewGroup.LayoutParams params = subHolder.textView.getLayoutParams();
int endHeight =(int) (200+Math.random()*(400-200+1));
params.height = endHeight;
subHolder.textView.setLayoutParams(params);

subHolder.textView.setText(datas.get(position).getTitle());
subHolder.imageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
clickRecycler.longClickRecycler(position);
return true;
}
});
subHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickRecycler.clickRecycler(position);
}
});
}


public void addData(Bean.T1348647853363Bean data){
if(data!= null){
datas.add(data);
notifyItemInserted(datas.size()-1);
}
}

public void addDatas(ArrayList<Bean.T1348647853363Bean> allData){
if(datas != null && datas.size()> 0){
int startIndex = datas.size();
datas.addAll(allData);
int endIndex = datas.size();
notifyItemRangeInserted(startIndex,endIndex);
}
}

public void removeData(int postion){
if(postion<= datas.size()){
datas.remove(postion);
notifyItemChanged(postion);

}
}

public void removeAll(){
datas.clear();
notifyDataSetChanged();
}


class SubHolder extends BaseHolder{

private TextView textView;
private ImageView imageView;

public SubHolder(@NonNull View itemView) {
super(itemView);
}

@Override
public void bindItem(View view) {
textView = view.findViewById(R.id.txt_item);
imageView = view.findViewById(R.id.img_item);
}
}
}