2012-09-25 22:16:35 xiao12593a 阅读数 544

本例使用activity实现弹出滑动窗口或菜单,主要是使用了一些设置activity的样式来实现弹出窗口和滑动效果,实现如下:

第一步:设计要弹出窗口的xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical"
  >

<LinearLayout 
    android:id="@+id/pop_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:layout_alignParentBottom="true"
     android:background="@drawable/btn_style_alert_dialog_background"
     >

    
    <Button
        android:id="@+id/btn_take_photo"
        android:layout_marginLeft="20dip"
        android:layout_marginRight="20dip"
        android:layout_marginTop="20dip"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="拍照"
        android:background="@drawable/btn_style_alert_dialog_button"
        android:textStyle="bold"
         />

    <Button
        android:id="@+id/btn_pick_photo"
        android:layout_marginLeft="20dip"
        android:layout_marginRight="20dip"
        android:layout_marginTop="5dip" 
         android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="从相册选择"
         android:background="@drawable/btn_style_alert_dialog_button"
         android:textStyle="bold"
         />

    <Button
        android:id="@+id/btn_cancel"
       android:layout_marginLeft="20dip"
       android:layout_marginRight="20dip"
       android:layout_marginTop="15dip" 
	   android:layout_marginBottom="15dip"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text="取消"
       android:background="@drawable/btn_style_alert_dialog_cancel"
       android:textColor="#ffffff"
       android:textStyle="bold"
       
        />
</LinearLayout>
</RelativeLayout>

 第二步:创建SelectPicPopupWindow类继承Activity类并实现OnClickListener接口(可以不用在这里实现这个借口,根据自己需要和方便实现),其他代码实现跟编写常规Activity一样就OK,如下:

mport android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class SelectPicPopupWindow extends Activity implements OnClickListener{

	private Button btn_take_photo, btn_pick_photo, btn_cancel;
	private LinearLayout layout;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.alert_dialog);
		btn_take_photo = (Button) this.findViewById(R.id.btn_take_photo);
		btn_pick_photo = (Button) this.findViewById(R.id.btn_pick_photo);
		btn_cancel = (Button) this.findViewById(R.id.btn_cancel);
		
		layout=(LinearLayout)findViewById(R.id.pop_layout);
		
		//添加选择窗口范围监听可以优先获取触点,即不再执行onTouchEvent()函数,点击其他地方时执行onTouchEvent()函数销毁Activity
		layout.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Toast.makeText(getApplicationContext(), "提示:点击窗口外部关闭窗口!", 
						Toast.LENGTH_SHORT).show();	
			}
		});
		//添加按钮监听
		btn_cancel.setOnClickListener(this);
		btn_pick_photo.setOnClickListener(this);
		btn_take_photo.setOnClickListener(this);
	}
	
	//实现onTouchEvent触屏函数但点击屏幕时销毁本Activity
	@Override
	public boolean onTouchEvent(MotionEvent event){
		finish();
		return true;
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_take_photo:
			break;
		case R.id.btn_pick_photo:				
			break;
		case R.id.btn_cancel:				
			break;
		default:
			break;
		}
		finish();
	}
	
}

 

 第三步:编写MainActivity类,这里很简单就是点击启动刚才要实现窗口的MainActivity即可:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity {
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) this.findViewById(R.id.text);
        //把文字控件添加监听,点击弹出自定义窗口
        tv.setOnClickListener(new OnClickListener() {			
			public void onClick(View v) {
				startActivity(new Intent(MainActivity.this,SelectPicPopupWindow.class));
			}
		});
    }
    
}
 

第四步:这里要注意下AndroidManifest.xml对SelectPicPopupWindow的配置跟常规的不一样为该activity改添加android:theme属性,如下:

<activity android:name=".SelectPicPopupWindow" android:theme="@style/MyDialogStyleBottom" /> 

 第五步:这一步是实现本实例最重要的一部就是设置android:theme属性样式以实现本例所需要的效果,如下:

 

    <style name="AnimBottom" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
        <item name="android:windowExitAnimation">@anim/push_bottom_out</item>
    </style>

    <style name="MyDialogStyleBottom" parent="android:Theme.Dialog">
        <item name="android:windowAnimationStyle">@style/AnimBottom</item>
        <item name="android:windowFrame">@null</item>
 <!-- 边框 -->
        <item name="android:windowIsFloating">true</item>
 <!-- 是否浮现在activity之上 -->
        <item name="android:windowIsTranslucent">true</item>
 <!-- 半透明 -->
        <item name="android:windowNoTitle">true</item>
 <!-- 无标题 -->
        <item name="android:windowBackground">@android:color/transparent</item>
 <!-- 背景透明 -->
        <item name="android:backgroundDimEnabled">true</item>
 <!-- 模糊 -->
    </style>

 第六步:在贴出弹出和销毁时的动画效果代码:

 

