[view] 06_下拉菜单(使用PopupWindow+ListView实现)

Android 4.0

下拉菜单 (使用PopupWindow+ListView实现)

popupwindow中showAtLocation和showAsDropDown区别
实现以下类似的下拉效果:

1、布局
a) activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <EditText
        android:id="@+id/et_number"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:ems="12"
        android:hint="请输入账号"
        android:inputType="number" >
        <requestFocus />
    </EditText>
    <Button
        android:id="@+id/bt"
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:layout_alignBottom="@id/et_number"
        android:layout_alignRight="@id/et_number"
        android:layout_alignTop="@id/et_number"
        android:background="@drawable/button"
        android:gravity="center" />
</RelativeLayout>  
b) qq_list_item.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="wrap_content"
    android:gravity="center_vertical"
    android:orientation="vertical" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <ImageView
            android:id="@+id/iv_user_header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:clickable="false"
            android:focusable="false"
            android:src="@drawable/user" />
        <TextView
            android:id="@+id/tv_qq_number"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_weight="10"
            android:gravity="center"
            android:text="qq号码" />
        <ImageButton
            android:id="@+id/ib_delete"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="10dp"
            android:layout_weight="1"
            android:background="@drawable/delete" />
        <!-- android:src="@drawable/delete"不要用src,有背景图标 -->
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="#33000000" />
</LinearLayout>
2、核心代码:
package cn.zengfansheng.pulldownMenu;
 
import java.util.ArrayList;
import java.util.Random;
 
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
 
public class MainActivity extends Activity implements OnClickListener {
 
    private EditText et_number;
    private Button bt;
 
    private MyAdapter adapter;// 数据适配器
 
    private ArrayList<Integer> qqList;// qq列表
    private PopupWindow popupWindow;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        et_number = (EditText) this.findViewById(R.id.et_number);
        bt = (Button) this.findViewById(R.id.bt);
 
        bt.setOnClickListener(this);
 
        // et_number还没有渲染完毕,获取不到值,为0
        // int et_height = et_number.getHeight();
        // System.out.println(et_height);
 
        qqList = new ArrayList<Integer>();
        for (int i = 0; i < 20; i++) {
            Random random = new Random();
            int nextInt = random.nextInt(89999);
            qqList.add(10000 + nextInt);
        }
    }
 
    @Override
    public void onClick(View v) {
 
        if (popupWindow==null) {
 
            // 点击按钮时,弹出一个PopupWindow
            //PopupWindow popupWindow = new PopupWindow(contentView, width, height, focusable)
 
            // 1、new一个PopupWindow
            ListView contentView = new ListView(getApplicationContext());
            contentView.setCacheColorHint(0x00000000);
            if (adapter == null) {
                adapter = new MyAdapter();
            }
            contentView.setAdapter(adapter);
 
            popupWindow = new PopupWindow(contentView ,et_number.getWidth(), LayoutParams.WRAP_CONTENT, true);
 
            // 2、设置PopupWindow的背景图片,很有必要,以为没有设置背景,动画播放不了
            popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
 
            // 3、设置PopupWindow显示的位置
            // 3-1、对齐方式
            //int gravity1 = Gravity.NO_GRAVITY;//相当于Gravity.LEFT | Gravity.TOP
            //int gravity = Gravity.LEFT + Gravity.TOP;// 51
 
            // 3-2、显示的位置,0为x轴,1为y轴
            //int[] location = new int[2];
            //et_number.getLocationInWindow(location);
            //int et_height = et_number.getHeight();
            // LayoutParams params = et_number.getLayoutParams();
            // int height = params.height;
 
            // 3-3、依赖的父窗体
            // ViewParent parent = bt.getParent();
            //View parent = this.findViewById(R.id.rl);
        }
        //popupWindow.showAtLocation(parent, gravity, location[0], et_height+location[1]);
        popupWindow.showAsDropDown(et_number, 0, 0);
    }
    private class MyAdapter extends BaseAdapter{
 
        @Override
        public int getCount() {
            if (qqList != null) {
                return qqList.size();
            }
            return 0;
        }
        @Override
        public Object getItem(int position) {
            return null;
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
 
            LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
            View view = null;
            ViewHolder viewHolder = null;
            if (convertView != null && convertView instanceof LinearLayout) {
                view = convertView;
                viewHolder = (ViewHolder) view.getTag();
            } else {
 
                view = inflater.inflate(R.layout.qq_list_item, null);
 
                viewHolder = new ViewHolder();
                //viewHolder.iv_header = (ImageView) view.findViewById(R.id.iv_user_header);
                viewHolder.tv_number = (TextView) view.findViewById(R.id.tv_qq_number);
                viewHolder.tv_number.setOnClickListener(new OnClickListener() {
 
                    @Override
                    public void onClick(View v) {
                        int qqnumber = qqList.get(position);
                        et_number.setText(String.valueOf(qqnumber));
                        popupWindow.dismiss();
                    }
                });
 
                viewHolder.ib_delete = (ImageButton) view.findViewById(R.id.ib_delete);
                viewHolder.ib_delete.setOnClickListener(new OnClickListener() {
 
                    @Override
                    public void onClick(View v) {
                        // 将该行记录给删除
                        qqList.remove(position);
                        adapter.notifyDataSetChanged();
                    }
                });
 
                view.setTag(viewHolder);
            }
 
            int qq = qqList.get(position);
            viewHolder.tv_number.setText("" + qq);
            return view;
        }
    }
    private static class ViewHolder {
        //private ImageView iv_header;
        private TextView tv_number;
        private ImageButton ib_delete;
    }
}
结果:

问题: 

分析:由于使用PopupWindow使用了下面这句
View parent = View.inflate(getApplicationContext(), R.layout.qq_list_itemnull);  
popupWindow.showAtLocation(parent, gravity, location[0], et_height+location[1]); 
解决:
View parent = this.findViewById(R.id.rl);
注意:
ViewParent parent = bt.getParent();返回的不是View而是ViewParent