今天來說,就是學習了如果從一個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來傳給下面的界面,然後下面的界面根據這個數來進行不同的伺服器請求,獲得不同的資料并顯示不同的資料清單
好的,今天的總結完畢了,學習的最好方法就是實戰,加油啊邱,向啊裡出發,睡覺了,晚安。