《Android編程權(quán)威指南》之對(duì)話框篇

終于來(lái)到第12章啦云茸!對(duì)話框在各類(lèi)應(yīng)用中見(jiàn)到的幾率還是蠻多的蜓堕,這可就實(shí)用了,漂亮點(diǎn)的對(duì)話框還是提升用戶體驗(yàn)?zāi)貇

創(chuàng)建 DialogFragment

曾經(jīng)的我寫(xiě)代碼闷畸,創(chuàng)建對(duì)話框,都是直接顯示AlertDialog視圖的吞滞,然而現(xiàn)在看到本書(shū)推薦是將AlertDialog封裝在DialogFragment(Fragment的子類(lèi))實(shí)例中使用佑菩,用FragmentManager管理,更為靈活冯吓。而且倘待,在旋轉(zhuǎn)設(shè)備時(shí)用AlertDialog的話會(huì)消失,而封裝在fragment中的AlertDialog則不會(huì)有此問(wèn)題(旋轉(zhuǎn)后组贺,對(duì)話框會(huì)被重建恢復(fù))凸舵。看來(lái)失尖,今后寫(xiě)代碼還是注意了啊奄,得轉(zhuǎn)變轉(zhuǎn)變了渐苏,多看書(shū),還是漲姿勢(shì)的菇夸。

截取自此書(shū)

  1. 創(chuàng)建DatePickerFragment的DialogFragment子類(lèi)琼富。
  2. 在DatePickerFragment中,創(chuàng)建并配置顯示DatePicker組件的AlertDialog實(shí)例庄新。(DatePickerFragment同樣由CrimePagerActivity托管)
  3. 借助FragmentManager在屏幕上顯示對(duì)話框鞠眉。

接下來(lái),實(shí)踐代碼啦择诈,注意引入支持庫(kù)中的包械蹋。

新一點(diǎn)的系統(tǒng)看到的日歷選擇器還是挺好看的喔~

使用布局文件實(shí)例化視圖對(duì)象能更加方便的拓展噢,推薦用布局文件羞芍。雖然哗戈,

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
 DatePicker datePicker = new DatePicker(getActivity()); 
 return new AlertDialog.Builder(getActivity()) 
 .setView(datePicker) 
 ... 
 .create(); 
} 

這樣也能創(chuàng)建DatePicker對(duì)象。

設(shè)備配置改變時(shí)荷科,具有ID屬性的視圖可以保存運(yùn)行狀態(tài)唯咬;而以dialog_date.xml布局創(chuàng)建DatePicker時(shí),編譯工具已為DatePicker生成了唯一的ID畏浆。所以胆胰,設(shè)備旋轉(zhuǎn),用戶所選日期也都會(huì)得到保留全度。

fragment 間的數(shù)據(jù)傳遞

現(xiàn)在同一個(gè)activity托管的兩個(gè)fragment之間要進(jìn)行數(shù)據(jù)傳遞了煮剧,來(lái)吧,本小結(jié)開(kāi)始了将鸵。

截取自此書(shū)
事件流圖:
截圖自此書(shū)

  1. 在DatePickerFragment中新建一個(gè)newInstance(Date)方法,然后將Date作為argument附加給fragment佑颇,這樣就將crime的日期傳遞給DatePickerFragment了顶掉。

這里由于DatePicker對(duì)象初始化涉及到整數(shù)形式的年、月挑胸、日痒筒,所以使用到了Calendar對(duì)象,用Date配置它茬贵,從而得到年月日簿透。有關(guān)Calendar、Date知識(shí)點(diǎn)解藻,實(shí)踐總結(jié)篇 :http://www.reibang.com/p/57cd6ead77c0

  1. 將CrimeFragment設(shè)置成DatePickerFragment的目標(biāo)fragment老充;傳遞數(shù)據(jù)給目標(biāo)fragment;在目標(biāo)fragment的 onActivityResult()接收數(shù)據(jù)螟左。

fragment中的public void setTargetFragment(Fragment fragment, int requestCode) 方法可以建立兩個(gè)fragment的關(guān)聯(lián)啡浊。

dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE); 

DatePrickerFragment中添加下述方法觅够,為了返回傳遞數(shù)據(jù):

private void sendResult(int resultCode, Date date) {
        if (getTargetFragment() == null) {
            return;
        }
        Intent intent = new Intent();
        intent.putExtra(EXTRA_DATE, date);

        getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);

}

接收數(shù)據(jù)核心代碼:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK){
            return;
        }
        if (requestCode == REQUEST_DATE){
            Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
            mCrime.setDate(date);
            updateDate(btnDate, mCrime);
        }
    }

可以覆蓋DialogFragment.
onCreateView(...)方法,以便顯示全屏fragment巷嚣,根據(jù)不同的需求喘先,可實(shí)現(xiàn)不同設(shè)備上的信息呈現(xiàn)。

挑戰(zhàn)練習(xí):更多對(duì)話框

