Android開發(fā)小工具-搖一搖顯示當前頁面信息

當項目工程越來越大之后腌零,大家都會覺得維護起來越來越吃力应役,如果測試或者UI拿著手機或者截圖說這個頁面和它的設想有點出入情组,告訴你是不是他們的姿勢不對,哈哈箩祥,別想啦院崇,他們是說你的頁面有bug了。

如果恰巧這些都是你寫的袍祖,那么很好的底瓣,你可以分分鐘找到指定的頁面,發(fā)現指定的問題盲泛,然后帥氣的解決。

但是键耕,在很多時候寺滚,由于歷史遺留等等一系列原因,可能你都不知道這是什么時候寫的頁面屈雄,敲的代碼了村视,但是既然問題都提給你了,你總不能說這個不是我寫的酒奶,找我們老大吧(這樣估計會沒有年終獎的啦)蚁孔。

扯了這么多奶赔,接下來說說怎么解決相關的問題呢?其實之前公司就已經考慮到這個問題杠氢,做了一個調試搖一搖的功能站刑,但是當時那個功能做的十分的簡陋,只能搖一搖顯示當前的Activity鼻百,如果你的 Activity 上面有事嵌套著 Fragment 的話绞旅,那么不好意思,不會顯示對應 Fragment 的信息温艇,更別說如果一個 Activity 上面包含了多個 Fragment 的情況因悲。

fragment.jpg

例如圖一中,是在 Activity 中上半部分嵌套了一個 Fragment1 勺爱,下半部分又加載了 Fragment2 晃琳,在 Fragment2 中是由三個 Fragment 組成的。

fragment-彈窗.jpg

需求明確之后琐鲁,那么就一步一步來完成對應的功能就好啦卫旱,結合上面的巴拉巴拉的一堆話,大致需要有以下功能:

1绣否、搖一搖的功能
2誊涯、獲取當前top的 Activity
3、獲取當前 Activity 中顯示的 Fragment
4蒜撮、彈窗顯示
5暴构、特殊情況處理

接下來就一個一個開始擼吧。

搖一搖功能

獲取當前top的 Activity

這個功能很好實現啦段磨,不管是 Google 還是百度取逾,都能很快的找到想要的代碼。相關思路就是獲取系統(tǒng)的 SensorManager ,然后注冊 SensorManager 的加速度監(jiān)聽器苹支,當加速度大于預設值就響應相關事件砾隅。這里只需要注意監(jiān)聽的時機和解除監(jiān)聽的時機。

public void onStart() {
    //獲取 SensorManager 負責管理傳感器
    mSensorManager = ((SensorManager) context.getSystemService(Context.SENSOR_SERVICE));
    if (isEnable && mSensorManager != null) {
        //獲取加速度傳感器
        Sensor mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (mAccelerometerSensor != null) {
            mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager.SENSOR_DELAY_UI);
        }
    }
}


public void onPause() {
    if (mSensorManager != null) {
        mSensorManager.unregisterListener(this);
    }
}

其實到這里债蜜,第二個問題 獲取當前top的Activity 也解決了晴埂。

獲取當前 Activity 中顯示的 Fragment

獲取當前 Activity 中顯示的 Fragment,其實就是說獲取到 Activity 中所有的 Fragment 寻定,這個呢儒洛,就是使用 FragmentManagermanager.getFragments() 方法就好啦,然后在這些 Fragment 中獲取到當前正在顯示的 Fragment 狼速。這里 Fragment 是否顯示是由以下兩個方法來判斷的:f.isAdded() 琅锻、f.isHidden()。為什么不用一個就好了呢?因為添加 Fragment 可能是 replace() 也有可能是 hide() , show() 的方式恼蓬,在 replace() 之后惊完,通過 FragmentManager 還是可以獲取到對應的 Fragment ,只是它的 isAdded() 將是 false处硬,而且此時 isHidden() 也是 false小槐,所以就會出問題啦! 這里還要考慮 Fragment 嵌套 Fragment 的情況郁油,所以還需要使用到 f.getChildFragmentManager() 的方法遞歸查詢一下本股。另外如果這里是使用 ViewPager 來模式管理 Fragment 的話,那么這里還需要判斷 f.getUserVisibleHint()的返回情況桐腌。

