自定義 ShareView 之 NavigationBar 適配

ShareView

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

小米手機上截圖

這個功能如何實現的呢?貼下主要代碼(具體參考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();
    }

}

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

華為Nexus手機上截圖

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

so, that`s the problem !

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

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

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

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();
}

// 判斷設備是否有返回鍵、菜單鍵來確定是否有 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

孫福生的微信公眾號

關于我

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

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