日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

QuickContact分析及其弹出窗口实现

發(fā)布時間:2024/4/15 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QuickContact分析及其弹出窗口实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、簡介
?? ?QuickContact是為了應(yīng)用程序能夠快速方便的訪問聯(lián)系人,并且快速的運(yùn)用聯(lián)系人的信息執(zhí)行相應(yīng)操作而設(shè)計的。最常見的在Contacts應(yīng)用程序中如下圖所示:

?? ?在Activity中存在一個圖標(biāo),點(diǎn)擊該圖標(biāo)后彈出一個窗口,窗口中會有幾個圖標(biāo),不同的圖標(biāo)表示針對該聯(lián)系人進(jìn)行的不同操作,比如打電話,發(fā)短信,發(fā)送郵件,進(jìn)入主頁等等。圖標(biāo)的顯示和不顯示取決于該聯(lián)系人是否存在該種操作相關(guān)的信息。比如,如果該聯(lián)系人中如果存在郵箱的話,就可以出現(xiàn)發(fā)送郵件的圖標(biāo),否則就不會出現(xiàn)。


二、在自己的應(yīng)用程序中應(yīng)用QuickContact
?? ?在自己的程序中加入QuickContact十分方便,可以用Framework中的組件QuickContactBadge。
?? ?比如,我們創(chuàng)建一個Activity,設(shè)置它的layout如下:

  • <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"?
  • ??????????????android:orientation="vertical"?
  • ??????????????android:layout_width="fill_parent"?
  • ??????????????android:layout_height="fill_parent"?
  • ????????>?
  • ????<QuickContactBadge?
  • ????????????android:id="@+id/badge_small"?
  • ????????????android:layout_width="wrap_content"?
  • ????????????android:layout_height="wrap_content"?
  • ????????????android:src="@drawable/icon">?
  • ????</QuickContactBadge>?
  • </LinearLayout>?
  • ?? ?Activity的onCreate代碼如下:

  • QuickContactBadge?smallBadge?=?(QuickContactBadge)?findViewById(R.id.badge_small);?
  • smallBadge.assignContactFromEmail("winuxxan@gmail.com",?true);?
  • smallBadge.setMode(ContactsContract.QuickContact.MODE_LARGE);?
  • ?? ?主要還有一點(diǎn),要在AndroidManifest中設(shè)置android.permission.READ_CONTACTS的權(quán)限,否則,不會彈出窗口,而是直接進(jìn)入Contacts中的聯(lián)系人詳情界面。
    ?? ?運(yùn)行效果如圖:

    ?? ?由于本文不是針對QuickContactBadge的詳細(xì)講解,而是講解它的實(shí)現(xiàn)方法,從而能夠見賢思齊,設(shè)計出類似的功能。要了解QuickContactBadge的詳細(xì)用法可以看Android文檔,和google。


    三、結(jié)構(gòu)
    ?? ?系統(tǒng)在實(shí)現(xiàn)QuickContact包含三部分:
    ?? ?1、彈出界面。
    ?? ?2、ContactContract中的調(diào)用接口
    ?? ?3、組件QuickContactBadge。
    ?? ?彈出界面在應(yīng)用程序Contacts中編寫,這也是QuickContact的主要部分。
    ContactContract為方便使用QuickContact定義了幾個函數(shù),可以在不同的情形下顯示出QuickContact。
    ?? ?QuickContactBadge是為了方便開發(fā)者使用QuickContact,設(shè)計的一個組件,開發(fā)者只需要在自己的Layout中加入該組件,便可以方便的使用。而且該組件還支持根據(jù)郵箱、電話號碼等指定某個聯(lián)系人。實(shí)際上,QuickContactBadge在單擊的時候調(diào)用了ContactContract中的函數(shù)來顯示QuickContact。因此,實(shí)際上,ContactContract中的QuickContact可以完成更多情況下QuickContact的顯示。

    ?? ? ?框圖待補(bǔ)充

    四、QuickContactActivity和QuickContactWindow
    ?? ?為了使彈出窗口可以跨進(jìn)程共享,彈出界面的實(shí)現(xiàn)實(shí)際上是采用了透明Activity貼上一層View的方式。透明的Activity無疑就是QuickContactActivity了,在該Activity中含有一個QuickContactWindow的成員,通過QuickContactWindow將一個View貼到該Activity上。
    ?? ?那么,QuickContactWindow是如何將View貼到Activity上的呢?大家需要了解Activity,View,Window和WindowManager之間的關(guān)系,不明白的趕緊查下資料。
    ?? ?QuickContactWindow在創(chuàng)建時就會創(chuàng)建一個PhoneWindow,然后設(shè)置它的布局,進(jìn)行一系列的初始化,在顯示的時候,會查詢該聯(lián)系人的信息,查詢完畢后生成該聯(lián)系人的視圖,之后獲得PhoneWindow的根節(jié)點(diǎn),將該根節(jié)點(diǎn)加到WindowManager中,該View就會被貼到Activity中去了。


    五、ContactContract中的QuickContact
    ?? ?ContactContract中的QuickContact的顯示函數(shù),實(shí)際上就是用Intent開啟了QuickContactActivity。


    六、QuickContactBadge
    ?? ?QuickContactBadge繼承自ImageView,所以所有ImageView的函數(shù)都可以用來設(shè)置QuickContactBadge。當(dāng)點(diǎn)擊QuickContactBadge時,它調(diào)用了ContactContract中的QuickContact顯示函數(shù)。
    ?? ?為了為開發(fā)者提供方便,QuickContactBadge可以根據(jù)開發(fā)者提供的郵箱或電話號碼等信息找到該聯(lián)系人。


    七、見賢思齊?
    1、PopupWindow彈出窗口實(shí)現(xiàn)
    ?? ?其實(shí),單純實(shí)現(xiàn)彈出窗口是很簡單的,Android為我們提供了PopupWindow這個組件。通過這個組件我們可以將我們的窗口顯示在頂層,并且可以通過坐標(biāo)來決定它的位置。如下面的代碼:

  • private?void?showPopupWindow(int?x,?int?y,?int?width,?int?height)?{?
  • ????TextView?textView?=?new?TextView(this);?
  • ????textView.setText("Hello?popupWindow");?
  • ????textView.setBackgroundColor(Color.CYAN);?
  • ????PopupWindow?popupWindow?=?new?PopupWindow(textView,?width,?height);?
  • ????popupWindow.showAtLocation(getWindow().getDecorView(),?Gravity.NO_GRAVITY,?x,?y);?
  • }?
  • ?? ?顯示效果如下:

    ?? ?需要注意的一點(diǎn)就是,PopupWindow在Activity的onCreate函數(shù)中顯示是會出現(xiàn)錯誤的,用戶可以自行驗(yàn)證。解決方法不是本文暫不研究。


    2、Dialog的彈出窗口實(shí)現(xiàn)
    ?? ?我們常見的Dialog都是居中顯示的,而且背景會變暗,因此要Dialog實(shí)現(xiàn)彈出窗口的效果,就要解決任意位置顯示和背景不變暗的問題。
    ?? ?在Activity中寫如下代碼:

  • public?class?MyActivity?extends?Activity?{?
  • ?
  • ????@Override?
  • ????public?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.main);?
  • ????????//在指定位置顯示對話框?
  • showDialog(100,?100,?200,?200);?
  • ????}?
  • ?????
  • ????@Override?
  • ????protected?Dialog?onCreateDialog(int?id,?Bundle?args)?{?
  • ????????return?new?AlertDialog.Builder(this)?
  • ????????????.setTitle("Hello?Dialog!")?
  • ????????????.setMessage("Hello?Dialog")?
  • ????????????.create();?
  • ????}?
  • ?????
  • ????@Override?
  • ????protected?void?onPrepareDialog(int?id,?Dialog?dialog,?Bundle?args)?{?
  • ????????switch?(id)?{?
  • ????????case?1:?{?
  • //設(shè)置對話框的屬性?
  • ????????????Window?window?=?dialog.getWindow();?
  • ????????????WindowManager.LayoutParams?lp?=?window.getAttributes();?
  • ????????????lp.x?=?args.getInt("x");?
  • ????????????lp.y?=?args.getInt("y");?
  • ????????????lp.width?=?args.getInt("width");?
  • ????????????lp.height?=?args.getInt("height");?
  • ?????????????
  • ????????????lp.flags?&=?~WindowManager.LayoutParams.FLAG_DIM_BEHIND;?
  • ?
  • ????????????dialog.getWindow().setBackgroundDrawable(new?ColorDrawable(Color.argb(0,?0,?0,?0)));?
  • ????????}?
  • ????????????break;?
  • ?
  • ????????default:?
  • ????????????break;?
  • ????????}?
  • ?
  • ????????super.onPrepareDialog(id,?dialog,?args);?
  • ????}?
  • ?
  • ????private?void?showDialog(int?x,?int?y,?int?width,?int?height)?{?
  • ????????Bundle?bundle?=?new?Bundle();?
  • ????????bundle.putInt("x",?x);?
  • ????????bundle.putInt("y",?y);?
  • ????????bundle.putInt("width",?width);?
  • ????????bundle.putInt("height",?height);?
  • ?????????
  • ????????showDialog(1,?bundle);?
  • ????}?
  • }?
  • ?? ?在onPrepareDialog函數(shù)中,我們獲得了Dialog的Window,然后對位置和寬度進(jìn)行了設(shè)置,并且通過Flag取消了背景變暗的效果,最后我們得到的結(jié)果如下圖:

    ?? ?其實(shí),帶有Dialog主題的Activity也可以實(shí)現(xiàn)該效果,不過本人沒有實(shí)現(xiàn)背景不變暗,故不將代碼貼上了。


    3、跨進(jìn)程共享彈出窗口設(shè)計
    ?? ?我們能不能實(shí)現(xiàn)類似于QuickContact那樣的彈出窗口跨進(jìn)程共享呢?當(dāng)然是可以的。
    ?? ?可能我們會想到用一個透明的Activity,然后顯示一個PopupWindow來實(shí)現(xiàn),但是PopupWindow我們之前說過,在Activity的onCreate函數(shù)中顯示時會有問題。
    ?? ?我們也可能還會想到一個透明的Activity加一個Dialog來顯示,但是我們也知道,Dialog并不是像PopupWindow那樣是輕量級的,僅僅一個Activity的顯示就夠耗費(fèi)了,再顯示一個Dialog,那么耗費(fèi)就更大了。
    ?? ?我們可能還會想到用QuickContact的方式,創(chuàng)建一個Window,然后將該Window的根View貼到透明Activity上,然而,不幸的是,創(chuàng)建Window的函數(shù)是非公開的。
    ?? ?其實(shí),我們不需要創(chuàng)建一個Window,也能將View貼到Activity之中。見如下代碼:

  • public?class?PopupActivity?extends?Activity?{?
  • ????private?WindowManager?mWindowManager;?
  • ????private?View?mAddedView;?
  • ?????
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ?????????
  • ????????setContentView(R.layout.main);?
  • ?
  • ????????int?x?=?getIntent().getIntExtra("x",?0);?
  • ????????int?y?=?getIntent().getIntExtra("y",?0);?
  • ????????int?width?=?getIntent().getIntExtra("width",?200);?
  • ????????int?height?=?getIntent().getIntExtra("height",?200);?
  • ?
  • ????????//該TextView要貼到透明的Activity上?
  • ????????TextView?textView?=?new?TextView(this);?
  • ????????textView.setBackgroundColor(Color.CYAN);?
  • ????????textView.setWidth(width);?
  • ????????textView.setHeight(height);?
  • ????????mAddedView?=?textView;?
  • ?????????
  • ????????textView.setOnKeyListener(new?OnKeyListener()?{?
  • ?????????????
  • ????????????public?boolean?onKey(View?v,?int?keyCode,?KeyEvent?event)?{?
  • ????????????????mWindowManager.removeView(mAddedView);?
  • ????????????????finish();?
  • ????????????????return?false;?
  • ????????????}?
  • ????????});?
  • ?????????
  • ????????WindowManager.LayoutParams?params?=?new?WindowManager.LayoutParams();?
  • ????????params.x?=?x;?
  • ????????params.y?=?y;?
  • ????????params.width?=?width;?
  • ????????params.height?=?height;?
  • ????????params.flags?&=?~WindowManager.LayoutParams.FLAG_DIM_BEHIND;?
  • ????????params.packageName?=?this.getPackageName();?
  • ?
  • //貼到透明Activity上?
  • ????????mWindowManager?=?(WindowManager)getSystemService(Context.WINDOW_SERVICE);?
  • ????????mWindowManager.addView(textView,?params);?
  • ????}?
  • }?
  • ?? ?該Activity要設(shè)置成透明,可以在AndroidManifest中加入android:theme = "@android:style/Theme.Translucent"。
    ?? ?調(diào)用的代碼如下:

  • private?void?showPopupActivity(int?x,?int?y,?int?width,?int?height)?{?
  • ????????Intent?intent?=?new?Intent();?
  • ????????intent.setClass(this,?DialogActivity.class);?
  • ????????intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK??
  • ????????????????|?Intent.FLAG_ACTIVITY_CLEAR_TOP??
  • ????????????????|?Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);?
  • ????????intent.putExtra("x",?x);?
  • ????????intent.putExtra("y",?y);?
  • ????????intent.putExtra("width",?width);?
  • ????????intent.putExtra("height",?height);?
  • ????????startActivity(intent);?
  • ????}?
  • ?? ?最終效果如下:

    ?

    4、跨進(jìn)程共享彈出窗口的優(yōu)化
    ?? ?由于跨進(jìn)程共享的彈出窗口是重啟的一個新的Activity,因此花銷是比較大的,為了提高效率,我們需要做一些工作。
    ?? ?首先,設(shè)置Activity的launchMode為singleTop,通過該設(shè)置,當(dāng)該Activity已經(jīng)在棧頂時,可以直接調(diào)用onNewIntent函數(shù)而不是重新創(chuàng)建。
    ?? ?其次,設(shè)置Activity的taskAffinity為其他值,如:android:taskAffinity = "com.winuxxan.dialogactivity",并且開啟Activity時,設(shè)置flag:

  • intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK??
  • |?Intent.FLAG_ACTIVITY_CLEAR_TOP??
  • |?Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);?

  • ?? ?這樣,該Activity在一個單獨(dú)的Task中,并且只要該Task堆棧中存在該Activity,那么就不會重新創(chuàng)建,而是調(diào)用onNewIntent。
    ?? ?再次,當(dāng)隱藏該窗口時,不是銷毀掉,而是moveTaskToBack,這樣再次顯示時就不是重新創(chuàng)建,而是將后臺Task放到前臺。
    ?? ?通過這些手段就可以顯著的提高該彈出窗口的效率。

    總結(jié)

    以上是生活随笔為你收集整理的QuickContact分析及其弹出窗口实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。