1、自定义布局(密码框、对话框等等)
2、从下往上弹出效果的实现
一、对话框
第一步:
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类继承PopupWindow:
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.PopupWindow;
public class SelectPicPopupWindow extends PopupWindow {
private Button btn_take_photo, btn_pick_photo, btn_cancel;
private View mMenuView;
public SelectPicPopupWindow(Activity context,OnClickListener itemsOnClick) {
super(context);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMenuView = inflater.inflate(R.layout.alert_dialog, null);
btn_take_photo = (Button) mMenuView.findViewById(R.id.btn_take_photo);
btn_pick_photo = (Button) mMenuView.findViewById(R.id.btn_pick_photo);
btn_cancel = (Button) mMenuView.findViewById(R.id.btn_cancel);
//取消按钮
btn_cancel.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//销毁弹出框
dismiss();
}
});
//设置按钮监听
btn_pick_photo.setOnClickListener(itemsOnClick);
btn_take_photo.setOnClickListener(itemsOnClick);
//设置SelectPicPopupWindow的View
this.setContentView(mMenuView);
//设置SelectPicPopupWindow弹出窗体的宽
this.setWidth(LayoutParams.FILL_PARENT);
//设置SelectPicPopupWindow弹出窗体的高
this.setHeight(LayoutParams.WRAP_CONTENT);
//设置SelectPicPopupWindow弹出窗体可点击
this.setFocusable(true);
//设置SelectPicPopupWindow弹出窗体动画效果
this.setAnimationStyle(R.style.AnimBottom);
//实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0xb0000000);
//设置SelectPicPopupWindow弹出窗体的背景
this.setBackgroundDrawable(dw);
//mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框
mMenuView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int height = mMenuView.findViewById(R.id.pop_layout).getTop();
int y=(int) event.getY();
if(event.getAction()==MotionEvent.ACTION_UP){
if(y<height){
dismiss();
}
}
return true;
}
});
}
}
第三步:编写MainActivity类实现测试:
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class MainActivity extends Activity {
//自定义的弹出框类
SelectPicPopupWindow menuWindow;
@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) {
//实例化SelectPicPopupWindow
menuWindow = new SelectPicPopupWindow(MainActivity.this, itemsOnClick);
//显示窗口
menuWindow.showAtLocation(MainActivity.this.findViewById(R.id.main), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0); //设置layout在PopupWindow中显示的位置
}
});
}
//为弹出窗口实现监听类
private OnClickListener itemsOnClick = new OnClickListener(){
public void onClick(View v) {
menuWindow.dismiss();
switch (v.getId()) {
case R.id.btn_take_photo:
break;
case R.id.btn_pick_photo:
break;
default:
break;
}
}
};
}
二、密码框
自定义密码框xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_main_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:id="@+id/iv_pay_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp" />
<TextView
android:id="@+id/tv_pay_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:text="@string/pin_id"
android:textColor="@color/white"
android:textSize="18dp" />
</RelativeLayout>
<!-- 6位密码框布局,需要一个圆角边框的shape作为layout的背景 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:orientation="horizontal">
<!-- inputType设置隐藏密码明文
textSize设置大一点,否则“点”太小了,不美观 -->
<TextView
android:id="@+id/tv_pass1"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:layout_margin="@dimen/dp_5"
android:background="@drawable/bg_circle_num_pwd"
android:gravity="center"
android:inputType="numberPassword"
android:paddingBottom="@dimen/dp_5"
android:textColor="@color/pwd_gray"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_pass2"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:layout_margin="@dimen/dp_5"
android:background="@drawable/bg_circle_num_pwd"
android:gravity="center"
android:inputType="numberPassword"
android:textColor="@color/pwd_gray"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_pass3"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:layout_margin="@dimen/dp_5"
android:background="@drawable/bg_circle_num_pwd"
android:gravity="center"
android:inputType="numberPassword"
android:textColor="@color/pwd_gray"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_pass4"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:layout_margin="@dimen/dp_5"
android:background="@drawable/bg_circle_num_pwd"
android:gravity="center"
android:inputType="numberPassword"
android:textColor="@color/pwd_gray"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_pass5"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:layout_margin="@dimen/dp_5"
android:background="@drawable/bg_circle_num_pwd"
android:gravity="center"
android:inputType="numberPassword"
android:textColor="@color/pwd_gray"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_pass6"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:layout_margin="@dimen/dp_5"
android:background="@drawable/bg_circle_num_pwd"
android:gravity="center"
android:inputType="numberPassword"
android:textColor="@color/pwd_gray"
android:textSize="15sp" />
</LinearLayout>
<TextView
android:id="@+id/tv_pay_forgetPwd"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:textColor="@color/white"
android:visibility="gone" />
<!-- 输入键盘 -->
<GridView
android:id="@+id/gv_keybord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ll_main_password"
android:horizontalSpacing="0.5dp"
android:numColumns="3"
android:textColor="@color/colorPrimary"
android:verticalSpacing="0.5dp" />
</LinearLayout>
</RelativeLayout>
PasswordView
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.skypine.skypine.R;
import com.skypine.skypine.ui.MainActivity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* Created by syhuang on 2017/7/19.
*/
public class PasswordView extends RelativeLayout {
/*********************
* 取消
******************/
public interface OnCancelListener {
public void OnCancel();
}
public void setCancelListener(OnCancelListener cancelListener) {
this.cancelListener = cancelListener;
}
OnCancelListener cancelListener;
/***************************************/
private MainActivity mContext;
private String mStringPassword; //输入的密码
private TextView[] mTextViewPsw; // 用数组保存6个TextView
private GridView mGridView; //支付键盘布局
private ArrayList<Map<String, String>> valueList;
private ImageView mImageViewCancel;
private TextView mTextViewForgetPsw;
private int currentIndex = -1;// 用于记录当前输入密码格位置
private View mView;
private TextView mTextViewTitle;
private TextView mTextViewDel;
public PasswordView(Context context) {
super(context, null);
}
public PasswordView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = (MainActivity) context;
mView = View.inflate(context, R.layout.pay_view, null);
valueList = new ArrayList<>();
mTextViewPsw = new TextView[6];
mImageViewCancel = (ImageView) mView.findViewById(R.id.iv_pay_back);
mTextViewPsw[0] = (TextView) mView.findViewById(R.id.tv_pass1);
mTextViewPsw[1] = (TextView) mView.findViewById(R.id.tv_pass2);
mTextViewPsw[2] = (TextView) mView.findViewById(R.id.tv_pass3);
mTextViewPsw[3] = (TextView) mView.findViewById(R.id.tv_pass4);
mTextViewPsw[4] = (TextView) mView.findViewById(R.id.tv_pass5);
mTextViewPsw[5] = (TextView) mView.findViewById(R.id.tv_pass6);
mGridView = (GridView) mView.findViewById(R.id.gv_keybord);
mTextViewTitle = (TextView) mView.findViewById(R.id.tv_pay_title);
mTextViewForgetPsw = (TextView) mView.findViewById(R.id.tv_pay_forgetPwd);
setView();
addView(mView); //必须要,不然不显示控件
}
// 初始化按钮上应该显示的数字
private void setView() {
for (int i = 1; i < 16; i++) {
Map<String, String> map = new HashMap<>();
if (i < 10) {
map.put("name", String.valueOf(i));
} else if (i == 10) {//没有
map.put("name", "");
} else if (i == 11) {//
map.put("name", String.valueOf(0));
} else if (i == 12) {
map.put("name", "");
} else if (i == 13) {
map.put("name", " ");
} else if (i == 14) {
map.put("name", "");
}
valueList.add(map);
}
mGridView.setAdapter(adapter);
}
public interface OnPasswordInputFinish {
public void inputFinish();
}
/**
* 设置监听方法,在第6位输入完后触发
*/
public void setOnFinishInput(final OnPasswordInputFinish pass) {
mTextViewPsw[5].addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().length() == 1) {
mStringPassword = ""; //每次触发都要将mStringPassword置空再重新获取,避免由于输入删除再输入造成混乱
for (int i = 0; i < 6; i++) {
mStringPassword += mTextViewPsw[i].getText().toString().trim();
}
pass.inputFinish();//接口中要实现的方法,完成密码输入完成后的响应逻辑
}
}
});
}
/**
* 清除所有密码
*/
public void clearAll() {
// currentIndex= -1;
// mTextViewPsw[0].setBackgroundResource(R.drawable.bg_circle_num_pwd);
// mTextViewPsw[1].setBackgroundResource(R.drawable.bg_circle_num_pwd);
// mTextViewPsw[2] .setBackgroundResource(R.drawable.bg_circle_num_pwd);
// mTextViewPsw[3]. setBackgroundResource(R.drawable.bg_circle_num_pwd);
// mTextViewPsw[4]. setBackgroundResource(R.drawable.bg_circle_num_pwd);
// mTextViewPsw[5].setBackgroundResource(R.drawable.bg_circle_num_pwd);
// mTextViewPsw[0].setText("");
// mTextViewPsw[1].setText("");
// mTextViewPsw[2] .setText("");
// mTextViewPsw[3]. setText("");
// mTextViewPsw[4]. setText("");
// mTextViewPsw[5].setText("");
currentIndex=5;
while (true)
if (currentIndex - 1 >= -1) { // 判断是否删除完毕
TextView temp = mTextViewPsw[currentIndex--];
temp.setText("");
temp.setBackgroundResource(R.drawable.bg_circle_num_pwd);
} else {
break;
}
}
/**
* 获取输入的密码
*/
public String getPassword() {
return mStringPassword;
}
/**
* 返回取消支付的ImageView
*/
public ImageView getCancel() {
return mImageViewCancel;
}
// /**
// * 返回取消
// */
// public TextView getmTextViewCancel() {
// return mTextViewCancel;
// }
/**
* 返回忘记密码的TextView
*/
public TextView getForgetPsw() {
return mTextViewForgetPsw;
}
/**
* 返回标题的TextView
*/
public TextView getTitle() {
return mTextViewTitle;
}
// GridView的适配器
BaseAdapter adapter = new BaseAdapter() {
@Override
public int getCount() {
return valueList.size();
}
@Override
public Object getItem(int position) {
return valueList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_pay_gride, null);
holder = new ViewHolder();
holder.btnKey = (TextView) convertView.findViewById(R.id.btn_keys);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btnKey.setText(valueList.get(position).get("name"));
if (position == 12) {
// mTextViewCancel=holder.btnKey;
// holder.btnKey.setBackgroundResource(R.drawable.selector_key_del);
holder.btnKey.setText("取消");
}
if (position == 14) {
mTextViewDel = holder.btnKey;
// holder.btnKey.setBackgroundResource(R.drawable.selector_key_del);
holder.btnKey.setText("删除");
}
if (position == 9 || position == 11 || position == 13) {
holder.btnKey.setBackground(null);
holder.btnKey.setText("");
}
holder.btnKey.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (position < 11 && currentIndex != 9 && position != 9) { //点击0-9按钮
if (currentIndex >= -1 && currentIndex < 5) { //判断输入位置
TextView temp = mTextViewPsw[++currentIndex];
temp.setText(valueList.get(position).get("name"));
temp.setBackgroundResource(R.drawable.bg_circle_num_pwd_visiable);
}
} else {
if (position == 14) { //点击退格键
if (currentIndex - 1 >= -1) { // 判断是否删除完毕
TextView temp = mTextViewPsw[currentIndex--];
temp.setText("");
temp.setBackgroundResource(R.drawable.bg_circle_num_pwd);
}
}
if (position == 12) {
//退出
cancelListener.OnCancel();
}
}
}
});
return convertView;
}
};
static class ViewHolder {
public TextView btnKey;
}
}
自定义popwind
<?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">
<com.view.PasswordView
android:id="@+id/pv_pop_win"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.view.PasswordView>
</LinearLayout>
使用:
private static PopupWindow mPopupWindow;
private static View popView;
private static PasswordView mPasswordView;
popView = View.inflate(context, R.layout.pop_window, null);
mPopupWindow = new PopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mPopupWindow.setTouchable(true);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
// 设置动画
mPopupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
mPopupWindow.getContentView().setFocusableInTouchMode(true);
mPopupWindow.getContentView().setFocusable(true);
mPopupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
// mPopupWindow.showAsDropDown(controlPager,0,0);
mPasswordView = (PasswordView) popView.findViewById(R.id.pv_pop_win);
// mPasswordView.getTitle().setText(getString(R.string.pin_id));
mPasswordView.setOnFinishInput(new PasswordView.OnPasswordInputFinish() {
@Override
public void inputFinish() {
mPopupWindow.dismiss();
lock.setMove(true);
//验证车辆密码
// checkCarPwd(mPasswordView.getPassword());
if (mPasswordView.getPassword().equals(AppConfig.getInstance().getString("key", ""))) {
//密码正确
listener.onSuccess();
} else {
//密码错误
listener.onError();
}
}
});
mPasswordView.setCancelListener(new PasswordView.OnCancelListener() {
@Override
public void OnCancel() {
lock.setMove(true);
mPopupWindow.dismiss();
}
});
参考:
http://www.tuicool.com/articles/beABNjq
http://104zz.iteye.com/blog/1685389
http://www.jb51.net/article/94888.htm
我的另外一篇文章:
popupWindow自定义(2)