使用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的方式不存在第一种手机键盘不显示的问题。