您的位置:首页 > 移动开发 > Android开发

Android PopupWindow实现从顶部弹出下拉菜单左、中、右

2015-10-19 19:08 633 查看
本实例的自定义下拉菜单主要是继承PopupWindow类来实现的弹出窗体,各种布局效果可以根据自己定义设计。弹出的动画效果主要用到了translate、alpha、scale,具体实现步骤如下:

先上效果图如下:左边下拉菜单、中间下拉菜单、右边下拉菜单







1.主界面布局 activity_main.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"
android:background="#ffffff" >

<include
android:id="@+id/main_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/urm_top" />

<TextView
android:id="@+id/rule_line_tv"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@id/main_top"
android:background="@color/reserve_line" />

<LinearLayout
android:id="@+id/main_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/rule_line_tv"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp" >

<TextView
android:id="@+id/left_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_horizontal"
android:maxLength="4"
android:singleLine="true"
android:text="我负责的线索" />

<TextView
android:id="@+id/middle_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_horizontal"
android:maxLength="4"
android:singleLine="true"
android:text="团队" />

<TextView
android:id="@+id/right_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_horizontal"
android:maxLength="4"
android:singleLine="true"
android:text="自定义" />
</LinearLayout>

<TextView
android:id="@+id/rule_line01_tv"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@id/main_ll"
android:background="@color/reserve_line" />

<TextView
android:id="@+id/main_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="主界面" />

</RelativeLayout>


2.主界面测试类 MainActivity.java

package com.popuptest;

import java.util.ArrayList;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.RelativeLayout.LayoutParams;
import android.app.Activity;

public class MainActivity extends Activity implements OnClickListener {

public static int screenW, screenH;

private ImageButton backBtn, createBtn;
private Button confirmBtn;
private TextView topTv;
private LinearLayout topll;
private ImageView topIv;
private TextView topLineTv;

private TopMiddlePopup middlePopup;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
getScreenPixels();
initWidget();
}

/**
* 初始化控件
*/
private void initWidget() {
backBtn = (ImageButton) findViewById(R.id.urm_back_btn);
createBtn = (ImageButton) findViewById(R.id.urm_create_btn);
confirmBtn = (Button) findViewById(R.id.urm_confirm_btn);

topll = (LinearLayout) findViewById(R.id.urm_top_ll);
topIv = (ImageView) findViewById(R.id.urm_top_iv);

topLineTv = (TextView) findViewById(R.id.rule_line_tv);

topTv = (TextView) findViewById(R.id.urm_top_tv);
topTv.setText("企业客户");

backBtn.setOnClickListener(this);
createBtn.setOnClickListener(this);
confirmBtn.setOnClickListener(this);
topll.setOnClickListener(this);

}

/**
* 设置弹窗
*
* @param type
*/
private void setPopup(int type) {
middlePopup = new TopMiddlePopup(MainActivity.this, screenW, screenH,
onItemClickListener, getItemsName(), type);
}

/**
* 设置弹窗内容
*
* @return
*/
private ArrayList<String> getItemsName() {
ArrayList<String> items = new ArrayList<String>();
items.add("企业客户");
items.add("集团客户");
items.add("公海客户");
return items;
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.urm_back_btn:
setPopup(1);
middlePopup.show(topLineTv);
break;
case R.id.urm_create_btn:
setPopup(2);
middlePopup.show(topLineTv);
break;
case R.id.urm_confirm_btn:

break;
case R.id.urm_top_ll:
setPopup(0);
middlePopup.show(topLineTv);
break;
}
}

/**
* 弹窗点击事件
*/
private OnItemClickListener onItemClickListener = new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
System.out.println("--onItemClickListener--:");
middlePopup.dismiss();
}
};

/**
* 获取屏幕的宽和高
*/
public void getScreenPixels() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenW = metrics.widthPixels;
screenH = metrics.heightPixels;
}

}


3.自定义弹窗类 TopMiddlePopup.java

package com.popuptest;

import java.util.ArrayList;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.AdapterView.OnItemClickListener;

