做專案過程中遇到的那些坑
佈局分析圖
首先寫公共類BasePager,在構造方法呼叫initView( )初始化view,該view是幾個子pager共有的比如標題欄,側滑的點選按鈕,還有initData()初始化資料;當孩子需要初始化資料;或者繫結資料;聯網請求資料並且繫結的時候,重寫該方法
在父佈局是RelativeLayout中居中的方法
Android:layout_centerInParent="true"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--標題欄-titlebar-->
<include layout="@layout/titlebar"/>
<!--各個頁面的檢視,都是新增到FrameLayout裡面,addView-->
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
在子pager的初始化資料會把子檢視view通過addView()新增到BasePager的FrameLayout中
左上角按鈕的開關左選單
ib_menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity mainActivity = (MainActivity) context;
mainActivity.getSlidingMenu().toggle();//關<->開
}
});
Viewpager的介面卡
@Override
public Object instantiateItem(ViewGroup container, int position) {
BasePager basePager=basePagers.get(position);//各個子頁面的例項
View rootView=basePager.rootView;//代表各個子頁面
//呼叫各個頁面的initData()方法
basePager.initData();
container.addView(rootView);
return rootView;//注意是返回rootView是該子頁面
}
注意是返回它的頁面而不是例項
遮蔽viewPager滑動,因為你想先左滑出選單,沒有遮蔽viewPager你會左滑到它的左頁面而不是左選單
方法:這時候只能自定義一個ViewPager,繼承ViewPager改寫它的方法
@Override
public boolean onTouchEvent(MotionEvent ev) {
return true;
}
這個方法是螢幕觸控事件的分發器,把返回值改為true,就是消費掉觸控事件,說白了就不會執行觸控事件了
按鈕點選切換頁面
rgMain.setOnCheckedChangeListener(new MyOnCheckedchangeListener());
class MyOnCheckedchangeListener implements
RadioGroup.OnCheckedChangeListener {
@Override
public void onCheckedChanged(RadioGroup group, @IdRes int
checkedId) {
switch (checkedId) {
case R.id.rb_home:
viewPager.setCurrentItem(0,false);//false設定沒有抖的那種動畫效果
break;
case R.id.rb_newscenter:
viewPager.setCurrentItem(1,false);
break;
case R.id.rb_smartservic:
viewPager.setCurrentItem(2,false);
break;
case R.id.rb_setting:
viewPager.setCurrentItem(3,false);
break;
}
}
}
遮蔽ViewPager資料預載入
有個現象,就是我剛開啟app,它會自動初始化前面兩個頁面資料,主頁面和新聞中心頁面,當我點選第二個新聞中心按鈕,它就初始化第三個頁面,點選第三個按鈕就初始化第四個頁面,所以我們要遮蔽掉Viewpager資料預載入方法:讓initData()不會被呼叫,本來想在每個子頁面的initData()在RadioButton的監聽被呼叫,其實這個不對,如果在左選單選擇呢,那就不會被初始化了,所以直接在該viewpager中呼叫,要在view的監聽器中呼叫,而不是介面卡所以好辦了,寫個處理ViewPager頁面滑動的監聽事件OnPageChangListener
//監聽某個頁面被選中,初始化對應的頁面的資料
viewPager.addOnPageChangeListener(new
MyaddOnPageChangeListener());
private class MyaddOnPageChangeListener implements
ViewPager.OnPageChangeListener {
//當頁面被滑動的時候被呼叫
@Override
public void onPageScrolled(int position, float positionOffset, int
positionOffsetPixels) {
}
//頁面跳轉完再後呼叫
@Override
public void onPageSelected(int position) {
basePagers.get(position).initData();
}
//狀態被改變的時候呼叫
@Override
public void onPageScrollStateChanged(int state) {
}
}
但是,剛進入的時候第一個頁面是沒有初始化的,所以要在初始化資料的時候呼叫第
一個頁面的initData()
遮蔽指定頁面不能拖拽出選單,因為有時候選單是為某個頁面設計的,不是所有的頁面有點尷尬,我本來的想法是在MainActivity設定為不可以拖拽,那在指定頁面設定拖拽,發現是行不通的,一旦觸控的到指定頁面設定為可以拖拽,後面的頁面都可以拖拽,所以要在每個頁面的觸控事件一個一個設定,還有,MainActivity設定為可以拖拽,否則那個選單按鈕按不了
重構(也就是把程式碼提取出來裝進去一個void方法)
alt +shift+m
手動解析
快取資料
在快取類
public static void putString(Context context, String key, String value) {
SharedPreferences sp = context.getSharedPreferences("NewsMessage",
Context.MODE_PRIVATE);
sp.edit().putString(key,value).commit();
}
在聯網請求之前獲取快取
String saveJson=CacheUtils.getString
(context,Constants.NEWSCENTER_PAGER_URL);
if(!TextUtils.isEmpty(saveJson)) {
processData(saveJson);
}
快取資料
在聯網請求之前先在getString快取裡看看有沒有以前儲存的Json,如果有就直接解析
資料,如果沒有就聯網請求(在聯網請求成功的方法裡putString快取資料)
配置聯網請求
聯網地址
編寫一個常量類Constants.java。配置聯網請求地址
public class Constants {
//聯網請求的ip和埠(伺服器地址)
public static final String BASE_URL=" URL地址 ";
//新聞中心的網路地址
public static final String NEWSCENTER_PAGER_URL=BASE_URL+" ";
點選右箭頭切換下一個頁面
在initView()方法新增
//Indicator右邊按鈕的點選事件
ib_tab_next.setOnClickListener(new MyTabNextListener());
private class MyTabNextListener implements View.OnClickListener {
@Override
public void onClick(View v) {
viewpPager_detail.setCurrentItem(viewpPager_detail.getCurrentItem()+1);
}
}
解決頁籤手指按下從左到右滑動的bug,有一種方法可以阻止父層的View截獲touch事件,就是呼叫getParent.requestDisallowInterceptTouchEvent(true)方法一旦底層View收到touch的action後呼叫這個方法那麼父層就不會再呼叫onIntercepTouchEvent了,也不會截獲以後的action
在NewsCenterPager請求網路連線,獲得資料,通過context獲得MainActivity再通過MainActivity根據tag獲得LeftmenuFragment,呼叫setData()方法將資料傳入LeftmenuFragment
在新聞中心的解析資料成功後,把詳情頁面新增到新聞中心
detailBasePagers = new ArrayList<>();
detailBasePagers.add(new NewsMenuDetailPager(context));
detailBasePagers.add(new TopicMenuDetailPager(context));
detailBasePagers.add( new PhotosMenuDetailPager(context));
detailBasePagers.add(new InteracMenuDetailPager(context));
//一層一層地去,先在MainActivity獲得ContentFragment,再在ContentFragment
獲得NewsCenterPager,然後在NewsCenterPager切換詳情頁面
ContentFragment contentFragment= mainActivity.getContentFragment();
NewsCenterPager newsCenterPager=
contentFragment.getNewsCenterPager();
newsCenterPager.swichPager(prePosition);
//注意以後監聽頁面的變化,TabPageIndicator監聽頁面的變化,當第0個頁面是可以拖拽出左選單,其他不可以
tabPageIndicator.setOnPageChangeListener(new MyOnPageChangeListener());
//監聽器類
private class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(position==0){
isEnaleSlidingMenu(SlidingMenu.TOUCHMODE_FULLSCREEN);
}else {
isEnaleSlidingMenu(SlidingMenu.TOUCHMODE_NONE);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
紅點設定
ll_point_group.removeAllViews();//移除所有紅點
for(int i=0;i<topNews.size();i++){
ImageView imageDot=new ImageView(context);
imageDot.setBackgroundResource(R.drawable.tab_imagedot_selector);
if(i==0){
imageDot.setEnabled(true);
}else {
imageDot.setEnabled(false);
}
ll_point_group.addView(imageDot);
}
監聽頁面的變化,設定紅點的變化和文字變化
viewPager_tab.setOnPageChangeListener(new MyOnPageChangeListener());