PopupWindow的使用和兩個案例

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()的用法




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章