@Nullable
private List<Fragment> getTopFragments() {
    if (manager == null) {
        return null;
    }
    List<Fragment> fragments = manager.getFragments();
    List<Fragment> topFragments = new ArrayList<>();
    if (fragments == null) {
        return null;
    }
    int size = fragments.size();
    for (int i = size - 1; i >= 0; i--) {
        Fragment f = fragments.get(i);
        if (f.isAdded() && !f.isHidden() && f.getUserVisibleHint()) {
            Fragment t = getTopFragment(f.getChildFragmentManager());//遞歸
            if (t != null) {
                topFragments.add(t);
            } else {
                topFragments.add(f);
            }
        }

    }
    return topFragments;
}

@Nullable
private Fragment getTopFragment(FragmentManager manager) {
    List<Fragment> fragments = manager.getFragments();
    if (fragments == null) {
        return null;
    }
    int size = fragments.size();
    for (int i = size - 1; i >= 0; i--) {
        Fragment f = fragments.get(i);
         if (f.isAdded() && !f.isHidden() && f.getUserVisibleHint()) {
            Fragment tTopFragment = getTopFragment(f.getChildFragmentManager());
            return tTopFragment == null ? f : tTopFragment;
        }
    }
    return null;
}

彈出顯示

到這里拄显,就可以拿到一個棧頂 Fragment 的集合了,比如說如果是兩層嵌套(Activity -> parentFragment -> childFragment )的話,這個集合中就是 childFragment 案站。那么又怎么回溯上去獲取到這么一個層級關系呢躬审?簡單說這個就是找爸爸的步驟啦。在 Fragment 中有一個 getParentFragment() 的方法蟆盐,通過該方法承边,就可以將爸爸們全部找出來了。只是這里是倒序的(Activity -> childFragment -> parentFragment )石挂,我們最終的效果需要是正序的博助,所以還需要反轉一下集合。

List<Fragment> topFragments = getTopFragments();
if (topFragments == null) {
    sb.append(context.getClass().getSimpleName());
    dialog.setMessage(sb.toString());
    dialog.show();
    //只有Activity不包含Fragment
    return;
}
//從最top的Fragment回溯parent痹愚,到了root的時候結束富岳。
ArrayList<Fragment> names;
for (Fragment topFragment : topFragments) {
    //Glide 使用Fragment來控制相關的request,不再考慮的范圍內
    if (GLIDE_FRAGMENT.equals(topFragment.getClass().getName())) {
        continue;
    }
    //先添加Activity的名稱
    sb.append(context.getClass().getSimpleName());
    names = new ArrayList<>();
    //倒序找ParentFragment
    while (topFragment != null) {
        names.add(0, topFragment);//反轉順序
        topFragment = topFragment.getParentFragment();
    }
    int length = names.size();
    for (int i = 0; i < length; i++) {
        Fragment name = names.get(i);
        sb.append("\n");
        for (int j = 0; j <= i; j++) {
            sb.append("    ");
        }
        sb.append(name.getClass().getSimpleName());
    }
    sb.append("\n\n");

}
if (sb.length() == 0) {
    sb.append(context.getClass().getSimpleName());
}
dialog.setMessage(sb.toString());
dialog.show();

特殊情況處理

使用 Glide 加載圖片的時候拯腮,它默認會添加一個沒有頁面的 SupportRequestManagerFragment 來獲取相關生命處理相關的圖片加載窖式,所以它是需要我們過濾掉的。

另外动壤,如果某一個頁面不需要或者相關功能和搖一搖是沖突的話萝喘,這里提供了一個 isEnable 的字段來控制當前頁面是否支持搖一搖的功能。

