1. 程式人生 > >Android介面回撥總結,以及運用到彈窗PopWindow的Demo實現

Android介面回撥總結,以及運用到彈窗PopWindow的Demo實現

背景:

最近專案中接觸到介面回撥,以及Android彈窗PopWindow元件的使用,現在利用學到的知識自己寫了一個簡單的Demo,練習下在Android下如何運用介面回撥,來實現彈窗PopWindow的功能。

程式碼結構:

1. 定義一個介面:OnSelectItemListener。定義一個方法 void selectItem(String name, int type),作為點選彈窗的每個Item的回撥介面。

2. 自定義彈窗類:MyPopupWindow,其佈局檔案為popup_window.xml。當在MainActivity呼叫其建構函式建立物件時,同時執行initPopupWindow()函式,給每個Item設定監聽器,監聽點選Item時,回撥介面函式selectItem("Pop Window A", POP_WINDOW_ITEM_1),該函式在MainActivity中實現。

3. 主Activity: MainActivity。其佈局檔案為一個Button和一個TextView。監聽Button,每當點選則彈出PopWindow,呈現三個Item。呼叫MyPopupWindow類中的方法setOnSelectItemListener(OnSelectItemListener listener),傳入OnSelectItemListener 物件作為引數,同時實現回撥介面OnSelectItemListener的方法void selectItem(String name, int type)。

主Activity: MainActivity.java

package com.lambdroid.callbacktest2;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


//聯絡介面的回撥以及PopWindow彈窗的簡單使用
public class MainActivity extends Activity {

    private MyPopupWindow myPopupWindow;
    private Button btn_pop_window;
    private TextView tv_display;
    protected Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        btn_pop_window = (Button) findViewById(R.id.btn_pop_window);
        tv_display = (TextView) findViewById(R.id.tv_display);

        //給Button設定事件監聽:彈出彈窗
        btn_pop_window.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myPopupWindow.show(btn_pop_window);
            }
        });

        myPopupWindow = new MyPopupWindow(context);

        //實現OnSelectItemListener介面的selectItem方法:對於彈窗三個Item的事件監聽
        myPopupWindow.setOnSelectItemListener(new OnSelectItemListener() {
            @Override
            public void selectItem(String name, int type) {
                //點選電站列表,彈出彈框
                if (myPopupWindow != null && myPopupWindow.isShowing()) {
                    myPopupWindow.dismiss();
                }

                tv_display.setText(name);

                switch (type){
                    case MyPopupWindow.POP_WINDOW_ITEM_1:
                        Toast.makeText(context, "我是彈窗A, 我的英文名是" + name, Toast.LENGTH_SHORT).show();
                        break;
                    case MyPopupWindow.POP_WINDOW_ITEM_2:
                        Toast.makeText(context, "我是彈窗B, 我的英文名是" + name, Toast.LENGTH_SHORT).show();
                        break;
                    case MyPopupWindow.POP_WINDOW_ITEM_3:
                        Toast.makeText(context, "我是彈窗C, 我的英文名是" + name, Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }

            }
        });
    }
}

activity_main.xml

<?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"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_pop_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_margin="20dp"
        android:padding="20dp"
        android:text="Pop Window"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_display"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:text="Hello World!"
        android:textSize="30sp" />
</LinearLayout>


自定義彈窗類:MyPopupWindow.java

package com.lambdroid.callbacktest2;

import android.app.ActionBar;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

public class MyPopupWindow implements View.OnClickListener{
    private PopupWindow mPopWindow;
    private Context mContext;
    private LinearLayout llPop1;
    private LinearLayout llPop2;
    private LinearLayout llPop3;
    private int pw_height;
    public static final int POP_WINDOW_ITEM_1 = 1;
    public static final int POP_WINDOW_ITEM_2 = 2;
    public static final int POP_WINDOW_ITEM_3 = 3;
    private OnSelectItemListener listener;
    
    public void setOnSelectItemListener(OnSelectItemListener listener){
        this.listener = listener;
    }

    public MyPopupWindow(Context context){
        mContext = context;
        initPopupWindow();                  //初始化彈窗
    }