public class TopMiddlePopup extends PopupWindow {

private Context myContext;
private ListView myLv;
private OnItemClickListener myOnItemClickListener;
private ArrayList<String> myItems;
private int myWidth;
private int myHeight;
private int myType;

// 判断是否需要添加或更新列表子类项
private boolean myIsDirty = true;

private LayoutInflater inflater = null;
private View myMenuView;

private LinearLayout popupLL;

private PopupAdapter adapter;

public TopMiddlePopup(Context context) {
// TODO Auto-generated constructor stub
}

public TopMiddlePopup(Context context, int width, int height,
OnItemClickListener onItemClickListener, ArrayList<String> items,
int type) {

inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myMenuView = inflater.inflate(R.layout.top_popup, null);

this.myContext = context;
this.myItems = items;
this.myOnItemClickListener = onItemClickListener;
this.myType = type;

this.myWidth = width;
this.myHeight = height;

System.out.println("--myWidth--:" + myWidth + "--myHeight--:"
+ myHeight);
initWidget();
setPopup();
}

/**
* 初始化控件
*/
private void initWidget() {
myLv = (ListView) myMenuView.findViewById(R.id.popup_lv);
popupLL = (LinearLayout) myMenuView.findViewById(R.id.popup_layout);
myLv.setOnItemClickListener(myOnItemClickListener);

if (myType == 1) {
android.widget.RelativeLayout.LayoutParams lpPopup = (android.widget.RelativeLayout.LayoutParams) popupLL
.getLayoutParams();
lpPopup.width = (int) (myWidth * 1.0 / 4);
lpPopup.setMargins(0, 0, (int) (myWidth * 3.0 / 4), 0);
popupLL.setLayoutParams(lpPopup);
} else if (myType == 2) {
android.widget.RelativeLayout.LayoutParams lpPopup = (android.widget.RelativeLayout.LayoutParams) popupLL
.getLayoutParams();
lpPopup.width = (int) (myWidth * 1.0 / 4);
lpPopup.setMargins((int) (myWidth * 3.0 / 4), 0, 0, 0);
popupLL.setLayoutParams(lpPopup);
}
}

/**
* 设置popup的样式
*/
private void setPopup() {
// 设置AccessoryPopup的view
this.setContentView(myMenuView);
// 设置AccessoryPopup弹出窗体的宽度
this.setWidth(LayoutParams.MATCH_PARENT);
// 设置AccessoryPopup弹出窗体的高度
this.setHeight(LayoutParams.MATCH_PARENT);
// 设置AccessoryPopup弹出窗体可点击
this.setFocusable(true);
// 设置AccessoryPopup弹出窗体的动画效果
if (myType == 1) {
this.setAnimationStyle(R.style.AnimTopLeft);
} else if (myType == 2) {
this.setAnimationStyle(R.style.AnimTopRight);
} else {
//this.setAnimationStyle(R.style.AnimTop);
this.setAnimationStyle(R.style.AnimTopMiddle);
}
// 实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0x33000000);
// 设置SelectPicPopupWindow弹出窗体的背景
this.setBackgroundDrawable(dw);

myMenuView.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {

int height = popupLL.getBottom();
int left = popupLL.getLeft();
int right = popupLL.getRight();
System.out.println("--popupLL.getBottom()--:"
+ popupLL.getBottom());
int y = (int) event.getY();
int x = (int) event.getX();
if (event.getAction() == MotionEvent.ACTION_UP) {
if (y > height || x < left || x > right) {
System.out.println("---点击位置在列表下方--");
dismiss();
}
}
return true;
}
});
}

/**
* 显示弹窗界面
*
* @param view
*/
public void show(View view) {
if (myIsDirty) {
myIsDirty = false;
adapter = new PopupAdapter(myContext, myItems, myType);
myLv.setAdapter(adapter);
}

showAsDropDown(view, 0, 0);
}

}


4.自定义弹窗布局 top_popup.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout
android:id="@+id/popup_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#ffffff"
android:orientation="vertical" >

<ListView
android:id="@+id/popup_lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/content_line"
android:dividerHeight="0.5dp" >
</ListView>

<TextView
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/reserve_line" />
</LinearLayout>

</RelativeLayout>


5.弹窗类表适配器类 PopupAdapter

package com.popuptest;

import java.util.ArrayList;
import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

