1. 程式人生 > >做專案過程中遇到的那些坑

做專案過程中遇到的那些坑

佈局分析圖

這裡寫圖片描述
首先寫公共類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());