智慧北京[下篇]
承接上篇文章 : 智慧北京[上篇]
一,網絡請求
- 本項目服務器端數據的獲取採用的是 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的指示器,能實現豐富多彩的指示效果