2017-06-06 18:53:32 jifashihan 阅读数 598
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14543 人正在学习 去看看 传智

UI需要android和IOS统一,搜索框为IOS风格,在网上找了一个
【Android自定义控件】仿IOS风格的搜索框

在此基础上,对焦点进行了处理,默认不获得焦点,点击以后得到焦点,并弹出软键盘

/**
 * 仿IOS搜索框,默认字体居中,点击搜索框,字体移到左侧

 */

public class SearchEditText extends AppCompatEditText implements View.OnFocusChangeListener, View.OnKeyListener, TextWatcher, View.OnClickListener
{
    private static final String TAG = "SearchEditText";
    /**
     * 图标是否默认在左边
     */
    private boolean isIconLeft = false;
    /**
     * 是否点击软键盘搜索
     */
    private boolean pressSearch = false;
    /**
     * 软键盘搜索键监听
     */
    private OnSearchClickListener listener;

    private Drawable[] drawables; // 控件的图片资源
    private Drawable drawableLeft, drawableDel; // 搜索图标和删除按钮图标
    private int eventX, eventY; // 记录点击坐标
    private Rect rect; // 控件区域
    private Context context;

    public void setOnSearchClickListener(OnSearchClickListener listener)
    {
        this.listener = listener;
    }

    public interface OnSearchClickListener
    {
        void onSearchClick(View view);

        void onTextChanged(String text);

        void beforeTextChanged(String text);

        void afterTextChanged(String text);

        void viewClick();
    }

    public SearchEditText(Context context)
    {
        this(context, null);
        this.context = context;
        init();
    }


    public SearchEditText(Context context, AttributeSet attrs)
    {
        this(context, attrs, android.R.attr.editTextStyle);
        this.context = context;
        init();
    }


    public SearchEditText(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }


    private void init()
    {
        //默认不获取焦点
        setFocusable(false);
        setOnFocusChangeListener(this);
        setOnKeyListener(this);
        addTextChangedListener(this);
        setOnClickListener(this);

        //关闭粘贴复制功能
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            setCustomInsertionActionModeCallback(new ActionMode.Callback()
            {
                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu)
                {
                    return false;
                }

                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu)
                {
                    return false;
                }

                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item)
                {
                    return false;
                }

                @Override
                public void onDestroyActionMode(ActionMode mode)
                {

                }
            });
        }
        setLongClickable(false);

    /*    SoftKeyBoardListener.setListener(context, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener()
        {
            @Override
            public void keyBoardShow(int height)
            {
            }

            @Override
            public void keyBoardHide(int height)
            {   //键盘关闭,搜索框失去焦点,显示正常的列表,隐藏搜索列表,设置上拉下拉可用
                setFocusable(false);
                clearFocus();


            }
        });
                */

    }

    @Override
    public void onClick(View v)
    {
        if (pressSearch)
        {
            return;
        }
        if (!isFocused())
        {
            //点击控件获取焦点,弹出键盘
            setFocusableInTouchMode(true);
            requestFocus();
            isIconLeft = true;
            invalidate();
            setHint("请输入关键字");

        }
        setSelectAllOnFocus(false);
        InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.showSoftInput(this, 0);

        /*InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);*/
        if (listener != null)
        {
            listener.viewClick();
        }

    }


    @Override
    protected void onDraw(Canvas canvas)
    {
        if (isIconLeft)
        { // 如果是默认样式,直接绘制
            if (length() < 1)
            {
                drawableDel = null;
            }
            this.setCompoundDrawablesWithIntrinsicBounds(drawableLeft, null, drawableDel, null);
            super.onDraw(canvas);
        }
        else
        { // 如果不是默认样式,需要将图标绘制在中间
            if (drawables == null)
                drawables = getCompoundDrawables();
            if (drawableLeft == null)
                drawableLeft = drawables[0];
            float textWidth = getPaint().measureText(getHint().toString());
            int drawablePadding = getCompoundDrawablePadding();
            int drawableWidth = drawableLeft.getIntrinsicWidth();
            float bodyWidth = textWidth + drawableWidth + drawablePadding;
            canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);
            super.onDraw(canvas);
        }
    }


    @Override
    public void onFocusChange(View v, boolean hasFocus)
    {
        // 被点击时,恢复默认样式
        if (!pressSearch && TextUtils.isEmpty(getText().toString()))
        {
            isIconLeft = hasFocus;
        }
    }

    //点击取消等操作,复原搜索框
    public void setDefault()
    {
        setFocusable(false);
        clearFocus();
        setText("");
        setHint("搜索");
        isIconLeft = false;
        pressSearch = false;
        invalidate();
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event)
    {
        pressSearch=false;
        //加入&& event.getAction() == KeyEvent.ACTION_DOWN防止执行两次
        if (listener != null && event.getAction() == KeyEvent.ACTION_DOWN)
        {
            pressSearch = (keyCode == KeyEvent.KEYCODE_ENTER);
            if (pressSearch)
            {
                /*隐藏软键盘*/
                InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm.isActive())
                {
                    imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
                }
                listener.onSearchClick(v);
                pressSearch = false;
                setFocusable(false);
                clearFocus();
            }
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
// 清空edit内容
        if (drawableDel != null && event.getAction() == MotionEvent.ACTION_UP)
        {
            eventX = (int) event.getRawX();
            eventY = (int) event.getRawY();
            Log.i(TAG, "eventX = " + eventX + "; eventY = " + eventY);
            if (rect == null)
                rect = new Rect();
            getGlobalVisibleRect(rect);
            rect.left = rect.right - drawableDel.getIntrinsicWidth();
            if (rect.contains(eventX, eventY))
            {
                //点击删除按钮,清空文字,关闭软键盘,设置焦点不可用
                setText("");
                setFocusable(false);
                /*隐藏软键盘*/
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm.isActive())
                {
                    imm.hideSoftInputFromWindow(this.getApplicationWindowToken(), 0);
                }
                // listener.onSearchClick(this);
            }
        }
