android自定義Dialog實(shí)現(xiàn)底部彈窗

android自定義Dialog實(shí)現(xiàn)底部彈窗

拿到這個(gè)需求,很多人都是直接想用popWindow 實(shí)現(xiàn)薄嫡,但是這樣的效果我們完全可以根據(jù)系統(tǒng)的Dialog 自定義一個(gè)。

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("SSS");
builder.show();

這樣就直接顯示出一個(gè)對(duì)話框,但是替蔬,這個(gè)對(duì)話框在屏幕的中間厨幻,然后相嵌,我們?nèi)ゲ榭磀ialog的源碼:
看dialog.show()里面判斷了是否正在顯示中,并沒有和根布局有關(guān)系克胳,看這個(gè)類的父類平绩。里面的show()中:

public void show() {
    if (mShowing) {
        if (mDecor != null) {
            if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
            }
            mDecor.setVisibility(View.VISIBLE);
        }
        return;
    }

    mCanceled = false;

    if (!mCreated) {
        dispatchOnCreate(null);
    } else {
        // Fill the DecorView in on any configuration changes that
        // may have occured while it was removed from the WindowManager.
        final Configuration config = mContext.getResources().getConfiguration();
        mWindow.getDecorView().dispatchConfigurationChanged(config);
    }

    onStart();
    mDecor = mWindow.getDecorView();

    if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
        final ApplicationInfo info = mContext.getApplicationInfo();
        mWindow.setDefaultIcon(info.icon);
        mWindow.setDefaultLogo(info.logo);
        mActionBar = new WindowDecorActionBar(this);
    }

    WindowManager.LayoutParams l = mWindow.getAttributes();
    if ((l.softInputMode
            & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
        WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
        nl.copyFrom(l);
        nl.softInputMode |=
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
        l = nl;
    }

    mWindowManager.addView(mDecor, l);
    mShowing = true;

    sendShowMessage();
}

這個(gè)調(diào)用addView 進(jìn)去,我們Dialog就是這樣加進(jìn)去的漠另;
可以看到Dialog的源碼中的方法捏雌,也有onCreate( ) 他也是初始化 對(duì)話框的

/**
 * Similar to {@link Activity#onCreate}, you should initialize your dialog
 * in this method, including calling {@link #setContentView}.
 * @param savedInstanceState If this dialog is being reinitialized after a
 *     the hosting activity was previously shut down, holds the result from
 *     the most recent call to {@link #onSaveInstanceState}, or null if this
 *     is the first time.
 */
protected void onCreate(Bundle savedInstanceState) {
}

看Dialog 的實(shí)現(xiàn)類。里面有個(gè)日期彈窗的實(shí)現(xiàn)類笆搓,效果如下性湿,更多時(shí)間篩選的對(duì)話框可以看我的另一個(gè)自定義的 文章:

系統(tǒng)的效果如下:
[圖片上傳失敗...(image-ceb45e-1511342382391)]

自定義Dialog實(shí)現(xiàn)

1.創(chuàng)建一個(gè)自定義類繼承dialog類,創(chuàng)建布局满败,當(dāng)成Activity 重寫onCreate()看效果

public class SmartDialog extends Dialog {
    public SmartDialog(@NonNull Context context) {
        super(context);
    }

    public SmartDialog(@NonNull Context context, @StyleRes int themeResId) {
        super(context, themeResId);
    }

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.smartlayout);
}

}

布局文件:

<?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">
    <TextView
      android:layout_width="match_parent"
      android:layout_margin="10dp"
      android:layout_height="wrap_content"
      android:id="@+id/title"
      android:text="自定義風(fēng)格彈窗"
        />
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

點(diǎn)擊事件調(diào)用:

SmartDialog smartDialog = new SmartDialog(DialogShowActivity.this);
smartDialog.setTitle("我是Title");
smartDialog.show();
image.png

