android自定义PopupWindow组件

android自定义PopupWindow组件

      在移动开发过程中,有时我们需要设置一个弹出框做为菜单,如微信中弹出框。为了达到这个效果,可以自定义PopupWindow组件来完成,笔者简单自定义了这个
组件。

    先来看看效果图:

 

 

      下面是代码部分:

      activity_main.xml 

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

    <LinearLayout
        android:id="@+id/fragmentsyllabus_Topmain"
        android:layout_width="fill_parent"
        android:layout_height="45dip"
        android:background="@drawable/mmtitle_bg_alpha"
        android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="100dp"
            android:layout_height="45dp"
            
            android:layout_weight="1"
            android:orientation="vertical" >

            <ImageView
                android:id="@+id/mainTop_SettingIR"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_gravity="right|center_vertical"
                android:layout_marginRight="30dp"
                android:clickable="true"
                android:src="@drawable/mainmenu_selector" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

example_popup.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:background="@drawable/title_function_bg"
    android:orientation="vertical" >  
  
    <ListView  
        android:id="@+id/title_list"  
        android:layout_width="160dp"  
        android:layout_height="fill_parent"  
        android:cacheColorHint="#123456"  
        android:divider="@drawable/mm_title_functionframe_line"  
        android:listSelector="@drawable/title_list_selector"  
        android:padding="3dp"  
        android:scrollingCache="false" />  
  
</LinearLayout>  

自定义PopWindow

package com.example.popupwindowtest;

import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

@SuppressLint("InflateParams")
public class ExamplePopupWindow extends PopupWindow{

	private Context context;
	
	//屏幕的宽、高
	@SuppressWarnings("unused")
	private int screenWidth,screenHeight;
	//弹出框的位置
	private final int[] location = new int[2];
	//定义矩形
	private Rect rect = new Rect();
	
	private ListView listView;
	
	private int popupGravity = Gravity.NO_GRAVITY;
	
	private OnItemOnClickListener itemOnClickListener;
	
	//选项集合
	private ArrayList<ActionItem> actionItems = new ArrayList<ActionItem>();
	private boolean isDirty = false;
	
	//用于设置选中或取消
	private ImageView choice;
	
	public void setImageCon(ImageView choice){
		this.choice = choice;
	}
	
	public ExamplePopupWindow(Context context,int width,int height){
		this.context = context;
		//设置弹出窗体的宽
		this.setWidth(width);
		//设置弹出窗体的高
		this.setHeight(height);
		//设置窗体可击点
		this.setFocusable(true);
		this.setTouchable(true);
		this.setOutsideTouchable(true);
		//点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作
		this.setBackgroundDrawable(new ColorDrawable());
		screenWidth = Util.getScreenWidth(context);
		screenHeight = Util.getScreenHeight(context);
		//添加窗体的控件
		this.setContentView(LayoutInflater.from(context).inflate(R.layout.example_popup, null));
		
		initUI();
		
		//当窗体消失时回调该接口
		this.setOnDismissListener(new OnDismissListener() {

	        @Override
		    public void onDismiss() {
				// TODO Auto-generated method stub
				choice.setSelected(false);
			}
		});
	}
	
	private void initUI(){
		listView = (ListView)this.getContentView().findViewById(R.id.title_list);
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// TODO Auto-generated method stub
				dismiss();
				//Main_Activity才能获得actionItem对象
				if (itemOnClickListener != null)
					itemOnClickListener.onItemClick(actionItems.get(arg2),arg2);
			}
		});
	}
	
	public void show(View view){
		view.getLocationOnScreen(location);
		//只是为了得到底边Y值
		rect.set(location[0], location[1], location[0] + view.getWidth(),
				location[1] + view.getHeight());
		if (isDirty) {
			populateActions();
		}
		//设置窗体的位置
		showAtLocation(view, popupGravity, screenWidth - (getWidth() / 2),
				rect.bottom);
		choice.setSelected(true);
	}
	
	private void populateActions() {
		isDirty = false;
		listView.setAdapter(new BaseAdapter() {
			
			@Override
			public View getView(int arg0, View arg1, ViewGroup arg2) {
				// TODO Auto-generated method stub
				TextView textView = null;
				if (arg1 == null) {
					textView = new TextView(context);
					textView.setTextColor(context.getResources().getColor(
							android.R.color.white));
					textView.setTextSize(14);
					// 设置文本居中
					textView.setGravity(Gravity.CENTER);
					// 设置文本域的范围
					textView.setPadding(0, 10, 0, 10);
					// 设置文本在一行内显示(不换行)
					textView.setSingleLine(true);
				} else {
					textView = (TextView) arg1;
				}

				ActionItem item = actionItems.get(arg0);

				// 设置文本文字
				textView.setText(item.mTitle);
				// 设置文字与图标的间隔
				textView.setCompoundDrawablePadding(10);
				// 设置在文字的左边放一个图标

				textView.setCompoundDrawablesWithIntrinsicBounds(
						item.mDrawable, null, null, null);
				// ///
				// 注意这段代码一定要写到上面那行代码的下面 要不然 就没有效果

				return textView;
			}
			
			@Override
			public long getItemId(int arg0) {
				// TODO Auto-generated method stub
				return arg0;
			}
			
			@Override
			public Object getItem(int arg0) {
				// TODO Auto-generated method stub
				return actionItems.get(arg0);
			}
			
			@Override
			public int getCount() {
				// TODO Auto-generated method stub
				return actionItems.size();
			}
		});
	}
	
	public void addAction(ActionItem action) {
		if (action != null) {
			actionItems.add(action);
			isDirty = true;
		}
	}
	
	public void cleanAction() {
		if (actionItems.isEmpty()) {
			actionItems.clear();
			isDirty = true;
		}
	}
	
	public ActionItem getAction(int position) {
		if (position < 0 || position > actionItems.size())
			return null;
		return actionItems.get(position);
	}
	
	public void setItemOnClickListener(
			OnItemOnClickListener onItemOnClickListener) {
		this.itemOnClickListener = onItemOnClickListener;
	}
	
	public static interface OnItemOnClickListener{
		public void onItemClick(ActionItem item, int position);
	}
}