// 删除按钮被按下时改变图标样式
        if (drawableDel != null && event.getAction() == MotionEvent.ACTION_DOWN)
        {
            eventX = (int) event.getRawX();
            eventY = (int) event.getRawY();
            Log.i(TAG, "eventX = " + eventX + "; eventY = " + eventY);
            if (rect == null)
                rect = new Rect();
            getGlobalVisibleRect(rect);
            rect.left = rect.right - drawableDel.getIntrinsicWidth();
            if (rect.contains(eventX, eventY))
                drawableDel = this.getResources().getDrawable(R.drawable.delete_new);
        }
        else
        {
            drawableDel = this.getResources().getDrawable(R.drawable.delete_new);
        }
        return super.onTouchEvent(event);
    }


    @Override
    public void afterTextChanged(Editable arg0)
    {
        if (this.length() < 1)
        {
            drawableDel = null;
        }
        else
        {
            drawableDel = this.getResources().getDrawable(R.drawable.delete_new);
        }
        if (listener != null)
        {
            listener.afterTextChanged(arg0 + "");
        }
    }


    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3)
    {
        if (listener != null)
        {
            listener.beforeTextChanged(arg0 + "");
        }
    }

    @Override
    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3)
    {
        if (listener != null)
        {
            listener.onTextChanged(arg0 + "");
        }

    }
}
2018-01-13 22:03:34 Sure_Min 阅读数 421
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14543 人正在学习 去看看 传智

说起来毕业也一年半了,一直想把积累的一些东西搬到博客上来但找不到什么时间(其实是因为懒,>_<),现在有点时间就做一些吧,万事开头难,嘿嘿。

 

今天带来一个自定义控件叫IosDialog,就是ios上那种风格的有一个确定键一个返回键的文本提示对话框。控件是很早以前写的,之所以写这个控件是因为UI在做效果图的时候总是参照ios的风格来做,而ios那边有现成的控件,android这边我觉得每次都copy一大段的代码太麻烦了,于是就封装了这个控件。废话说了一堆,下面正片开始。

 

先自定义一个对话框风格,在styles文件下添加如下代码:

<!-- 自定义对话框风格 -->
<style name="CustomDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
</style>

然后要定义一些对话框的背景资源文件,比如白色圆角背景,按钮的selector什么的,代码如下:

dialog_top_up.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp" />

</shape>

dialog_bottom_left_up.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners android:bottomLeftRadius="10dp" />

</shape>

dialog_bottom_left_down.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />

    <corners android:bottomLeftRadius="10dp" />

</shape>

dialog_bottom_left_selector.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_bottom_left_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_bottom_left_down" android:state_pressed="true"></item>

</selector>

dialog_bottom_right_up.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners android:bottomRightRadius="10dp" />

</shape>

dialog_bottom_right_down.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />

    <corners android:bottomRightRadius="10dp" />

</shape>

dialog_bottom_right_selector.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_bottom_right_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_bottom_right_down" android:state_pressed="true"></item>

</selector>

以上一共7个xml文件都添加到drawable目录下就可以了,没什么好讲的。


然后在layout目录下新建一个对话框的布局文件dialog_ios.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="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/dialog_top_up"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:id="@+id/title_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="20dp"
            android:text="我是标题"
            android:textColor="#4a4a4a"
            android:textSize="18sp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="40dp"
            android:padding="20dp">

            <TextView
                android:id="@+id/content_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="我是文字"
                android:textColor="#666666"
                android:textSize="16sp" />

        </RelativeLayout>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#dddddd" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/cancel_button"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:background="@drawable/dialog_bottom_left_selector"
            android:gravity="center"
            android:text="取消"
            android:textColor="#1e90ff"
            android:textSize="16sp" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#dddddd" />

        <Button
            android:id="@+id/asure_button"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:background="@drawable/dialog_bottom_right_selector"
            android:gravity="center"
            android:text="确定"
            android:textColor="#1e90ff"
            android:textSize="16sp" />

    </LinearLayout>

</LinearLayout>


以上准备工作都弄完以后就可以上控件IosDialog的本体了,如下:

public class IosDialog extends Dialog {
    private Context context;

    private TextView titleTextView;
    private TextView contentTextView;
    private Button cancelButton;
    private Button asureButton;
    private View view;

    //标题
    private String title;

    //内容
    private String text;

    //确定按钮的文字
    private String asureText;

    //取消按钮是的文字
    private String cancelText;

    //对话框位于屏幕位置
    private int gravity;

    //标题大小
    private int titleTextSize;

    //标题颜色
    private int titleTextColor;

    //内容大小
    private int textSize;

    //内容颜色
    private int textColor;

    //确定和取消按钮文字大小
    private int buttonTextSize;

    //确定按钮文字颜色
    private int buttonAsureTextColor;

    //取消按钮文字颜色
    private int buttonCancelTextColor;

    //对话框宽度
    private int width;

    //对话框高度
    private int height;

    //确定和取消按钮点击回调接口
    private OnButtonClickListener listener;

    public IosDialog(Context context) {
        super(context, R.style.CustomDialog);
        this.context = context;
    }

    public IosDialog(Context context, int theme) {
        super(context, theme);
        this.context = context;
    }