public class PopupAdapter extends BaseAdapter {
private Context myContext;
private LayoutInflater inflater;
private ArrayList<String> myItems;
private int myType;

public PopupAdapter(Context context, ArrayList<String> items, int type) {
this.myContext = context;
this.myItems = items;
this.myType = type;

inflater = LayoutInflater.from(myContext);

}

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

@Override
public String getItem(int position) {
return myItems.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
PopupHolder holder = null;
if (convertView == null) {
holder = new PopupHolder();
convertView = inflater.inflate(R.layout.top_popup_item, null);
holder.itemNameTv = (TextView) convertView
.findViewById(R.id.popup_tv);
if (myType == 0) {
holder.itemNameTv.setGravity(Gravity.CENTER);
} else if (myType == 1) {
holder.itemNameTv.setGravity(Gravity.LEFT);
} else if (myType == 2) {
holder.itemNameTv.setGravity(Gravity.RIGHT);
}
convertView.setTag(holder);
} else {
holder = (PopupHolder) convertView.getTag();
}
String itemName = getItem(position);
holder.itemNameTv.setText(itemName);
return convertView;
}

private class PopupHolder {
TextView itemNameTv;
}

}


6.子item布局 top_popup_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:padding="10dp" >

<TextView
android:id="@+id/popup_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/urm_tv"/>

</RelativeLayout>


7.主界面顶部布局 urm_top.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#eeeeee" >

<ImageButton
android:id="@+id/urm_back_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="@null"
android:contentDescription="@string/app_name"
android:src="@drawable/back" />

<LinearLayout
android:id="@+id/urm_top_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_vertical"
android:orientation="horizontal" >

<TextView
android:id="@+id/urm_top_tv"
style="@style/main_tv_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="企业客户" />

<ImageView
android:id="@+id/urm_top_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@null"
android:contentDescription="@string/app_name"
android:src="@drawable/switch02" />
</LinearLayout>

<RelativeLayout
android:id="@+id/urm_top_right_rl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" >

<ImageButton
android:id="@+id/urm_create_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:contentDescription="@string/app_name"
android:src="@drawable/btn_add_2x" />

<Button
android:id="@+id/urm_confirm_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:gravity="center_vertical"
android:padding="10dp"
android:text="确定"
android:textColor="@color/blue2"
android:textSize="18sp"
android:visibility="gone" />
</RelativeLayout>

<ImageButton
android:id="@+id/urm_search_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/urm_top_right_rl"
android:background="@null"
android:contentDescription="@string/app_name"
android:src="@drawable/search"
android:visibility="gone" />

</RelativeLayout>


8.styles.xml文件

<resources>

<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>

<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>

<style name="AnimTop" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/push_top_in</item>
<item name="android:windowExitAnimation">@anim/push_top_out</item>
</style>

<style name="AnimTopRight" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/top_right_in</item>
<item name="android:windowExitAnimation">@anim/top_right_out</item>
</style>

<style name="AnimTopLeft" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/top_left_in</item>
<item name="android:windowExitAnimation">@anim/top_left_out</item>
</style>

<style name="AnimTopMiddle" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/top_middle_in</item>
<item name="android:windowExitAnimation">@anim/top_middle_out</item>
</style>

<style name="main_tv_style">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#000000</item>
</style>

<style name="urm_tv">
<item name="android:textSize">18sp</item>
</style>
</resources>


9.各种动画效果

push_top_in.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 从屏幕上面进入 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<translate
android:duration="500"
android:fromYDelta="-100%p"
android:toYDelta="0" />

<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0" />

</set>


push_top_out.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 从屏幕上面退出 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<translate
android:duration="500"
android:fromYDelta="0"
android:toYDelta="-100%p" />

<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.0" />

</set>


top_left_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<scale
android:duration="500"
android:fillAfter="false"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="0%"
android:pivotY="0%"
android:toXScale="1.0"
android:toYScale="1.0" />

</set>


top_left_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<scale
android:duration="500"
android:fillAfter="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="0%"
android:pivotY="0%"
android:toXScale="0.0"
android:toYScale="0.0" />

</set>


top_middle_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<scale
android:duration="500"
android:fillAfter="false"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="0%"
android:toXScale="1.0"
android:toYScale="1.0" />

</set>


top_middle_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<scale
android:duration="500"
android:fillAfter="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="0%"
android:toXScale="0.0"
android:toYScale="0.0" />

</set>


top_right_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<scale
android:duration="500"
android:fillAfter="false"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="100%"
android:pivotY="0%"
android:toXScale="1.0"
android:toYScale="1.0" />

</set>


top_right_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<scale
android:duration="500"
android:fillAfter="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="100%"
android:pivotY="0%"
android:toXScale="0.0"
android:toYScale="0.0" />

</set>


运行项目即可搞定!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: