1. 程式人生 > >Android 轉載---自定義PopWindow 類似於QQ右上角的效果

Android 轉載---自定義PopWindow 類似於QQ右上角的效果

前段時間在個人開發的專案中需要用到彈出選單,類似QQ右上角的彈出選單,自己使用popwin的次數也不是很多,其中也遇到過一點問題,今天正好有時間就把一些經驗分享給大家。 
先來看看最終實現過後的效果怎麼樣,下面放上圖 
這裡寫圖片描述 
自定義的彈出選單是繼承的popwin,並不是view 因為沒有必要重複造車輪,如果想要實現某種特殊的效果另說。首先建立類MyPopWindow繼承Popwindow。

public class MyPopWindow extends PopupWindow implements View.OnClickListener {
    private Context context;
    private
View view; private LinearLayout scan; private LinearLayout add; public MyPopWindow(Context context) { this(context, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); } public MyPopWindow(Context context, int width, int height) { super(context); this
.context = context; setWidth(width); setHeight(height); setFocusable(true); setOutsideTouchable(true); setTouchable(true); view = LayoutInflater.from(context).inflate(R.layout.layout_mypopwin,null); setContentView(view); scan = (LinearLayout) view.findViewById(R.id.scan); add = (LinearLayout) view.findViewById(R.id.add); } @Override
public void onClick(View view) { switch (view.getId()){ case R.id.scan: break; case R.id.add: break; } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

下面給出最開始的佈局檔案

<?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">
    <LinearLayout
        android:id="@+id/scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="掃一掃"
            android:textSize="16sp"/>
    </LinearLayout>
    <View
        android:layout_width="wrap_content"
        android:layout_height="0.5dp"
        android:background="#cdcdcd"/>
    <LinearLayout
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加好友"
            android:textSize="16sp"/>
    </LinearLayout>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在activity中呼叫自定義彈出選單看看目前的效果 
這裡寫圖片描述 
呼叫的程式碼MyPopWindow win = new MyPopWindow (MainActivity.this, 200,150);指定了彈出選單的寬高,如果不給就會預設給出wrap_content,就會沾滿整個螢幕的寬度。這個樣子還是比較簡陋,現在在佈局檔案中加上.9圖的背景圖,在來看看效果

<?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"
    android:background="@drawable/title_function_bg">
    <LinearLayout
        android:id="@+id/scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="掃一掃"
            android:textSize="16sp"/>
    </LinearLayout>
    <View
        android:layout_width="wrap_content"
        android:layout_height="0.5dp"
        android:background="#cdcdcd"/>
    <LinearLayout
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加好友"
            android:textSize="16sp"/>
    </LinearLayout>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

執行後的效果 
這裡寫圖片描述 
美觀了一點,但是背景後面還有背景什麼情況,那麼問題來了,怎麼解決這個問題?那就需要在popwin的構造方法中加入setBackgroundDrawable(new BitmapDrawable()),難看的方形背景就會消失了。 
這裡寫圖片描述 
接近目標效果了,現在的問題是,每次增加一個選單項都要手動的定製寬高很煩人,想讓它自己適應高度、寬度,所以那就得修改佈局檔案了,想想android能夠自由增加item的控制元件不少,首先想到的就是listview。修改佈局檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/title_function_bg">
    <ListView
        android:id="@+id/title_list"
        android:layout_width="120dp"
        android:layout_height="fill_parent"
        android:cacheColorHint="#00000000"
        android:divider="@drawable/popu_line"
        android:padding="3dp"
        android:scrollingCache="false"
        android:listSelector="@drawable/title_list_selector"/>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

然後修改自定義的popwindow

public class CustomWin extends PopupWindow {
    private Context context;
    private View view;
    private ListView listView;
    private List<String> list;

    public CustomWin(Context context) {
        this(context, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    public CustomWin(Context context, int with, int height) {
        this.context = context;
        setWidth(with);
        setHeight(height);
        //設定可以獲得焦點
        setFocusable(true);
        //設定彈窗內可點選
        setTouchable(true);
        //設定彈窗外可點選
        setOutsideTouchable(true);
        setBackgroundDrawable(new BitmapDrawable());
        view = LayoutInflater.from(context).inflate(R.layout.popwin_menu,null);
        setContentView(view);
        setAnimationStyle(R.style.popwin_anim_style);
        initData();
    }

    private void initData() {
        listView = (ListView) view.findViewById(R.id.title_list);
        list = new ArrayList<String>();
        list.add("新增好友");
        list.add("掃一掃");
        list.add("支付寶");
        list.add("視訊聊天");
        //設定列表的介面卡
        listView.setAdapter(new BaseAdapter() {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                TextView textView = null;

                if (convertView == null) {
                    textView = new TextView(context);
                    textView.setTextColor(Color.rgb(255,255,255));
                    textView.setTextSize(14);
                    //設定文字居中
                    textView.setGravity(Gravity.CENTER);
                    //設定文字域的範圍
                    textView.setPadding(0, 13, 0, 13);
                    //設定文字在一行內顯示(不換行)
                    textView.setSingleLine(true);
                } else {
                    textView = (TextView) convertView;
                }
                //設定文字文字
                textView.setText(list.get(position));
                //設定文字與圖示的間隔
//                textView.setCompoundDrawablePadding(0);
//                //設定在文字的左邊放一個圖示
//                textView.setCompoundDrawablesWithIntrinsicBounds(R.mipmap., null, null, null);

                return textView;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public Object getItem(int position) {
                return list.get(position);
            }

            @Override
            public int getCount() {
                return list.size();
            }
        });
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

最終效果圖

這裡寫圖片描述

補充:

我是使用xml進行item的佈局的:

<?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"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="140px"
        android:paddingLeft="10dp"
        >
        <ImageView
            android:id="@+id/diy_pop_image"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/diy_popwindow_sort"
            android:adjustViewBounds="true"
            android:layout_gravity="center_vertical"
            />
        <TextView
            android:id="@+id/diy_pop_text"
            android:layout_width="200dp"
            android:layout_height="30dp"
            android:text="選擇排序方式"
            android:textColor="#111"
            android:textSize="15sp"
            android:layout_gravity="center_vertical"
            android:gravity="center_vertical"
            android:layout_marginLeft="20dp"
            />
    </LinearLayout>

</LinearLayout>

而且在進行使用adapter的時候,需要使用item.xml方式:

//設定列表介面卡
        listview.setAdapter(new BaseAdapter() {
            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public Object getItem(int position) {
                return list.get(position);
            }

            @Override
            public int getCount() {
                return list.size();
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ImageView image = null;
                TextView text = null;

                if(convertView==null){
                    convertView = LayoutInflater.from(context).inflate(R.layout.diy_popwindow_item,null);
                    image = (ImageView) convertView.findViewById(R.id.diy_pop_image);
                    text = (TextView) convertView.findViewById(R.id.diy_pop_text);
                }
                image.setImageResource(list.get(position).getImageId());
                text.setText(list.get(position).getText());
               return convertView;
            }
        });