今天来说,就是学习了如果从一个RecyclerView的一个item点击后进入另一个界面,在进入另一个界面的时候就是向服务器那边获得数据,然后向界面放置数据去,在这个过程中,运用了MVC框架和回调的机制
一,首先是与后台进行数据的交流,今天后台给我的数据大致就是如下面的例子
{
"code": 0,
"msg": "查询成功",
"data": {
"number": 0,
"size": 20,
"totalElements": 18,
"content": [
{
"equipmentId": "092219031001",
"sid": 3,
"equipmentName": "092219031001",
"equipmentQrcode": null,
"equipmentLon": null,
"equipmentLat": null,
"equipmentModel": null,
"equipmentType": null,
"manufacturerName": null,
"manufacturerId": null,
"productionDate": null,
"equipmentxz": null,
"stationId": null,
"equipmentBname": null,
"macAddr": null,
"startOnlineTime": null,
"stopOnlineTime": null,
"dbTime": null,
"power": null,
"nationalStandard": null,
"status": null,
"useCode": null,
"supportOrder": null,
"businessHours": null,
"payType": null,
"isValid": null,
"createTime": 1564540391000,
"updateTime": 1564540391000,
"guns": [
{
"gid": "09221903100101",
"state": 0
},
{
"gid": "09221903100102",
"state": 0
}
]
},
{
"equipmentId": "092219031002",
"sid": 3,
"equipmentName": "092219031002",
"equipmentQrcode": null,
"equipmentLon": null,
"equipmentLat": null,
"equipmentModel": null,
"equipmentType": null,
"manufacturerName": null,
"manufacturerId": null,
"productionDate": null,
"equipmentxz": null,
"stationId": null,
"equipmentBname": null,
"macAddr": null,
"startOnlineTime": null,
"stopOnlineTime": null,
"dbTime": null,
"power": null,
"nationalStandard": null,
"status": null,
"useCode": null,
"supportOrder": null,
"businessHours": null,
"payType": null,
"isValid": null,
"createTime": 1564540391000,
"updateTime": 1564540391000,
"guns": [
{
"gid": "09221903100201",
"state": 0
},
{
"gid": "09221903100202",
"state": 2
}
]
}
}
也就是说当你访问那个接口成功后,后台就会返回给你这个responBody的Json的格式,由此来看,我们首先需要做的是
(1)确定好需要用到的是Post还是GET的格式,
(2)我们这边自己封装好后的某些框架就会把这个JSON的数据变成一个String的字符串格式,那么此时我们就需要调用
JSONObject object1 = JSON.parseObject(object);//这个object就是我们变成的一个String的字符串格式,这里的作用就是变成一个JSONObject
然后此时我们就需要看好后台给我们的是哪一些键了,比如上面有返回一个 code的东西。此时我们就可以通过下面的代码来获得这个code的值是什么,从而来判断是不是返回成功
int code = object1.getInteger("code");//object1就运用到了
可以看到当code是0的时候,这个时候,那么就是成功,那么就是能得到data的数据
此时我们就可以通过下面的代码来获得data
JSONObject data = object1.getJSONObject("data");
经过获得data我们可以发现,其实data里面的content存放的就是一个数组,那么我们就应该使用下面的代码来获得数组的
JSONArray content = data.getJSONArray("content");//JSONArray就是把content里面的东西按照一个一个去把它们放置到数组里去使用
那么此时就应该使用一个for循环来把需要得到的数据放到自己所需要的地方去,而有时候,我们在一个数组里面的一格子的里面存放的数据里面也包含了一个数组,那么此时我们就需要在for循环里面再建立一个新的for循环,依次去获得我们需要的数据,然后把数据存放到我们所建立的类里面去
如下面的代码
for (int i =0;i<content.size();i++){
JSONObject o = content.getJSONObject(i);//这里的作用就是等于获得数组里面的一格存放的东西。此时就是那个o
String equipmentId = o.getString("equipmentId");//这里的作用就是把那个格子里面的东西按照后台所写的那些键去获得出
JSONArray content1 = o.getJSONArray("guns");//
List<Gun> gunList = new ArrayList<>();
Gun gun = new Gun();
for (int i1=0;i1<content1.size();i1++){
JSONObject o1 = content1.getJSONObject(i1);
String mGid = o1.getString("gid");
int mState = Integer.parseInt(o1.getString("state"));
gun.setGid(mGid);
gun.setState(mState);
gunList.add(gun);
}
EquipmentMsg equipmentMsg = new EquipmentMsg();
equipmentMsg.setEquipmentId(equipmentId);
equipmentMsg.setGuns(gunList);
mEquipmentMsgs.add(equipmentMsg);//这边的作用的作用就是我们已经从服务器那边获得了数据并把那些数据放置到我们所需要的那些类里面去了
}
mView.onEquipmentCallback(mEquipmentMsgs);
}
二.这部分要讲的是使用MVC的格式来对界面进行传递数据
这里我们可以看到在上面的代码中有这么一段代码
mView.onEquipmentCallback(mEquipmentMsgs);
这段代码的作用就是把我们从服务器那边得到的数据,使用回调机制去显示在列表上去
(1)要使用MVC,那么就先需要建立一个接口,里面存放的是回调的代码,如下面的代码
public interface IMonitorView extends IView {
void onStationCallback(List<MonitorMsg> data);
void onEquipmentCallback(List<EquipmentMsg> data);
}
然后建立一个抽象类去继承上面的接口
public abstract class MonitorViewImpl implements IMonitorView {
@Override
public void onStationCallback(List<MonitorMsg> data) {
}
@Override
public void onEquipmentCallback(List<EquipmentMsg> data) {
}
}
(2)然后就需要建立一个IController的接口,里面最好包含了这个方法,用来退出活动时取消与View的联系
public interface IController {
void onDestroy();
}
然后建立一个基础的类用来后面的类可以的进行是哦那个
public class BaseController<V extends IView> implements IController {
protected V mView;
public BaseController(V view) {
this.mView = view;
}
@Override
public void onDestroy() {
this.mView = null;//在这里取消联系
}
}
然后建立一个实用的类,如下面的某个类
public class MonitorController extends BaseController<IMonitorView> {
private List<MonitorMsg> mData = new ArrayList<>();//这个的作用就是用来存放从后台获得的数据的
private List<EquipmentMsg> mEquipmentMsgs = new ArrayList<>();
public MonitorController(IMonitorView view) {
super(view);
}
这里的IMonitorView就是我们上面所设计的包含回调的类
在这边我们看见没有,mView的存在,但是确实在上面的后台处理却可以使用
mView.onStationCallback(mData);
这是因为mView已经在BaseController里面使用protected这个权限来让子类可以使用了
最后就是我们需要在activity或是fragment里面去使用了
首先我们需要添加下面的代码
private MonitorController mMonitorController;//建立一个Controller的引用,然后在onCreate()周期里面去实例化
下面的代码就是我们所建立的回调的的就是实现,也就是我们在Controller中使用mView.onEquipmentCallback(mData);
但是具体的实现的功能的代码是在这里实现的
private MonitorViewImpl monitorCallback = new MonitorViewImpl() {
@Override
public void onFailure(String s) {
}
@Override
public void onEquipmentCallback(List<EquipmentMsg> data) {
if (mAdapter != null) {
mAdapter.setItems(data);
}
}
};
最重要的就是早onCreate()方法里面去添加下面的代码,不然是没有起到作用的
mMonitorController = new MonitorController(monitorCallback);//也就是把回调赋给Controller
然后正常情况下面,我们会去在
onCreateView()方法里面去调用Controller里面的方法,如下面的代码
mMonitorController.getEqupiment(0);
三.利用RecyclerView来进行数据的展示
对于RecyclerView来说,我们首先就需要创建一个自己的Adapter,如下面的就是我创建的一个Adapter
public class MonitorDetailListAdapter<T extends Object> extends RecyclerView.Adapter<MonitorDetailListAdapter.MonitorViewHolder> {
private List<EquipmentMsg> mItems;//根据需求来设计出列表的东西
public MonitorDetailListAdapter() {
mItems = new ArrayList<>();//必须初始化,不然就会爆出空指针的错误
}
public void setItems(List<EquipmentMsg> items) {
mItems = items;
notifyDataSetChanged();
}
@NonNull
@Override
public MonitorViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_monitor_detail_item, viewGroup, false);//联系好我们自己设计好的item的界面
return new MonitorViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MonitorViewHolder orderViewHolder, int i) {
orderViewHolder.mStationName.setText(mItems.get(i).getEquipmentId());//列表的排序是多少个就对应着哪一个的序号的
orderViewHolder.mGunSize.setText(mItems.get(i).getGuns().size() + "个插枪");//这边的数据就是通过我们从后台得到的数据来设置好界面上的数据
}
@Override
public int getItemCount() {
return mItems.size();
}
static class MonitorViewHolder extends RecyclerView.ViewHolder {
private TextView mStationName;//充电桩的ID
// private TextView mState;//状态
private TextView mGunSize;
MonitorViewHolder(@NonNull View itemView) {
super(itemView);
mStationName = itemView.findViewById(R.id.monitor_station_detail_name);//绑定好界面之间的关系
mGunSize = itemView.findViewById(R.id.monitor_detail_status);
}
}
}
而今天踩到的最大的坑就是,我在某个界面还没出现的时候就去获得它的数据,也就是说,我是先跳转到另一个界面,但是却是在另一个界面去使用Controller来获得另一个界面的数据,可想而是当然是获取不到数据了,因为当界面跳转后,其实前面的那个活动一个消失了,此时活动都没有了,怎么调用,所以,用获得另一个界面的数据,最好就是放在另一个界面去获得,也就是先跳转界面,然后去另一个界面去获得数据,如下面的代码
mAdapter.setItemClickListener(new OnRecyclerViewClickListener() {
@Override
public void onItemClickListener(View view) {
Log.d("小邱" ,"onItemClickListener: ");
// int position = mRecyclerView.getChildAdapterPosition(view);//获得列表对应的那个数目
Intent intent = new Intent(AppUtils.getContext(), MonitorContainerActivity.class);
AppUtils.getContext().startActivity(intent);
// mMonitorController.getEqupiment(position);//这个是错的这个是错的
}
@Override
public void onItemLongClickListener(View view) {
}
});
从上面来说,就是具体的另一个界面的数据也就是在MonitorContainerActivity里面去处理的的,或是在这个activity的fragment里面去获得,而对于是哪一个iitem的话,我们可以使用
int position = mRecyclerView.getChildAdapterPosition(view);//获得列表对应的那个数目来
这个来获得那个item,有时需要把这个position来传给下面的界面,然后下面的界面根据这个数来进行不同的服务器请求,获得不同的数据并显示不同的数据列表
好的,今天的总结完毕了,学习的最好方法就是实战,加油啊邱,向啊里出发,睡觉了,晚安。