(另寫(xiě)一個(gè)名為T(mén)imePickerFragment的對(duì)話框fragment廷粒,允許用戶使用TimePicker組件選擇crime發(fā)生的具體時(shí)間窘拯。在CrimeFragment用戶界面上再添加一個(gè)按鈕,以顯示TimePickerFragment視圖界面坝茎。)

我的解決方案吧树枫,創(chuàng)建TimePickerFragment這里的寫(xiě)法跟上述一樣的啦,然后CrimeFragment添加了個(gè)按鈕選時(shí)間景东,更新還是在date的那個(gè)按鈕上砂轻。上代碼啦:

public class TimePickerFragment extends DialogFragment {

    private static final String ARG_TIME = "time";
    public static final String EXTRA_TIME =
            "com.bignerdranch.android.criminalintent.time";
    private TimePicker mTimePicker;
    private Calendar mCalendar;

    public static TimePickerFragment newInstance(Date date) {

        Bundle bundle = new Bundle();
        bundle.putSerializable(ARG_TIME, date);

        TimePickerFragment timePickerFragment = new TimePickerFragment();
        timePickerFragment.setArguments(bundle);
        return timePickerFragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        Date date = (Date) getArguments().getSerializable(ARG_TIME);
        mCalendar = Calendar.getInstance();
        mCalendar.setTime(date);
        int hour = mCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = mCalendar.get(Calendar.MINUTE);

        View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_time, null);

        mTimePicker = view.findViewById(R.id.dialog_time_picker);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mTimePicker.setHour(hour);
            mTimePicker.setMinute(minute);
        } else {
            mTimePicker.setCurrentHour(hour);
            mTimePicker.setCurrentMinute(minute);
        }

        return new AlertDialog.Builder(getActivity())
                .setView(view)
                .setTitle(R.string.time_picker_title)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        int hour, minute;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            hour = mTimePicker.getHour();
                            minute = mTimePicker.getMinute();
                        } else {
                            hour = mTimePicker.getCurrentHour();
                            minute = mTimePicker.getCurrentMinute();
                        }
                        mCalendar.set(Calendar.HOUR_OF_DAY, hour);
                        mCalendar.set(Calendar.MINUTE, minute);

                        sendResult(Activity.RESULT_OK, mCalendar.getTime());
                    }
                })
                .show();
    }

    private void sendResult(int resultCode, Date date) {

        if (getTargetFragment() == null) {
            return;
        }

        Intent intent = new Intent();
        intent.putExtra(EXTRA_TIME, date);

        getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);

    }
}

CrimeFragment.java中的核心代碼:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK){
            return;
        }
        if (requestCode == REQUEST_DATE){
            Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
            mCrime.setDate(date);
            updateDate(btnDate, mCrime);
        }else if (requestCode == REQUEST_TIME){
            Date date = (Date) data.getSerializableExtra(TimePickerFragment.EXTRA_TIME);
            mCrime.setDate(date);
            updateDate(btnDate, mCrime);
        }
    }

應(yīng)該還是很容易看懂的,emmm... 我是這么想嘍~~~

挑戰(zhàn)練習(xí):實(shí)現(xiàn)響應(yīng)式 DialogFragment

這個(gè)挑戰(zhàn)練習(xí)貌似有點(diǎn)復(fù)雜斤吐,最后都叫我提前學(xué)習(xí)17章內(nèi)容再來(lái)完成了搔涝,所以...哈哈~ 先這樣吧,先不做了和措。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庄呈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子派阱,更是在濱河造成了極大的恐慌诬留,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贫母,死亡現(xiàn)場(chǎng)離奇詭異文兑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)腺劣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)绿贞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人橘原,你說(shuō)我怎么就攤上這事籍铁。” “怎么了趾断?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拒名,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我芋酌,道長(zhǎng)增显,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任隔嫡,我火速辦了婚禮甸怕,結(jié)果婚禮上甘穿,老公的妹妹穿的比我還像新娘。我一直安慰自己梢杭,他們只是感情好温兼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著武契,像睡著了一般募判。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咒唆,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天届垫,我揣著相機(jī)與錄音,去河邊找鬼全释。 笑死装处,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浸船。 我是一名探鬼主播妄迁,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼李命!你這毒婦竟也來(lái)了鲫寄?” 一聲冷哼從身側(cè)響起谬哀,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤妓肢,失蹤者是張志新(化名)和其女友劉穎者疤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體阔籽,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡流妻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仿耽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片合冀。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖项贺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情峭判,我是刑警寧澤开缎,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站林螃,受9級(jí)特大地震影響奕删,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疗认,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一完残、第九天 我趴在偏房一處隱蔽的房頂上張望伏钠。 院中可真熱鬧,春花似錦谨设、人聲如沸熟掂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赴肚。三九已至,卻和暖如春二蓝,著一層夾襖步出監(jiān)牢的瞬間誉券,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工刊愚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踊跟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓鸥诽,卻偏偏與公主長(zhǎng)得像商玫,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衙传,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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