push_bottom_in.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="200"
        android:fromYDelta="100%p"
        android:toYDelta="0"        
     />      
</set>

 push_buttom_out.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑出式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    
    <translate
        android:duration="200"
        android:fromYDelta="0"
        android:toYDelta="50%p" />
</set>

 注意:这两个xml需要放在res/anim的anim文件夹下

 

第七步;运行效果如图:


 

 

2017-01-13 16:46:32 Hubert_bing 阅读数 1437

由于公司禁掉了上传功能,无法使用github等,将自己的代码分享出去。
但是自己做了一个仿IOS的弹出框感觉非常好用,想分享出来,因此就直接把相关代码贴出来,有兴趣的可以直接拷贝使用,遇到使用问题也可以留言。
做之前在网上也看到过很多类似的,但是觉得封装的都不好,因此重新封装了一下,更便于使用。
这里写图片描述
先来看下使用:

new IOSActionSheetDialog.Builder(mActivity)
                .setTitle("title")
                //.setSheetItemList(sheetItemList)//添加item集合
                .addSheetItem("itemName","#007aff")//添加单个条目
                .setOnItemClickListener(new IOSActionSheetDialog.OnItemClickListener() {
                    @Override
                    public void onItemClick(LinearLayout parent, View view, int position) {
                        //do something
                    }
                })
//                .setTitleHeight(57)//可选项
//                .setTitleSize(20)
                .build()
                .show();

主要类:

package com.example.app.widget;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * 仿IOS样式的弹出框
 * <p/>
 * please use {@link IOSActionSheetDialog.Builder} to create a instance ,do not use "new".
 * such as:
 * <pre>
 * new IOSActionSheetDialog.Builder(MainActivity.this)
 *                .setTitle("title")
 *                .addSheetItem("item_name", IOSActionSheetDialog.COLOR_IOS_RED)
 *                .setOnItemClickListener(new IOSActionSheetDialog.OnItemClickListener() {
 *                          @Override
 *                          public void onItemClick(LinearLayout parent, View view, int position) {
 *                                          //do some thing
 *                           }
 *                 })
 *                 .build()
 *                 .show();
 * </pre>
 *
 * @author huburt
 * @date 2017-01-11 14:16
 */
public class IOSActionSheetDialog extends Dialog {
    //IOS版蓝色
    public static final String COLOR_IOS_BLUE = "#037BFF";
    //IOS版红色
    public static final String COLOR_IOS_RED = "#FD4A2E";

    public static final String COLOR_IOS_GREY = "#8F8F8F";

    //title参数
    private int mTitleSize = 13;
    private int mTitleHeight = 45;
    private String mTitleColor = COLOR_IOS_GREY;

    //条目参数
    private int mItemTextSize = 18;
    private int mItemHeight = 45;
    private boolean isItemTextBold = false;

    //底部参数
    private int mCancelHeight = 45;
    private int mCancelTextSize = 18;
    private String mCancelTextColor = COLOR_IOS_BLUE;
    private boolean isCancelTextBold = false;

    //屏幕宽度
    private int mWidth;
    //屏幕高度
    private int mHeight;
    //屏幕密度
    private float mDensity;

    private ScrollView mSvContent;
    private LinearLayout mLvContent;
    private TextView mTvTitle;
    private TextView mTvCancel;

    private OnItemClickListener mOnItemClickListener;

    private List<SheetItem> mSheetItemList;
    private String mTitle;
    private boolean isShowTitle;


    public IOSActionSheetDialog(Context context, List<SheetItem> sheetItemList,
                                String title, OnItemClickListener onItemClickListener,
                                boolean cancelable, boolean canceledOnTouchOutside) {
        //传入style设置window参数
        super(context, R.style.ActionSheetDialogStyle);

        mSheetItemList = sheetItemList;
        mTitle = title;
        mOnItemClickListener = onItemClickListener;
        setCancelable(cancelable);
        setCanceledOnTouchOutside(canceledOnTouchOutside);

        //获取屏幕参数
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        display.getMetrics(outMetrics);
        mWidth = outMetrics.widthPixels;
        mHeight = outMetrics.heightPixels;
        mDensity = outMetrics.density;
        init();
    }

    private void init() {
        // 获取Dialog布局
        View view = LayoutInflater.from(getContext()).inflate(R.layout.view_actionsheet, null);
        // 设置Dialog最小宽度为屏幕宽度
        view.setMinimumWidth(mWidth);

        mSvContent = (ScrollView) view.findViewById(R.id.sLayout_content);
        mLvContent = (LinearLayout) view.findViewById(R.id.lLayout_content);
        mTvTitle = (TextView) view.findViewById(R.id.txt_title);
        mTvCancel = (TextView) view.findViewById(R.id.txt_cancel);
        mTvCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        if (!TextUtils.isEmpty(mTitle)) {
            setTitle(mTitle);
        }

        Window dialogWindow = getWindow();
        dialogWindow.setGravity(Gravity.LEFT | Gravity.BOTTOM);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        lp.x = 0;
        lp.y = 0;
        dialogWindow.setAttributes(lp);
        setContentView(view);
    }