    public IosDialog createDialog() {
        view = LayoutInflater.from(context).inflate(R.layout.dialog_ios, null);

        titleTextView = (TextView) view.findViewById(R.id.title_textview);
        contentTextView = (TextView) view.findViewById(R.id.content_textview);
        cancelButton = (Button) view.findViewById(R.id.cancel_button);
        asureButton = (Button) view.findViewById(R.id.asure_button);
        titleTextView.setVisibility(title != null ? View.VISIBLE : View.GONE);
        titleTextView.setText(title);
        titleTextView.setTextColor(titleTextColor != 0 ? titleTextColor : Color.parseColor("#4a4a4a"));
        titleTextView.setTextSize(titleTextSize != 0 ? titleTextSize : 18);
        contentTextView.setText(text);
        contentTextView.setTextColor(textColor != 0 ? textColor : Color.parseColor("#666666"));
        contentTextView.setTextSize(textSize != 0 ? textSize : 16);
        cancelButton.setText(cancelText != null ? cancelText : "取消");
        cancelButton.setTextColor(buttonCancelTextColor != 0 ? buttonCancelTextColor : Color.parseColor("#1e90ff"));
        cancelButton.setTextSize(buttonTextSize != 0 ? buttonTextSize : 16);
        asureButton.setText(asureText != null ? asureText : "确定");
        asureButton.setTextColor(buttonAsureTextColor != 0 ? buttonAsureTextColor : Color.parseColor("#1e90ff"));
        asureButton.setTextSize(buttonTextSize != 0 ? buttonTextSize : 16);
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onCancelClick();
            }
        });
        asureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onAsureClick();
            }
        });

        show();
        setContentView(view);
        getWindow().getAttributes().gravity = gravity != 0 ? gravity : Gravity.CENTER;
        getWindow().setLayout(width != 0 ? width : getWindowWidth((Activity) context)
                - 2 * dp2px(45), height != 0 ? height : WindowManager.LayoutParams.WRAP_CONTENT);
        setCanceledOnTouchOutside(false);
        setCancelable(true);

        return this;
    }

    public void setAsureText(String asureText) {
        this.asureText = asureText;
    }

    public void setButtonAsureTextColor(int buttonAsureTextColor) {
        this.buttonAsureTextColor = buttonAsureTextColor;
    }

    public void setButtonCancelTextColor(int buttonCancelTextColor) {
        this.buttonCancelTextColor = buttonCancelTextColor;
    }

    public void setButtonTextSize(int buttonTextSize) {
        this.buttonTextSize = buttonTextSize;
    }

    public void setCancelText(String cancelText) {
        this.cancelText = cancelText;
    }

    public void setGravity(int gravity) {
        this.gravity = gravity;
    }

    public void setTitleTextSize(int titleTextSize) {
        this.titleTextSize = titleTextSize;
    }

    public void setTitleTextColor(int titleTextColor) {
        this.titleTextColor = titleTextColor;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
    }

    public void setView(View view) {
        this.view = view;
    }

    public void setDialogSize(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public interface OnButtonClickListener {
        void onAsureClick();

        void onCancelClick();
    }

    public void setOnButtonClickListener(OnButtonClickListener listener) {
        this.listener = listener;
    }

    private int getWindowWidth(Activity activity) {
        WindowManager windowManager = activity.getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        return display.getWidth();
    }

    private int dp2px(float dipValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public static class DialogBuilder {
        IosDialog dialog;

        public DialogBuilder(Context context) {
            dialog = new IosDialog(context);
        }

        /**
         * 设置对话框在屏幕的位置
         * @param gravity 类Gravity下的位置常数
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setGravity(int gravity) {
            dialog.setGravity(gravity);

            return this;
        }

        /**
         * 设置确定按钮文字
         * @param asureText 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setAsureText(String asureText) {
            dialog.setAsureText(asureText);
            return this;
        }

        /**
         * 设置确定按钮文字颜色
         * @param buttonAsureTextColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setButtonAsureTextColor(int buttonAsureTextColor) {
            dialog.setButtonAsureTextColor(buttonAsureTextColor);
            return this;
        }

        /**
         * 设置取消按钮文字颜色
         * @param buttonCancelTextColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setButtonCancelTextColor(int buttonCancelTextColor) {
            dialog.setButtonCancelTextColor(buttonCancelTextColor);
            return this;
        }

        /**
         * 设置确定和取消按钮的文字大小
         * @param buttonTextSize 文字大小,单位sp
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setButtonTextSize(int buttonTextSize) {
            dialog.setButtonTextSize(buttonTextSize);
            return this;
        }

        /**
         * 设置取消按钮文字
         * @param cancelText 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setCancelText(String cancelText) {
            dialog.setCancelText(cancelText);
            return this;
        }

        /**
         * 设置对话框大小
         * @param width   对话框宽度,单位px
         * @param height  对话框高度,单位px
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setDialogSize(int width, int height) {
            dialog.setDialogSize(width, height);
            return this;
        }

        /**
         * 设置标题大小
         * @param titleTextSize 文字大小,单位sp
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTitleTextSize(int titleTextSize) {
            dialog.setTextSize(titleTextSize);
            return this;
        }

        /**
         * 设置标题颜色
         * @param titleTextColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTitleTextColor(int titleTextColor) {
            dialog.setTitleTextColor(titleTextColor);
            return this;
        }

        /**
         * 设置标题
         * @param title 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTitle(String title) {
            dialog.setTitle(title);
            return this;
        }

        /**
         * 设置内容
         * @param text 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setText(String text) {
            dialog.setText(text);
            return this;
        }

        /**
         * 设置内容颜色
         * @param textColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTextColor(int textColor) {
            dialog.setTextColor(textColor);
            return this;
        }

        /**
         * 设置内容大小
         * @param textSize 文字大小,单位sp
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTextSize(int textSize) {
            dialog.setTextSize(textSize);
            return this;
        }

        /**
         * 设置确定和取消按钮的点击回调
         * @param listener 回调接口
         * @return 当前的DialogBuilder
         */
        public DialogBuilder addListener(OnButtonClickListener listener) {
            dialog.setOnButtonClickListener(listener);
            return this;
        }

        /**
         * 创建对话框,放在最后执行
         * @return 创建的IosDialog实体
         */
        public IosDialog create() {
            return dialog.createDialog();
        }
    }
}

这里稍微说明一下,控价引用建造者模式的思想,通过创建内部类DialogBuilder(建造者)的实体,设置好相关参数后调用它下面的create方法即可,相关参数个方法的意义已经在注释里写的很清楚了,不再累述。


最后就可以调用了。贴上MainActivity的代码:
public class MainActivity extends Activity {
    private Button button;

    private IosDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }

    private void initData() {

    }

    private void initView() {
        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }仿ios风格

    private void showDialog() {
        dialog = new IosDialog.DialogBuilder(this)
                .setText("嫁给我好吗?")
                .addListener(new IosDialog.OnButtonClickListener() {
                    @Override
                    public void onAsureClick() {
                        Toast.makeText(MainActivity.this, "太好了", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }

                    @Override
                    public void onCancelClick() {
                        Toast.makeText(MainActivity.this, "悲伤的故事", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                })
                .create();
    }
}

这里稍微说明一下,控价引用建造者模式的思想,通过创建内部类DialogBuilder(建造者)的实体,设置好相关参数后调用它下面的create方法即可,相关参数个方法的意义已经在注释里写的很清楚了,不再累述。


最后就可以调用了。贴上MainActivity的代码:

public class MainActivity extends Activity {
    private Button button;

    private IosDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }

    private void initData() {

    }

    private void initView() {
        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }

    private void showDialog() {
        dialog = new IosDialog.DialogBuilder(this)
                .setText("嫁给我好吗?")
                .addListener(new IosDialog.OnButtonClickListener() {
                    @Override
                    public void onAsureClick() {
                        Toast.makeText(MainActivity.this, "太好了", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }

                    @Override
                    public void onCancelClick() {
                        Toast.makeText(MainActivity.this, "悲伤的故事", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                })
                .create();
    }
}

布局文件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:gravity="center_horizontal"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_margin="10dp"
        android:text="SHOW DIALOG" />

</LinearLayout>

只有一个按钮。


最简单的调用方法只需要new IosDialog.DialogBuilder(this)创建一个DialogBuilder的实体,然后.setText设置文字内容,然后.addListener添加一个按钮点击的回调,最后.create(),一个对话框就弹出来了,效果如下:

                                                               

控件支持设置更多的自定义属性,比如在原来的代码上添加:

dialog = new IosDialog.DialogBuilder(this)
        ...

        .setAsureText("嗯")
        .setCancelText("你是个好人")
        .setTextColor(Color.parseColor("#bc8f8f"))
        
        ...
        .create();

就可以改变按钮的文字内容和说明文字的颜色,效果如下:

                                                                

控件还支持添加一个标题,使用setTitle方法(不设置标题时标题栏自动隐藏),添加如下代码:

dialog = new IosDialog.DialogBuilder(this)
       ...

        .setButtonCancelTextColor(Color.parseColor("#aaaaaa"))
        .setTitle("求婚大作战")
       
        ...
        .create();

再次运行,效果如下:

                                                                

更多设置方法的含义在控件源码中都有详细说明,大家可以自己试一试。

 

总结一下控件的用法就是:new一个DialogBulder,根据需要set一堆东西,最后create一下。是不是很简单?建造者模式真是懒人的福利,哈哈哈。


最后附上源码地址:点击打开链接


这次的内容就到这里,我们下次再见


2018-01-13 23:02:29 Sure_Min 阅读数 2177
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14543 人正在学习 去看看 传智

这次还是带来一个Android仿Ios风格的控件。Ios里有个控件叫ActionSheet,就是那种从下往上弹出的选项卡,比如下面这个效果:

                                                                 

UI在设计效果图的时候,添加图片、选择性别之类的功能经常会这么设计,ios那边有个ActionSheet可以用,android这边就比较麻烦了(有时候会感叹ios的一些控件确实要比android封装得更彻底)于是就自己封装了一个,名字也叫ActionSheet。控件其实是很久以前写的,现在拿出来跟大家分享一下。话不多说,正片开始。


首先这个控件继承自Dialog,需要先定义一个style和弹入弹出的动画。首先在res目录下新建一个anim文件夹,并在这个文件夹下新建两个动画文件

actionsheet_in.xml和 actionsheet_out,xml,如下:

actionsheet_in.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromYDelta="100%"
    android:toYDelta="0" />

actionsheet_out.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromYDelta="0"
    android:toYDelta="100%" />

然后就定义一个style并绑定这两个动画。在styles文件先添加以下内容:

<style name="ActionSheetStyle" parent="@android:style/Theme.Dialog">
    <!-- 背景透明 -->
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <!-- 浮于Activity之上 -->
    <item name="android:windowIsFloating">true</item>
    <!-- 边框 -->
    <item name="android:windowFrame">@null</item>
    <!-- Dialog以外的区域模糊效果 -->
    <item name="android:backgroundDimEnabled">true</item>
    <!-- 无标题 -->
    <item name="android:windowNoTitle">true</item>
    <!-- 半透明 -->
    <item name="android:windowIsTranslucent">true</item>
    <!-- Dialog进入及退出动画 -->
    <item name="android:windowAnimationStyle">@style/ActionSheetAnimation</item>
</style>


<!-- ActionSheet进出动画 -->
<style name="ActionSheetAnimation" parent="@android:style/Animation.Dialog">
    <item name="android:windowEnterAnimation">@anim/actionsheet_in</item>
    <item name="android:windowExitAnimation">@anim/actionsheet_out</item>
</style>

然后是最麻烦的地方,定义背景资源文件,一共12个(没办法,好看是有代价的 >_<)。在drawable目录下创建以下12个资源文件:

dialog_bottom_up.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp" />

</shape>
dialog_bottom_down.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />

    <corners
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp" />

</shape>

dialog_bottom_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_bottom_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_bottom_down" android:state_pressed="true"></item>

</selector>

dialog_top_up.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp" />

</shape>

dialog_top_down.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />

    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp" />

</shape>
dialog_top_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_top_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_top_down" android:state_pressed="true"></item>

</selector>

dialog_white_up.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners android:radius="10dp" />

</shape>

dialog_white_down.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />
    
</shape>

dialog_white_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_white_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_white_down" android:state_pressed="true"></item>

</selector>

layout_white_up.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />
    
</shape>

layout_white_down.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />
    
</shape>

layout_white_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/layout_white_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/layout_white_down" android:state_pressed="true"></item>

</selector>

终于搞好了,好麻烦的说。接下来就可以上ActionDialog的本体了,如下:

ActionDialog.java:

public class ActionSheet extends Dialog {
    private Context context;

    private LinearLayout parentLayout;
    private TextView titleTextView;
    private ArrayList<Button> sheetList;
    private Button cancelButton;

    // 标题
    private String title;

    //就取消按钮文字
    private String cancel;

    // 选择项文字列表
    private ArrayList<String> sheetTextList;

    // 标题颜色
    private int titleTextColor;

    // 取消按钮文字颜色
    private int cancelTextColor;

    // 选择项文字颜色
    private int sheetTextColor;

    // 标题大小
    private int titleTextSize;

    // 取消按钮文字大小
    private int cancelTextSize;

    // 选择项文字大小
    private int sheetTextSize;

    // 标题栏高度
    private int titleHeight;

    // 取消按钮高度
    private int cancelHeight;

    // 选择项高度
    private int sheetHeight;

    // 弹出框距离底部的高度
    private int marginBottom;

    // 取消按钮点击回调
    private View.OnClickListener cancelListener;

    // 选择项点击回调列表
    private ArrayList<View.OnClickListener> sheetListenerList;

    public ActionSheet(Context context) {
        super(context, R.style.ActionSheetStyle);
        init(context);
    }

    public ActionSheet(Context context, int theme) {
        super(context, theme);
        init(context);
    }

    private void init(Context context) {
        this.context = context;

        cancel = "取消";
        titleTextColor = Color.parseColor("#aaaaaa");
        cancelTextColor = Color.parseColor("#666666");
        sheetTextColor = Color.parseColor("#666666");
        titleTextSize = 14;
        cancelTextSize = 16;
        sheetTextSize = 16;
        titleHeight = dp2px(40);
        cancelHeight = dp2px(40);
        sheetHeight = dp2px(40);
        marginBottom = dp2px(10);

        sheetList = new ArrayList<>();
        sheetTextList = new ArrayList<>();
        sheetListenerList = new ArrayList<>();
    }

    private ActionSheet createDialog() {
        parentLayout = new LinearLayout(context);
        parentLayout.setBackgroundColor(Color.parseColor("#00000000"));
        parentLayout.setOrientation(LinearLayout.VERTICAL);

        if (title != null) {
            titleTextView = new TextView(context);
            titleTextView.setGravity(Gravity.CENTER);
            titleTextView.setText(title);
            titleTextView.setTextColor(titleTextColor);
            titleTextView.setTextSize(titleTextSize);
            titleTextView.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.dialog_top_up));
            LinearLayout.LayoutParams titleLayoutParams = new LinearLayout.LayoutParams
                    (ViewGroup.LayoutParams.MATCH_PARENT, titleHeight);
            parentLayout.addView(titleTextView, titleLayoutParams);
        }
        for (int i = 0; i < sheetTextList.size(); i++) {
            if (i == 0 && title != null) {
                View topDividerLine = new View(context);
                topDividerLine.setBackgroundColor(Color.parseColor("#eeeeee"));
                parentLayout.addView(topDividerLine, new LinearLayout
                        .LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(1)));
            }

            Button button = new Button(context);
            button.setGravity(Gravity.CENTER);
            button.setText(sheetTextList.get(i));
            button.setTextColor(sheetTextColor);
            button.setTextSize(sheetTextSize);
            if (title != null) {
                if (i == sheetTextList.size() - 1) {
                    button.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.dialog_bottom_selector));
                } else {
                    button.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.layout_white_selector));
                }
            } else {
                if (sheetTextList.size() == 1) {
                    button.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.dialog_white_selector));
                } else {
                    if (i == 0) {
                        button.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.dialog_top_selector));
                    } else if (i == sheetTextList.size() - 1) {
                        button.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.dialog_bottom_selector));
                    } else {
                        button.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.layout_white_selector));
                    }
                }
            }
            button.setOnClickListener(sheetListenerList.get(i));
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
                    (ViewGroup.LayoutParams.MATCH_PARENT, sheetHeight);
            parentLayout.addView(button, layoutParams);
            sheetList.add(button);

            if (i != sheetTextList.size() - 1) {
                View bottomDividerLine = new View(context);
                bottomDividerLine.setBackgroundColor(Color.parseColor("#eeeeee"));
                parentLayout.addView(bottomDividerLine, new LinearLayout
                        .LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(1)));
            }
        }

        cancelButton = new Button(context);
        cancelButton.setGravity(Gravity.CENTER);
        cancelButton.setText(cancel);
        cancelButton.setTextColor(cancelTextColor);
        cancelButton.setTextSize(cancelTextSize);
        cancelButton.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.dialog_white_selector));
        cancelButton.setOnClickListener(cancelListener);
        LinearLayout.LayoutParams cancelParams = new LinearLayout.LayoutParams
                (ViewGroup.LayoutParams.MATCH_PARENT, cancelHeight);
        cancelParams.setMargins(0, dp2px(10), 0, 0);
        parentLayout.addView(cancelButton, cancelParams);

        getWindow().setGravity(Gravity.BOTTOM);
        getWindow().getAttributes().y = marginBottom;
        show();
        setContentView(parentLayout);
        setCancelable(true);
        setCanceledOnTouchOutside(true);

        return this;
    }

    private void addSheet(String text, View.OnClickListener listener) {
        sheetTextList.add(text);
        sheetListenerList.add(listener);
    }

    public void setCancel(String text) {
        this.cancel = text;
    }

    public void setCancelHeight(int height) {
        this.cancelHeight = dp2px(height);
    }

    public void setCancelTextColor(int color) {
        this.cancelTextColor = color;
    }

    public void setCancelTextSize(int textSize) {
        this.cancelTextSize = textSize;
    }

    public void setSheetHeight(int height) {
        this.sheetHeight = dp2px(height);
    }

    public void setSheetTextColor(int color) {
        this.sheetTextColor = color;
    }

    public void setSheetTextSize(int textSize) {
        this.sheetTextSize = textSize;
    }

    public void setTitle(String text) {
        this.title = text;
    }

    public void setTitleHeight(int height) {
        this.titleHeight = height;
    }

    public void setTitleTextColor(int color) {
        this.titleTextColor = color;
    }

    public void setTitleTextSize(int textSize) {
        this.titleTextSize = textSize;
    }

    public void setMargin(int bottom) {
        this.marginBottom = dp2px(bottom);
    }

    public void addCancelListener(View.OnClickListener listener) {
        this.cancelListener = listener;
    }

    private int dp2px(float dipValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public static class DialogBuilder {
        ActionSheet dialog;

        public DialogBuilder(Context context) {
            dialog = new ActionSheet(context);
        }

        /**
         * 添加一个选择项
         * @param text 选择项文字
         * @param listener 选择项点击回调监听
         * @return 当前DialogBuilder
         */
        public DialogBuilder addSheet(String text, View.OnClickListener listener) {
            dialog.addSheet(text, listener);
            return this;
        }

        /**
         * 设置取消按钮文字
         * @param text 文字内容
         * @return 当前DialogBuilder
         */
        public DialogBuilder setCancel(String text) {
            dialog.setCancel(text);
            return this;
        }

        /**
         * 设置取消按钮高度
         * @param height 高度值,单位dp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setCancelHeight(int height) {
            dialog.setCancelHeight(height);
            return this;
        }

        /**
         * 设置取消按钮文字颜色
         * @param color 颜色值
         * @return 当前DialogBuilder
         */
        public DialogBuilder setCancelTextColor(int color) {
            dialog.setCancelTextColor(color);
            return this;
        }

        /**
         * 设置取消按钮文字大小
         * @param textSize 大小值,单位sp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setCancelTextSize(int textSize) {
            dialog.setCancelTextSize(textSize);
            return this;
        }

        /**
         * 设置选择项高度
         * @param height 高度值,单位dp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setSheetHeight(int height) {
            dialog.setSheetHeight(height);
            return this;
        }

        /**
         * 设置选择项文字颜色
         * @param color 颜色值
         * @return 当前DialogBuilder
         */
        public DialogBuilder setSheetTextColor(int color) {
            dialog.setSheetTextColor(color);
            return this;
        }

        /**
         * 设置选择项文字大小
         * @param textSize 大小值,单位sp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setSheetTextSize(int textSize) {
            dialog.setSheetTextSize(textSize);
            return this;
        }

        /**
         * 设置标题
         * @param text 文字内容
         * @return 当前DialogBuilder
         */
        public DialogBuilder setTitle(String text) {
            dialog.setTitle(text);
            return this;
        }

        /**
         * 设置标题栏高度
         * @param height 高度值,单位dp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setTitleHeight(int height) {
            dialog.setTitleHeight(height);
            return this;
        }

        /**
         * 设置标题颜色
         * @param color 颜色值
         * @return 当前DialogBuilder
         */
        public DialogBuilder setTitleTextColor(int color) {
            dialog.setTitleTextColor(color);
            return this;
        }

        /**
         * 设置标题大小
         * @param textSize 大小值,单位sp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setTitleTextSize(int textSize) {
            dialog.setTitleTextSize(textSize);
            return this;
        }

        /**
         * 设置弹出框距离底部的高度
         * @param bottom 距离值,单位dp
         * @return 当前DialogBuilder
         */
        public DialogBuilder setMargin(int bottom) {
            dialog.setMargin(bottom);
            return this;
        }

        /**
         * 设置取消按钮的点击回调
         * @param listener 回调监听
         * @return
         */
        public DialogBuilder addCancelListener(View.OnClickListener listener) {
            dialog.addCancelListener(listener);
            return this;
        }

        /**
         * 创建弹出框,放在最后执行
         * @return 创建的 ActionSheet 实体
         */
        public ActionSheet create() {
            return dialog.createDialog();
        }
    }
}

