PopupWindow在安卓中使用很广, 如微信的点赞等等跳出的窗体
下面看实例一:
不多说,直接上代码:
private void AreaPopupWindow() {
if(mPopupWindow == null) {
View areaContentView = createAreaContentView();
int width = mActivity.getWindowManager().getDefaultDisplay().getWidth();
int height = ViewGroup.LayoutParams.WRAP_CONTENT;
boolean focusable = true;
mPopupWindow = new PopupWindow(areaContentView, width, height, focusable);
mPopupWindow.setBackgroundDrawable(new ColorDrawable()); //点击返回键要让popupwindow消失需要给它设置一个背景
mPopupWindow.setOutsideTouchable(true);
}
//显示Popupwindow
View anchor = mTvWangdianqiandaoAreaPopup; //指定popupWindow显示在什么控件的下方
int xoff = 2; // 指定PopupWindow x方向的偏移量
int yoff = 40; // 指定PopupWindow y方向的偏移量
mPopupWindow.showAsDropDown(anchor,xoff,yoff);
}
/** 创建地区PopupWindow显示的内容 */
private View createAreaContentView() {
View contentView = LayoutInflater.from(mActivity).inflate(R.layout.view_qingwuexcute_area_popup,null);
final ListView area1 = (ListView) contentView.findViewById(R.id.lv_area1);
final ListView area2 = (ListView) contentView.findViewById(R.id.lv_area2);
area1.setVerticalScrollBarEnabled(false); //隐藏两个条目右边的滑动条
area2.setVerticalScrollBarEnabled(false);
area2.setVisibility(View.INVISIBLE);
mWangDianArea2Adapter = new WangDianArea2Adapter();
area2.setAdapter(mWangDianArea2Adapter); //给2设置适配器
final WangDianArea1Adapter wangDianArea1Adapter = new WangDianArea1Adapter();
area1.setAdapter(wangDianArea1Adapter);
area1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//选中更改area1中条目的背景色 和文字的颜色
//将点击条目的位置 传给area1的adapter
wangDianArea1Adapter.setItemClickPosition(position);
//给ListView2 加一个动画
area2.setVisibility(View.VISIBLE);
ObjectAnimator animator1 = ObjectAnimator.ofFloat(area2, "translationY", -100.0f, 0);
AnimatorSet set = new AnimatorSet();
set.play(animator1);
set.setDuration(300);
set.start();
//这里处理 点击左边的ListView的条目,让右边的ListView刷新集合 (第二种实现方式:让右边ListView滚动到对应的条目显示)
mDifferentWangDianQianDaoArea2Beens = AllArea2Lists.get(position);
mWangDianArea2Adapter.updataRightData(mDifferentWangDianQianDaoArea2Beens);
area2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//更改area2中选中的条目的 颜色和对号的显示
//循环条目
for(int i = 0; i < mDifferentWangDianQianDaoArea2Beens.size();i++) {
WangDianQianDaoArea2Bean area2Bean = mDifferentWangDianQianDaoArea2Beens.get(i);
area2Bean.isChecked = false;
if(position == i) {
area2Bean.isChecked = true;
}
}
mWangDianArea2Adapter.notifyDataSetChanged();
//更改上方区域中的内容
mTvWangdianqiandaoAreaPopup.setText(mDifferentWangDianQianDaoArea2Beens.get(position).area2);
//保存区域中第一个条目到sp中
SharedPreferences sp = mActivity.getSharedPreferences("hz", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("wangdianqiandao_area",mDifferentWangDianQianDaoArea2Beens.get(position).area2);
editor.commit();
mPopupWindow.dismiss(); //让悬浮窗体消失
}
});
}
});
return contentView;
}
这个例子, 是PopupWindow显示在什么控件的下方,并且距离控件的偏移量可以设定; 注意点击popupWindow 和返回键可以让PopupWindow消失的写法
实例二:
这个Demo弹出的是PopupWindow, 上代码:
package com.example.popupwindowpaydemo.view;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
import com.example.popupwindowpaydemo.BottomDialogListener;
import com.example.popupwindowpaydemo.R;
/**
* 底部支付弹窗的Popupwindow
*/
public class MyBottomPopupWindow extends PopupWindow implements View.OnClickListener {
public BottomDialogListener mListener;
private final TextView mTv_back;
private final EditText mEt_input;
private final Button mBt_cancel;
private final Button mBt_confirm;
private Context mContext;
private final View mView;
public MyBottomPopupWindow(Context context,BottomDialogListener listener) {
this.mListener = listener;
this.mContext = context;
//PopupWindow显示的内容
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = layoutInflater.from(context).inflate(R.layout.view_mypopupwindow,null);
mTv_back = (TextView) mView.findViewById(R.id.tv_back);
mTv_back.setOnClickListener(this);
mEt_input = (EditText) mView.findViewById(R.id.et_input);
mBt_cancel = (Button) mView.findViewById(R.id.bt_cancel);
mBt_confirm = (Button) mView.findViewById(R.id.bt_confirm);
mBt_cancel.setOnClickListener(this);
mBt_confirm.setOnClickListener(this);
this.setContentView(mView);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_back:
this.dismiss();
break;
case R.id.bt_cancel:
this.dismiss();
break;
case R.id.bt_confirm:
String str = mEt_input.getText().toString().trim();
if(TextUtils.isEmpty(str)) {
Toast.makeText(mContext,"密码为空",Toast.LENGTH_SHORT).show();
return;
}
//调用接口中的方法 回调给页面
if(mListener != null) {
mListener.onDataToActivity(str,mView); //为什么要讲view传过去 ?
dismiss();
}
break;
}
}
}
继承了PopupWindow, 对属性进行设置, 并且加入接口回调;
这个弹出窗体的布局有点奥妙:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:id="@+id/tv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:text="→"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="请输入交易密码"/>
</RelativeLayout>
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/bt_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消"/>
<Button
android:id="@+id/bt_confirm"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="确认"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</ScrollView>
整体用ScrollView进行包装, 弹窗弹起的时候,软键盘一般是会覆盖一部分输入框的,这是非常不好看的。之所以demo中没有出现这种情况,是通过了特殊的处理——>将整个弹窗布局外包一层ScrollView,这样方便软键盘弹起找到输入框焦点时会将整个布局往上顶。但,这还不够,一定要在ScrollView中设置一个属性:android:fillViewport="true"
MainActivity中的代码:
package com.example.popupwindowpaydemo;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import com.example.popupwindowpaydemo.view.MyBottomPopupWindow;
public class MainActivity extends AppCompatActivity {
private TextView tv_pwd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_pwd = (TextView) findViewById(R.id.tv_pwd);
}
public void click(View view) {
MyBottomPopupWindow myBottomPopupWindow = new MyBottomPopupWindow(this, new BottomDialogListener() {
@Override
public void onDataToActivity(String str, View v) {
//回调 回来的数据 ,由于接口中已经做了让窗体消息的处理,故这里不做处理
tv_pwd.setText(str);
}
});
myBottomPopupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
myBottomPopupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
myBottomPopupWindow.setOutsideTouchable(false);
// myBottomPopupWindow.setAnimationStyle(R.style.DialogShowStyle);
myBottomPopupWindow.setBackgroundDrawable(new ColorDrawable());
myBottomPopupWindow.setFocusable(true);
//设置PopupWIndow显示的位置, 设置窗口显示在parent布局的位置显示
myBottomPopupWindow.showAtLocation(this.findViewById(R.id.activity_main), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL,0,0);
InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);//自动打开软键盘
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
}
popupWindow 设置setFocusable为true, 才能让Edittext获得焦点 输入密码;同时 这里可以设置一个背景色,由于他是包含整个父窗体的
注意showAtLoacation()和showAsDropDown()的用法