    @Override
    public void show() {
        adjustUI();
        showSheetItems();
        super.show();
    }

    private void adjustUI() {
        //调整title高度
        LinearLayout.LayoutParams titleParams = (LinearLayout.LayoutParams) mTvTitle.getLayoutParams();
        int height = (int) (mTitleHeight * mDensity + 0.5f);
        titleParams.height = height;
        mTvTitle.setLayoutParams(titleParams);
        //调整title字体大小
        mTvTitle.setTextSize(mTitleSize);
        try {
            int color = Color.parseColor(mTitleColor);
            mTvTitle.setTextColor(color);
        } catch (Exception e) {
            e.printStackTrace();
            mTvTitle.setTextColor(getContext().getResources().getColor(R.color.actionsheet_gray));
        }

        //调整cancel高度
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mTvCancel.getLayoutParams();
        height = (int) (mCancelHeight * mDensity + 0.5f);
        layoutParams.height = height;
        mTvCancel.setLayoutParams(layoutParams);
        //调整cancel字体大小
        mTvCancel.setTextSize(mCancelTextSize);
        try {
            int color = Color.parseColor(mCancelTextColor);
            mTvCancel.setTextColor(color);
        } catch (Exception e) {
            e.printStackTrace();
            mTvCancel.setTextColor(getContext().getResources().getColor(R.color.actionsheet_blue));
        }
        //cancel字体是否加粗
        mTvCancel.getPaint().setFakeBoldText(isCancelTextBold);
    }

    private void showSheetItems() {
        if (mSheetItemList == null || mSheetItemList.size() <= 0) {
            return;
        }
        int size = mSheetItemList.size() - 1;

        // 添加条目过多的时候控制高度
        if (size >= 7) {
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mSvContent.getLayoutParams();
            params.height = mHeight / 2;
            mSvContent.setLayoutParams(params);
        }

        for (int i = 0; i <= size; i++) {
            final int index = i;
            SheetItem sheetItem = mSheetItemList.get(i);

            TextView textView = new TextView(getContext());
            textView.setText(sheetItem.name);
            textView.setTextSize(mItemTextSize);
            textView.setGravity(Gravity.CENTER);

            int height = (int) (mItemHeight * mDensity + 0.5f);
            textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height));

            textView.getPaint().setFakeBoldText(isItemTextBold);

            // 背景图片
            if (size == 0) {
                if (isShowTitle) {
                    textView.setBackgroundResource(R.drawable.actionsheet_bottom_selector);
                } else {
                    textView.setBackgroundResource(R.drawable.actionsheet_single_selector);
                }
            } else {
                if (isShowTitle) {
                    if (i >= 0 && i < size) {
                        textView.setBackgroundResource(R.drawable.actionsheet_middle_selector);
                    } else {
                        textView.setBackgroundResource(R.drawable.actionsheet_bottom_selector);
                    }
                } else {
                    if (i == 0) {
                        textView.setBackgroundResource(R.drawable.actionsheet_top_selector);
                    } else if (i < size) {
                        textView.setBackgroundResource(R.drawable.actionsheet_middle_selector);
                    } else {
                        textView.setBackgroundResource(R.drawable.actionsheet_bottom_selector);
                    }
                }
            }

            // 字体颜色
            try {
                int color = Color.parseColor(sheetItem.color);
                textView.setTextColor(color);
            } catch (Exception e) {
                e.printStackTrace();
                textView.setTextColor(Color.parseColor(COLOR_IOS_BLUE));
            }

