android 点击button 出现popupwindow的二级联动菜单

来源:互联网 发布:制作印章软件 编辑:程序博客网 时间:2024/05/22 14:04

项目中遇到一个popupwindow的二级联动菜单,就花了时间搞了一下。先看一下实现效果。我用真机测试,就简单拍了一张。

Demo结构:


一.布局文件

1.activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <Button        android:id="@+id/btn1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="显示popupwindow" /></RelativeLayout>

2.popupwindow_layout.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="horizontal"     android:id="@+id/popupwindow">    <FrameLayout        android:id="@+id/root_popupwindow"        android:layout_width="0dp"        android:layout_height="200dp"        android:layout_weight="1" >        <ListView            android:id="@+id/root_listview"            android:layout_width="match_parent"            android:layout_height="match_parent"             android:background="#bdbdbd"            android:cacheColorHint="#00000000"            android:listSelector="#00000000"            >        </ListView>    </FrameLayout>    <FrameLayout        android:id="@+id/sub_popupwindow"        android:layout_width="0dp"         android:layout_height="200dp"        android:layout_weight="1"        android:background="#00000000"        >        <ListView            android:id="@+id/sub_listview"            android:layout_width="match_parent"            android:layout_height="match_parent"             android:background="#ffffff"            >        </ListView>    </FrameLayout></LinearLayout>

3.root_listview_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="match_parent"    android:orientation="vertical"     android:id="@+id/root_item">            <TextView        android:gravity="center_vertical"android:layout_marginLeft="20dp"        android:id="@+id/item_name_text"        android:layout_width="wrap_content"        android:layout_height="40dp"        android:text="20sp"        ></TextView></LinearLayout>

二.java代码

1.获取屏幕宽高的工具类

package com.lql.multilistviewdemo;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Rect;import android.util.DisplayMetrics;import android.view.View;import android.view.WindowManager;/** * 鑾峰緱灞忓箷鐩稿叧鐨勮緟鍔╃被 *  * @author zhy *  */public class ScreenUtils{private ScreenUtils(){/* cannot be instantiated */throw new UnsupportedOperationException("cannot be instantiated");}/** * 鑾峰緱灞忓箷楂樺害 *  * @param context * @return */public static int getScreenWidth(Context context){WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.widthPixels;}/** * 鑾峰緱灞忓箷瀹藉害 *  * @param context * @return */public static int getScreenHeight(Context context){WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.heightPixels;}/** * 鑾峰緱鐘舵�佹爮鐨勯珮搴� *  * @param context * @return */public static int getStatusHeight(Context context){int statusHeight = -1;try{Class<?> clazz = Class.forName("com.android.internal.R$dimen");Object object = clazz.newInstance();int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());statusHeight = context.getResources().getDimensionPixelSize(height);} catch (Exception e){e.printStackTrace();}return statusHeight;}/** * 鑾峰彇褰撳墠灞忓箷鎴浘锛屽寘鍚姸鎬佹爮 *  * @param activity * @return */public static Bitmap snapShotWithStatusBar(Activity activity){View view = activity.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bmp = view.getDrawingCache();int width = getScreenWidth(activity);int height = getScreenHeight(activity);Bitmap bp = null;bp = Bitmap.createBitmap(bmp, 0, 0, width, height);view.destroyDrawingCache();return bp;}/** * 鑾峰彇褰撳墠灞忓箷鎴浘锛屼笉鍖呭惈鐘舵�佹爮 *  * @param activity * @return */public static Bitmap snapShotWithoutStatusBar(Activity activity){View view = activity.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bmp = view.getDrawingCache();Rect frame = new Rect();activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;int width = getScreenWidth(activity);int height = getScreenHeight(activity);Bitmap bp = null;bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height- statusBarHeight);view.destroyDrawingCache();return bp;}}

2.RootListViewAdapter.java(根目录ListView适配器)