最后琼懊,就是我們如何方便調用相關的功能呢阁簸?這里對外提供了相關的方法:

private ShakeHelper(Context context) {
    this.context = context;
    dialog = new AlertDialog.Builder(context).create();
    dialog.setOnDismissListener(this);
    sb = new StringBuilder();
    if (context instanceof FragmentActivity) {
        manager = ((FragmentActivity) context).getSupportFragmentManager();
    }
}

//搖一搖是否可用,默認可用
public void setEnable(boolean enable) {
    isEnable = enable;
}

//獲取搖一搖的實例
public static ShakeHelper initShakeHelper(Context context) {
    return new ShakeHelper(context);
}

//回調Activity的onStart()
public void onStart() {
    //獲取 SensorManager 負責管理傳感器
    mSensorManager = ((SensorManager) context.getSystemService(Context.SENSOR_SERVICE));
    if (isEnable && mSensorManager != null) {
        //獲取加速度傳感器
        Sensor mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (mAccelerometerSensor != null) {
            mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager.SENSOR_DELAY_UI);
        }
    }
}

//回調Activity的onPause()
public void onPause() {
    if (mSensorManager != null) {
        mSensorManager.unregisterListener(this);
    }
}

相關源碼下載

戳我

---- Edit By Joe At 2017 02 13 ----

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末哼丈,一起剝皮案震驚了整個濱河市启妹,隨后出現的幾起案子,更是在濱河造成了極大的恐慌削祈,老刑警劉巖翅溺,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異髓抑,居然都是意外死亡咙崎,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門吨拍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來褪猛,“玉大人,你說我怎么就攤上這事羹饰∫磷蹋” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵队秩,是天一觀的道長笑旺。 經常有香客問我,道長馍资,這世上最難降的妖魔是什么筒主? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮鸟蟹,結果婚禮上乌妙,老公的妹妹穿的比我還像新娘。我一直安慰自己建钥,他們只是感情好藤韵,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著熊经,像睡著了一般泽艘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奈搜,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天悉盆,我揣著相機與錄音,去河邊找鬼馋吗。 笑死焕盟,一個胖子當著我的面吹牛,可吹牛的內容都是我干的宏粤。 我是一名探鬼主播脚翘,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绍哎!你這毒婦竟也來了来农?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤崇堰,失蹤者是張志新(化名)和其女友劉穎沃于,沒想到半個月后涩咖,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡繁莹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年檩互,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咨演。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡闸昨,死狀恐怖,靈堂內的尸體忽然破棺而出薄风,到底是詐尸還是另有隱情饵较,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布遭赂,位于F島的核電站循诉,受9級特大地震影響,放射性物質發(fā)生泄漏撇他。R本人自食惡果不足惜打洼,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逆粹。 院中可真熱鬧募疮,春花似錦、人聲如沸僻弹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矿辽。三九已至,卻和暖如春荤西,著一層夾襖步出監(jiān)牢的瞬間卸耘,已是汗流浹背退敦。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚣抗,地道東北人侈百。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像翰铡,于是被迫代替她去往敵國和親钝域。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,275評論 25 707
  • 作者介紹馮宇飛 锭魔,現任人人車Android客戶端架構師例证。 本文回顧總結了人人車公司Android客戶端的架構演進歷...
    passiontim閱讀 1,545評論 0 9
  • 在shell命令終端中,Ctrl+n相當于方向向下的方向鍵迷捧,Ctrl+p相當于方向向上的方向鍵织咧。 在命令終端中通過...
    追趕時間閱讀 1,037評論 0 2
  • 不要試圖完全讀懂我 完全自以為是了解別人 讀懂的只是一部分 或許只是屬于你的一部分 只是以你的思想灌輸 選擇跟你講...
    鋼鐵俠_9912閱讀 256評論 0 1
  • “在這個無論多么操蛋的世界里胀葱,我總會等到姍姍來遲的你◇厦桑” ——阿肆
    饒川玉閱讀 506評論 0 1