            // 点击事件
            textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnItemClickListener != null) {
                        mOnItemClickListener.onItemClick(mLvContent, v, index);
                    }
                    dismiss();
                }
            });
            mLvContent.addView(textView);
        }

    }

    public void setTitle(CharSequence title) {
        isShowTitle = true;
        mTvTitle.setVisibility(View.VISIBLE);
        mTvTitle.setText(title);
    }

    public void setTitleColor(String color) {
        mTitleColor = color;
    }

    public void setTitleSize(int size) {
        mTitleSize = size;
    }

    public void setTitleHeight(int height) {
        mTitleHeight = height;
    }

    public void setItemTextSize(int size) {
        mItemTextSize = size;
    }

    public void setItemHeight(int height) {
        mItemHeight = height;
    }

    public void setCancelHeight(int cancelHeight) {
        mCancelHeight = cancelHeight;
    }

    public void setCancelTextSize(int cancelTextSize) {
        mCancelTextSize = cancelTextSize;
    }

    public void setCancelTextColor(String cancelTextColor) {
        mCancelTextColor = cancelTextColor;
    }

    public void setItemTextBold(boolean itemTextBold) {
        isItemTextBold = itemTextBold;
    }

    public void setCancelTextBold(boolean cancelTextBold) {
        isCancelTextBold = cancelTextBold;
    }

    public OnItemClickListener getOnItemClickListener() {
        return mOnItemClickListener;
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        mOnItemClickListener = onItemClickListener;
    }


    public static class Builder {
        private android.content.Context context;
        private List<SheetItem> mSheetItemList;
        private OnItemClickListener onItemClickListener;
        private boolean cancelable = true;
        private boolean canceledOnTouchOutside = true;
        private String title;
        private int mTitleSize = 13;
        private int mTitleHeight = 45;
        private String mTitleColor = COLOR_IOS_GREY;
        private int mItemTextSize = 18;
        private int mItemHeight = 45;
        private int mCancelHeight = 45;
        private int mCancelTextSize = 18;
        private String mCancelTextColor = COLOR_IOS_BLUE;
        private boolean isCancelTextBold = false;
        private boolean isItemTextBold = false;

        public Builder(Context context) {
            this.context = context;
        }

        public Builder setOnItemClickListener(OnItemClickListener onItemClickListener) {
            this.onItemClickListener = onItemClickListener;
            return this;
        }

        public Builder addSheetItem(String name, String color) {
            if (mSheetItemList == null) {
                mSheetItemList = new ArrayList<SheetItem>();
            }
            mSheetItemList.add(new SheetItem(name, color));
            return this;
        }

        public Builder setCancelable(boolean cancelable) {
            this.cancelable = cancelable;
            return this;
        }

        public Builder setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
            this.canceledOnTouchOutside = canceledOnTouchOutside;
            return this;
        }

        public Builder setSheetItemList(List<SheetItem> sheetItemList) {
            mSheetItemList = sheetItemList;
            return this;
        }

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

        public Builder setTitleSize(int size) {
            mTitleSize = size;
            return this;
        }

        public Builder setTitleHeight(int height) {
            mTitleHeight = height;
            return this;
        }

        public Builder setTitleColor(String color) {
            mTitleColor = color;
            return this;
        }

        public Builder setItemHeight(int height) {
            mItemHeight = height;
            return this;
        }

        public Builder setItemTextSize(int size) {
            mItemTextSize = size;
            return this;
        }

        public Builder setCancelHeight(int cancelHeight) {
            mCancelHeight = cancelHeight;
            return this;
        }

        public Builder setCancelTextSize(int cancelTextSize) {
            mCancelTextSize = cancelTextSize;
            return this;
        }

        public Builder setCancelTextColor(String cancelTextColor) {
            mCancelTextColor = cancelTextColor;
            return this;
        }

        public Builder setCancelTextBold(boolean cancelTextBold) {
            isCancelTextBold = cancelTextBold;
            return this;
        }

        public Builder setItemTextBold(boolean itemTextBold) {
            isItemTextBold = itemTextBold;
            return this;
        }

        public IOSActionSheetDialog build() {
            IOSActionSheetDialog sheetDialog = new IOSActionSheetDialog(context, mSheetItemList, title, onItemClickListener, cancelable, canceledOnTouchOutside);
            sheetDialog.setTitleHeight(mTitleHeight);
            sheetDialog.setTitleSize(mTitleSize);
            sheetDialog.setTitleColor(mTitleColor);
            sheetDialog.setItemHeight(mItemHeight);
            sheetDialog.setItemTextSize(mItemTextSize);
            sheetDialog.setCancelHeight(mCancelHeight);
            sheetDialog.setCancelTextSize(mCancelTextSize);
            sheetDialog.setCancelTextColor(mCancelTextColor);
            sheetDialog.setItemTextBold(isItemTextBold);
            sheetDialog.setCancelTextBold(isCancelTextBold);
            return sheetDialog;
        }
    }

    public interface OnItemClickListener {
        void onItemClick(LinearLayout parent, View view, int position);
    }

    public static class SheetItem {
        String name;
        String color;

        public SheetItem(String name, String color) {
            this.name = name;
            this.color = color;
        }
    }
}

dialog的style

<!-- 自定义仿IOS的ActionSheet底部Dialog的样式 ,有模糊效果 -->
    <style name="ActionSheetDialogStyle" 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/ActionSheetDialogAnimation</item>
    </style>

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

@anim/actionsheet_dialog_in

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromYDelta="100%"
    android:toYDelta="0" />

@anim/actionsheet_dialog_out

<?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%" />