package com.lql.multilistviewdemo;import android.content.Context;import android.graphics.Color;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.LinearLayout;import android.widget.TextView;/** * 二级目录的根目录的数据适配器 * @author Administrator * */public class RootListViewAdapter extends BaseAdapter {private Context context;private LayoutInflater inflater;private String[] items;private int selectedPosition = -1;public void setSelectedPosition(int selectedPosition) {this.selectedPosition = selectedPosition;}public RootListViewAdapter(Context context){this.context = context;inflater = LayoutInflater.from(context);}public void setItems(String[] items) {this.items = items;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn items.length;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder;if(convertView == null){holder = new ViewHolder();convertView = (View)inflater.inflate(R.layout.root_listview_item, parent , false);holder.item_text =(TextView) convertView.findViewById(R.id.item_name_text);holder.item_layout = (LinearLayout)convertView.findViewById(R.id.root_item);convertView.setTag(holder);}else{holder = (ViewHolder)convertView.getTag();}/** * 该项被选中时改变背景色 */if(selectedPosition == position){//Drawable item_bg = new ColorDrawable(R.color.sub_list_color);holder.item_layout.setBackgroundColor(Color.WHITE);}else{//Drawable item_bg = new ColorDrawable(R.color.sub_list_color);holder.item_layout.setBackgroundColor(Color.TRANSPARENT);}holder.item_text.setText(items[position]);return convertView;}class ViewHolder{TextView item_text;LinearLayout item_layout;}}

3.SubListViewAdapter.java

package com.lql.multilistviewdemo;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;/** * 二级目录的子目录的数据适配器 * @author Administrator * */public class SubListViewAdapter extends BaseAdapter {private String[][] sub_items;private Context context;private int root_position;private LayoutInflater inflater;public SubListViewAdapter(Context context, String[][] sub_items,int position) {this.context = context;inflater = LayoutInflater.from(context);this.sub_items = sub_items;this.root_position = position;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn sub_items[root_position].length;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn sub_items[root_position][position];}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder;if (convertView == null) {holder = new ViewHolder();convertView = (View) inflater.inflate(R.layout.root_listview_item,parent, false);holder.item_text = (TextView) convertView.findViewById(R.id.item_name_text);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}holder.item_text.setText(sub_items[root_position][position]);return convertView;}class ViewHolder{TextView item_text;}}

4.MainActivity.java

package com.lql.multilistviewdemo;import android.app.Activity;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup.LayoutParams;import android.widget.AdapterView;import android.widget.Button;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.PopupWindow;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener {private Button showPopBtn;/** * popupwindow *  */private PopupWindow mPopupWindow;/** * 二级菜单的根目录 */private ListView rootListView;/** * 根目录的节点 */private String[] roots = new String[] { "附近", "排序", "筛选" };/** * 子目录节点 */private String[][] sub_items = new String[][] {new String[] { "海淀区", "西城区", "石景山区", "东城区", "朝阳区" },new String[] { "离我最近", "人气最高", "评价最好", "人均最低", "人均最高" },new String[] { "全部类型", "优惠券商户", "闪惠商户", "预约服务", "上门服务" } };private ListView subListView;/** * 弹出的popupWindow布局 */private LinearLayout popupLayout;/** * 子目录的布局 */private FrameLayout subLayout;/** * 根目录被选中的节点 */private int selectedPosition;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);showPopBtn = (Button) findViewById(R.id.btn1);showPopBtn.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.btn1:showPopBtn(ScreenUtils.getScreenWidth(MainActivity.this),ScreenUtils.getScreenHeight(MainActivity.this));break;default:break;}}private void showPopBtn(int screenWidth, int screenHeight) {// TODO Auto-generated method stubLayoutInflater inflater = LayoutInflater.from(MainActivity.this);popupLayout = (LinearLayout) inflater.inflate(R.layout.popupwindow_layout, null, false);rootListView = (ListView) popupLayout.findViewById(R.id.root_listview);final RootListViewAdapter adapter = new RootListViewAdapter(MainActivity.this);adapter.setItems(roots);rootListView.setAdapter(adapter);/** * 子popupWindow */subLayout = (FrameLayout) popupLayout.findViewById(R.id.sub_popupwindow);/** * 初始化subListview */subListView = (ListView) popupLayout.findViewById(R.id.sub_listview);/** * 弹出popupwindow时,二级菜单默认隐藏,当点击某项时,二级菜单再弹出 */subLayout.setVisibility(View.INVISIBLE);/** * 初始化mPopupWindow */mPopupWindow = new PopupWindow(popupLayout, screenWidth,LayoutParams.WRAP_CONTENT, true);/** * 有了mPopupWindow.setBackgroundDrawable(new BitmapDrawable()); * 这句可以使点击popupwindow以外的区域时popupwindow自动消失 但这句必须放在showAsDropDown之前 */mPopupWindow.setBackgroundDrawable(new BitmapDrawable());/** * popupwindow的位置,第一个参数表示位于哪个控件之下 第二个参数表示向左右方向的偏移量,正数表示向左偏移,负数表示向右偏移 * 第三个参数表示向上下方向的偏移量,正数表示向下偏移,负数表示向上偏移 *  */mPopupWindow.showAsDropDown(showPopBtn, -5, 5);// 在控件下方显示popwindowmPopupWindow.update();rootListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {// TODO Auto-generated method stub/** * 选中root某项时改变该ListView item的背景色 */adapter.setSelectedPosition(position);adapter.notifyDataSetInvalidated();selectedPosition = position;SubListViewAdapter subAdapter = new SubListViewAdapter(MainActivity.this, sub_items, position);subListView.setAdapter(subAdapter);/** * 选中某个根节点时,使显示相应的子目录可见 */subLayout.setVisibility(View.VISIBLE);subListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {// TODO Auto-generated method stubpopupLayout.setVisibility(View.GONE);Toast.makeText(MainActivity.this,sub_items[selectedPosition][position],Toast.LENGTH_SHORT).show();}});}});}}

color文件中有两个color项,很简单就不单独贴出了

3 0