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

android 自定义下拉菜单

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

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







1.主界面布局 activity_main.xml:

[html] view
plain copy

<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

[java] view
plain copy

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

[java] view
plain copy

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

[html] view
plain copy

<?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

[java] view
plain copy

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

[html] view
plain copy

<?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

[html] view
plain copy

<?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文件

[html] view
plain copy

<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

[html] view
plain copy

<?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

[html] view
plain copy

<?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

[html] view
plain copy

<?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

[html] view
plain copy

<?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

[html] view
plain copy

<?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

[html] view
plain copy

<?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

[html] view
plain copy

<?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

[html] view
plain copy

<?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>

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