Android自定义PopupWindow 动画

本文详细介绍了如何在Android应用中自定义PopupWindow,并通过实例演示了如何设置其位置及动画效果,提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在公司项目中需要自定义PopupWindow,在這里记录下,方便以后可以查看,自定义PopupWindow 主要的难点是显示的位置在哪里,在這里也有讲解到,代码上传下,动画文件的代码就不上了,有要求的可以去這个地址下载:


demo 下载:  http://download.youkuaiyun.com/detail/pigseesunset/9704740






activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:orientation="horizontal"
    tools:context="com.testopensourceapplication.popwindondemo.MainActivity">

    <LinearLayout
        android:id="@+id/ll_hud_dismiss_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="#000000"
        android:gravity="center"
        android:orientation="horizontal"
        android:visibility="visible"
        android:weightSum="4">

        <TextView
            android:id="@+id/fg_tv_hud_exit_navi"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/control_bg"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center"
            android:nextFocusDown="@+id/fg_tv_hud_switch_model"
            android:nextFocusLeft="@+id/fg_tv_hud_see_plan"
            android:nextFocusRight="@+id/fg_tv_hud_switch_model"
            android:nextFocusUp="@+id/fg_tv_hud_see_plan"
            android:text="退出导航"
            android:textColor="#ffffff"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/fg_tv_hud_switch_model"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/control_bg"
            android:clickable="true"
            android:focusable="true"
            android:gravity="center"
            android:nextFocusDown="@+id/fg_tv_hud_nearby_addr"
            android:nextFocusLeft="@+id/fg_tv_hud_exit_navi"
            android:nextFocusRight="@+id/fg_tv_hud_nearby_addr"
            android:nextFocusUp="@+id/fg_tv_hud_exit_navi"
            android:text="模式切换"
            android:textColor="#ffffff"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/fg_tv_hud_nearby_addr"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/control_bg"
            android:clickable="true"
            android:focusable="true"
            android:gravity="center"
            android:nextFocusDown="@+id/fg_tv_hud_see_plan"
            android:nextFocusLeft="@+id/fg_tv_hud_switch_model"
            android:nextFocusRight="@+id/fg_tv_hud_see_plan"
            android:nextFocusUp="@+id/fg_tv_hud_switch_model"
            android:text="附近"
            android:textColor="#ffffff"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/fg_tv_hud_see_plan"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/control_bg"
            android:clickable="true"
            android:focusable="true"
            android:gravity="center"
            android:nextFocusDown="@+id/fg_tv_hud_exit_navi"
            android:nextFocusLeft="@+id/fg_tv_hud_nearby_addr"
            android:nextFocusRight="@+id/fg_tv_hud_exit_navi"
            android:nextFocusUp="@+id/fg_tv_hud_nearby_addr"
            android:text="全览图"
            android:textColor="#ffffff"
            android:textSize="30sp"/>
    </LinearLayout>
</FrameLayout>


hud_menu.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:background="@drawable/left_side_bg"
    android:orientation="vertical"
    android:weightSum="4">
    <TextView
        android:id="@+id/hm_tv_nearby_bank"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@drawable/control_bg"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:nextFocusDown="@+id/hm_tv_search_parking_lot"
        android:nextFocusLeft="@+id/hm_im_close_pop"
        android:nextFocusRight="@+id/hm_tv_search_parking_lot"
        android:nextFocusUp="@+id/hm_im_close_pop"
        android:text="银行"
        android:textColor="#ffffff"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/hm_tv_search_parking_lot"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@drawable/control_bg"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:nextFocusDown="@+id/hm_tv_search_gas_station"
        android:nextFocusLeft="@+id/hm_tv_nearby_bank"
        android:nextFocusRight="@+id/hm_tv_search_gas_station"
        android:nextFocusUp="@+id/hm_tv_nearby_bank"
        android:text="停车场"
        android:textColor="#ffffff"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/hm_tv_search_gas_station"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@drawable/control_bg"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:nextFocusDown="@+id/hm_tv_search_hotel"
        android:nextFocusLeft="@+id/hm_tv_search_parking_lot"
        android:nextFocusRight="@+id/hm_tv_search_hotel"
        android:nextFocusUp="@+id/hm_tv_search_parking_lot"
        android:text="加油站"
        android:textColor="#ffffff"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/hm_tv_search_hotel"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@drawable/control_bg"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:nextFocusDown="@+id/hm_im_close_pop"
        android:nextFocusLeft="@+id/hm_tv_search_gas_station"
        android:nextFocusRight="@+id/hm_im_close_pop"
        android:nextFocusUp="@+id/hm_tv_search_gas_station"
        android:text="酒店"
        android:textColor="#ffffff"
        android:textSize="25sp" />
</LinearLayout>


CustomerPopWindow.class

package com.testopensourceapplication.popwindondemo;

import android.app.Activity;
import android.view.Gravity;
import android.view.View;
import android.widget.PopupWindow;

/**
 * Created by HE on 2016/12/7.
 */
public class CustomerPopWindow extends PopupWindow {

    /**
     *
     * @param context  上下文对象
     * @param layout  PopupWindow的View
     * @param popWidth   PopupWindow的宽
     * @param popHight   PopupWindow的高
     * @param PointView  指定控件
     * @param gravity  指定位置
     * @param animationStyle  动画类型 没有填-1
     * @param Xpixl    x轴偏移量(偏移量要自己根据界面坐标算)
     * @param Ypixl  y轴偏移量(偏移量要自己根据界面坐标算)
     */
    public CustomerPopWindow(final Activity context,View layout, int popWidth,int popHight,View PointView,
                             int gravity,int animationStyle,int Xpixl,int Ypixl ){{

        // 设置 PopupWindow的View
        this.setContentView(layout);
        //设置弹出窗体的宽高
        this.setWidth(popWidth);
        this.setHeight(popHight);
        //设置弹出窗体可点击
        this.setFocusable(true);
        this.setOutsideTouchable(true);
        //刷新状态
        this.update();

        this.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.left_side_bg));

