智慧北京[下篇]
承接上篇文章 : 智慧北京[上篇]
一,网络请求
- 本项目服务器端数据的获取采用的是 XUtils 框架进行网络请求。
- xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持,拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响,国产开源
- 正如其名字一样,该框架的确牛X。XUtils框架具有四大功能模块:网络请求(HttpUitls),View事件注解绑定(ViewUtils),图片处理(BitmapUtils),数据库操作(DbUtils)
XUtils项目地址:https://github.com/wyouflf/xUtils
使用xUtils快速开发框架需要有以下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
网络请求:
public void getDataFromService(HttpRequest.HttpMethod method,String url){
HttpUtils httpUtils = new HttpUtils();
httpUtils.send(method,url, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
//请求网络成功
}
@Override
public void onFailure(HttpException e, String s) {
//请求失败
}
});
}
View事件注解:(全注解方式就可以进行UI绑定和事件绑定)
public class MainActivity extends Activity{
//通过注解绑定控件
@ViewInject(R.id.textview)
TextView textView;
@ViewInject(R.id.button)
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.inject(this); //注解view和事件
}
//通过注解来设置Button的点击事件
@OnClick(R.id.button)
public void onButClick(View view){
Toast.makeText(this, "哎呀,我被点击啦...", Toast.LENGTH_SHORT).show();
}
}
更多使用细节请移步其GitHub地址:https://github.com/wyouflf/xUtils
二:缓存策略
- 智慧北京项目里的数据是缓存到SharedPreferences里的,具体缓存策略是:应用启动都后首先从缓存里读取数据,依靠列表的下拉刷新实现数据更新,这样给用户一个良好的体验。若缓存里没有数据再从服务器端获取数据,从服务器获取到数据后解析json数据然后填充到UI里,并且在SharedPreferences做一份json数据的缓存。
即:
String cacheData=sp.getCacheData();
if(cacheData!=null){
//读缓存,将数据填充UI。依靠listview的下拉刷新,实现数据及时更新,营造良好的用户体验,节约用户流量
......
}else{
//从服务器端获取数据,填充UI.并且在sp里做一份缓存。下次进入应用直接读缓存
......
}
- 当然你也可以将数据存储在File文件或SD卡里,考虑到有些手机可能没有SD卡,so一般数据的缓存大部分都是以xml方式存储在sp或 data/data/应用包名 的文件目录里
三:ViewPagerIndicator
- ViewPageIndicator,ViewPager想必大家都知道,而Indicator是指示器的意思,故ViewPageIndicator就是ViewPager的指示器,本项目新闻中心的新闻分类的滑动视图采用的就是ViewPagerIndicator来实现的
ViewPagerIndicator项目地址:https://github.com/JakeWharton/ViewPagerIndicator,下载其library库后集成到你工程里即可
- 如图:
此页面xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:background="#e0e0e4"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.viewpagerindicator.TabPageIndicator
android:id="@+id/tabPagerIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/next_pager_image"
/>
<ImageView
android:id="@+id/next_pager_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:layout_alignParentRight="true"
android:layout_marginRight="2dp"
android:layout_centerVertical="true"
android:padding="10dp"
android:src="@mipmap/news_cate_arr" />
</RelativeLayout>
<android.support.v4.view.ViewPager
android:id="@+id/detailnewsvpitemtpager_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
新闻详情类
public class DeatilNewsPager extends BaseMenuDetailPager {
@Bind(R.id.detailnewsvpitemtpager_viewpager)
ViewPager viewPager;
@Bind(R.id.tabPagerIndicator)
TabPageIndicator tabPageIndicator;
@Bind(R.id.next_pager_image)
ImageView imageButton_nextPager;
public int currentPosition;
private Activity activity;
private ArrayList<NewsJson.NewsChildrenData> childrenDatas;
private ArrayList<DetailNewsVpItemPager> detailNewsVpItemPagerArrayList;
public DeatilNewsPager(Activity activity, ArrayList<NewsJson.NewsChildrenData> children) {
super(activity);
this.childrenDatas = children;
}
@Override
public View initView(Activity activity) {
this.activity = activity;
View view = View.inflate(activity, R.layout.layout_detailnewsvpitemtpager, null);
ButterKnife.bind(this, view);
return view;
}
@Override
public void initData() {
Log.v("TAG", "加载侧滑视图----新闻");
//根据服务器端获取的item来加载页面数
detailNewsVpItemPagerArrayList = new ArrayList<>();
DetailNewsVpItemPager detailNewsVpItemPager;
//根据服务器端返回的数据结果,加载tab页数
for (int i = 0; i < childrenDatas.size(); i++) {
detailNewsVpItemPager = new DetailNewsVpItemPager(activity, childrenDatas.get(i));
detailNewsVpItemPagerArrayList.add(detailNewsVpItemPager);
}
//为vp绑定数据
viewPager.setAdapter(new VpAdapter());
//监听vp的滑动监听
MainActivity mainAty = (MainActivity) activity;
final SlidingMenu sdm = mainAty.getSlidingMenu();
//设置vp的指示器***
tabPageIndicator.setViewPager(viewPager);
tabPageIndicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//第一页开启侧滑,其他也则关闭侧滑
if (position == 0) {
sdm.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
} else {
sdm.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
}
currentPosition = position;
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
class VpAdapter extends PagerAdapter {
@Override
public int getCount() {
return detailNewsVpItemPagerArrayList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
//【依据vp的加载缓存机制,以下两个方法会不断的回掉。若vp包含的是fragment则回掉的是onCreateView()方法,销毁onDestroyView()】
@Override
public Object instantiateItem(ViewGroup container, int position) {
DetailNewsVpItemPager item = detailNewsVpItemPagerArrayList.get(position);
View view = item.mRootView;
container.addView(view);
//加载数据***
item.initData();
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public CharSequence getPageTitle(int position) {
return childrenDatas.get(position).title;
}
}
@OnClick(R.id.next_pager_image)
public void nextPagerClick(View view) {
int currentPosition = viewPager.getCurrentItem()+1;
if(currentPosition<detailNewsVpItemPagerArrayList.size()){
tabPageIndicator.setCurrentItem(currentPosition);//tabPageIndicator已经自动帮我们解决了角标越界问题
}
}
}
四:项目所用开源框架
SlidingMenu:https://github.com/jfeinstein10/SlidingMenu
侧滑菜单组件,实现左/右滑动打开菜单视图效果。XUtils: https://github.com/wyouflf/xUtils
- HttpUtils:支持同步,异步方式的请求,支持大文件上传,上传大文件不会oom
- ViewUtils:以注解方式绑定控件,android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定,简化findViewById和onClick
- Bitmaputils:图片的加载缓存,加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象
- DbUtils:数据库操作,android中的orm框架,一行代码就可以进行增删改查
Gson : https://github.com/google/gson
Gson 是 Google提供的用来在 Java对象和 JSON数据之间进行映射的 Java类库。可以将一个 JSON字符串转成一个 Java对象,或者反过来将一个java类对象转化为一个json对象
ViewPagerIndicator : https://github.com/JakeWharton/ViewPagerIndicator
ViewPager的指示器,能实现丰富多彩的指示效果