稍微说一下,依然是建造者模式的写法,内部类DialogBuilder是一个建造器,调用的时候通过新建一个DialogBuilder实体,设置好想要的参数,最后调用其create方法就建造完成了。
 
最后的最后,终于可以用了!MainActivity.class和activity_main.xml贴上:
MainActivity.class:
public class MainActivity extends Activity {
    private Button button;

    private ActionSheet actionSheet;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }

    private void initData() {

    }

    private void initView() {
        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSheet();
            }
        });
    }

    private void showSheet() {
        actionSheet=new ActionSheet.DialogBuilder(this)
                .addSheet("雷军", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "当然是雷布斯!", Toast.LENGTH_SHORT).show();
                        actionSheet.dismiss();
                    }
                })
                .addSheet("马化腾", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "当然是小马哥!", Toast.LENGTH_SHORT).show();
                        actionSheet.dismiss();
                    }
                })
                .addSheet("马云", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "当然是马爸爸!", Toast.LENGTH_SHORT).show();
                        actionSheet.dismiss();
                    }
                })
                .addCancelListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "容我三思", Toast.LENGTH_SHORT).show();
                        actionSheet.dismiss();
                    }
                })
                .create();
    }
}

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:gravity="center_horizontal"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_margin="10dp"
        android:text="SHOW SHEET" />

