Android之UI--打造萬能自定義Dialog
在我們開發app的時候,很多地方需要彈出一個對話方塊,我們要不就直接用系統的Dialog或者就是AlertDialog,但是美工給我們的效果圖片很多都是無法去實現的。接下來我們來看下自定義Dialog的使用方法:首先我給大家展示2個圖片:
上面的2組圖片使我們開發app經常需要的彈窗展示,四周是圓角,ios幾乎都是這個效果,裡面的文字資訊,顏色都可以改變。接下來我們逐一的進行講解怎麼去自定義Dialog做出這樣子的效果:
一:首先我們要在values檔案styles下,來寫dialog的風格:
<!-- dialog樣式 -->
<style name ="dialog_custom" parent="@android:style/Theme.Dialog">
<item name="android:windowIsFloating">true</item> <!--是否浮在介面上-->
<item name="android:windowIsTranslucent">true</item> <!--是否半透明-->
<item name="android:windowNoTitle">false</item > <!--是否有標題-->
<item name="android:windowBackground">@android:color/transparent</item> <!--視窗背景色透明-->
<item name="android:backgroundDimEnabled">false</item> <!--背景是否模糊顯示-->
</style>
<!-- dialog底部彈出選單動畫 -->
<style name ="bottom_menu_animation" parent="android:Animation">
<item name="@android:windowEnterAnimation">@anim/bottom_menu_enter</item>
<item name="@android:windowExitAnimation">@anim/bottom_menu_exit</item>
</style>
大家可以看到我在styles裡面還加了一個動畫效果風格,這個在後面自定義Dialog的時候會用到。@anim/bottom_menu_enter和@anim/bottom_menu_exit 分別是在res下建一個anim包添加了2個檔案bottom_menu_enter和bottom_menu_exit :
在bottom_menu_enter下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="400"
android:fromYDelta="100%p" />
</set>
在bottom_menu_exit 下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="600"
android:toYDelta="100%p" />
</set>
上面的動畫我就不在闡述了,繼續朝下說:
首先我們先想下,自定義一個Dialog,首先要繼承Dialog,然後就是要有構造方法,然後重寫裡面的某些方法,其實就是這樣子。如果我們在某個Activity或者Fragment裡面想要這個自定義Dialog的話,那麼我們就要new這個自定義的Dialog。
那麼我們就很自然的想到我們需要一個Context上下文,一個佈局檔案,如果我們還要操作佈局裡面的檔案的話,那我們還要佈局檔案裡面的id和監聽事件;
說到這裡:我們就開始一步一步的去寫這個自定義的檔案:
我們起一個自定義Dialog叫CenterDialog:
private Context context; // 上下文
private int layoutResID; // 佈局檔案id
private int[] listenedItems; // 要監聽的控制元件id
public CenterDialog(Context context, int layoutResID, int[] listenedItems) {
super(context, R.style.dialog_custom); //dialog的樣式
this.context = context;
this.layoutResID = layoutResID;
this.listenedItems = listenedItems;
}
通過上面的分析,我們已經把Context,佈局檔案,佈局檔案裡面的控制元件id還有構造方法都寫好了,這裡說下,因為佈局檔案裡面的id控制元件會有很多,所有寫了一個int[]陣列。
接下來我們重寫onCreate()方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.setGravity(Gravity.CENTER); // 此處可以設定dialog顯示的位置為居中
window.setWindowAnimations(R.style.bottom_menu_animation); // 新增動畫效果
setContentView(layoutResID);
WindowManager windowManager = ((Activity) context).getWindowManager();
Display display = windowManager.getDefaultDisplay();
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.width = display.getWidth()*4/5; // 設定dialog寬度為螢幕的4/5
getWindow().setAttributes(lp);
setCanceledOnTouchOutside(true);// 點選Dialog外部消失
//遍歷控制元件id,新增點選事件
for (int id : listenedItems) {
findViewById(id).setOnClickListener(this);
}
}
接下來就是讓CenterDialog implements View.OnClickListener重寫onClick()方法,到這裡我們再想下,如果想在外部要監聽佈局檔案控制元件的事件,首先我們要對CenterDialog新增監聽事件,然後才可以進行控制控制元件的監聽事件?怎麼做呢?
如果java學的好的話,很明顯我們要在這裡面寫個介面,然後新增一個方法,讓外部重寫,那下面我們看下程式碼:
private OnCenterItemClickListener listener;
public interface OnCenterItemClickListener {
void OnCenterItemClick(CenterDialog dialog, View view);
}
public void setOnCenterItemClickListener(OnCenterItemClickListener listener) {
this.listener = listener;
}
@Override
public void onClick(View view) {
dismiss();//注意:我在這裡加了這句話,表示只要按任何一個控制元件的id,彈窗都會消失,不管是確定還是取消。
listener.OnCenterItemClick(this, view);
}
好了,自定義的CenterDialog已經書寫完畢,那我們呼叫看看:
首先寫個簡單的佈局:activity_main.xml
<?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:background="#F0EFF5">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="點選" />
</LinearLayout>
然後再寫個dialog佈局:dialog_layout.xml:
<?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:background="@drawable/dialog_center_background"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/dialog_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:text="需要寫的資訊"
android:textColor="#F88833"
android:textSize="20sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#cecece" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/dialog_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="取消"
android:textColor="#6FBF6A"
android:textSize="20sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#cecece" />
<TextView
android:id="@+id/dialog_sure"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="確定"
android:textColor="#6FBF6A"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
在MainActivity裡面:我們new出CenterDialog物件,並新增點選事件:
package com.fshsoft.dialogdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, CenterDialog.OnCenterItemClickListener {
private Button button;
private CenterDialog centerDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
centerDialog = new CenterDialog(this, R.layout.dialog_layout,
new int[]{R.id.dialog_cancel, R.id.dialog_sure});
centerDialog.setOnCenterItemClickListener(this);
}
@Override
public void onClick(View v) {
centerDialog.show();
}
@Override
public void OnCenterItemClick(CenterDialog dialog, View view) {
case R.id.dialog_sure:
Toast.makeText(MainActivity.this,"確定按鈕",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
在OnCenterItemClick();裡面我沒有進行取消按鈕的判斷,是因為在自定義的CenterDialog裡面我已經把所有控制元件的id,點選都dismiss了,前面已經提到了。
以上就是自定義dialog的內容,到這裡,也許你會說,我的佈局裡面需要一個取消按鈕,但是不是確定,是新增圖片這個字,我不可能再去寫個佈局把,你說的對,我們可以這樣子做:
new int[]{R.id.dialog_cancel, R.id.dialog_sure});
centerDialog.show();
TextView dialog_sure = (TextView) centerDialog.findViewById(R.id.dialog_sure);
dialog_sure.setText("新增圖片");
這裡需要注意的事就是,需要先把dialog給show()出來,然後通過centerDialog.findViewById(R.id.dialog_sure);才能拿到控制元件物件,然後在setText(“新增圖片”);當然還可以改變字型的顏色等等資訊,這裡就不再列舉。
以上就是全部內容,寫到這裡,你可以嘗試寫下第二張圖片的dialog.
不足之處請留言指正!有問題的可以給我留言!謝謝!