R.layout.view_actionsheet

<?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"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:padding="8dp">

    <TextView
        android:id="@+id/txt_title"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:background="@drawable/shape_actionsheet_top_normal"
        android:gravity="center"
        android:textColor="@color/actionsheet_gray"
        android:textSize="13sp"
        android:visibility="gone"
        tools:visibility="visible"/>

    <ScrollView
        android:id="@+id/sLayout_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fadingEdge="none"
         >
        <!--fadingEdge属性表示,滚动式边缘内容是否变淡-->
        <LinearLayout
            android:id="@+id/lLayout_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </ScrollView>

    <TextView
        android:id="@+id/txt_cancel"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/actionsheet_single_selector"
        android:gravity="center"
        android:text="取消"
        android:textColor="@color/actionsheet_blue"
        android:textSize="18sp"
         />

</LinearLayout>

actionsheet_top_selector.xml

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

    <item android:drawable="@drawable/shape_actionsheet_top_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/shape_actionsheet_top_normal"/>

</selector>

@drawable/shape_actionsheet_top_normal

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:bottom="0.5dp">
        <shape
            android:shape="rectangle">
            <solid android:color="#F4F4F4"/>
            <corners
                android:topLeftRadius="10dp"
                android:topRightRadius="10dp"/>

        </shape>
    </item>

</layer-list>

@drawable/shape_actionsheet_top_pressed

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#DFDFDF"/>
    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"/>

</shape>

@drawable/actionsheet_single_selector

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

    <item android:drawable="@drawable/shape_actionsheet_single_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/shape_actionsheet_single_normal"/>

</selector>

@drawable/shape_actionsheet_single_pressed

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#DFDFDF"/>
    <corners
        android:radius="10dp"/>

</shape>

@drawable/shape_actionsheet_single_normal

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#F4F4F4"/>
    <corners
        android:radius="10dp"/>

</shape>
2017-03-14 23:27:58 qq_16628781 阅读数 888

文章链接:

Android之底部弹窗

知识点:

1、dialog的简单使用;

2、自定义底部弹框;

3、新名词记录

{

5.0 转场动画

}

底部弹框:就是从手机屏幕底边位置弹出来,最常见的就是弹框里头有好几个选项让你选择。例如微信里面看一篇文章的时候,我们点击右上角的按钮,就会看到有一个弹框从底部弹出来,里面有各个选项可以点击选择。那么怎么来做呢?

思路其实很简单,一说到弹框,我们脑海里必然先想到的是dialog。这个东西可是很好用的呢,很多弹窗的提示,我们都是直接使用它的了。

这里有一个弹窗dialog的使用示例:

private void dialog(){  
        AlertDialog.Builder builder=new AlertDialog.Builder(this); 
        builder.setTitle("提示"); //设置标题  
        builder.setMessage("是否确认退出?"); //设置内容  
        builder.setIcon(R.mipmap.ic_launcher);//设置图标,图片id  
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { //设置确定按钮  
            @Override  
            public void onClick(DialogInterface dialog, int which) {  
                dialog.dismiss(); //关闭dialog  
                Toast.makeText(MainActivity.this, "确认" + which, Toast.LENGTH_SHORT).show();  
            }  
        });  
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { //设置取消按钮  
            @Override  
            public void onClick(DialogInterface dialog, int which) {  
                dialog.dismiss();  
                Toast.makeText(MainActivity.this, "取消" + which, Toast.LENGTH_SHORT).show();  
            }  
        });  
        //创建并显示出来  
        builder.create().show();  
    }  
效果图我就不展示出来了。大家可以将上面的代码在工程里头跑一跑就知道了。

那么如何来做我们底部的弹框呢,我们知道dialog是依附在window上面的,而window里头有一个setGravity(int)的方法,我们继承dialog,自定义一个控件,然后拿到dialog依附的这个Window,然后设置dialog显示的位置,并且把先要显示的内容以一个view传过去,我们直接显示出来就OK了。

下面我直接把我们继承自dialog的BottomDialog.java类直接贴出来。代码很简单,一看就明白了。我就不做过多的解释了。

import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;


/**
 * desc:自定义冲底部弹出来的弹框
 * <p>
 * author:kuyu.yaojt (tanksu)
 * <p>
 * email:yaojt@kuyumall.com
 * <p>
 * date:17/3/14
 */

public class BottomDialog extends Dialog {

    /*
     这两个文件都是在style.xml文件里头定义
        DialogTheme 样式:
     <style name="DialogTheme" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <!-- 边框 -->
        <item name="android:windowIsFloating">true</item>
        <!-- 是否浮现在activity之上 -->
        <item name="android:windowIsTranslucent">false</item>
        <!-- 半透明 -->
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:background">@android:color/transparent</item>
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 模糊 -->
    </style>

    DialogBottomAnim 动画数据,利用的是系统的动画
    <style name="DialogBottomAnim">
        <!--进入动画-->
        <item name="@android:windowEnterAnimation">@anim/dialog_enter</item>
        <!--退出动画-->
        <item name="@android:windowExitAnimation">@anim/dialog_exit</item>
    </style>
    */