    public void initPopupWindow(){
        View view = LayoutInflater.from(mContext).inflate(R.layout.popup_window, null);
        mPopWindow = new PopupWindow(view, ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, true);
        mPopWindow.setOutsideTouchable(true);
        /** 為其設定背景,使得其內外焦點都可以獲得 */
        mPopWindow.setBackgroundDrawable(new ColorDrawable());
        mPopWindow.setFocusable(true);
        pw_height = view.getHeight();

        llPop1 = (LinearLayout) view.findViewById(R.id.ll_pop_1);
        llPop1.setOnClickListener(this);
        llPop2 = (LinearLayout) view.findViewById(R.id.ll_pop_2);
        llPop2.setOnClickListener(this);
        llPop3 = (LinearLayout) view.findViewById(R.id.ll_pop_3);
        llPop3.setOnClickListener(this);
    }

    //監聽三個彈窗的點選事件
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.ll_pop_1:
                if(listener != null) {
                    listener.selectItem("Pop Window A", POP_WINDOW_ITEM_1);     //回撥介面
                }
                break;
            case R.id.ll_pop_2:
                if(listener != null) {
                    listener.selectItem("Pop Window B", POP_WINDOW_ITEM_2);
                }
                break;
            case R.id.ll_pop_3:
                if(listener != null) {
                    listener.selectItem("Pop Window C", POP_WINDOW_ITEM_1);
                }
                break;
            default:
                break;
        }
    }

    //顯示彈窗,並設定彈窗基於標題欄的顯示位置
    public void show(View view) {
        //popupwindow相對view位置x軸偏移量
        View viewTemp = mPopWindow.getContentView();
        viewTemp.measure(0, 0);
        int width = viewTemp.getMeasuredWidth();
        int xOffset = (view.getWidth() - width) / 2;
        mPopWindow.showAsDropDown(view, xOffset, 0);
    }

    /**
     * 退出popupwindow
     */
    public void dismiss() {
        if (mPopWindow != null && mPopWindow.isShowing()) {
            mPopWindow.dismiss();
        }
    }

    /**
     * popupwindow是否正在顯示
     */
    public boolean isShowing() {
        if(mPopWindow != null) {
            return mPopWindow.isShowing();
        }
        return false;
    }
}

popup_window.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/ll_alarm_type"
        android:layout_width="120dp"
        android:layout_height="130dp"
        android:orientation="vertical"
        android:background="@drawable/popupwindow"
        android:paddingBottom="16dp"
        android:paddingTop="16dp" >
        <LinearLayout
            android:id="@+id/ll_pop_1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:layout_marginTop="5dp"
            android:layout_gravity="center_horizontal"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="視窗 A"
                android:textSize="15sp"
                android:textColor="#ffffff"/>
        </LinearLayout>
        <LinearLayout
            android:id="@+id/ll_pop_2"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:layout_gravity="center_horizontal"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="視窗 B"
                android:textSize="15sp"
                android:textColor="#ffffff"/>

        </LinearLayout>
        <LinearLayout
            android:id="@+id/ll_pop_3"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:layout_gravity="center_horizontal"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="視窗 C"
                android:textSize="15sp"
                android:textColor="#FFFFFF"/>

        </LinearLayout>
    </LinearLayout>

</LinearLayout>

回撥介面:OnSelectItemListener
package com.lambdroid.callbacktest2;

public interface OnSelectItemListener {
    void selectItem(String name, int type);
}

Demo演示

點選Button,彈出彈窗,顯示三個Item

點選第二個Item,通過回撥函式,來實現TextView內容的修改,以及彈出Toast



總結

Java回撥情形涉及很多,本文屬於介面的非同步回撥:當不知道何時會執行介面的回撥函式,(通過介面回撥來對獲取到的資源的操作)。除此還有執行緒間的非同步回撥(子執行緒進行耗時操作,操作完畢通知主執行緒或將資料傳給主執行緒處理),以及利用介面回撥來實現執行緒間的資料通訊等等(Android可以利用Handler來實現)。等下次再舉例說明Java回撥函式的其它情形。