序言
最近快半個(gè)月沒(méi)寫博客畔规,不是偷懶而是在整理一些思路盗冷,最近的項(xiàng)目中開(kāi)始嘗試使用新框架丐枉,也一直在改進(jìn)中蕴潦,最后覺(jué)得差不多了準(zhǔn)備開(kāi)源出來(lái)蓬豁。10分鐘開(kāi)發(fā)網(wǎng)易新聞首頁(yè)有點(diǎn)夸大其詞,但是在我的Demo中修改一下樣式基本就能滿足大多數(shù)新聞客戶端的需求了熙掺,其他的APP更不在話下。
效果
1.這是長(zhǎng)截屏,主要展示的樣式的復(fù)雜度悠鞍,和網(wǎng)易新聞首頁(yè)相比差不了多少。
2.這是動(dòng)態(tài)效果模燥,集成了咖祭,下拉刷新,上拉加載更多蔫骂,錯(cuò)誤重試么翰,當(dāng)然這些界面都是可以自定義的。
3.直接使用布局文件實(shí)現(xiàn)自定義辽旋,最終框架將自動(dòng)替換與添加相應(yīng)的部分浩嫌。
布局文件如下
代碼就只有這么多
效果很爽
使用
1.配置
1.使用起來(lái)很簡(jiǎn)單,先看代碼
這是BaseFragment繼承自SmartListFragment戴已,而SmartListFragment就是我框架中的類了固该,這里面返回了當(dāng)前應(yīng)用的分頁(yè)策略,方便統(tǒng)一控制糖儡。
而首頁(yè)中就返回了一個(gè)配置文件的名字伐坏,這個(gè)配置文件放在res/raw下的。一切的黑科技都從配置文件開(kāi)始
我們來(lái)看看配置文件長(zhǎng)什么樣握联。就是一個(gè)很簡(jiǎn)單的json文件桦沉,為了方便截圖我收縮了一部分。
上面的文件對(duì)應(yīng)于這個(gè)類
而JsonAnalysisConfig定義如下:
例子
可能大家還不是很清楚金闽,我給大家做一個(gè)例子纯露,大家就明白了。以解析生成這個(gè)為例:
首先整體的數(shù)據(jù)結(jié)構(gòu)如下
我們關(guān)心的是這一部分
使用它去生成一個(gè)javabean,名字就叫channelItem可以使用Android Studio的Gson生成插件代芜。
接著我們編寫ViewHolder埠褪。
這是源碼很短,很簡(jiǎn)單實(shí)現(xiàn)了解耦:
package com.zgh.smartdemo.viewholder;
import android.content.Context;
import com.zgh.smartdemo.R;
import com.zgh.smartdemo.adapter.ChannelAdapter;
import com.zgh.smartdemo.bean.ChannelItem;
import com.zgh.smartdemo.util.ClickHelper;
import com.zgh.smartdemo.view.ChannelPageIndicator;
import com.zgh.smartdemo.view.PageGridView;
import com.zgh.smartlibrary.adapter.SmartAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zhuguohui on 2016/8/17.
*/
public class ChannelViewHolder extends SmartAdapter.SmartViewHolder<Object> {
@Override
public boolean isMyType(Object item) {
if (item instanceof List) {
List list = (List) item;
for (Object o : list) {
if (o == null) {
continue;
}
if (!(o instanceof ChannelItem)) {
return false;
}
}
return true;
}
return false;
}
@Override
public int getLayoutId() {
return R.layout.layout_channel;
}
protected PageGridView pageGridView;
ChannelPageIndicator channelPageIndicator;
ChannelAdapter adapter;
List<ChannelItem> channels = new ArrayList<>();
@Override
public void updateView(Context context, Object item) {
List<ChannelItem> channels = (List<ChannelItem>) item;
this.channels.clear();
this.channels.addAll(channels);
if (adapter == null) {
adapter = new ChannelAdapter(context, this.channels, getColums());
pageGridView.setAdapter(adapter);
pageGridView.setPageIndicator(channelPageIndicator);
pageGridView.setOnItemClickListener(new PageGridView.OnItemClickListener() {
@Override
public void onItemClick(PageGridView pageGridView, int position) {
ClickHelper.onClick(ChannelViewHolder.this.channels.get(position));
}
});
} else {
adapter.notifyDataSetChanged();
}
}
protected int getColums() {
return 4;
}
}
最后講我們的這些信息記錄到配置文件中
需要說(shuō)明的是jsonLocation挤庇,它的值是
//{表示解析一個(gè)對(duì)象钞速,[代表解析一個(gè)數(shù)據(jù),后面是數(shù)據(jù)的名字
//而[name:0 代表解析一個(gè)名叫name的json數(shù)據(jù)下面的第一個(gè)元素
{response[centers
我們來(lái)看看解析過(guò)程
如果不想被自動(dòng)填充為L(zhǎng)ist則在配置文件中設(shè)置如下屬性
打開(kāi)斷點(diǎn)看看數(shù)據(jù)解析出來(lái)的樣子
更多細(xì)節(jié)大家看Demo吧
個(gè)性化配置
1.數(shù)據(jù)解析器
覆蓋SmartListFragment的這個(gè)方法可以替換自己的數(shù)據(jù)解析器
前提實(shí)現(xiàn)這個(gè)接口
目前有一個(gè)默認(rèn)的實(shí)現(xiàn)
package com.zgh.smartlibrary.net.impl;
import android.content.Context;
import com.zgh.smartlibrary.net.NetRequest;
import com.zgh.smartlibrary.net.NetRequestHandler;
import com.zgh.smartlibrary.util.FileUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.builder.GetBuilder;
import com.zhy.http.okhttp.builder.HasParamsable;
import com.zhy.http.okhttp.builder.OkHttpRequestBuilder;
import com.zhy.http.okhttp.builder.PostFormBuilder;
import com.zhy.http.okhttp.callback.StringCallback;
import java.util.Map;
import okhttp3.Call;
/**
* Created by zhuguohui on 2016/9/6.
*/
public class SmartNetRequestHandler implements NetRequestHandler {
private final Context mContext;
private String HTTP_HEAD = "http";
private String HTTPS_HEAD = "https";
private String RAW_HEAD="raw://";
public SmartNetRequestHandler(Context context){
mContext=context;
}
@Override
public void handleNetRequest(final NetRequest netRequest) {
String url = netRequest.getUrl();
boolean isHttpRequest = false;
if (url != null && url.length() > 5) {
if (url.toLowerCase().startsWith(HTTP_HEAD) || url.toLowerCase().startsWith(HTTPS_HEAD)) {
isHttpRequest = true;
}
}
if(netRequest.getMethod()==null){
netRequest.setMethod(NetRequest.METHOD.GET);
}
if (isHttpRequest) {
GetBuilder getBuilder = null;
PostFormBuilder postFormBuilder = null;
OkHttpRequestBuilder requestBuilder;
HasParamsable hasParamsable;
switch (netRequest.getMethod()) {
case GET:
getBuilder = OkHttpUtils.get();
break;
case POST:
postFormBuilder = OkHttpUtils.post();
break;
}
requestBuilder = getBuilder != null ? getBuilder : postFormBuilder;
if (requestBuilder == null) {
onError(netRequest, "不支持的協(xié)議嫡秕!");
return;
}
hasParamsable = getBuilder != null ? getBuilder : postFormBuilder;
requestBuilder.url(url);
Map<String, String> params = netRequest.getParams();
if (params != null && params.size() > 0) {
for (String key : params.keySet()) {
hasParamsable.addParams(key, params.get(key));
}
}
requestBuilder.build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
SmartNetRequestHandler.this.onError(netRequest, e.getMessage());
}
@Override
public void onResponse(String response, int id) {
onSuccess(netRequest,response);
}
});
} else {
if(url.toLowerCase().startsWith(RAW_HEAD)){
String rawName = url.substring(RAW_HEAD.length());
String s = FileUtil.readRaw(mContext, rawName);
onSuccess(netRequest, s);
}else{
onError(netRequest,"不支持的協(xié)議渴语!");
return;
}
}
}
public void onError(NetRequest request, String msg) {
if (request != null && request.getResultListener() != null) {
request.getResultListener().onError(msg);
}
}
public void onSuccess(NetRequest request, Object data) {
if (request != null && request.getResultListener() != null) {
request.setData(data);
request.getResultListener().onSuccess(request);
}
}
@Override
public void cancelNetRequest(NetRequest netRequest) {
}
}
2.下拉刷控件替換
覆蓋這個(gè)方法
protected ListViewUpdateManger getUpdateManager(Context context){
return new PullToRefreshManger(context);
}
實(shí)現(xiàn)這個(gè)接口
/**
* 管理listview的上拉加載與下拉刷新
* Created by zhuguohui on 2016/9/5.
*/
public interface ListViewUpdateManger {
ListView getListView();
View getView();
void setState(IPagePolicy.PageState state);
void setAdapter(BaseAdapter adapter);
void setUpdateListener(UpdateListener listener);
interface UpdateListener {
void pullUp();
void pullDown();
}
void updateComplete();
void update(boolean showAnimation);
}
有一個(gè)默認(rèn)的實(shí)現(xiàn)PullToRefreshManger大家可以看看源碼
對(duì)數(shù)據(jù)進(jìn)行修改
對(duì)網(wǎng)絡(luò)請(qǐng)求修改
比如添加統(tǒng)一的token之類的
對(duì)頁(yè)面修改
1.代碼部分
2.布局部分
實(shí)現(xiàn)
東西太多看源碼吧