    /**
     * 构造函数
     *
     * @param context context
     * @param view    显示的view
     * @param cancel  点击外部是否可以取消
     */
    public BottomDialog(Context context, View view, boolean cancel) {
        this(context, view, R.style.DialogTheme, cancel);
    }

    /**
     * @param context           context
     * @param view              显示的view
     * @param style             布局样式
     * @param outsideCancelAble 点击外部是否可以取消
     */
    public BottomDialog(Context context, View view, int style, boolean outsideCancelAble) {
        super(context, style);
        setContentView(view);

        setCanceledOnTouchOutside(outsideCancelAble);

        Window window = getWindow();
        if (window != null) {
            /* 此处可以设置dialog显示的位置 */
            window.setGravity(Gravity.BOTTOM);

            /* 添加动画 */
            window.setWindowAnimations(R.style.DialogBottomAnim);

            ViewGroup.LayoutParams params = view.getLayoutParams();
            if (params == null) {
                params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            }
            /* 重新设置弹框的宽度 */
            params.width = window.getWindowManager().getDefaultDisplay().getWidth();

            view.setLayoutParams(params);
        }
    }

}

我把需要用到的资源文件,都直接放在上面这个类里头,你只需要将他们放到style.xml文件里头就可以了。

然后是怎么调用上面这个自定义的底部弹框类。很简单,如下:

View view = LayoutInflater.from(this).inflate(R.layout.popup_trans_dialog, null);
            mBottomDialog = new BottomDialog(this, view, true);
            createView(view);
createView(View)方法是对于显示的view里头操作的响应,BottomDialog只是紧紧帮你展示你的view,事件的监听响应都是外面去做的,例如有一个button,我们可以findviewbyid(),然后设置点击监听等等操作。
这就是今天的内容,如果任何问题,请及时与我联系,谢谢!
2016-12-14 22:45:09 qq_33599978 阅读数 2385

这里介绍三种弹出框android的弹出框AlertDialog,时间弹出框DatePickerDialog 和进度条弹出框showProgressDialog--我将在下一篇介绍自定义弹出框


这里我们我们同一个layout.xml来写按钮事,app中肯定是少不了与用户交互的各种dialog,所以我们可以用谷歌的工程师包装好的方法来做这个弹出框 android:onClick="(自定义的方法名)Gress"这个我们只需要在MainActivity。java中实现这个方法就行。例如
public class MainActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void Gress view) {
实现方法的代码
}
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.m_6dialog.MainActivity" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt1"
        android:text="普通弹出框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt2"
        android:text="时间弹出框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt3"
        android:text="进度条弹出框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt4"
        android:text="自定义弹出框" />

</LinearLayout>



第一个,普通弹出框AlertDialog

这里我三个按钮两个写了退出程序。

这里是实现代码

一般创建一个对话框需要经过以下几步:

  1、创建AlertDialog.Builder对象。

  2、调用AlertDialog.Builder的setTitle()或者setCustomTitle()方法设置标题。

  3、调用AlertDialog.Builder的setIcon()方法设置标题logo。

  4、调用AlertDialog.Builder的相关方法设置对话框内容。

  5、调用AlertDialog.Builder的setPositiveButton()、setNegativeButton()或setNeutralButton()方法添加多个按钮。

  6、调用AlertDialog.Builder的create()方法创建AlertDialog对象,再调用AlertDialog对象的show()方法将该对话框显示出来。

其中,第4步设置对话框的内容,这里有6种方法来指定:

  ·setMessage():设置对话框内容为简单文本内容。

  ·setItems():设置对话框内容为简单列表项。

  ·setSingleChoiceItems():设置对话框内容为单选列表项。

  ·setMultiChoiceItems():设置对话框内容为多选列表项。

  ·setAdapter():设置对话框内容为自定义列表项。

  ·setView():设置对话框内容为自定义View。

下面通过几个实例来介绍一下AlertDialog的用法。



package com.example.m_6dialong;

import java.util.Date;
import java.util.zip.Inflater;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

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

	/*
	 * 
	 * AlertDialog基本弹出框选择确定和取消
	 */
	public void Bt1(View view) {
		showAler();
	}

	void showAler() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("title");
		builder.setMessage("message");
		builder.setIcon(R.drawable.ic_launcher);
		// 1确定按钮排在第三个
		builder.setPositiveButton("text", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				finish();
			}
		});

		// 2否定按钮,排在第一个
		builder.setNegativeButton("text2", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				finish();

			}
		});

		// 3. 中立按钮排在第二个
		builder.setNeutralButton("zhong", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub

			}
		});
		builder.create().show();
	}
}


