Android中实现的一个底部弹出窗口,可根据需要扩充

        在很多应用中,我们都可以看到在应用的底部有一个可以向上弹出的窗口,我们可以在这里添加一些特定情况下才会用到的功能,这样能够使界面更简洁,设计更加合理,这次我将为大家带来一个这样类似功能的实现,如果有需要可以直接应用,或者经过改造扩充后应用。

       先来看一下底部弹出窗口的应用效果,这是从qq和新浪微博中截的图。

                                                               

      底部弹窗显示出来的效果大致就是这个样子 接下来就给大家介绍一下如何实现这样的效果的。

      实现一种UI的方式有多种,这里只是为大家介绍一种实现方式,其他方法可以自己探索。分析一下触发过程我们就能知道当我们点击某个按钮或者手机菜单键,此时弹窗弹出。在摊床上会有一些可以选择的功能,如QQ中的版本更新或者微博里的签到等。具体功能暂不研究,这里仅实现了界面效果。

      很明显,这个界面是覆盖整个屏幕的,当然有人会说,QQ的就没有覆盖整个屏幕。其实这只是视觉上的。整个弹窗的作用范围就是整个屏幕,否则就不会有点击空白弹窗弹回的效果。整个弹窗需要一个内部布局文件(就是显示出来的样子),一个按键的监听,用于弹出弹窗。需要注意的是这里用到的容器是Dialog,不是Activity

       好了,现在开始具体实现。首先我们需要一套内部布局

<?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"
    android:background="#00000000"
    android:gravity="bottom"
    android:orientation="vertical"
    android:padding="5dip" >

    <RelativeLayout
        android:id="@+id/imp_bottom_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true" >
  <Button
            android:id="@+id/cancle_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dip"
            android:background="@drawable/photo_cancel_selector"
            android:paddingBottom="10dip"
            android:paddingTop="10dip"
            android:text="取消"
            android:textSize="16sp" />
    </RelativeLayout>
</RelativeLayout>

      内容很简单,就是一个布局中放了一个按钮。如此而已。

      当然button我们需要用选择器来做一个点击选中和失去焦点时的变化效果,以下是用到的选择器,也就是上面布局里button的background部分。

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

    <item android:drawable="@drawable/photo_cancel_pressed" android:state_focused="true"/>
    <item android:drawable="@drawable/photo_cancel_pressed" android:state_focused="false" android:state_pressed="true"/>
    <item android:drawable="@drawable/photo_cancel_normal" android:state_focused="false"/>

</selector>


      这里的选择器里定义了三个item也就是三个状态,拥有焦点状态,失去焦点仍然点击状态,失去焦点状态。它的drawable属性定义了item具体需要显示的内容,这里用了两个xml文件来定义。

photo_cancel_pressed状态

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

    <gradient
        android:angle="90"
        android:endColor="#CACACB"
        android:startColor="#CACACB" />

    <corners
        android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />

</shape>

photo_cancel_normal状态

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

    <gradient
        android:angle="90"
        android:endColor="#EBEBEB"
        android:startColor="#EBEBEB" />


    <corners
        android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />

</shape>

      这里用到了一些选择器的渐变属性等内容,这些内容会单独介绍,这里先实现弹窗效果。
      当然进入退出时是要有动画的,接下来需要的是动画xml

进入动画:

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

    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:fromYDelta="1000"
        android:toXDelta="0"
        android:toYDelta="0" />

</set>


退出动画:

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

    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="1000" />

</set>


     为了使用更加方便,我们在styles文件里定义两个style。

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="transparentFrameWindowStyle" parent="android:style/Theme.Dialog">
        <item name="android:windowBackground">@drawable/background_android</item>
    </style>

    <style name="main_menu_animstyle">
        <item name="android:windowEnterAnimation">@anim/photo_dialog_in_anim</item>
        <item name="android:windowExitAnimation">@anim/photo_dialog_out_anim</item>
    </style>

</resources>

     好了,所有材料都准备好之后我们就开始让弹窗显示出来。其实准备好上面的内容之后我们的工作已经完成一大半了。剩下的就是对Dialog的属性进行一些设置,然后把监听绑好就可以了。

    

package com.example.pupdialog;


import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
	private Button btnPopup;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		btnPopup = (Button) findViewById(R.id.btn);
		btnPopup.setOnClickListener(this);
	}

	public void onClick(View v) {
		showDialog();
	}

	private void showDialog() {
		View view = getLayoutInflater().inflate(R.layout.photo_choose_dialog, null);
		final Dialog dialog = new Dialog(this, R.style.transparentFrameWindowStyle);
		dialog.setContentView(view, new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.WRAP_CONTENT));
		Window window = dialog.getWindow();
		// 为dialog设置动画
		window.setWindowAnimations(R.style.main_menu_animstyle);
		WindowManager.LayoutParams wl = window.getAttributes();
		//Dialog的初始位置
		wl.x = 0;
		wl.y = getWindowManager().getDefaultDisplay().getHeight();
		// 设置Dialog应该占的空间参数
		wl.width = ViewGroup.LayoutParams.MATCH_PARENT;
		wl.height = ViewGroup.LayoutParams.MATCH_PARENT;

		// 把参数设置到Dialog里
		dialog.onWindowAttributesChanged(wl);
		// 设置点击空白处消失
		dialog.setCanceledOnTouchOutside(true);
		// 展示Dialog
		dialog.show();
		// 取得Dialog里的按钮控件添加监听器
		Button button = (Button) view.findViewById(R.id.cancle_btn);
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dialog.cancel();
			}
		});
	}
}


      这里就是我们用到的唯一一个Activity,需要注意的是,这里的Activity实现了OnclickListener接口,当按钮被点击时就会调用OnClick方法,OnClick方法里又调用了showDialog方法,在这里实例化一个Dialog,并对Dialog的属性进行设置。

      showDialog里我们利用inflate方法载入一个布局文件,就是刚才我们定义的Dialog布局,得到Dialog的Window对象,并用它得到窗口属性,即WindowManager.LayoutParams,对这个属性进行一些设置,主要是关于Dialog的显示位置,显示大小等。另外可以使用setCanceledOnTouchOutside方法来设置dialog外部是否可以点击,可以点击的话,点击后弹窗dialog会消失。

      另外我们在Dialog里放的按钮,绑定一个监听器,用来监听当点击按钮时退出弹窗。

      基本实现就是这样,如果需要添加更多控件实现更多功能,只需要在dialog的布局文件里添加即可。

下面是Activity用到的布局文件:

<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"
    
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dip"
        android:text="弹出" />

   

</RelativeLayout>


最终效果

最后是Manifest文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.pupdialog"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
         >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

点击下载代码


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值