</LinearLayout>

简单的说一下,调用方法之前已经说了,其中addSheet方法每调用一次就会添加一条选线栏,需要输入选项栏文字,和点击的回调监听,这里监听直接用的是View下的OnClickListener,是不是很亲切?顺带一提,取消按钮是默认存在的,所以务必设置一下addCancelListener,不然点击取消会没反应。

来看一下效果,运行走起! 

                                                                 

控件支持添加标题栏,改变文字大小、颜色什么的,几行代码搞定,如下:

actionSheet=new ActionSheet.DialogBuilder(this)
        ...

        .setTitle("你觉得以下谁最帅?")
        .setCancel("容我三思")
        .setTitleTextColor(Color.parseColor("#ff69b4"))
        .setCancelTextColor(Color.parseColor("#aaaaaa"))
        .setSheetTextColor(Color.parseColor("#1e90ff"))
        
        ...
        .create();

再次运行,看一下效果:

                                                                

是不是很简单?更多设置选项在控件源码里都已经注释清楚了,大家可以自己试一试。


总结一下控件的用法就是:new一个DialogBulder,根据需要set一堆东西有几个选项卡就调用几次addSheet,最后create一下,搞定。


最后附上源码地址:点击打开链接


这次的内容就到这里,我们下次再见。








2018-07-31 23:56:37 ohaozy 阅读数 288
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14543 人正在学习 去看看 传智

