前言
Popwindow窗口是常见的控件之一,常常用于从屏幕下方弹出选择菜单。
简单的实现
1.PopUpWindow界面的XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="235dp"
android:layout_alignParentBottom="true"
android:background="#FFFFFFFF"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/tv_menu_popwindow_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="取消"
android:textColor="#FF999999"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_popwindow_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择方式"
android:textColor="#FF0F58A3"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_menu_popwindow_agree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="确认"
android:textColor="#FF0F58A3"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_menu_popwindow_list1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="45dp"
android:background="#fff"
android:gravity="center_horizontal"
android:text="拍照"
android:textColor="#FF0F58A3"
android:textSize="24sp" />
<TextView
android:id="@+id/tv_menu_popwindow_list2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="35dp"
android:background="#fff"
android:gravity="center_horizontal"
android:text="从相册选择"
android:textColor="#FF999999"
android:textSize="22sp" />
</LinearLayout>
</RelativeLayout>
2.继承PopupWindow
public class BottomMenuPopwindow extends PopupWindow implements View.OnClickListener {
private TextView mTvTitle;
private View mMenuView;
private Activity mContext;
public BottomMenuPopwindow(Activity context, String list1, String list2) {
LayoutInflater inflater = LayoutInflater.from(context);
mContext = context;
mMenuView = inflater.inflate(R.layout.popwindow_camera_or_album, null);
TextView btnCancel = mMenuView.findViewById(R.id.tv_menu_popwindow_cancel);
TextView btnAgree = mMenuView.findViewById(R.id.tv_menu_popwindow_agree);
TextView btnList1 = mMenuView.findViewById(R.id.tv_menu_popwindow_list1);
TextView btnList2 = mMenuView.findViewById(R.id.tv_menu_popwindow_list2);
mTvTitle = mMenuView.findViewById(R.id.tv_popwindow_title);
btnList1.setText(list1);
btnList2.setText(list2);
btnCancel.setOnClickListener(this);
btnList1.setOnClickListener(this);
btnList2.setOnClickListener(this);
btnAgree.setOnClickListener(this);
setContentView(mMenuView);
setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
setFocusable(true);
setAnimationStyle(R.style.bottom_menu_popwindow_anim_style);
//注意 要是点击外部空白处弹框消息 那么必须给弹框设置一个背景色 不然是不起作用的
setBackgroundDrawable(new BitmapDrawable());
//点击外部消失
setOutsideTouchable(true);
//设置可以点击
setTouchable(true);
}
/**
* 显示菜单
*/
public void show() {
if (isShowing()) {
dismiss();
} else {
setBackgroundAlpha(0.5f);
showAtLocation(mMenuView, Gravity.BOTTOM, 0, 0);
}
}
@Override
public void dismiss() {
super.dismiss();
setBackgroundAlpha(1.0f);
}
public void setTvTitle(String title) {
if (TextUtils.isEmpty(title)) {
mTvTitle.setText(title);
}
}
/**
* 改变背景透明度
*
* @param alpha
*/
private void setBackgroundAlpha(float alpha) {
WindowManager.LayoutParams layoutParams = mContext.getWindow().getAttributes();
layoutParams.alpha = alpha;
mContext.getWindow().setAttributes(layoutParams);
}
public interface OnList1ClickListener {
void onClick();
}
private OnList1ClickListener mOnList1ClickListener = null;
public void setOnList1ClickListener(OnList1ClickListener listener) {
mOnList1ClickListener = listener;
}
public interface OnList2ClickListener {
void onClick();
}
private OnList2ClickListener mOnList2ClickListener = null;
public void setOnList2ClickListener(OnList2ClickListener listener) {
mOnList2ClickListener = listener;
}
@Override
public void onClick(View view) {
dismiss();
switch (view.getId()) {
case R.id.tv_menu_popwindow_cancel:
break;
case R.id.tv_menu_popwindow_agree:
case R.id.tv_menu_popwindow_list1:
if (mOnList1ClickListener != null) {
mOnList1ClickListener.onClick();
}
break;
case R.id.tv_menu_popwindow_list2:
if (mOnList2ClickListener != null) {
mOnList2ClickListener.onClick();
}
break;
}
}
}
其中showAtLocation(mMenuView, Gravity.BOTTOM, 0, 0);
是控制PopUpWindow窗口出现的位置
showAtLocation(View parent, int gravity, int x, int y)
参数parent: 对弹窗的位置没有影响,主要作用获取windowtoken
参数gravity: 指定弹窗偏移方向的边缘
参数x: 坐标x方向的偏移
参数y: 坐标y方向的偏移
showAsDropDown(View anchor, int xoff, int yoff)
参数anchor: 弹窗依附的view
xoff : 坐标x方向的偏移 x+10表示向右偏移
yoff: 坐标y方向的偏移 y+10表示向下偏移
3.PopUpWindow出现动画
style.xml
<style name="bottom_menu_popwindow_anim_style">
<item name="android:windowEnterAnimation">@anim/pop_bottom_in</item>
<!-- 指定显示的动画xml -->
<item name="android:windowExitAnimation">@anim/pop_bottom_out</item>
<!-- 指定消失的动画xml -->
</style>
进场动画pop_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="300"
android:fromYDelta="100%p"
android:toYDelta="0"
/>
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
退场动画pop_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="0"
android:toYDelta="100%p" />
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
4.在MainActivity中调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomMenuPopwindow mMenuPopwindow = new BottomMenuPopwindow(MainActivity.this, "拍照", "从相册选择");
mMenuPopwindow.setTvTitle("请选择方式");
mMenuPopwindow.show();
}
}
配合时间选择器
1.PopUpWindow界面的XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="260dp"
android:layout_gravity="bottom"
android:background="#FFFFFFFF"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/tv_pop_scroll_selector_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="取消"
android:textColor="#FF999999"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择日期"
android:textColor="#FF0F58A3"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_pop_scroll_selector_agree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="确认"
android:textColor="#FF0F58A3"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.fenda.slock.ui.view.ScrollSelector
android:id="@+id/pop_scroll_selector_year"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1">
</com.fenda.slock.ui.view.ScrollSelector>
<com.fenda.slock.ui.view.ScrollSelector
android:id="@+id/pop_scroll_selector_month"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1">
</com.fenda.slock.ui.view.ScrollSelector>
<com.fenda.slock.ui.view.ScrollSelector
android:id="@+id/pop_scroll_selector_day"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1">
</com.fenda.slock.ui.view.ScrollSelector>
</LinearLayout>
</LinearLayout>
</LinearLayout>
2.滑动选择器的View
public class ScrollSelector extends View {
/**
* 获取选中项
*/
public int getSelectedIndex() {
return (int) (-offsetY + 0.5);
}
/**
* 设置选中项
*/
public void setSelectedIndex(int pos) {
if (pos < 0 || pos >= contents.size()) {
return;
}
offsetY = -pos + 1;
}
/**
* 设置项列表的内容
*/
public void setItemContents(ArrayList<String> list) {
/*当前选中项为原本列表项的最后一项时,如果重新指定的列表项的比原本的列表项的小
则会让当前的选中项为空,所以需要重新指定选中项*/
if (getSelectedIndex() >= list.size()) {
setSelectedIndex(list.size() - 1);
}
contents = list;
invalidate();
}
/**
* 设置显示的项数
*/
public void setShowItemNum(int num) {
showItemNum = num;
offsetY = (showItemNum - 1) / 2; //设置默认项
}
/**
* 设置分割线的颜色
*/
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
}
/**
* 设置选中状态字体的颜色
*/
public void setTextSelectorColor(int textSelectorColor) {
this.textSelectorColor = textSelectorColor;
}
/**
* 设置正常状态字体的颜色
*/
public void setTextNormalColor(int textNormalColor) {
this.textNormalColor = textNormalColor;
}
private final int DIVIDER_WIDTH = 0; //分割线的宽度
private final int DEFAULT_TEXTSIZE = DisplayUtil.sp2px(24); //默认字体大小
private final int SLEEP_TIME = 1000 / 60; //动画的延时时间,每秒大约80帧
private final int WHAT_INVALIDATE = 0; //重新绘制
private int showItemNum = 3; //显示的项数
private int dividerY; //绘制分隔线的y坐标
private int itemHeight; //每一项所占的高度
private int dividerColor = 0x008A8A8A; //分割线的颜色
private int textSelectorColor = 0xFF0F58A3; //选中状态文字的颜色
private int textNormalColor = 0xFF999999; //正常状态文字的颜色
private int marqueeX; //跑马灯的x坐标偏移
private int marqueeWidth; //跑马灯的宽度
private int borderWhenDown; //按下时的边界状态
private float offsetY; //项偏移的y坐标
private boolean isPress; //手指是否是按下状态
private boolean isFirst = true; //是否是首次绘制
private boolean isSkiping; //是否正在执行跳转
private boolean isStopSkiping; //是否要停止跳转
private boolean isHoming; //是否正在执行归位
private ArrayList<String> contents; //项的内容
private Paint mPaint; //画笔
private GestureDetector mDetector; //手势
private Handler mHandler; //异步处理
private RollThread rollThread; //滚动线程
private MarqueeThread marqueeThread; //跑马灯线程
public ScrollSelector(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //实例化画笔
mPaint.setTextSize(DEFAULT_TEXTSIZE); //设置字体大小
mPaint.setStrokeWidth(DIVIDER_WIDTH); //设置线条的宽度
mDetector = new GestureDetector(context, new MyGestureListener()); //实例化手势
contents = new ArrayList<>(); //初始化列表项的内容,防止出现空指针错误
mHandler = new Handler() { //实例化Handler
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
//重新绘制
case WHAT_INVALIDATE:
invalidate();
break;
}
}
};
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//计算每一项的高度
itemHeight = h / showItemNum;
//计算分割线的y坐标
dividerY = itemHeight * ((showItemNum - 1) / 2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制分割线
mPaint.setColor(dividerColor);
canvas.drawLine(0, dividerY, getWidth(), dividerY, mPaint);
canvas.drawLine(0, dividerY + itemHeight, getWidth(), dividerY + itemHeight, mPaint);
//边界限制
borderLimit();
//绘制项
for (int i = 0; i < showItemNum + 1; i++) {
//获取要绘制的项的序号
int index = (int) -offsetY + i - (showItemNum - 1) / 2;
if (index >= contents.size()) {
break;
}
if (index < 0) {
continue;
}
//获取字符串的宽高
String item = contents.get(index);
Rect bound = new Rect();
mPaint.getTextBounds(item, 0, item.length(), bound);
//绘制字符串
int x = bound.width() > getWidth() ? 0 : (getWidth() - bound.width()) / 2; //绘制文本的x坐标
int y = (int) (itemHeight * i + (offsetY - (int) offsetY) * itemHeight); //绘制文本的y坐标
y += (itemHeight + bound.height()) / 2; //绘制文本的基线偏移量
if (getSelectedIndex() == index) {
mPaint.setColor(textSelectorColor); //选中状态的字体颜色
//判断是否需要跑马灯
if (bound.width() > getWidth()) {
marqueeWidth = bound.width();
x = marqueeX;
if (isFirst) {
marquee();
}
} else {
marqueeWidth = 0;
}
} else {
mPaint.setColor(textNormalColor); //正常状态的字体颜色
}
canvas.drawText(item, x, y, mPaint);
if (isFirst) {
isFirst = false;
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//手指按下
if (event.getAction() == MotionEvent.ACTION_DOWN) {
isPress = true;
borderWhenDown = borderLimit();
marqueeX = 0;
if (isSkiping) {
isStopSkiping = true;
}
}
//手指抬起
if (event.getAction() == MotionEvent.ACTION_UP) {
isPress = false;
if (!isSkiping) {
homing();
}
marquee();
}
//手势判断
mDetector.onTouchEvent(event);
return true;
}
/**
* 归位
*/
private void homing() {
if (isHoming) {
return;
}
isHoming = true;
new HomingThread().start();
}
/**
* 滚动
*/
private void roll(float speed) {
if (rollThread != null && rollThread.isAlive()) {
return;
}
rollThread = new RollThread(speed);
rollThread.start();
}
/**
* 跳转
*
* @param dir true为跳转到顶部,false为跳转到底部
*/
private void skip(boolean dir) {
if (isSkiping) {
return;
}
isSkiping = true;
Log.e("tag", "skip");
new SkipThread(dir).start();
}
/**
* 跑马灯显示
*/
private void marquee() {
if (marqueeThread != null && marqueeThread.isAlive()) {
return;
}
marqueeThread = new MarqueeThread();
marqueeThread.start();
}
/**
* 边界限制
*
* @return -1为在顶部,1为在底部,0为不在边界
*/
private int borderLimit() {
if (offsetY >= 0) { //顶部边界
offsetY = 0;
return -1;
} else if (offsetY <= -contents.size() + 1) { //底部边界
offsetY = -contents.size() + 1;
return 1;
}
return 0;
}
/**
* 手势事件
*/
private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
/**
* 滑动
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
int border = borderLimit();
if (borderWhenDown == -1 && border == -1 && distanceY < 0) { //跳转到底部
skip(false);
} else if (borderWhenDown == 1 && border == 1 && distanceY > 0) { //跳转到顶部
skip(true);
} else if (!isSkiping) {
offsetY -= distanceY / itemHeight; //偏移量
invalidate();
}
return false;
}
/**
* 滚动
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float speed = velocityY / itemHeight / 20;
if (Math.abs(speed) > 0.5) {
roll(speed);
}
return super.onFling(e1, e2, velocityX, velocityY);
}
}
/**
* 自动返回中间位置的(归位)线程
*/
private class HomingThread extends Thread {
private final float MOVE_DISTANCE = 0.05f; //每一帧的移动距离(itemHeight的比例)
@Override
public void run() {
super.run();
float dy = 0;
while (!isPress) { //手指按下就停止归位
//取小数部分
float decimal = Math.abs(offsetY - (int) offsetY);
//大概达到中间位置
if (decimal > -MOVE_DISTANCE * 1.1 && decimal < MOVE_DISTANCE * 1.1) {
break;
}
//移动量
dy = decimal < 0.5 ? MOVE_DISTANCE : -MOVE_DISTANCE;
//防止超过位置
if ((int) offsetY != (int) (offsetY + dy)) {
break;
}
offsetY += dy;
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
//重新绘制
mHandler.sendEmptyMessage(WHAT_INVALIDATE);
}
//取整
if (!isPress) {
offsetY = (int) offsetY;
if (dy < 0) { //误差校正
offsetY--;
}
mHandler.sendEmptyMessage(WHAT_INVALIDATE);
}
isHoming = false;
}
}
/**
* 滚动的线程
*/
private class RollThread extends Thread {
private final float DAMPING = 0.1f; //速度的衰减,即每一帧之后的衰减量
private float speed; //滚动的速度,即每一帧移动的距离
public RollThread(float speed) {
this.speed = speed;
}
@Override
public void run() {
super.run();
boolean dir = speed > 0; //滚动方向,true为向上,false为向下
while (!isPress) {
offsetY += speed;
//显示越界
if (borderLimit() != 0) {
mHandler.sendEmptyMessage(WHAT_INVALIDATE);
break;
}
//速度衰减
speed += (dir ? -DAMPING : DAMPING);
//速度越界
if ((dir && speed < 0) || (!dir && speed > 0)) {
break;
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
//重新绘制
mHandler.sendEmptyMessage(WHAT_INVALIDATE);
}
//滚动完后归位
if (!isPress) {
homing();
}
}
}
/**
* 顶部和底部的跳转
*/
private class SkipThread extends Thread {
private final float SKIP_TIME = 1000; //跳转时间,1秒
private boolean dir; //true为跳转到顶部,false为跳转到底部
public SkipThread(boolean dir) {
this.dir = dir;
}
@Override
public void run() {
super.run();
float framesNum = SKIP_TIME / SLEEP_TIME; //总帧数
float speed = (contents.size()) / framesNum; //每帧移动的距离
if (!dir) {
speed *= -1;
}
while (!isStopSkiping && getSelectedIndex() != (dir ? 0 : contents.size() - 1)) {
offsetY += speed;
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(WHAT_INVALIDATE);
}
if (!isPress) {
homing();
}
isSkiping = false;
isStopSkiping = false;
}
}
/**
* 过长文字跑马灯显示的线程
*/
private class MarqueeThread extends Thread {
private final int moveDistance = 3; //每一帧的移动距离
@Override
public void run() {
super.run();
while (!isPress && marqueeWidth != 0) {
marqueeX -= moveDistance;
if (marqueeX < -marqueeWidth) {
marqueeX = getWidth();
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(WHAT_INVALIDATE);
}
}
}
}
3.继承PopupWindow
public class SrollSelectorTimePop extends PopupWindow implements View.OnClickListener {
private TextView mBtnCancel, mBtnAgree;
private View mMenuView;
private Activity mContext;
//滚动选择器
private ScrollSelector scrollSelectorYear;
private ScrollSelector scrollSelectorMonth;
private ScrollSelector scrollSelectorDay;
private ArrayList<String> yearList;
private ArrayList<String> monthList;
private ArrayList<String> dayList;
public SrollSelectorTimePop(Activity context) {
LayoutInflater inflater = LayoutInflater.from(context);
mContext = context;
mMenuView = inflater.inflate(R.layout.popwidow_sroll_selector, null);
mBtnCancel = mMenuView.findViewById(R.id.tv_pop_scroll_selector_cancel);
mBtnAgree = mMenuView.findViewById(R.id.tv_pop_scroll_selector_agree);
//获取滚动选择器控件
scrollSelectorYear = mMenuView.findViewById(R.id.pop_scroll_selector_year);
scrollSelectorMonth = mMenuView.findViewById(R.id.pop_scroll_selector_month);
scrollSelectorDay = mMenuView.findViewById(R.id.pop_scroll_selector_day);
mBtnCancel.setOnClickListener(this);
mBtnAgree.setOnClickListener(this);
setContentView(mMenuView);
setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
setFocusable(true);
setAnimationStyle(R.style.bottom_menu_popwindow_anim_style);
//注意 要是点击外部空白处弹框消息 那么必须给弹框设置一个背景色 不然是不起作用的
setBackgroundDrawable(new BitmapDrawable());
//点击外部消失
setOutsideTouchable(true);
//设置可以点击
setTouchable(true);
currentTime();
yearList = getYearList();
monthList = getMonthList();
dayList = getDayList();
}
/**
* 显示菜单
*/
public void show() {
if (isShowing()) {
dismiss();
} else {
//设置滚动选择器的项列表
scrollSelectorYear.setItemContents(yearList);
scrollSelectorMonth.setItemContents(monthList);
scrollSelectorDay.setItemContents(dayList);
setBackgroundAlpha(0.5f);
showAtLocation(mMenuView, Gravity.BOTTOM, 0, 0);
}
}
@Override
public void dismiss() {
super.dismiss();
setBackgroundAlpha(1.0f);
}
/**
* 改变背景透明度
*
* @param alpha
*/
private void setBackgroundAlpha(float alpha) {
WindowManager.LayoutParams layoutParams = ((Activity)
mContext).getWindow().getAttributes();
layoutParams.alpha = alpha;
((Activity) mContext).getWindow().setAttributes(layoutParams);
}
private void currentTime() {
Calendar calendar = Calendar.getInstance();
//获取系统的日期
//年
int year = calendar.get(Calendar.YEAR);
//月
int month = calendar.get(Calendar.MONTH) + 1;
//日
int day = calendar.get(Calendar.DAY_OF_MONTH);
scrollSelectorYear.setSelectedIndex(year - 2019);
scrollSelectorMonth.setSelectedIndex(month - 1);
scrollSelectorDay.setSelectedIndex(day - 1);
}
private ArrayList<String> getYearList() {
ArrayList<String> yearList = new ArrayList<>();
for (int a = 2019; a < 2049; a++) {
yearList.add(a + "");
}
return yearList;
}
private ArrayList<String> getMonthList() {
ArrayList<String> monthList = new ArrayList<>();
for (int a = 1; a < 13; a++) {
monthList.add(a + "");
}
return monthList;
}
private ArrayList<String> getDayList() {
ArrayList<String> dayList = new ArrayList<>();
for (int a = 1; a < 32; a++) {
dayList.add(a + "");
}
return dayList;
}
public interface OnAgreeClickListener {
void onClick(String year, String month, String day);
}
private OnAgreeClickListener mOnAgreeClickListener = null;
public void setAgreeOnClickListener(OnAgreeClickListener listener) {
mOnAgreeClickListener = listener;
}
@Override
public void onClick(View view) {
dismiss();
switch (view.getId()) {
case R.id.tv_pop_scroll_selector_cancel:
break;
case R.id.tv_pop_scroll_selector_agree:
String year = yearList.get(scrollSelectorYear.getSelectedIndex());
String month = monthList.get(scrollSelectorMonth.getSelectedIndex());
String day = dayList.get(scrollSelectorDay.getSelectedIndex());
if (mOnAgreeClickListener != null) {
mOnAgreeClickListener.onClick(year, month, day);
}
break;
}
}
}
4.出场动画
参考上面
5.在MainActivity中调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SrollSelectorTimePop mSrollSelectorTimePop = new SrollSelectorTimePop(this);
mSrollSelectorTimePop.setAgreeOnClickListener((year, month, day) -> {
String unLockDate = year + "/" + month + "/" + day;
LogUtil.i(unLockDate);
});
}
}