        //窗体显示的位置
        showAtCustomerLocation(PointView, gravity, animationStyle, Xpixl, Ypixl);
        }

    }

    /**
     *
     * @param PointView  指定控件
     * @param gravity 指定位置
     * @param direction  控件显示的位置
     * @param Xpixl x轴偏移量
     * @param Ypixl   y轴偏移量
     */
    public void showAtCustomerLocation(View PointView, int gravity, int direction, int Xpixl, int Ypixl){
        //指定控件上面显示
        if(gravity== Gravity.NO_GRAVITY){
            int[] location = new int[2];//指定控件的坐标,界面左上角是(0,0),记住这一点,具体什么方向显示就easy了
            PointView.getLocationOnScreen(location);
            switch (direction) {
                case 0://指定控件左面显示:
                    this.setAnimationStyle(R.style.popwin_anim_style_left);
                    this.showAtLocation(PointView, Gravity.NO_GRAVITY, location[0] - this.getWidth() + Xpixl, location[1] + Ypixl);
                    break;
                case 1://指定控件右面显示:
                    this.setAnimationStyle(R.style.popwin_anim_style_right);
                    this.showAtLocation(PointView, Gravity.NO_GRAVITY, location[0] + this.getWidth() + Xpixl, location[1] + Ypixl);
                    return;
                case 2://指定控件上面显示:
                    this.setAnimationStyle(R.style.popwin_anim_style);
                    this.showAtLocation(PointView, Gravity.NO_GRAVITY, location[0] + Xpixl, location[1] - this.getHeight() + Ypixl);
                    return;
                case 3: //指定控件下面显示:
                    this.setAnimationStyle(R.style.popwin_anim_style_down);
                    this.showAtLocation(PointView, Gravity.NO_GRAVITY, location[0] + Xpixl, location[1] + PointView.getHeight() + Ypixl);
                    return;
            }
        }
        //中间显示
        else {
            this.showAtLocation(PointView, gravity, 0, 0);
        }
    }
}


MainActivity.class


package com.testopensourceapplication.popwindondemo;

import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    LinearLayout ll_hud_dismiss_view;
    TextView fg_tv_hud_exit_navi;
    TextView fg_tv_hud_switch_model;
    TextView fg_tv_hud_nearby_addr;
    TextView fg_tv_hud_see_plan;



    TextView hm_tv_nearby_bank, hm_tv_search_parking_lot,
            hm_tv_search_gas_station, hm_tv_search_hotel;

    private CustomerPopWindow popupWindow = null;// 附近的地点
    int width;
    int height;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //透明导航栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
        initView();

    }

    public void initView(){

           //获取屏幕的宽高
        WindowManager wm = this.getWindowManager();
        width = wm.getDefaultDisplay().getWidth();
        height = wm.getDefaultDisplay().getHeight();

        ll_hud_dismiss_view = (LinearLayout)findViewById(R.id.ll_hud_dismiss_view);
        fg_tv_hud_exit_navi = (TextView) findViewById(R.id.fg_tv_hud_exit_navi);
        fg_tv_hud_switch_model = (TextView) findViewById(R.id.fg_tv_hud_switch_model);
        fg_tv_hud_nearby_addr = (TextView) findViewById(R.id.fg_tv_hud_nearby_addr);
        fg_tv_hud_see_plan = (TextView) findViewById(R.id.fg_tv_hud_see_plan);
        fg_tv_hud_exit_navi.setOnClickListener(this);
        fg_tv_hud_switch_model.setOnClickListener(this);
        fg_tv_hud_nearby_addr.setOnClickListener(this);
        fg_tv_hud_see_plan.setOnClickListener(this);


    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.fg_tv_hud_exit_navi:
                break;
            case  R.id.fg_tv_hud_switch_model:
                break;
            case R.id.fg_tv_hud_nearby_addr:
                showPopupWindow();
                break;
            case R.id.fg_tv_hud_see_plan:
                break;
            default:
                break;

        }
    }
    private void showPopupWindow(){
//填冲布局
        LinearLayout layout_menu = (LinearLayout) LayoutInflater.from(
                MainActivity.this).inflate(R.layout.hud_menu, null);
        hm_tv_nearby_bank = (TextView) layout_menu
                .findViewById(R.id.hm_tv_nearby_bank);

        hm_tv_search_gas_station = (TextView) layout_menu
                .findViewById(R.id.hm_tv_search_gas_station);

        hm_tv_search_parking_lot = (TextView) layout_menu
                .findViewById(R.id.hm_tv_search_parking_lot);

        hm_tv_search_hotel = (TextView) layout_menu
                .findViewById(R.id.hm_tv_search_hotel);

        hm_tv_nearby_bank.setOnClickListener(this);
        hm_tv_search_gas_station.setOnClickListener(this);
        hm_tv_search_parking_lot.setOnClickListener(this);
        hm_tv_search_hotel.setOnClickListener(this);

        popupWindow = new CustomerPopWindow(MainActivity.this, layout_menu, width / 4, height / 2, ll_hud_dismiss_view, Gravity.NO_GRAVITY, 2, width/2, 0);
        if (!hm_tv_nearby_bank.isFocused()) {
            hm_tv_nearby_bank.requestFocus();
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值