网页原地址:http://www.jq22.com/demo/uiAlertView201712071705/#

挺喜欢这个弹出层插件,效果如下:

可惜嵌套使用时存在问题,只能弹出第一层。也即弹出:“确定要删除吗?”,回调函数里再弹出“删除成功”的提示就存在bug。

查阅代码后发现问题的根源是弹出第一层点击后,关闭弹出层时,直接使用类选择器,且动态生成的层所取id都一致,导致后来弹出的层还没有展现就被remove了。

修改后直接按原来用法使用即可。

修改如下:粗体为修改的内容。

(function($) {
    $.extend({
                alertView : function(options) {
                    var currTime=((new Date()).getTime()+"").substring(8);
                    var mask_Id="popup_dialog_mask_"+currTime;
                    var dialog_Id="popup_dialog_"+currTime;

                    var defaults = {
                        showMask : true,
                        title : "",
                        msg : "",
                    };
                    var settings = {};
                    if ($.type(options) == "string") {
                        settings = defaults;
                        settings.msg = options;
                    } else if ($.type(options) == "object") {
                        settings = $.extend(true, defaults, options);
                    }
                    if (!settings.buttons || settings.buttons.length == 0) {
                        settings.buttons = [ {
                            title : "确定"
                        } ];
                    }
                    $.closeView(mask_Id,dialog_Id);
                    if (settings.showMask) {
                        $("body")
                                .append(
                                        '<div id="'+mask_Id+'" class="lodding-mask"></div>');
                    }
                    var popupDialog = $('<div id="'+dialog_Id+'" class="popup-dialog"></div>');
                    if (settings.title) {
                        popupDialog.append('<h3 id="popup-dialog-title_"'+currTime+'>'
                                + settings.title + '</h3>');
                    }
                    popupDialog
                            .append('<p id="popup-dialog-msg_"'+currTime+' class="message '
                                    + ((settings.title ? "" : "margin-top-15"))
                                    + '">' + settings.msg + '</p>');
                    if (settings.input && $.type(settings.input) == 'object') {
                        var html = "<input"
                        $.each(settings.input, function(key, value) {
                            html += ' ' + key + '="' + value + '"';
                        })
                        html += "/>";
                        $(html).appendTo(popupDialog);
                    }
                    var btnSize = settings.buttons.length;
                    if (btnSize == 2) {
                        var buttonGroup = $('<div class="ui-grid-a group"></div>');
                        $.each(settings.buttons, function(i, btnJson) {
                            var color = btnJson.color ? 'style="color:'
                                    + btnJson.color + '"' : "";
                            var button = $('<div class="ui-block-'
                                    + (i == 0 ? "a" : "b") + '" ' + color + '>'
                                    + btnJson.title + '</div>');
                            addBtnEvent(button, btnJson,mask_Id,dialog_Id);
                            buttonGroup.append(button);
                        });
                        popupDialog.append(buttonGroup);
                    } else {
                        $.each(settings.buttons, function(i, btnJson) {
                            var color = btnJson.color ? 'style="color:'
                                    + btnJson.color + '"' : "";
                            var button = $('<div class="ui-grid-a'
                                    + (i == 0 ? " group" : "") + '" ' + color
                                    + '>' + btnJson.title + '</div>');
                            addBtnEvent(button, btnJson,mask_Id,dialog_Id);
                            popupDialog.append(button);
                        })
                    }
                    $("body").append(popupDialog);
                },
                closeView : function(maskId,dialogId) {
                    /*$(".popup-dialog, .lodding-mask").fadeOut(50, function() {
                        $(this).remove();
                    });*/
                    $("#"+maskId+",#"+dialogId).fadeOut(50, function() {
                        $(this).remove();
                    });

                }
            });
    function addBtnEvent(btn, btnJson,maskId,dialogId) {
        btn.on("click", function() {
            if (btnJson.click && typeof (btnJson.click) == "function") {
                var content = $(this).closest("div.popup-dialog");
                var val = $.trim(content.find("input").val());
                btnJson.click(val, content);
            }
            if (!btnJson.hasOwnProperty("autoClose")
                    || btnJson.autoClose != false) {
                $.closeView(maskId,dialogId);
            }
        });
    }
})(jQuery);
jQuery(function() {
    document.body.addEventListener('touchstart', function() {
    });
});

