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