自定義 ShareView 之 NavigationBar 適配

ShareView

分享功能在實際項目開發(fā)中經(jīng)常用到的,有可能是在屏幕中間彈出的 Dialog 對話框,也有可能是從屏幕下方滑上來的視圖。本文是自定義從屏幕下方滑上來的分享控件,將 ShareView add 到 DecorView 上,但是在帶 NavigationBar 導航條的手機上出現(xiàn)適配問題,下面是我碰到的問題及解決方法。

小米手機上截圖

這個功能如何實現(xiàn)的呢?貼下主要代碼(具體參考GitHub上項目)。

public class ShareView {

    private Activity mActivity;
    private View fullMaskView; // 蒙層視圖
    private View contentLayout; // 分享視圖
    private int panelHeight = 0; // 分享視圖高度

    public ShareView(Activity activity) {
        this.mActivity = activity;
        initShareView(activity);
    }

    private void initShareView(Activity activity) {
        fullMaskView = View.inflate(activity, R.layout.ui_view_full_mask_layout, null);
        contentLayout = LayoutInflater.from(activity).inflate(R.layout.ui_share, null);
        ButterKnife.bind(this, contentLayout);

        attachView();
        initListener();
    }

    // 將該View添加到根布局
    private void attachView() {
        ((ViewGroup) mActivity.getWindow().getDecorView()).addView(fullMaskView);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.BOTTOM;
        ((ViewGroup) mActivity.getWindow().getDecorView()).addView(contentLayout, params);
        fullMaskView.setVisibility(View.GONE);
        contentLayout.setVisibility(View.GONE);
    }

    // 動畫顯示布局
    public void show() {
        fullMaskView.setVisibility(View.VISIBLE);
        contentLayout.setVisibility(View.VISIBLE);
        contentLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                contentLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                ViewGroup parent = (ViewGroup) contentLayout.getParent();
                panelHeight = parent.getHeight() - contentLayout.getTop();
                ObjectAnimator.ofFloat(contentLayout, "translationY", panelHeight, 0).setDuration(200).start();
            }
        });
    }

    // 動畫隱藏布局
    public void hide() {
        fullMaskView.setVisibility(View.GONE);
        ObjectAnimator.ofFloat(contentLayout, "translationY", 0, panelHeight).setDuration(200).start();
    }

}

你覺得有問題嗎?我覺得沒問題,因為在項目中使用了幾個版本了,還經(jīng)過測試的,肯定沒問題,但是看下面的效果圖

華為Nexus手機上截圖

不仔細看也沒有問題啊,再看下,是不是“取消”按鈕沒啦,是不是屏幕下面多出一個 NavigationBar 的條目呢。

so, that`s the problem !

上面這張圖是在華為 Nexus 手機上截的圖,這么一來這個自定義 ShareView 在所有屏幕底下帶有 NavigationBar 的手機上都會有問題,經(jīng)過測試,確實是這樣的,雖然對于整體功能沒有太大影響,但是仍不可以忍受。

我們使用的大多數(shù) Android 手機上的Home鍵,返回鍵以及menu鍵都是實體觸摸感應(yīng)按鍵,但是,一些手機生廠商包括 Google 在內(nèi)它們并沒有實體按鍵或觸摸感應(yīng)按鍵,取而代之的是在屏幕的下方加上 NavigationBar 導航條,我是很吐糟這種設(shè)計的,雖然這使得手機外觀的設(shè)計更加簡約。

找到原因就是找到解決辦法了,先獲取手機是否有導航條,有則在顯示和隱藏動畫的時候多加上導航條的高度

private int navigationBarHeight = 0; // 導航欄高度

// 將該View添加到根布局
private void attachView() {
    // ...
    if (hasNavigationBar(mActivity)) {
        navigationBarHeight = getNavigationBarHeight(mActivity);
    }
}

// 動畫顯示布局
public void show() {
    // ...
    ObjectAnimator.ofFloat(contentLayout, "translationY", panelHeight, -navigationBarHeight).setDuration(200).start();
}

// 動畫隱藏布局
public void hide() {
    // ...
    ObjectAnimator.ofFloat(contentLayout, "translationY", -navigationBarHeight, panelHeight).setDuration(200).start();
}

// 判斷設(shè)備是否有返回鍵、菜單鍵來確定是否有 NavigationBar
public static boolean hasNavigationBar(Context context) {
    boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
    boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
    if (!hasMenuKey && !hasBackKey) {
        return true;
    }
    return false;
}

// 獲取 NavigationBar 的高度
public static int getNavigationBarHeight(Activity activity) {
    Resources resources = activity.getResources();
    int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
    return resources.getDimensionPixelSize(resourceId);
}

這樣就OK了,效果圖如下

華為Nexus手機上截圖

具體參考GitHub上項目

解決辦法參考:http://blog.csdn.net/lnb333666/article/details/41821149

孫福生的微信公眾號

關(guān)于我

個人郵箱:sfsheng0322@126.com
GitHub主頁
簡書主頁
個人博客
新浪微博

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,654評論 4 61
  • 一 讀過的人告訴我,王小波的《黃金時代》口味太重,有點黃,你還是別看了,我沒聽,這還是老師們推薦過的閱讀書目,江湖...
    沂茗閱讀 375評論 2 2
  • 6. 為了形成一個最可靠的觀點,作者將會認為一下哪項最重要?給出你的理由。 a 尋找能支持你的觀點的論據(jù) b 分辨...
    梁夢婷閱讀 258評論 0 1
  • 就在我對自己的職業(yè)規(guī)劃頗感迷茫的時候,我的集團導師來找我聊天,聊了一個小時,頗有豁然開朗之意??偟淖谥加袃蓷l:1....
    115c3253903d閱讀 719評論 0 4

友情鏈接更多精彩內(nèi)容