安卓中的彈窗界面介紹(AlertDialog、ProgressDialog,PopupWindow)遇到問題繼續補充

AlertDialog的使用

介紹

AlertDialog可以在當前界面彈出一個對話框,這個對話框是置頂於所有的界面元素上,可以屏蔽掉其他控件的交互能力,在代碼中使用靈活簡單。

功能

  1. 基本使用(設置標題,內容,自定義內容區域)
  2. 讓Dialog鋪滿屏幕
  3. 在自定義Dialog上彈出軟鍵盤
  4. 保持Dialog不退出
  5. 自定義Dialog的介紹

推薦

這裏推薦一個Git項目,上面提供的比較多的功能:
material-dialogs

基本使用

AlertDialog.Builder builder= new AlertDialog.Builder(MainActivity.this);
builder.setTitle("這是一個DiaLog");
//設置標題       
builder.setMessage("你確定你知道了嗎");
//設置內容
builder.setIcon(R.mipmap.ic_launcher);
//設置頭像Icon
builder.show();
/**解釋說明:
AlertDialog是通說Builder構建者模式來創建的,其中使用builder來創建Dialog,
通過show()方法展示*/

這裏寫圖片描述


添加按鈕

上面都是簡單使用,在彈出框上還可以添加事件按鈕,一共可以監聽四種事件
在上面基礎上添加在builder.show()之前

//添加一個確定按鈕,打印log發現是 i=-1
builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Log.d("Main","用戶點擊了確定按鈕");
                Log.d("Main","用戶點擊了確定按鈕"+i);
            }
        });
//添加一個取消按鈕,打印log 發現是 i=-2
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Log.d("Main","用戶點擊了取消按鈕");
                Log.d("Main","用戶點擊了取消按鈕"+i);
            }
        });
 //添加一箇中立按鈕,打印log,發現是 i=-3
        builder.setNeutralButton("中立", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Log.d("Main","用戶點擊了中立");
                Log.d("Main","用戶點擊了中立"+i);
            }
        });
//這個方法是監聽當用戶點擊了dialog窗體之外的方法,
// dialog.setCancelable(false);如果存在這句話的話,那麼這個監聽就無效了,
//哪怕用戶按回退鍵
//注意的是,這個監聽所指窗體之外也包括了用戶按回退鍵這個動作 
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialogInterface) {
              Log.d("Main","用戶點擊了視圖外面");
            }
        });
       
       
        /**你會發現你可以使用好多setNegativeButton,方法來設置按鈕,但是最終有效果    
        最後添加或執行的。這樣你就可以根據不同的情況來展示不同的AlertDialog界面了
        另外你點了哪一個按鈕,那麼AlertDialog窗體就會消失*/

這裏寫圖片描述


修改內容主題部分

當然,那就不能使用setMessage()這個方法了。

第一種:展示列表內容
builder.setItems(ss, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Log.d("Main","點擊了內容區域");
                Log.d("Main","點擊了"+i); //會發現下角標是從0、1、2開始變化的
            }
        }); 
//說明這裏的ss其實: private String [] ss = {"項羽","劉邦","韓信"};

這裏寫圖片描述

展示單選框內容
builder.setSingleChoiceItems(ss, 1, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {               
                Log.d("Main","最後確定的是"+i);
                //這個的特色是選中之後,dialog並不會消失,但是會確定i,用來定位的。
            }
        });
         //這個是帶有單選框的,參數二是默認選中哪一個,比如1就是默認選中1位置的

這裏寫圖片描述


展示覆選框內容
builder.setMultiChoiceItems(ss, dd, new DialogInterface.OnMultiChoiceClickListener() {
  @Override
  public void onClick(DialogInterface dialogInterface, int i, boolean b) {
                Log.d("Main",""+dialogInterface);
                Log.d("Main",""+i);
                Log.d("Main",""+b);
            }
//這裏面參數二是默認選中哪幾項,是一個Boolean類型的數組
//當用戶改變一個item 的條目的時候,就會走一遍監聽,將改變的那一個item的位置i以及變化變化之後的
//狀態true 或者 false 都可以知道
//前面的ss有多長,那麼dd就應該有多長,要不然就會存在數組越界
        });
