Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.ui;
     18 
     19 import android.content.Context;
     20 import android.graphics.Rect;
     21 import android.view.LayoutInflater;
     22 import android.view.View;
     23 import android.view.View.MeasureSpec;
     24 import android.view.ViewGroup;
     25 import android.view.ViewTreeObserver;
     26 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
     27 import android.widget.AdapterView;
     28 import android.widget.AdapterView.OnItemClickListener;
     29 import android.widget.BaseAdapter;
     30 import android.widget.ListView;
     31 import android.widget.PopupWindow;
     32 import android.widget.TextView;
     33 
     34 import com.android.gallery3d.R;
     35 
     36 import java.util.ArrayList;
     37 
     38 public class PopupList {
     39 
     40     public static interface OnPopupItemClickListener {
     41         public boolean onPopupItemClick(int itemId);
     42     }
     43 
     44     public static class Item {
     45         public final int id;
     46         public String title;
     47 
     48         public Item(int id, String title) {
     49             this.id = id;
     50             this.title = title;
     51         }
     52 
     53         public void setTitle(String title) {
     54             this.title = title;
     55         }
     56     }
     57 
     58     private final Context mContext;
     59     private final View mAnchorView;
     60     private final ArrayList<Item> mItems = new ArrayList<Item>();
     61     private PopupWindow mPopupWindow;
     62     private ListView mContentList;
     63     private OnPopupItemClickListener mOnPopupItemClickListener;
     64     private int mPopupOffsetX;
     65     private int mPopupOffsetY;
     66     private int mPopupWidth;
     67     private int mPopupHeight;
     68 
     69     public PopupList(Context context, View anchorView) {
     70         mContext = context;
     71         mAnchorView = anchorView;
     72     }
     73 
     74     public void setOnPopupItemClickListener(OnPopupItemClickListener listener) {
     75         mOnPopupItemClickListener = listener;
     76     }
     77 
     78     public void addItem(int id, String title) {
     79         mItems.add(new Item(id, title));
     80     }
     81 
     82     public void clearItems() {
     83         mItems.clear();
     84     }
     85 
     86     private final PopupWindow.OnDismissListener mOnDismissListener =
     87             new PopupWindow.OnDismissListener() {
     88         @SuppressWarnings("deprecation")
     89         @Override
     90         public void onDismiss() {
     91             if (mPopupWindow == null) return;
     92             mPopupWindow = null;
     93             ViewTreeObserver observer = mAnchorView.getViewTreeObserver();
     94             if (observer.isAlive()) {
     95                 // We used the deprecated function for backward compatibility
     96                 // The new "removeOnGlobalLayoutListener" is introduced in API level 16
     97                 observer.removeGlobalOnLayoutListener(mOnGLobalLayoutListener);
     98             }
     99         }
    100     };
    101 
    102     private final OnItemClickListener mOnItemClickListener =
    103             new OnItemClickListener() {
    104         @Override
    105         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    106             if (mPopupWindow == null) return;
    107             mPopupWindow.dismiss();
    108             if (mOnPopupItemClickListener != null) {
    109                 mOnPopupItemClickListener.onPopupItemClick((int) id);
    110             }
    111         }
    112     };
    113 
    114     private final OnGlobalLayoutListener mOnGLobalLayoutListener =
    115             new OnGlobalLayoutListener() {
    116         @Override
    117         public void onGlobalLayout() {
    118             if (mPopupWindow == null) return;
    119             updatePopupLayoutParams();
    120             // Need to update the position of the popup window
    121             mPopupWindow.update(mAnchorView,
    122                     mPopupOffsetX, mPopupOffsetY, mPopupWidth, mPopupHeight);
    123         }
    124     };
    125 
    126     public void show() {
    127         if (mPopupWindow != null) return;
    128         mAnchorView.getViewTreeObserver()
    129                 .addOnGlobalLayoutListener(mOnGLobalLayoutListener);
    130         mPopupWindow = createPopupWindow();
    131         updatePopupLayoutParams();
    132         mPopupWindow.setWidth(mPopupWidth);
    133         mPopupWindow.setHeight(mPopupHeight);
    134         mPopupWindow.showAsDropDown(mAnchorView, mPopupOffsetX, mPopupOffsetY);
    135     }
    136 
    137     private void updatePopupLayoutParams() {
    138         ListView content = mContentList;
    139         PopupWindow popup = mPopupWindow;
    140 
    141         Rect p = new Rect();
    142         popup.getBackground().getPadding(p);
    143 
    144         int maxHeight = mPopupWindow.getMaxAvailableHeight(mAnchorView) - p.top - p.bottom;
    145         mContentList.measure(
    146                 MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
    147                 MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST));
    148         mPopupWidth = content.getMeasuredWidth() + p.top + p.bottom;
    149         mPopupHeight = Math.min(maxHeight, content.getMeasuredHeight() + p.left + p.right);
    150         mPopupOffsetX = -p.left;
    151         mPopupOffsetY = -p.top;
    152     }
    153 
    154     private PopupWindow createPopupWindow() {
    155         PopupWindow popup = new PopupWindow(mContext);
    156         popup.setOnDismissListener(mOnDismissListener);
    157 
    158         popup.setBackgroundDrawable(mContext.getResources().getDrawable(
    159                 R.drawable.menu_dropdown_panel_holo_dark));
    160 
    161         mContentList = new ListView(mContext, null,
    162                 android.R.attr.dropDownListViewStyle);
    163         mContentList.setAdapter(new ItemDataAdapter());
    164         mContentList.setOnItemClickListener(mOnItemClickListener);
    165         popup.setContentView(mContentList);
    166         popup.setFocusable(true);
    167         popup.setOutsideTouchable(true);
    168 
    169         return popup;
    170     }
    171 
    172     public Item findItem(int id) {
    173         for (Item item : mItems) {
    174             if (item.id == id) return item;
    175         }
    176         return null;
    177     }
    178 
    179     private class ItemDataAdapter extends BaseAdapter {
    180         @Override
    181         public int getCount() {
    182             return mItems.size();
    183         }
    184 
    185         @Override
    186         public Object getItem(int position) {
    187             return mItems.get(position);
    188         }
    189 
    190         @Override
    191         public long getItemId(int position) {
    192             return mItems.get(position).id;
    193         }
    194 
    195         @Override
    196         public View getView(int position, View convertView, ViewGroup parent) {
    197             if (convertView == null) {
    198                 convertView = LayoutInflater.from(mContext)
    199                         .inflate(R.layout.popup_list_item, null);
    200             }
    201             TextView text = (TextView) convertView.findViewById(android.R.id.text1);
    202             text.setText(mItems.get(position).title);
    203             return convertView;
    204         }
    205     }
    206 }
    207