Android中Dialog使用小记

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

猜你喜欢

转载自blog.csdn.net/yao_94/article/details/80833426