4.怎么获取Rss feeds数据?
我在这里使用的是volley + 自定义的xmlRequest,在文章底部有附源码,主要写大概获取和使用方式:
首先自定义一个接口:
public interface RssLoadListener {
void onLoadSuccess(List<RssInfo> rssInfoList);//获取成功
void onLoadFailed();//获取失败
void onNetWorkFailed();//网络错误
void onBeginLoad();//开始任务
}
让RssLoad下载任务时候实现这个接口并作为参数传进去, 有了这个接口,我们在哪里需要下载数据的时候就可以这么应用:
new RssLoadModel(context,RSS_URL).excute(new RssLoadListener() {
@Override
public void onBeginLoad() {
view.showLoading();//刚开始下载的操作
}
@Override
public void onLoadSuccess(List<RssInfo> rssInfoList) {
//下载成功后要做什么
Log.d(TAG, "onLoadSuccess: ");
view.hideLoading();
view.showResult(rssInfoList);
}
@Override
public void onLoadFailed() {
//若失败后的操作
view.hideLoading();
view.showError("更新失败");
}
@Override
public void onNetWorkFailed() {
view.showError("网络不可用");
view.hideLoading();
}
});
RssLoadModel是一个负责下载的类,里面的excute方法负责下载,并在下载过程中调用loadListener的方法,比如下载成功就调用onLoadSuccess(),至于里面成功后应该怎么做,就由你来实现,这样就达到了将状态和结果传递出去的目的。
public void excute(final RssLoadListener loadListener){
if(!NetworkUtils.isNetworkAvailable(context)){
loadListener.onNetWorkFailed();//网络失败
return;
}
loadListener.onBeginLoad();
XMLRequest xmlRequest = new XMLRequest(Constants.RSS_URL,
new Response.Listener<XmlPullParser>() {
@Override
public void onResponse(XmlPullParser response) {
parserXML(response);
loadListener.onLoadSuccess(rssInfos);
//调用下载成功,将结果传递出去
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
loadListener.onLoadFailed();//失败
}
});
mQueue.add(xmlRequest);
}
XMLRequest 是继承volley.Request的自定义类,volley是一个方便Android应用网络操作框架,默认没有XML的request,(宝宝不开心):
public class XMLRequest extends Request<XmlPullParser> {
private final Response.Listener<XmlPullParser> mListener;
public XMLRequest(int method, String url, Response.Listener<XmlPullParser> listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
public XMLRequest(String url, Response.Listener<XmlPullParser> listener, Response.ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
//需要加,否则获取不到数据
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/xml; charset=utf-8");
return headers;
}
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
try {
String xmlString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
Log.d("tag",xmlString);
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlString));
return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(XmlPullParser response) {
mListener.onResponse(response);
}
}
5.mvp
VIew
-
MvpView类是个接口
public interface MvpView {}
-
RssView 继承MvpView接口,具体的View类需要实现下面的方法,那么presenter想要控制具体的View类操作,就可以直接调用showLoading()等方法,这也是针对抽象编程。
public interface RssView extends MvpView {
/**
* 显示loading下载视图
*/
void showLoading();
/**
*隐藏loading下载视图
*/
void hideLoading();
/**
* 显示错误信息
* @param msg
*/
void showError(String msg);
/**
* 显示结果
* @param rssInfos
*/
void showResult(List<RssInfo> rssInfos);
/**
* @param title
*/
void showTitle(String title);
}
-
具体的view类,这里使用Activity作为view类,现在很多都将fragment作为view,将activity控制生命周期。
public class MainActivity extends BaseActivty implements RssView
需要实现下列方法,实现这么多方法给谁调用呢?当然是Presenter了。
@Override
public void showLoading() {//显示下载
progressWheel.setVisibility(View.VISIBLE);
swipeRefreshLayout.setVisibility(View.GONE);
ValueAnimator progressFadeInAnim = ObjectAnimator.ofFloat(progressWheel, "alpha", 0, 1, 1);
progressFadeInAnim.start();
}
@Override
public void hideLoading() {//隐藏下载
progressWheel.setVisibility(View.GONE);
swipeRefreshLayout.setVisibility(View.VISIBLE);
swipeRefreshLayout.setRefreshing(false); // close refresh animator
ValueAnimator progressFadeInAnim = ObjectAnimator.ofFloat(progressWheel, "alpha", 1, 0, 0);
progressFadeInAnim.start();
}
@Override
public void showError(String msg) {//显示错误信息
new SweetAlertDialog(this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText(msg)
.show();
}
@Override
public void showResult(List<RssInfo> rssInfos) {//显示结果
rssAdapter.setRssInfos(rssInfos);
}
@Override
public void showTitle(String title) {//显示标题
((TextView)findViewById(R.id.toolbar_title)).setText(title);
}
Presenter
MvpPresenter 接口,里面有两个方法attachView和detachView,负责将MvpView 绑定在MvpPresenter和解除绑定;例如在view类里面调用
presenter.attachView(this);
将自己传进去,这样 presenter就拥有了view,也就可以随心所欲地控制view了,Presenter通过接口进行对View的操作。
public interface MvpPresenter<V extends MvpView> {
/**
* 将 MvpView 绑定在MvpPresenter
* @param view
*/
public void attachView(V view);
/**
* @param retainInstance
* 解除绑定
*/
public void detachView(boolean retainInstance);
}
RssPresenter类
/**
* Created by cheng on 16-7-24.
*/
public class RssPresenter implements MvpPresenter<RssView> {
private final static String TAG = "RssPresenter";
private RssView view;
private Context context;
public RssPresenter(Context context) {
this.context = context;
}
public void startLoadTask() {//开始下载
if (view == null) {
Log.w(TAG, "please attach view first.");
return;
}
new RssLoadModel(context,RSS_URL).excute(new RssLoadListener() {
@Override
public void onBeginLoad() {
view.showLoading();
}
@Override
public void onLoadSuccess(List<RssInfo> rssInfoList) {
Log.d(TAG, "onLoadSuccess: ");
view.hideLoading();
view.showResult(rssInfoList);
}
@Override
public void onLoadFailed() {
view.hideLoading();
view.showError("更新失败");
}
@Override
public void onNetWorkFailed() {
view.showError("网络不可用");
view.hideLoading();
}
});
}
@Override
public void attachView(RssView view) {
this.view = view;
}
@Override
public void detachView(boolean retainInstance) {
// TODO
}
}