使用dialog除了可以用AlertDialog.Builder方法直接生成,也可以使用DialogFragment的形式來建立。
第一種方式:
第一種方式有兩種寫法,當dialog對話框中含有edittext等可輸入控件時,需要把builder.create().show()方法寫在setView()方法之後,要不然會出現手機上鍵盤顯示不出來的問題。
例如下面這種代碼實作的對話框,當點選輸入的edittext時,手機上鍵盤顯示不出來,如下:
private void weightClick(float bodyWeight) {
final AlertDialog alertDialog = new AlertDialog.Builder(SettingActivity.this, R.style.my_dialog).create();
alertDialog.show();
if (alertDialog.getWindow() == null) {
return;
}
alertDialog.getWindow().setContentView(R.layout.view_dialog_input);
TextView msg = (TextView) alertDialog.findViewById(R.id.tv_msg);
Button cancel = (Button) alertDialog.findViewById(R.id.btn_cancle);
Button sure = (Button) alertDialog.findViewById(R.id.btn_sure);
final EditText input = (EditText) alertDialog.findViewById(R.id.input);
if (msg == null || cancel == null || sure == null || input == null) {
return;
}
msg.setText("設定體重");
input.setText(String.valueOf(bodyWeight));
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
sure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String val = input.getText().toString();
if (!TextUtils.isEmpty(val) && val.length() > 0) {
float bodyWeight = Float.parseFloat(val);
setting.setBodyWeight(bodyWeight);
if (adapter != null) {
adapter.notifyDataSetChanged();
}
} else {
Utils.makeToast(SettingActivity.this, "請輸入正确的參數!");
}
alertDialog.dismiss();
}
});
}
其中的style.my_dialog的内容為:
<style name="my_dialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
</style>
R.layout.view_dialog_iput的内容為:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/item_margin"
android:layout_marginRight="@dimen/item_margin"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
android:layout_marginLeft="@dimen/item_margin"
android:layout_marginRight="@dimen/item_margin"
android:layout_marginTop="25dp"
android:gravity="center"
android:textColor="@color/fontBlack"
android:textSize="@dimen/text_size"
android:textStyle="bold" />
<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:background="@drawable/dialog_background"
android:inputType="numberDecimal"
android:textColor="@color/fontBlack" />
<View style="@style/DividingLine" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<Button
android:id="@+id/btn_cancle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:text="取消"
android:textColor="#3995fa"
android:textSize="@dimen/text_size"
android:textStyle="bold" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="@color/dividing_line" />
<Button
android:id="@+id/btn_sure"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:text="确定"
android:textColor="#3995fa"
android:textSize="@dimen/text_size"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
第二種方式使用DialogFragment實作,考慮到項目中會用到很多dialog,可以将基本的實作稍微提取一下,寫一個基類,如下寫了BaseDialogFragment類,内容如下:
public abstract class BaseDialogFragment extends DialogFragment implements View.OnClickListener{
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//點選外部消失
getDialog().setCanceledOnTouchOutside(true);
//點選傳回鍵不消失
getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) {
if(keyCode == KeyEvent.KEYCODE_BACK){
return true;
}
return false;
}
});
//将對話框内部的背景設定為透明
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
View rootView = inflater.inflate(getLayout(),container,false);
findItemView(rootView);
return rootView;
}
public abstract int getLayout() ;
public abstract void findItemView(View rootView);
public abstract void onItemClick(View view);
@Override
public void onClick(View view) {
onItemClick(view);
}
}
每次顯示dialog時繼承該基類,重寫需要的方法。如下實作的StepLengthFragment,在其中定義了listener,以便實作對話框與調用對話框的activity之間的資料傳遞。
public class StepLengthFragment extends BaseDialogFragment {
public static final String STEP_LENGTH = "stepLength";
private StepDataListener listener;
public interface StepDataListener {
void setStepData(float stepLen);
}
private EditText inputStepLen;
@Override
public int getLayout() {
return R.layout.view_dialog_input;
}
public static StepLengthFragment newInstance(float stepLen){
StepLengthFragment fragment = new StepLengthFragment();
Bundle bundle = new Bundle();
bundle.putFloat(STEP_LENGTH,stepLen);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof StepDataListener){
listener = (StepDataListener) context;
}else{
throw new IllegalArgumentException("activity must implements StepDataListener");
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
@Override
public void findItemView(View rootView) {
TextView msg = (TextView) rootView.findViewById(R.id.tv_msg);
Button cancel = (Button) rootView.findViewById(R.id.btn_cancle);
Button sure = (Button) rootView.findViewById(R.id.btn_sure);
inputStepLen = (EditText) rootView.findViewById(R.id.input);
msg.setText(R.string.setting_step_length);
float stepLength = getArguments().getFloat(STEP_LENGTH);
inputStepLen.setText(String.valueOf(stepLength));
cancel.setOnClickListener(this);
sure.setOnClickListener(this);
}
@Override
public void onItemClick(View view) {
switch (view.getId()) {
case R.id.btn_cancle:
getDialog().dismiss();
break;
case R.id.btn_sure:
String val = inputStepLen.getText().toString();
if(!TextUtils.isEmpty(val) && val.length() > 0){
float stepLen = Float.parseFloat(val);
//傳回資料給settingactivity
listener.setStepData(stepLen);
} else {
Utils.makeToast(getActivity(), getString(R.string.please_input_exact_params));
}
getDialog().dismiss();
break;
default:
break;
}
}
}
在調用對話框的activity中實作該接口,以便資料傳遞。 activity中啟動對話框的代碼為:
switch (position) {
case 0: {
final float stepLen = setting.getSetpLength();
holder.desc.setText(String.format(getResources().getString(R.string.stepLen), stepLen));
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// stepClick(stepLen);
StepLengthFragment stepLengthDialog = StepLengthFragment.newInstance(stepLen);
stepLengthDialog.show(getSupportFragmentManager(), STEP_LENGTH_DIALOG);
}
});
}
實作該fragment的接口,實作相應的接口
public class SettingActivity extends BaseActivity implements StepLengthFragment.StepDataListener, BodyWeightFragment.WeightDataListener {
@Override
public void setStepData(float stepLen) {
Log.e("555", "setStepData: from StepLengthFragment "+stepLen );
setting.setStepLength(stepLen);
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
這種實作dialog的方式不存在第一種手機鍵盤不顯示的問題。