ActionItem类

package com.example.popupwindowtest;

import android.content.Context;
import android.graphics.drawable.Drawable;

public class ActionItem {
	// 定义图片对象
	public Drawable mDrawable;
	// 定义文本对象
	public CharSequence mTitle;

	public ActionItem(Drawable drawable, CharSequence title) {
		this.mDrawable = drawable;
		this.mTitle = title;
	}

	public ActionItem(Context context, int titleId, int drawableId) {
		this.mTitle = context.getResources().getText(titleId);
		this.mDrawable = context.getResources().getDrawable(drawableId);
	}

	public ActionItem(Context context, CharSequence title, int drawableId) {
		this.mTitle = title;
		this.mDrawable = context.getResources().getDrawable(drawableId);

	}
}


Util类

package com.example.popupwindowtest;

import android.content.Context;  

public class Util {  
    /** 
     * 得到设备屏幕的宽度 
     */  
    public static int getScreenWidth(Context context) {  
        return context.getResources().getDisplayMetrics().widthPixels;  
    }  
  
    /** 
     * 得到设备屏幕的高度 
     */  
    public static int getScreenHeight(Context context) {  
        return context.getResources().getDisplayMetrics().heightPixels;  
    }  
  
    /** 
     * 得到设备的密度 
     */  
    public static float getScreenDensity(Context context) {  
        return context.getResources().getDisplayMetrics().density;  
    }  
  
    /** 
     * 把密度转换为像素 
     */  
    public static int dip2px(Context context, float px) {  
        final float scale = getScreenDensity(context);  
        return (int) (px * scale + 0.5);  
    }  
}  


MainActivity类

package com.example.popupwindowtest;

import com.example.popupwindowtest.ExamplePopupWindow.OnItemOnClickListener;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;

public class MainActivity extends Activity{

	private ExamplePopupWindow examplePopupWindow;
	private ImageView imageView;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		examplePopupWindow = new ExamplePopupWindow(getApplicationContext(),LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
		examplePopupWindow.addAction(new ActionItem(getApplicationContext(), "选项1", R.drawable.capture_topmenu));
		examplePopupWindow.addAction(new ActionItem(getApplicationContext(), "选项2", R.drawable.capture_topmenu));
		examplePopupWindow.addAction(new ActionItem(getApplicationContext(), "选项3", R.drawable.capture_topmenu));
		examplePopupWindow.setItemOnClickListener(new OnItemOnClickListener(){

			@Override
			public void onItemClick(ActionItem item, int position) {
				// TODO Auto-generated method stub
				switch (position) {
				case 0:	
					System.out.println(item.mTitle);
					break;
				case 1:
					System.out.println(item.mTitle);
					break;
				case 3:
					System.out.println(item.mTitle);
					break;
				}
			}
			
		});
		imageView = (ImageView)this.findViewById(R.id.mainTop_SettingIR);
		imageView.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				examplePopupWindow.setImageCon(imageView);
				examplePopupWindow.show(arg0);
			}
		});
	}

}


源码下载地址:http://download.csdn.net/detail/hardor/9105109

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当您需要更高级的弹窗样式和交互时,可以使用 PopupWindow 来创建自定义布局的弹窗。下面是使用 PopupWindow 创建自定义布局的步骤: 1. 创建自定义布局文件:首先,创建一个 XML 文件来定义您的自定义布局。例如,您可以创建一个名为 `custom_popup.xml` 的文件,并在其中定义您希望显示的布局。 2. 实例化 PopupWindow:在您的 Activity 或 Fragment 中,实例化 PopupWindow 对象。 ```java LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View customView = inflater.inflate(R.layout.custom_popup, null); PopupWindow popupWindow = new PopupWindow(customView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ``` 3. 设置 PopupWindow 属性:根据需要,设置 PopupWindow 的属性,例如背景、动画效果、焦点等。 ```java popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); popupWindow.setFocusable(true); // 设置动画效果 popupWindow.setAnimationStyle(R.style.PopupAnimation); ``` 4. 设置布局中的控件和事件:通过 `customView` 获取布局中的控件,并设置相应的事件监听器。 ```java Button button = customView.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 处理点击事件 } }); ``` 5. 显示弹窗:使用 `showAtLocation()` 或 `showAsDropDown()` 方法显示弹窗。`showAtLocation()` 方法可以显示在指定的位置,而 `showAsDropDown()` 方法则可以显示在某个视图的下方。 ```java View anchorView = findViewById(R.id.anchor_view); // 锚点视图 popupWindow.showAsDropDown(anchorView); // 或者使用 showAtLocation() 方法 ``` 这样,您就可以使用 PopupWindow 创建自定义布局的弹窗。希望对您有所帮助!如果有任何问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值