第二个  显示时间的弹出框DatePickerDialog,TimePickerDialog


——DatePickerDialog,TimePickerDialog

这两个对话框功能简单,用法也很简单。只需要两步就可以了:

1)通过new关键字创建实例,调用show()将对话框显示出来

2)绑定监听器,从而通过监听器获取用户设置的事件

这里只有把上面的Bt1方法换掉就可以


public void Bt2(View view) {
		date();
	}

	private void date() {

		/* DatePickerDialog datePickerDialog1= new DatePickerDialog(context,
		 callBack, year, monthOfYear, dayOfMonth)
		 callBack 是使用了匿名内部类*/

		DatePickerDialog datePickerDialog = new DatePickerDialog(this,
				new OnDateSetListener() {

					@Override
					public void onDateSet(DatePicker view, int year,
							int monthOfYear, int dayOfMonth) {
						// TODO Auto-generated method stub

					}
				}, new Date().getDate(), new Date().getMonth() + 1,
				new Date().getDay());
		datePickerDialog.show();
		System.out.println(new Date().getDate() + "getDate");
		System.out.println(new Date().getMonth() + "getMonth");
		System.out.println(new Date().getDay() + "getDay");
		System.out.println(new Date().getTime() + "getTime");
		System.out.println(new Date().getYear() + "year");

	}


第三个。进度条弹出框


——ProgressDialog

使用ProgressDialog进度条对话框有两种方式:

1)如果只是创建一个简单的进度对话框,

调用ProgressDialog提供的静态show()方法显示对话框即可

这里的参数boolean indeterminate设置是否是不明确的状态。

2)创建ProgressDialog,然后调用方法对对话框中的进度条进行设置,

设置完成后将对话框显示出来即可。

ProgressDialog包含如下的方法:

 

 a)setTitle("提示信息");

 b)setMessage(charSequence)设置对话框里显示的消息

 c)setMax(int)设置对话框中进度条的最大值

 d)setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)设置对话框里进度条的风格

 e)setIndeterminate(boolean)设置进度条是否显示不明确值,不明确就是滚动条的当前值自动在最小到最大值之间来回移动,形成这样一个动画效果,这个只是告诉别人“我正在工作”,但不能提示工作进度到哪个阶段。主要是在进行一些无法确定操作时间的任务时作为提示。而“明确”就是根据你的进度可以设置现在的进度值

 f)p.dismiss()关闭对话框

 

——补充

补充:还有其他的方式也可以完成对话框

1)在需要设置成对话框的Activity在AndroidManifest.xml中配置

android:theme="@android:style/Theme.Dialog"

2)PopWindow也可以做类似对话框风格的窗口

只需要两步就可以完成:

 a)创建PopWindow对象,为其设置布局内容与宽度、高度

 b)调用pop.showAsDropDown(View)将PopupWindow作为View组件以下拉组件显示出来,

 或者调用showAtLocation()方法将PopupWindow在指定位置显示出来

第一个参数指定PopupWindow的锚点view,即依附在哪个view上。

第二个参数指定起始点

第三,四个参数设置以起始点的右下角为原点,向向右、下各偏移量。
/*
	 * 
	 * 
	 * ProgressDialog 进度条弹窗 必须定义public的方法Button的onClick方法
	 */
	public void Bt3(View view) {
		// TODO Auto-generated method stub
		showProgressDialog();

	}

	private void showProgressDialog() {
		// TODO Auto-generated method stub

		ProgressDialog progressDialog = new ProgressDialog(this);
		progressDialog.setMessage("下载");

		progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

		progressDialog.show();
	}

总结:  三个的实现方法都很简单,现在来看全部代码,我将在下一篇重点介绍自定义弹出框和事件逻辑

package com.example.m_6dialong;