設(shè)置View的 屬性肤频,讓彈窗到底部

requestWindowFeature(Window.FEATURE_NO_TITLE);//事情定需不需要加
setContentView(R.layout.smartlayout);
WindowManager.LayoutParams params = getWindow().getAttributes();
if(params!=null){
    //獲取屬性可能失敗 為空
    params.gravity= Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
    getWindow().setAttributes(params);
}
image.png

更改布局,添加數(shù)據(jù)

這里我們簡單做一個(gè)ListView


image.png

.顯示效果你會(huì)發(fā)現(xiàn)沒有完全填充算墨,這個(gè)時(shí)候宵荒,再去看我們調(diào)用Dialog 默認(rèn)的構(gòu)造函數(shù),

查看源碼净嘀。更改style

public Dialog(@NonNull Context context) {
    this(context, 0, true);
}
if (createContextThemeWrapper) {
    if (themeResId == 0) {
        final TypedValue outValue = new TypedValue();
        context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
        themeResId = outValue.resourceId;
    }
    mContext = new ContextThemeWrapper(context, themeResId);
} else {
    mContext = context;
}

如果走默認(rèn)的構(gòu)造就不顯示报咳,去SDK中找到 R.attr.dialogTheme 先找到自己對(duì)應(yīng)版本的SDK 到自己項(xiàng)目 的build.gradle 中找到
進(jìn)到自己的安裝目錄下找對(duì)于的 dialogTheme 發(fā)現(xiàn)只是定義了 類型,并沒具體定義挖藏。然后去themes 里面找到:

 <!-- Dialog attributes -->
        <item name="dialogTheme">@style/Theme.Dialog</item>
        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons</item>
        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title</item>
        <item name="dialogTitleDecorLayout">@layout/dialog_title</item>
        <item name="dialogPreferredPadding">@dimen/dialog_padding</item>

因?yàn)椴]有找到具體的定義屬性暑刃,再去搜索 Theme.Dialog 去 style 中找下 沒找到,發(fā)現(xiàn)這個(gè)文件就在 themes 中,如下:


  <style name="Theme.Dialog">
        <item name="windowFrame">@null</item>
        <item name="windowTitleStyle">@style/DialogWindowTitle</item>
        <item name="windowBackground">@drawable/panel_background</item>
        <item name="windowIsFloating">true</item>
        <item name="windowContentOverlay">@null</item>
        <item name="windowAnimationStyle">@style/Animation.Dialog</item>
        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
        <item name="windowActionModeOverlay">true</item>

        <item name="colorBackgroundCacheHint">@null</item>

        <item name="textAppearance">@style/TextAppearance</item>
        <item name="textAppearanceInverse">@style/TextAppearance.Inverse</item>

        <item name="textColorPrimary">@color/primary_text_dark</item>
        <item name="textColorSecondary">@color/secondary_text_dark</item>
        <item name="textColorTertiary">@color/tertiary_text_dark</item>
        <item name="textColorPrimaryInverse">@color/primary_text_light</item>
        <item name="textColorSecondaryInverse">@color/secondary_text_light</item>
        <item name="textColorTertiaryInverse">@color/tertiary_text_light</item>
        <item name="textColorPrimaryDisableOnly">@color/primary_text_dark_disable_only</item>
        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_light_disable_only</item>
        <item name="textColorPrimaryNoDisable">@color/primary_text_dark_nodisable</item>
        <item name="textColorSecondaryNoDisable">@color/secondary_text_dark_nodisable</item>
        <item name="textColorPrimaryInverseNoDisable">@color/primary_text_light_nodisable</item>
        <item name="textColorSecondaryInverseNoDisable">@color/secondary_text_light_nodisable</item>
        <item name="textColorHint">@color/hint_foreground_dark</item>
        <item name="textColorHintInverse">@color/hint_foreground_light</item>
        <item name="textColorSearchUrl">@color/search_url_text</item>

        <item name="textAppearanceLarge">@style/TextAppearance.Large</item>
        <item name="textAppearanceMedium">@style/TextAppearance.Medium</item>
        <item name="textAppearanceSmall">@style/TextAppearance.Small</item>
        <item name="textAppearanceLargeInverse">@style/TextAppearance.Large.Inverse</item>
        <item name="textAppearanceMediumInverse">@style/TextAppearance.Medium.Inverse</item>
        <item name="textAppearanceSmallInverse">@style/TextAppearance.Small.Inverse</item>

        <item name="listPreferredItemPaddingLeft">10dip</item>
        <item name="listPreferredItemPaddingRight">10dip</item>
        <item name="listPreferredItemPaddingStart">10dip</item>
        <item name="listPreferredItemPaddingEnd">10dip</item>

        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
    </style>

