Android PopupWindow实现从顶部弹出下拉菜单左、中、右
2015-10-19 19:08
633 查看
本实例的自定义下拉菜单主要是继承PopupWindow类来实现的弹出窗体,各种布局效果可以根据自己定义设计。弹出的动画效果主要用到了translate、alpha、scale,具体实现步骤如下:
先上效果图如下:左边下拉菜单、中间下拉菜单、右边下拉菜单
1.主界面布局 activity_main.xml:
2.主界面测试类 MainActivity.java
3.自定义弹窗类 TopMiddlePopup.java
4.自定义弹窗布局 top_popup.xml
5.弹窗类表适配器类 PopupAdapter
6.子item布局 top_popup_item.xml
7.主界面顶部布局 urm_top.xml
8.styles.xml文件
9.各种动画效果
push_top_in.xml
push_top_out.xml
top_left_in.xml
top_left_out.xml
top_middle_in.xml
top_middle_out.xml
top_right_in.xml
top_right_out.xml
运行项目即可搞定!
先上效果图如下:左边下拉菜单、中间下拉菜单、右边下拉菜单
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>
运行项目即可搞定!
相关文章推荐
- Android studio Gradle home can not be found - Android Studio错误
- Android Camera 使用小结
- [Android应用开发] 04.页面跳转和数据传输
- Android SQLite 的学习
- Android中帧布局-FrameLayout和网格布局-GridLayout
- Android的使用介绍
- Android ViewPager屏蔽预加载
- Android permission 访问权限大全
- Android一百个错误整理(一)
- 使用Android Studio向GitHub提交代码
- 使用Android Studio向GitHub提交代码
- Android第一周-项目下各文件夹的作用
- AndroidWear开发之HelloWorld篇
- AndroidWear开发之开发环境[前奏]
- ExpandableListView的用法(类似QQ好友展示)
- 底层 添加资源到android源码中-修改framework层
- Android6.0给开发者带来哪些影响
- Support Design Library 之 TabLayout 使用与分析
- Android单元测试
- Android ViewPage禁止重复加载