import java.util.Date;
import java.util.zip.Inflater;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

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

	/*
	 * 
	 * AlertDialog基本弹出框选择确定和取消
	 */
	public void Bt1(View view) {
		showAler();
	}

	void showAler() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("title");
		builder.setMessage("message");
		builder.setIcon(R.drawable.ic_launcher);
		// 1确定按钮排在第三个
		builder.setPositiveButton("text", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				finish();
			}
		});

		// 2否定按钮,排在第一个
		builder.setNegativeButton("text2", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				finish();

			}
		});

		// 3. 中立按钮排在第二个
		builder.setNeutralButton("zhong", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub

			}
		});
		builder.create().show();
	}

	/*
	 * 
	 * DatePickerDialog 时间基本弹出框
	 */
	public void Bt2(View view) {
		date();
	}

	private void date() {

		/* DatePickerDialog datePickerDialog1= new DatePickerDialog(context,
		 callBack, year, monthOfYear, dayOfMonth)
		 callBack 是使用了匿名内部类*/

		DatePickerDialog datePickerDialog = new DatePickerDialog(this,
				new OnDateSetListener() {

					@Override
					public void onDateSet(DatePicker view, int year,
							int monthOfYear, int dayOfMonth) {
						// TODO Auto-generated method stub

					}
				}, new Date().getDate(), new Date().getMonth() + 1,
				new Date().getDay());
		datePickerDialog.show();
		System.out.println(new Date().getDate() + "getDate");
		System.out.println(new Date().getMonth() + "getMonth");
		System.out.println(new Date().getDay() + "getDay");
		System.out.println(new Date().getTime() + "getTime");
		System.out.println(new Date().getYear() + "year");

	}

	/*
	 * 
	 * 
	 * ProgressDialog 进度条弹窗 必须定义public的方法Button的onClick方法
	 */
	public void Bt3(View view) {
		// TODO Auto-generated method stub
		showProgressDialog();

	}

	private void showProgressDialog() {
		// TODO Auto-generated method stub

		ProgressDialog progressDialog = new ProgressDialog(this);
		progressDialog.setMessage("下载");

		progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

		progressDialog.show();
	}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.m_6dialog.MainActivity" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt1"
        android:text="普通弹出框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt2"
        android:text="时间弹出框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt3"
        android:text="进度条弹出框" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Bt4"
        android:text="自定义弹出框" />

</LinearLayout>



2017-03-02 15:42:42 ayrascal 阅读数 769

准备:

public class ActionSheet {
   public interface OnActionSheetSelected {
      void onClick(int whichButton);
   }

   private ActionSheet() {
   }

   public static Dialog showSheet(final Context context, final int layoutId,
         final OnActionSheetSelected actionSheetSelected,
         final OnCancelListener cancelListener) {
      final Dialog dialog = new Dialog(context, R.style.ActionSheet);
      final LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      final LinearLayout layout = (LinearLayout) inflater.inflate(layoutId,
            null);
      final int cFullFillWidth = 10000;
      layout.setMinimumWidth(cFullFillWidth);

      final Window w = dialog.getWindow();
      final WindowManager.LayoutParams lp = w.getAttributes();
      lp.x = 0;
      final int cMakeBottom = -1000;
      lp.y = cMakeBottom;
      lp.gravity = Gravity.BOTTOM;
      dialog.onWindowAttributesChanged(lp);
      dialog.setCanceledOnTouchOutside(true);
      if (cancelListener != null) {
         dialog.setOnCancelListener(cancelListener);
      }

      dialog.setContentView(layout);
      dialog.show();

      return dialog;
   }
}
<style name="ActionSheet" parent="@android:style/Theme.Dialog">

应用:

private ActionSheet.OnActionSheetSelected mOnActionSheetSelected;
private Dialog mActionSheet;
调用showGetPhotoDialog()方法

public void onActionSheetClicked(final View view) {
   mOnActionSheetSelected.onClick(view.getId());
}

public void setOnSheetClicked(final ActionSheet.OnActionSheetSelected onActionSheetSelected) {
   mOnActionSheetSelected = onActionSheetSelected;
}

private void showGetPhotoDialog() {
   mActionSheet = ActionSheet.showSheet(this, R.layout.actionsheet_dialog, getOnActionSheetClicked(), null);
}

private ActionSheet.OnActionSheetSelected getOnActionSheetClicked() {

   return new ActionSheet.OnActionSheetSelected() {

      @Override
      public void onClick(final int whichButton) {
         switch (whichButton) {
            case R.id.tv_button1:
               
               break;
 	    case R.id.tv_button2:
               
               break;
case R.id.tv_calendar: mActionSheet.dismiss(); break; default: break; } mActionSheet.dismiss(); } };}
布局:

<?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:background="@color/clear"
    android:orientation="vertical"
    android:padding="5dp" >

    <TextView
        android:id="@+id/tv_botton1"
android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/actionsheet_top_selector" android:clickable="true" android:gravity="center" android:onClick="onActionSheetClicked" android:text="Button1" android:textSize="18sp" /> <TextView android:id="@+id/tv_botton2" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/actionsheet_bottom_selector" android:clickable="true" android:gravity="center" android:onClick="onActionSheetClicked" android:text="Button2" android:textColor="@color/green_title_bar" android:textSize="18sp" /> <TextView android:id="@+id/cancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:background="@drawable/actionsheet_single_selector" android:clickable="true" android:gravity="center" android:onClick="onActionSheetClicked" android:text="@string/cancle" android:textColor="@color/cancle_blue" android:textSize="18sp" /></LinearLayout>




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