我們重點(diǎn)看這個(gè)屬性: <item name="windowBackground">@drawable/panel_background</item>
在資源文件中搜索這個(gè)panel_background,打開你會(huì)發(fā)現(xiàn)是一張 .9圖片如下:


image.png

我們自己在項(xiàng)目中實(shí)現(xiàn)一個(gè)style 去重寫這個(gè)background 屬性膜眠,去覆蓋

    <!--自定義對(duì)話框-->
    <style name="MtStyle" parent="@style/Theme.AppCompat.Dialog">
        <!-- Customize your theme here. -->
        <item name="android:windowBackground">@android:color/white</item>
    </style>

然后在代碼中去使用就直接多傳遞一個(gè)參數(shù)去設(shè)置:

 public Smartdialog(@NonNull Context context) {
        super(context,R.style.MtStyle);
    }

這樣就實(shí)現(xiàn)我們要的效果岩臣,和PopWindow 一樣溜嗜,但是注意了,在一些新的版本上該效果還是有間隙架谎,這個(gè)就要去研究對(duì)應(yīng)SDK的剛才那個(gè)屬性 中的參數(shù)影響了炸宵。試了兩個(gè)版本都不行。狐树。焙压。。只有在老版本上可以抑钟,不過也給大家提供了一個(gè)思路涯曲!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市在塔,隨后出現(xiàn)的幾起案子幻件,更是在濱河造成了極大的恐慌,老刑警劉巖蛔溃,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绰沥,死亡現(xiàn)場離奇詭異,居然都是意外死亡贺待,警方通過查閱死者的電腦和手機(jī)徽曲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麸塞,“玉大人秃臣,你說我怎么就攤上這事∧墓ぃ” “怎么了奥此?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雁比。 經(jīng)常有香客問我稚虎,道長,這世上最難降的妖魔是什么偎捎? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任蠢终,我火速辦了婚禮,結(jié)果婚禮上茴她,老公的妹妹穿的比我還像新娘寻拂。我一直安慰自己沸移,他們只是感情好哥倔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布蹲蒲。 她就那樣靜靜地躺著,像睡著了一般赡麦。 火紅的嫁衣襯著肌膚如雪朴皆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天泛粹,我揣著相機(jī)與錄音遂铡,去河邊找鬼。 笑死晶姊,一個(gè)胖子當(dāng)著我的面吹牛扒接,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播们衙,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼钾怔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蒙挑?” 一聲冷哼從身側(cè)響起宗侦,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忆蚀,沒想到半個(gè)月后矾利,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馋袜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年男旗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欣鳖。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡察皇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出观堂,到底是詐尸還是另有隱情让网,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布师痕,位于F島的核電站溃睹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胰坟。R本人自食惡果不足惜因篇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笔横。 院中可真熱鬧竞滓,春花似錦、人聲如沸吹缔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厢塘。三九已至茶没,卻和暖如春肌幽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抓半。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工喂急, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人笛求。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓廊移,卻偏偏與公主長得像,于是被迫代替她去往敵國和親探入。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狡孔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容