简单用法:先加工下代码,使用起来更方便:

var DZW={

   confirm : function(info,okFun,cancelFun){
       var json = {
                title:"",
                msg:info,
                buttons:[
                    { title:"确定",color:"red",click:function(){if(okFun)okFun();} },
                    { title:"取消",color:"green",click:function(){if(cancelFun)cancelFun();} }
                ]
            }
       $.alertView(json);
   },
   alert : function(info,fun){
       var json = {
                title:"",
                msg:info,
                buttons:[
                    { title:"确定",color:"red",click:function(){if(fun)fun();} }
                ]
            }
       $.alertView(json);
   }
}

<script type="text/javascript">

function goDel(url){
    DZW.confirm('确定要删除吗?', function(){
        $("body").mLoading("show");
        var json=DZW.getJsonData(url,param);
        setTimeout(function(){
            $("body").mLoading("hide");
            if(json.msg = "success"){
                DZW.alert("删除成功!",function(){
                    location.href="/stutask/student/calendar.do";
                });
            }else{
                DZW.alert(json.msg);
            }
        },200);
    });
}
</script>

完整代码及使用demo请移步:https://download.csdn.net/download/ohaozy/10575769

2016-07-25 09:53:30 bfbx5173 阅读数 3265
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14543 人正在学习 去看看 传智

尊重原创转载请注明:http://blog.csdn.net/bfbx5173/article/details/52020733


UI 老是喜欢以iOS风格为主,同时产品要求两边风格一致。这个时候就悲催了。 什么时候我md可以当家做主,不过事还是要继续做。


   


在此分享一个仿iOS7的底部弹出框。

自定义Dialog 之前在  滚轮控件LoopView+自定义Dialog [时间地域选择器] Picker

有谈到过写法,是java中常用的一种构造者模式,大家多多练习一下就都会了。


public class BottomMenuDialog extends Dialog {

    public BottomMenuDialog(Context context, int themeResId) {
        super(context, themeResId);
    }

    public static class Params {
        private final List<BottomMenu> menuList = new ArrayList<>();
        private View.OnClickListener cancelListener;
        private String menuTitle;
        private String cancelText;
        private Context context;
    }

    public static class Builder {
        private boolean canCancel = true;
        private boolean shadow = true;
        private final Params p;

        public Builder(Context context) {
            p = new Params();
            p.context = context;
        }

        public Builder setCanCancel(boolean canCancel) {
            this.canCancel = canCancel;
            return this;
        }

        public Builder setShadow(boolean shadow) {
            this.shadow = shadow;
            return this;
        }

        public Builder setTitle(String title) {
            this.p.menuTitle = title;
            return this;
        }

        public Builder addMenu(String text, View.OnClickListener listener) {
            BottomMenu bm = new BottomMenu(text, listener);
            this.p.menuList.add(bm);
            return this;
        }