//附上數組dd:  private boolean []dd ={true,false,true};

這裏寫圖片描述


使用自定義內容區域

如果上面的內容還不是能過滿足你,可以使用自己定義佈局樣式

首先準備一個佈局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#47ec38"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="請輸入你的建議"
        android:background="@null"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="請輸入你的建議"
        android:background="@null"
        />

</LinearLayout>

其次在show()方法執行之前調用這個方法:
 builder.setView(R.layout.sd);
 ***這裏注意的是,在AlertDialog展示的內容區域,只能放一個內容,要不然就會出問題的***,

這裏寫圖片描述


如何讓dialog從底部彈出

需要注意的是,前面的都可以通過builder來完成,但是這個需要通過AlertDialog來完成,
其實,可以是在builder的基礎上,新建一個AlertDialog(也就是說,你在builder.create方法之後在調用builder修改屬性,對於生成的dialog是沒有意義的,沒有效果),因爲你同時調用builder.show()還有dialog.show(),你會發現,兩個窗體都會出現,誰先調用誰現出來,但是都會出來。當然了,AlertDialog 對象有許多值是不能設置的,是要builder來完成基礎的搭建,並且builder也不能完成許多操作,比如調用dismiss()方法,還比如下面的,讓dialog從底部彈出,這種修改窗體的。
/*介紹了這麼多,其實最簡單來講:你前面構建了一個builder,然後你也得到了一個dialog對象,但是你最後在使用的時候使用builder.show(),那麼最後展示出來的是builder配置的樣式,和dialog配置的一點關係沒有/

AlertDialog mDialog = builder.create(); //得到一個新建的AlertDialog窗體對象
 Window window = mDialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setWindowAnimations(R.style.mydialog);
mDialog.setCanceledOnTouchOutside(true);
mDialog.show();

這裏引用了style格式文件,

 <style name="mystyle" parent="android:Animation">  
<item name="@android:windowEnterAnimation">@anim/dialog_enter
</item>  //進入時的動畫  
<item name="@android:windowExitAnimation">@anim/dialog_exit
</item>    //退出時的動畫  
</style>  
進入時候動畫,根據具體需求來寫,這裏只是例子罷了
 <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>
  
退出時候動畫
<set xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <translate
        android:duration="300"
        android:fromYDelta="0"
        android:toYDelta="50%"
        />

    <alpha
        android:duration="300"
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        />

</set>

讓Dialog和屏幕一樣寬

在使用AlertDialog時候很大情況不僅需要從底部彈出,還希望的是要鋪滿全屏,先看幾張效果圖:
(1)使用 alertDialog.setView(views);
這裏寫圖片描述

(2)alertDialog.setView(views,40,40,40,40);
這裏寫圖片描述

發現我在佈局的時候,確實是讓其match_parent了,但是展示出來卻沒有效果,從網上找了代碼如下:

View views = LayoutInflater.from(this).inflate(R.layout.myitem,null,false);
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setMessage("這是一個測試的例子");
        builder.setNegativeButton("哈哈", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Toast.makeText(MainActivity.this,"點擊了哈哈",Toast.LENGTH_SHORT).show();
            }
        });
        builder.setView(views);//也可以展示出來
        AlertDialog alertDialog = builder.create();
        Window window = alertDialog.getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(R.style.mystyle);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setAttributes(lp);
        alertDialog.show();

運行發現,還是原樣,如圖一,沒有達到自己想要的結果。
其實,在寫代碼時候:
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this,R.style.DialogTheme);
給其使用上主題就可以了,

< style name="DialogTheme" parent="@android:style/Theme.Dialog">
        < item name="android:windowFrame">@null</item>移除邊框
        < item name="android:windowNoTitle">true</item>去除頂部標題欄
        < item name="android:windowIsTranslucent">true</item>窗體透明
        < item name="android:background">@android:color/white</item>背景透明
        < item name="android:windowBackground">@android:color/transparent</item>窗體背景透明
        < item name="android:windowIsFloating">false</item>窗體是否浮動
        < item name="android:backgroundDimEnabled">true</item>背景是否昏暗
        < item name="android:backgroundDimAmount">0.6</item>昏暗數量
    < /style>

如果上面的還不可以,那麼可以使用辦法(推薦):

        Window window = getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        layoutParams.horizontalMargin = 0;
        window.setAttributes(layoutParams);
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 
        window.getDecorView().setPadding(0,0,0,0);
        window.setGravity(Gravity.BOTTOM);

如何在自定義Dialog上彈出軟鍵盤

1、自定義主題-在使用自定義dialog的時候設置

    <style name="dialog_soft_input" parent="Theme.AppCompat.Light.Dialog.Alert">
        <item name="android:windowSoftInputMode">stateVisible|adjustPan</item>
    </style>

2、自定義dialog-示例

public class MyInfoDialog extends Dialog {


    private onClicker monClicker = null; //自定義接口,實現接口回調
    private Context context;


    public void setMonClicker(onClicker monClicker) {
        this.monClicker = monClicker;
    }

    protected MyInfoDialog(Context context) {
        super(context);
        this.context = context;
    }

    public MyInfoDialog(Context context, int themeResId) {
        super(context, themeResId);
        this.context = context;
    }

    private EditText myEditText;
    private TextView myTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_info_dialog_input);

        myEditText = findViewById(R.id.editText_input_send_dialog);
        myTextView = findViewById(R.id.textview_input_send_dialog);

        Window window = getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        layoutParams.horizontalMargin = 0;
        window.setAttributes(layoutParams);
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        window.getDecorView().setPadding(0,0,0,0);
        window.setGravity(Gravity.BOTTOM);

        myTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String input =  myEditText.getText().toString().trim();
                if (monClicker != null){
                    monClicker.sendInput(input);
                }
                dismiss();
            }
        });
        myEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm.isActive()) {
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                    return false;
                }
                return false;
            }
        });

  額外注意的是,我集成的是Dialog,並不是AlertDialog,上述代碼如果使用AlertDialog,並不能彈出鍵盤來。


    }
}

如何讓讓dialog不退出

前面知道dialog可以有三個按鈕的監聽,但是你會發現,當你點擊了某一個按鈕之後,它就會消失,這是因爲:
這裏以設置setPositiveButton爲例子,

public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
            P.mPositiveButtonText = text;
            P.mPositiveButtonListener = listener;
            return this;
        }
//可以發現:設置的text賦給了mPositiveButteonText,
//設置的監聽賦給了mPositiveButtonListener

關鍵是p:

  //這個是在AlertDialog的Builder裏面,這是在AlertController中定義的內部類,裏面定義了大量的屬性
  private final AlertController.AlertParams P;

在AlertParams 中有一個方法:

 public void apply(AlertController dialog) {
            if (mCustomTitleView != null) {
                dialog.setCustomTitle(mCustomTitleView);
            } else {
                if (mTitle != null) {
                    dialog.setTitle(mTitle);
                }
                if (mIcon != null) {
                    dialog.setIcon(mIcon);
                }
                if (mIconId != 0) {
                    dialog.setIcon(mIconId);
                }
                if (mIconAttrId != 0) {
                    dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
                }
            }
            if (mMessage != null) {
                dialog.setMessage(mMessage);
            }
            if (mPositiveButtonText != null) {
                dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText, mPositiveButtonListener, null);
            }
            if (mNegativeButtonText != null) {
                dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mNegativeButtonText,mNegativeButtonListener, null);
            }
            if (mNeutralButtonText != null) {
                dialog.setButton(DialogInterface.BUTTON_NEUTRAL, mNeutralButtonText,mNeutralButtonListener, null);
            }
            // For a list, the client can either supply an array of items or an
            // adapter or a cursor
            if ((mItems != null) || (mCursor != null) || (mAdapter != null)) {
                createListView(dialog);
            }
            if (mView != null) {
                if (mViewSpacingSpecified) {
                    dialog.setView(mView, mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
mViewSpacingBottom);
                } else {
                    dialog.setView(mView);
                }
            } else if (mViewLayoutResId != 0) {
                dialog.setView(mViewLayoutResId);
            }   
        }
//可以發現,在這個名爲應用的方法中,有如下代碼
//dialog.setButton(DialogInterface.BUTTON_POSITIVE, //mPositiveButtonText, mPositiveButtonListener, null);
//而setButton方法是AlertController中定義的方法,如下:
 public void setButton(int whichButton, CharSequence text, DialogInterface.OnClickListener listener, Message msg) {
           if (msg == null && listener != null) {
            msg = mHandler.obtainMessage(whichButton, listener);
        }//如果msg不爲空,並且存在聽者,可以得到相對應的msg
        switch (whichButton) {
          //針對與各種不同的按鈕whichButton,通過前面的調用,可以發現,
          //whichButton就是一些int數值,下面完成賦值操作
            case DialogInterface.BUTTON_POSITIVE:
                mButtonPositiveText = text;
                mButtonPositiveMessage = msg;
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                mButtonNegativeText = text;
                mButtonNegativeMessage = msg;
                break;

            case DialogInterface.BUTTON_NEUTRAL:
                mButtonNeutralText = text;
                mButtonNeutralMessage = msg;
                break;

            default:
                throw new IllegalArgumentException("Button does not exist");
        }
    }

上述表示,設置完監聽的底層操作,用於接下來的點擊事件。

在AlertDialog類中的onCreate方法中,存在:
mAlert.installContent();
在AlertController類中找到這個方法,裏面調用了,
setupView();
裏面存在:
setupButtons(buttonPanel);
在這個方法中會發現:
mButtonPositive.setOnClickListener(mButtonHandler);
然後,會發現mButtonHandler參數
  private final View.OnClickListener mButtonHandler = new View.OnClickListener() {
        @Override
 public void onClick(View v) {
  final Message m;
  if (v == mButtonPositive && mButtonPositiveMessage != null) {
   m = Message.obtain(mButtonPositiveMessage);
            } else if (v == mButtonNegative && mButtonNegativeMessage != null) {
                m = Message.obtain(mButtonNegativeMessage);
            } else if (v == mButtonNeutral && mButtonNeutralMessage != null) {
                m = Message.obtain(mButtonNeutralMessage);
            } else {
                m = null;
            }
            if (m != null) {
                m.sendToTarget();
            }         mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG, mDialog).sendToTarget();
        }
    };
   //會對於前面準備的相對應的msgt進行判斷,然後,要是存在的話,就會調用sendToTarget()方法。異步的方式通知Handler的handleMessage方法執行我們最開始設置的監聽器中的onClick()方法。通過發送MSG_DISMISS_DIALOG消息,在Handler的handleMessage()方法中調用dismiss()方法退出dialog,這就是爲什麼點擊按鈕之後對話框無條件退出的原因。
總結:dialog的時候一般會調用setPositiveButton()方法傳入我們自己的監聽器,然後在create()(show會首先執行create)的時候該監聽器會被賦值給dialog內部AlertParams對象的mPositiveButtonListener屬性,然後該對象的apply()方法將該賦值後的mPositiveButtonListener封裝在一個message對象中,
//上述是準備工作,下述是刺激事件,
在按鈕被點擊之後,就會獲取我們先前message對象中封裝的監聽器,進而調用該監聽器的onClick()方法執行我們在setPositiveButton()中傳入的監聽器邏輯,同時發送消息調用dismiss()方法讓對話框消失。

解決辦法:
用戶輸入不滿意的話就通過反射修改mShowing的值爲false,再手動調用dismiss(),由於mShowing爲false,對話框就不會消失

 mBuilder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Field field = null;
                try {
                    field = dialogInterface.getClass().getSuperclass().getSuperclass().getDeclaredField("mShowing");
                    field.setAccessible(true);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
                if (is != 3) {
                    try {
                        field.set(dialogInterface, false);
                        dialogInterface.dismiss();
                        Toast.makeText(MainActivity.this, "還不夠,現在是" + is, Toast.LENGTH_SHORT).show();
                        is++;
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(MainActivity.this, "還不夠,現在是" + is, Toast.LENGTH_SHORT).show();
                    try {
                        field.set(dialogInterface,true);
                        dialogInterface.dismiss();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        通過上述就可以不退出了

注意:

(1)setView和setContentView()兩者的區別:
setView()覆蓋AlertDialog的Title和Button之間的部分,而setContentView()全部覆蓋。
如果不注意這點的話,很容易在使用自定義樣式的時候,出現黑框。

自定義AlertDialog,建議這樣用,比較簡單直接

public class YinSiDialog extends AlertDialog {

    public YinSiDialog(Context context) {
        super(context);
    }



    private TextView butongyiText;
    private TextView tongyiText;
    private WebSettings webSettings;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_yin_si);
      //和Activity一樣用
        butongyiText = findViewById(R.id.textView_yin_si_butongyi);
        tongyiText = findViewById(R.id.textView_yin_si_tongyi);
        Window window = getWindow();
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//關鍵代碼,要不然無法全部用你的背景
        //上面兩句是你自定義佈局展示出來的關鍵,沒有這句話的話,你的dialog的寬度就是系統默認的,你在佈局中設置的寬度,
        只是改變內容區域,
        initWebView();
        setCancelable(false);
        butongyiText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (butongyiInfo != null){
                    butongyiInfo.clickBtn();
                }
                dismiss();

            }
        });

        tongyiText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (tongyiInfo != null){
                    tongyiInfo.clickBtn();
                }
                dismiss();
            }
        });

    }


    //自定義接口,用來完成接口回調功能
    private InfoDialogInterface butongyiInfo;
    private InfoDialogInterface tongyiInfo;

    public void setButongyiInfo(InfoDialogInterface butongyiInfo) {
        this.butongyiInfo = butongyiInfo;
    }

    public void setTongyiInfo(InfoDialogInterface tongyiInfo) {
        this.tongyiInfo = tongyiInfo;
    }
}

ProgressDialog的使用

介紹

與AlertDialog類似,都是可以在界面上彈出一個對話框,都能夠屏蔽掉其他空間愛你的交互能力。

基本使用

 progressDialog = new ProgressDialog(MainActivity.this);
 //這是創建方式之一,還有一種,是需要兩個參數,參數二是主題,int theme;
 progressDialog.setTitle("這是一個ProgressDialog");
 //設置題目
 progressDialog.setMessage("這裏面是內容區域");
 //設置內容區域
 progressDialog.setIcon(R.mipmap.ic_launcher);
 //設置Icon
 progressDialog.show();

這裏寫圖片描述


添加按鈕

與AlertDialog類似,也是提供了三個按鈕的操作,一共可以有四個監聽事件

progressDialog.setButton(ProgressDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
  @Override
  public void onClick(DialogInterface dialogInterface, int i) {
      Log.d("Main",""+i);//-2
     }
   });

progressDialog.setButton(ProgressDialog.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialogInterface, int i) {
           Log.d("Main",""+i);//-1
       }
        });

progressDialog.setButton(ProgressDialog.BUTTON_NEUTRAL, "其他", new DialogInterface.OnClickListener() {
   @Override
   public void onClick(DialogInterface dialogInterface, int i) {
       Log.d("Main",""+i);//-3
     }
    });
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
     @Override
     public void onCancel(DialogInterface dialogInterface) {
       Log.d("Main","點擊了空白區域");
        }
   });
        //上述四個動作一點,progressDialog也是消失
        //除非設置progressDialog.setCancelable(false);當然設置這個屬性,表示的是
        //針對於點擊空白處和回退鍵處無效了,那麼點擊三個按鈕還是一樣會隱藏dialog窗體

這裏寫圖片描述


改變中間顯示內容

可以根據不同的style確定不同的style

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//會展示一個條形狀
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//就是默認的,不斷轉圈的樣式()就是圖一的樣式
看看ProgressDialog.SYTLE_HORIZONTAL是什麼??

這裏寫圖片描述


通過上面,你會發現,類似於下載的那個progress,

在show()方法之前,可以
 progressDialog.setIndeterminate(false);
 //這樣就可以保證可以修改進度了
 在show方法之後可以調用:
 progressDialog.setProgress(10);
 //改變進度條的樣式
// 通過下面方法可以改變進度條的顏色。progressDialog.setProgressDrawable(getResources().getDrawable(R.drawable.ss));

這裏寫圖片描述


PopupWindow的使用

介紹

其實AlertDialog使用起來已經比較方便了,但是其 有一個致命的缺點,就是不能隨意的設置彈出位置,當然,你也可以通過設置彈出的某些屬性完成,但肯定不方便,所以PopupWindow推出使用.

創建PopupWindow

一共有四種方法創建PopUpWindow


//方法一:
public PopupWindow (Context context)
//方法二:
public PopupWindow(View contentView)
//方法三:
public PopupWindow(View contentView, int width, int height)
//方法四:
public PopupWindow(View contentView, int width, int height, boolean focusable)
--------------------- 
作者:啓艦 
來源:CSDN 
原文:https://blog.csdn.net/harvic880925/article/details/49272285 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

系統提供四種方法,官產方法四,其參數最全,表明PopupWindow在使用過程中最關鍵的四部分

contentView 你要設置給PopupWindow使其顯示的內容

width 與 height 必須設置的,要不然PopupWindow無法顯示

focusable 是否可以接受點擊

用法

PopupWindow popupWindow = new PopupWindow(MainActivity.this);
//填充出彈出的View
View pop_view = getLayoutInflater().inflate(R.layout.pop_up_view,null);
//設置給popupwindow
popupWindow.setContentView(pop_view);
//必須給popupwindow設置大小
popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); // 可以設置大小,也可以用這樣設定
 popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
//進行展示
popupWindow.showAsDropDown(textView);
//展示出來,參數一是錨點,就是相對於哪一個View來展示,另外你還可以選擇三個參數的該方法,
可以通過設置x,y設置偏移量

結果如圖一
R.layout.pop_up_view就是設置給PopupWindow的佈局,你希望展示什麼,就怎麼佈局
圖一
你會發現挺醜的,背景還是黑色的,那麼嘗試給自己的佈局文件:R.layout.pop_up_view ,在根哪裏設置
android:background="#FFFFFF",運行效果如下圖二
圖二
這樣就好看多了

如果進行下面配置 popupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);

效果如下:
在這裏插入圖片描述
會把下面全部填充了

另一種展示出來方式showAtLocation

   popupWindow.showAtLocation(textView,Gravity.BOTTOM,0,0);
  雖然設置給textview,但是其自動找父佈局進行展示,結果如下

在這裏插入圖片描述

注意,上面的popupwindow點擊外部不能取消,必須進行下面操作纔可以

 //但是有一點需要注意的是,你都不能點擊外部取消,所以必須進行下面的操作
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
 //設置背景色爲透明
 //如果你的佈局文件設置背景顏色了,那麼還是會展示佈局的背景顏色,就不再是透明的了
popupWindow.setOutsideTouchable(true);

如果你的佈局文件裏面沒有設置根背景,那麼就是透明的,效果如下:
在這裏插入圖片描述

給內容區域添加點擊事件

                //添加點擊事件
                TextView textView = pop_view.findViewById(R.id.first_textView);
                textView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this,"點擊了第一個條目",Toast.LENGTH_SHORT).show();
                        popupWindow.dismiss();
                    }
                });

你會發現,添加了popupWindow.dismiss(),因爲你點擊了相應的控件之後,PopupWindow不會主動dismiss
在這裏插入圖片描述

給PopUpWindows添加動畫

1 先定義兩個動畫,一個是進來動畫,一個是出去動畫
進來動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate

        android:duration="600"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

    <alpha

        android:duration="600"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

</set>

出去動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:duration="600"
        android:fromYDelta="0"
        android:toYDelta="100%p" />

    <alpha
        android:duration="600"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />

</set>

寫一個主題文件

  <style name="pop_anim" parent="android:Animation">

        <item name="android:windowEnterAnimation">@anim/pop_enter_animation</item>

        <item name="android:windowExitAnimation">@anim/pop_exit_animator</item>

    </style>

給PopUpWindows使用

        mPopupWindow.setAnimationStyle(R.style.pop_anim);
這樣PopUpWindow就可以帶有動畫了.
給PopupWindows釋放內存
可以在Activity的onDestroy中,調用:
if(popUpWindow != null ){
  popUpWindow.dismiss();
  popUpWindw = null;
  }
  這樣可以避免內存的回收.

持續更新中,遇到問題,回來補充

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