之前一直覺得QQ換頭像彈出的對話框挺好看的,而且在項目中也有這個
需求,於是寫一個Demo出來分享一下。
話不多說,先來張效果圖看看。
上面是QQ中的效果。
上面的效果圖爲需要實現的效果。
簡單來說,就是彈出了一個對話框。接下來說說是怎麼實現的。
對話框Dialog中的是自定義View,下面先貼出代碼head_dialog。
<?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:gravity="bottom"
android:orientation="vertical">
<TextView
android:id="@+id/tv_take_dy_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@drawable/selector_top_round"
android:gravity="center"
android:padding="@dimen/dialog_padding"
android:text="@string/take_dy_photo"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_16" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/cut_view_height"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@color/grey" />
<TextView
android:id="@+id/tv_select_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@drawable/selector_none_round"
android:gravity="center"
android:padding="@dimen/dialog_padding"
android:text="@string/select_photo"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_16" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/cut_view_height"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@color/grey" />
<TextView
android:id="@+id/tv_take_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@drawable/selector_none_round"
android:gravity="center"
android:padding="@dimen/dialog_padding"
android:text="@string/take_photo"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_16" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/cut_view_height"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@color/grey" />
<TextView
android:id="@+id/tv_look_big_pic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:background="@drawable/selector_bottom_round"
android:gravity="center"
android:padding="@dimen/dialog_padding"
android:text="@string/look_big_pic"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_16" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dialog_margin"
android:background="@drawable/selector_all_round"
android:gravity="center"
android:padding="@dimen/dialog_padding"
android:text="@string/cancel"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_16" />
</LinearLayout>
這裏用的是TextView而沒有用Button,是因爲個人覺得點擊Button的
時候出現的陰影出超出下方邊緣,這樣會影響視覺效果。
整個佈局在底部,通過android:gravity=”bottom”來控制。
一共有5個按鈕,共分爲4種:
最頂上的一個TextView爲上方2個圓角
中間2個位爲矩形不帶圓角
倒數第二個爲下方2個圓角
最後一個爲全到圓角
怎樣畫圓角?
下面給出其中一個TextView的樣式top_round_normal.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="@color/little_grey"
android:startColor="@color/little_grey" />
<!--設置圓角 上方圓角未點擊-->
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
在shape根標籤中表明瞭是畫rectangle矩形。gradient是指漸變色,這
裏用的是同一種顏色。而corners標籤下的四個屬性顧名思義就是指定矩
形四個角的弧度的。
繪製完圓角後,發現TextView是有點擊反饋效果的。自然而然想到了寫
一個selector來區分點擊的狀態和正常狀態,top_round_normal.xml是
正常狀態,點擊狀態只需要更換一下gradient標籤中的顏色即可。
給出其中一個selector代碼:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/top_round_normal" android:state_focused="false" android:state_pressed="false" />
<item android:drawable="@drawable/top_round_pressed" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/top_round_pressed" android:state_focused="false" android:state_pressed="true" />
</selector>
然後通過background設置給TextView即可。
自定義Dialog視圖完成,下面該說說怎麼實現彈出Dialog了。
Dialog dialog = new Dialog(this, R.style.transparentFrameWindowStyle);
得到一個Dialog的實例,第二個參數爲Dialog的樣式。
<style name="transparentFrameWindowStyle" parent="android:style/Theme.Dialog">
<item name="android:windowBackground">@drawable/photo_choose_bg</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/trans" />
<!--四個圓角 未點擊-->
<corners android:radius="20dp" />
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
這裏設置顏色爲#00000000透明色,是爲了將Dialog的背景色與
整個窗體顏色保持一致以達到是一個整體的效果。
Dialog dialog = new Dialog(this,
R.style.transparentFrameWindowStyle);
dialog.setContentView(view,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
然後將view設置給dialog顯示出來並設置寬高。
在Dialog彈出是伴隨着進來和出去兩種動畫效果。
在res目錄下新建anim文件夾,新建2個資源文件。
dialog_anim_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="1000"
android:toXDelta="0"
android:toYDelta="0" />
</set>
dialog_anim_out:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="1000" />
</set>
Window window = dialog.getWindow();
window.setWindowAnimations(R.style.anim_style);
WindowManager.LayoutParams layoutParams =
window.getAttributes();
layoutParams.x = 0;
layoutParams.y =
getWindowManager().getDefaultDisplay().getHeight();
//保證dialog窗體可以水平鋪滿
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
//設置dialog的擺放位置
dialog.onWindowAttributesChanged(layoutParams);
//設置點擊dialog以爲的區域dialog消失
dialog.setCanceledOnTouchOutside(true);
dialog.show();
獲取到Dialog所在的窗體,然後通過window.setWindowAnimations()
方法設置動畫。方法接收一個style。
style中正好有
android:windowEnterAnimation //進入動畫
android:windowExitAnimation //退出動畫
因此在style文件中定義好動畫,然後設置給setWindowAnimations().
<style name="anim_style">
<item name="android:windowEnterAnimation">@anim/dialog_anim_in</item>
<item name="android:windowExitAnimation">@anim/dialog_anim_out</item>
</style>
最後設置寬高和擺放位置show出來。
最後需要提一點的是,由於這些按鈕都是TextView,直接點擊是
沒有變色效果的,這是因爲還沒有給它們增加監聽。
我們可以給它們設置一個空監聽也可。
dialog.findViewById(R.id.tv_take_dy_photo).setOnClickListener(null);
由於個人水平有限,整個過程描述的比較零散,特此獻上小Demo
完整Demo在這裏