        public Builder addMenu(int textId, View.OnClickListener listener) {
            return addMenu(p.context.getString(textId), listener);
        }

        public Builder setCancelListener(View.OnClickListener cancelListener) {
            p.cancelListener = cancelListener;
            return this;
        }

        public Builder setCancelText(int resId) {
            p.cancelText = p.context.getString(resId);
            return this;
        }

        public Builder setCancelText(String text) {
            p.cancelText = text;
            return this;
        }

        public BottomMenuDialog create() {
            final BottomMenuDialog dialog = new BottomMenuDialog(p.context, shadow ? R.style.Theme_Light_NoTitle_Dialog : R.style.Theme_Light_NoTitle_NoShadow_Dialog);
            Window window = dialog.getWindow();
            window.setWindowAnimations(R.style.Animation_Bottom_Rising);

            window.getDecorView().setPadding(0, 0, 0, 0);
            WindowManager.LayoutParams lp = window.getAttributes();
            lp.width = WindowManager.LayoutParams.MATCH_PARENT;
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
            window.setAttributes(lp);
            window.setGravity(Gravity.BOTTOM);

            View view = LayoutInflater.from(p.context).inflate(R.layout.dialog_bottom_menu, null);

            TextView btnCancel = (TextView) view.findViewById(R.id.btn_cancel);
            ViewGroup layContainer = (ViewGroup) view.findViewById(R.id.lay_container);
            LayoutParams lpItem = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
            LayoutParams lpDivider = new LayoutParams(LayoutParams.MATCH_PARENT, 1);
            int dip1 = (int) (1 * p.context.getResources().getDisplayMetrics().density + 0.5f);
            int spacing = dip1 * 12;

            boolean hasTitle = !TextUtils.isEmpty(p.menuTitle);
            if (hasTitle) {
                TextView tTitle = new TextView(p.context);
                tTitle.setLayoutParams(lpItem);
                tTitle.setGravity(Gravity.CENTER);
                tTitle.setTextColor(0xFF8F8F8F);
                tTitle.setText(p.menuTitle);
                tTitle.setTextSize(17);
                tTitle.setPadding(0, spacing, 0, spacing);
                tTitle.setBackgroundResource(R.drawable.common_dialog_selection_selector_top);
                layContainer.addView(tTitle);

                View viewDivider = new View(p.context);
                viewDivider.setLayoutParams(lpDivider);
                viewDivider.setBackgroundColor(0xFFCED2D6);
                layContainer.addView(viewDivider);
            }

            for (int i = 0; i < p.menuList.size(); i++) {
                BottomMenu bottomMenu = p.menuList.get(i);
                TextView bbm = new TextView(p.context);
                bbm.setLayoutParams(lpItem);
                int backgroundResId = R.drawable.common_dialog_selection_selector_center;
                if (p.menuList.size() > 1) {
                    if (i == 0) {
                        if (hasTitle) {
                            backgroundResId = R.drawable.common_dialog_selection_selector_center;
                        } else {
                            backgroundResId = R.drawable.common_dialog_selection_selector_top;
                        }
                    } else if (i == p.menuList.size() - 1) {
                        backgroundResId = R.drawable.common_dialog_selection_selector_bottom;
                    }
                } else if (p.menuList.size() == 1) {
                    backgroundResId = R.drawable.common_dialog_selection_selector_singleton;
                }
                bbm.setBackgroundResource(backgroundResId);
                bbm.setPadding(0, spacing, 0, spacing);
                bbm.setGravity(Gravity.CENTER);
                bbm.setText(bottomMenu.funName);
                bbm.setTextColor(0xFF007AFF);
                bbm.setTextSize(19);
                bbm.setOnClickListener(bottomMenu.listener);
                layContainer.addView(bbm);

                if (i != p.menuList.size() - 1) {
                    View viewDivider = new View(p.context);
                    viewDivider.setLayoutParams(lpDivider);
                    viewDivider.setBackgroundColor(0xFFCED2D6);
                    layContainer.addView(viewDivider);
                }
            }

            if (!TextUtils.isEmpty(p.cancelText)) {
                btnCancel.setText(p.cancelText);
            }

            if (p.cancelListener != null) {
                btnCancel.setOnClickListener(p.cancelListener);
            } else {
                btnCancel.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });
            }


            dialog.setContentView(view);
            dialog.setCanceledOnTouchOutside(canCancel);
            dialog.setCancelable(canCancel);
            return dialog;
        }


    }

    private static class BottomMenu {
        public String funName;
        public View.OnClickListener listener;

        public BottomMenu(String funName, View.OnClickListener listener) {
            this.funName = funName;
            this.listener = listener;
        }
    }
}

主体代码如上,逻辑并不是很难。

名字不会取,所以就叫BottomMenuDialog了, 嘿嘿 通俗易懂。

先通过Builder配置一些可变的属性 ,然后在create的时候将这个自己配置的Bottom构建出来。


之后在activity中:

findViewById(R.id.b_5).setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                mBottomMenuDialog = new BottomMenuDialog.Builder(MainActivity.this)
                        .setTitle("更换封面")
                        .addMenu("从手机相册选择", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                mBottomMenuDialog.dismiss();
                                Toast.makeText(v.getContext(), "从手机相册选择" , Toast.LENGTH_SHORT).show();
                            }
                        }).addMenu("从空间相册选择", new View.OnClickListener() {
                             @Override
                             public void onClick(View v) {
                                 mBottomMenuDialog.dismiss();
                                 Toast.makeText(v.getContext(), "从空间相册选择" , Toast.LENGTH_SHORT).show();
                             }
                         }).addMenu("拍一张", new View.OnClickListener() {
                             @Override
                             public void onClick(View v) {
                                 mBottomMenuDialog.dismiss();
                                 Toast.makeText(v.getContext(), "拍一张" , Toast.LENGTH_SHORT).show();
                             }
                         }).create();
                mBottomMenuDialog.show();
            }
        });

希望能给刚入手的朋友提供帮助,同时节约时间。


[戳我转到源码地址,是一个demo工程,导入ide可直接运行]



仿ios中button效果

阅读数 1137

没有更多推荐了,返回首页