popupWindow自定義(1)
popupWindow自定義(2)
首先看看效果圖:
接著上篇文章的荚醒,上次講述了自定義的密碼框發(fā)現(xiàn)在時(shí)間使用過(guò)程中讹堤,當(dāng)點(diǎn)擊物理按鍵返回鳞尔,密碼框不消失拇囊,而是當(dāng)前的Activity退出了校摩,這次優(yōu)化了這個(gè)bug一些默認(rèn)的配置封裝起來(lái)了冗荸,且在使用的時(shí)候更加方便父阻。不多說(shuō),直接貼代碼:
自定義密碼框:
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.text.Editable;
import android.text.TextWatcher;
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;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.skypine.skypine.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class PasswordPopupWindow extends PopupWindow {
private Context mContext;
private View mMenuView;
private String mStringPassword; //輸入的密碼
private TextView[] mTextViewPsw; // 用數(shù)組保存6個(gè)TextView
private GridView mGridView; //支付鍵盤(pán)布局
private ArrayList<Map<String, String>> valueList;
private ImageView mImageViewCancel;
private TextView mTextViewForgetPsw;
private int currentIndex = -1;// 用于記錄當(dāng)前輸入密碼格位置
private TextView mTextViewTitle;
private TextView mTextViewDel;
private TextView cancelButton;
private TextView okButton;
private OnCancelListener cancelListener; //取消
public PasswordPopupWindow(Context context) {
super(context);
mContext = context;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMenuView = inflater.inflate(R.layout.password_dialog, null);
valueList = new ArrayList<>();
mTextViewPsw = new TextView[6];
mImageViewCancel = (ImageView) mMenuView.findViewById(R.id.iv_pay_back);
mTextViewPsw[0] = (TextView) mMenuView.findViewById(R.id.tv_pass1);
mTextViewPsw[1] = (TextView) mMenuView.findViewById(R.id.tv_pass2);
mTextViewPsw[2] = (TextView) mMenuView.findViewById(R.id.tv_pass3);
mTextViewPsw[3] = (TextView) mMenuView.findViewById(R.id.tv_pass4);
mTextViewPsw[4] = (TextView) mMenuView.findViewById(R.id.tv_pass5);
mTextViewPsw[5] = (TextView) mMenuView.findViewById(R.id.tv_pass6);
mGridView = (GridView) mMenuView.findViewById(R.id.gv_keybord);
mTextViewTitle = (TextView) mMenuView.findViewById(R.id.tv_pay_title);
mTextViewForgetPsw = (TextView) mMenuView.findViewById(R.id.tv_pay_forgetPwd);
/**/
cancelButton = (TextView) mMenuView.findViewById(R.id.cancelButton);
okButton = (TextView) mMenuView.findViewById(R.id.okButton);
setView();
//取消按鈕
cancelButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//取消
cancelListener.OnCancel();
//銷毀彈出框
dismiss();
}
});
//設(shè)置SelectPicPopupWindow的View
this.setContentView(mMenuView);
//設(shè)置SelectPicPopupWindow彈出窗體的寬
this.setWidth(LayoutParams.FILL_PARENT);
//設(shè)置SelectPicPopupWindow彈出窗體的高
this.setHeight(LayoutParams.WRAP_CONTENT);
//設(shè)置SelectPicPopupWindow彈出窗體可點(diǎn)擊
this.setFocusable(true);
//設(shè)置SelectPicPopupWindow彈出窗體動(dòng)畫(huà)效果
this.setAnimationStyle(R.style.mypopwindow_anim_style);
//實(shí)例化一個(gè)ColorDrawable顏色為半透明
ColorDrawable dw = new ColorDrawable(0xb0000000);
//設(shè)置SelectPicPopupWindow彈出窗體的背景
this.setBackgroundDrawable(dw);
//mMenuView添加OnTouchListener監(jiān)聽(tīng)判斷獲取觸屏位置如果在選擇框外面則銷毀彈出框
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;
}
});
}
/*********************
* 取消
******************/
public interface OnCancelListener {
public void OnCancel();
}
public void setCancelListener(OnCancelListener cancelListener) {
this.cancelListener = cancelListener;
}
// 初始化按鈕上應(yīng)該顯示的數(shù)字
private void setView() {
for (int i = 1; i < 13; i++) {
Map<String, String> map = new HashMap<>();
if (i < 10) {
map.put("name", String.valueOf(i));
} else if (i == 10) {//沒(méi)有
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();
}
/**
* 設(shè)置監(jiān)聽(tīng)方法侄旬,在第6位輸入完后觸發(fā)
*/
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 = ""; //每次觸發(fā)都要將mStringPassword置空再重新獲取肺蔚,避免由于輸入刪除再輸入造成混亂
for (int i = 0; i < 6; i++) {
mStringPassword += mTextViewPsw[i].getText().toString().trim();
}
pass.inputFinish();//接口中要實(shí)現(xiàn)的方法,完成密碼輸入完成后的響應(yīng)邏輯
}
}
});
}
/**
* 清除所有密碼
*/
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;
}
/**
* 返回標(biāo)題的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 = (Button) 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) {
holder.btnKey.setText("取消");
}
if (position == 14) {
mTextViewDel = holder.btnKey;
holder.btnKey.setText("刪除");
}
if (position == 9 || position == 11 || position == 13) {
holder.btnKey.setBackground(null);
holder.btnKey.setText("");
}
okButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (currentIndex - 1 >= -1) { // 判斷是否刪除完畢
TextView temp = mTextViewPsw[currentIndex--];
temp.setText("");
temp.setBackgroundResource(R.drawable.bg_circle_num_pwd);
}
}
});
holder.btnKey.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (position < 11 && currentIndex != 9 && position != 9) { //點(diǎn)擊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) { //點(diǎn)擊退格鍵
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 Button btnKey;
}
}
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:layout_alignParentBottom="true"
android:gravity="center_horizontal"
android:orientation="vertical">
<RelativeLayout
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="wrap_content"
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位密碼框布局儡羔,需要一個(gè)圓角邊框的shape作為layout的背景 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dp_15"
android:gravity="center"
android:orientation="horizontal">
<!-- inputType設(shè)置隱藏密碼明文
textSize設(shè)置大一點(diǎn)婆排,否則“點(diǎn)”太小了,不美觀 -->
<TextView
android:id="@+id/tv_pass1"
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
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="12sp"/>
<TextView
android:id="@+id/tv_pass2"
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
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_15"
android:layout_height="@dimen/dp_15"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
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_15"
android:layout_height="@dimen/dp_15"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
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_15"
android:layout_height="@dimen/dp_15"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
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_15"
android:layout_height="@dimen/dp_15"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
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"/>
</LinearLayout>
<!-- 輸入鍵盤(pán) -->
<GridView
android:id="@+id/gv_keybord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="@dimen/dp_50"
android:horizontalSpacing="0.5dp"
android:numColumns="3"
android:textColor="@color/colorPrimary"
android:verticalSpacing="0.5dp"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:padding="@dimen/dp_10">
<TextView
android:id="@+id/cancelButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dp_10"
android:text="@string/pay_cancle"
android:textColor="@color/white"
android:textSize="@dimen/sp_15"/>
<TextView
android:id="@+id/okButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="right"
android:padding="@dimen/dp_10"
android:text="@string/pay_delete"
android:textColor="@color/white"
android:textSize="@dimen/sp_15"/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
style
<!-- 這個(gè)是popwindow -->
<style name="mypopwindow_anim_style">
<item name="android:windowEnterAnimation">@anim/popshow_anim</item>
<!-- 指定顯示的動(dòng)畫(huà)xml -->
<item name="android:windowExitAnimation">@anim/pophidden_anim</item>
<!-- 指定消失的動(dòng)畫(huà)xml -->
</style>
popshow_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
pophidden_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromYDelta="0"
android:toYDelta="50%p" />
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
如果大家看懂了這個(gè)笔链,再也不怕任何自定義的彈框段只,根據(jù)這個(gè)原理,可以封裝任意的彈框
比如看看下面類似滴滴打車的搜索頁(yè)面可以用PopWindow 實(shí)現(xiàn)鉴扫,可以自己試試赞枕。
感謝批評(píng)與指導(dǎo)