【Android UI设计与开发】第09期:底部菜单栏(四)Fragment+PopupWindow仿QQ空间最新版底部菜单栏
转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9023451
在今天的这篇文章当中,我依然会以实战加理论结合的方式教大家如何设计出自己觉得很炫的UI界面。好的,话不多说,进入正题。今天的这篇文章主要是以仿QQ空间的底部菜单栏效果为主,实现的效果有:
<1>实现了点击按钮时的切换图片效果;
<2>实现了点击按钮时的切换界面效果;
<3>实现了点击中间圆形按钮时弹出菜单以及按钮图片切换效果;
<4>实现了点击空白处和返回键按钮来关闭弹出菜单。
有个地方需要注意的是,弹出菜单栏后,点击里面的选项按钮会导致中间的圆形按钮切换为普通状态,这是因为在实际的项目中,点击菜单选项按钮之后会进入别的界面,所以也就不存在点击了之后圆形的按钮切换为普通的状态效果了,所以这里也不需要太在意。为了实现效果,这里只适配了480x800 hdpi的屏幕大小。
一、效果图
有图才有真相
二、项目结构图
三、代码详细编写
1、主布局界面,activity_main.xml:
[html] view plain copy
- <spanstyle="font-size:12px;"><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <FrameLayout
- android:id="@+id/frame_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_above="@+id/frameLayout1"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:background="#ffffff">
- </FrameLayout>
- <FrameLayout
- android:id="@+id/frameLayout1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentLeft="true"
- android:background="@drawable/toolbar_bg_normal">
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_marginTop="1dp"
- android:gravity="center_horizontal">
- <FrameLayout
- android:id="@+id/layout_friendfeed"
- android:layout_width="fill_parent"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:background="@drawable/tab_btn_background">
- <ImageView
- android:id="@+id/image_friendfeed"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|center"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/tab_friendfeed_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center"
- android:layout_marginBottom="6.0dip"
- android:text="动态"
- android:textColor="#ffffff"
- android:textSize="10sp"/>
- </FrameLayout>
- <FrameLayout
- android:id="@+id/layout_myfeed"
- android:layout_width="fill_parent"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:background="@drawable/tab_btn_background">
- <ImageView
- android:id="@+id/image_myfeed"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|center"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/tab_myfeed_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center"
- android:layout_marginBottom="6.0dip"
- android:text="与我想关"
- android:textColor="#ffffff"
- android:textSize="10sp"/>
- </FrameLayout>
- <FrameLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- </FrameLayout>
- <FrameLayout
- android:id="@+id/layout_home"
- android:layout_width="fill_parent"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:background="@drawable/tab_btn_background">
- <ImageView
- android:id="@+id/image_home"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|center"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/tab_home_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center"
- android:layout_marginBottom="6.0dip"
- android:text="我的空间"
- android:textColor="#ffffff"
- android:textSize="10sp"/>
- </FrameLayout>
- <FrameLayout
- android:id="@+id/layout_more"
- android:layout_width="fill_parent"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:background="@drawable/tab_btn_background">
- <ImageView
- android:id="@+id/image_more"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|center"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/tab_more_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center"
- android:layout_marginBottom="6.0dip"
- android:text="更多"
- android:textColor="#ffffff"
- android:textSize="10sp"/>
- </FrameLayout>
- </LinearLayout>
- </FrameLayout>
- <ImageView
- android:id="@+id/toggle_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:src="@drawable/toolbar_btn_normal"/>
- <ImageView
- android:id="@+id/plus_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignTop="@+id/frameLayout1"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="6dip"
- android:src="@drawable/toolbar_plus"/>
- </RelativeLayout></span>
<1> 最外层使用的是RelativeLayout,主要是为了容易摆放底部菜单栏的位置;
<2> 然后是一个FrameLayout,主要用来存放显示Fragment的内容,这里的ID取名为frame_content是用来替换Fragment对象的,在后面的代码中会用到;
<3> 最下面的底部菜单栏中外层使用了FrameLayout,之所以使用FrameLayout是为了让底部菜单栏中间的按钮也可以摆放进来,实现一种叠加的效果;
<4> 里面嵌套了LinearLayout,使用它是为了能够使用layout_weight属性,可以用来更好的摆放按钮,还可以实现自适应屏幕的效果(关于自适应屏幕的内容后面会有专题详细讲解)
<5> 最后里面又嵌套了一个FrameLayout,使用它可以很方便的实现图标在上文字在下的效果,最主要的原因是使用它可以很容易的再添加一个消息提醒的小图片(实际的开发中会用到,此项目中没有用到)
2、弹出菜单的布局界面,popwindow_layout.xml:
[html] view plain copy
- <spanstyle="font-size:12px;"><?xmlversion="1.0"encoding="utf-8"?>
- <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="@drawable/popwindow_bg"
- android:orientation="vertical"
- tools:ignore="UselessParent">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="15dp"
- android:orientation="horizontal">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="5dp"
- android:layout_weight="1"
- android:orientation="vertical">
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/popwindow_write_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="5.0dip"
- android:shadowColor="#ff000000"
- android:shadowDx="1.0"
- android:shadowDy="1.0"
- android:shadowRadius="1.0"
- android:text="说说"
- android:textColor="#ffffffff"
- android:textSize="13.0dip"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="5dp"
- android:layout_weight="1"
- android:orientation="vertical">
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/popwindow_voice_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="5.0dip"
- android:shadowColor="#ff000000"
- android:shadowDx="1.0"
- android:shadowDy="1.0"
- android:shadowRadius="1.0"
- android:text="语音"
- android:textColor="#ffffffff"
- android:textSize="13.0dip"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="5dp"
- android:layout_weight="1"
- android:orientation="vertical">
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/popwindow_camera_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="5.0dip"
- android:shadowColor="#ff000000"
- android:shadowDx="1.0"
- android:shadowDy="1.0"
- android:shadowRadius="1.0"
- android:text="照片"
- android:textColor="#ffffffff"
- android:textSize="13.0dip"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="5dp"
- android:layout_weight="1"
- android:orientation="vertical">
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/popwindow_picture_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="5.0dip"
- android:shadowColor="#ff000000"
- android:shadowDx="1.0"
- android:shadowDy="1.0"
- android:shadowRadius="1.0"
- android:text="视频"
- android:textColor="#ffffffff"
- android:textSize="13.0dip"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="5dp"
- android:layout_weight="1"
- android:orientation="vertical">
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="1.0dip"
- android:src="@drawable/popwindow_sign_btn"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="5.0dip"
- android:shadowColor="#ff000000"
- android:shadowDx="1.0"
- android:shadowDy="1.0"
- android:shadowRadius="1.0"
- android:text="签到"
- android:textColor="#ffffffff"
- android:textSize="13.0dip"/>
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
- </RelativeLayout></span>
[html] view plain copy
- <spanstyle="font-size:12px;"><?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ImageView
- android:id="@+id/imageview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:scaleType="fitCenter"
- android:src="@drawable/xianjian01">
- </ImageView>
- </LinearLayout></span>
- <spanstyle="font-size:12px;"><?xmlversion="1.0"encoding="utf-8"?>
- <selectorxmlns:android="http://schemas.android.com/apk/res/android">
- <itemandroid:drawable="@drawable/toolbar_friendfeed_pressed"android:state_selected="true"/>
- <itemandroid:drawable="@drawable/toolbar_friendfeed_normal"/>
- </selector></span>
- <spanstyle="font-size:12px;">packagecom.yangyu.mycustomtab03;
- importandroid.content.Context;
- importandroid.graphics.drawable.BitmapDrawable;
- importandroid.os.Bundle;
- importandroid.support.v4.app.FragmentActivity;
- importandroid.support.v4.app.FragmentTransaction;
- importandroid.view.Gravity;
- importandroid.view.LayoutInflater;
- importandroid.view.MotionEvent;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.view.View.OnTouchListener;
- importandroid.widget.FrameLayout;
- importandroid.widget.ImageView;
- importandroid.widget.LinearLayout;
- importandroid.widget.PopupWindow;
- importandroid.widget.PopupWindow.OnDismissListener;
- publicclassMainActivityextendsFragmentActivityimplementsOnClickListener{
- //定义Fragment页面
- privateFragmentPage1fragmentPage1;
- privateFragmentPage2fragmentPage2;
- privateFragmentPage3fragmentPage3;
- privateFragmentPage4fragmentPage4;
- //定义布局对象
- privateFrameLayoutfriendfeedFl,myfeedFl,homeFl,moreFl;
- //定义图片组件对象
- privateImageViewfriendfeedIv,myfeedIv,homeIv,moreIv;
- //定义按钮图片组件
- privateImageViewtoggleImageView,plusImageView;
- //定义PopupWindow
- privatePopupWindowpopWindow;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- initData();
- //初始化默认为选中点击了“动态”按钮
- clickFriendfeedBtn();
- }
- /**
- *初始化组件
- */
- privatevoidinitView(){
- //实例化布局对象
- friendfeedFl=(FrameLayout)findViewById(R.id.layout_friendfeed);
- myfeedFl=(FrameLayout)findViewById(R.id.layout_myfeed);
- homeFl=(FrameLayout)findViewById(R.id.layout_home);
- moreFl=(FrameLayout)findViewById(R.id.layout_more);
- //实例化图片组件对象
- friendfeedIv=(ImageView)findViewById(R.id.image_friendfeed);
- myfeedIv=(ImageView)findViewById(R.id.image_myfeed);
- homeIv=(ImageView)findViewById(R.id.image_home);
- moreIv=(ImageView)findViewById(R.id.image_more);
- //实例化按钮图片组件
- toggleImageView=(ImageView)findViewById(R.id.toggle_btn);
- plusImageView=(ImageView)findViewById(R.id.plus_btn);
- }
- /**
- *初始化数据
- */
- privatevoidinitData(){
- //给布局对象设置监听
- friendfeedFl.setOnClickListener(this);
- myfeedFl.setOnClickListener(this);
- homeFl.setOnClickListener(this);
- moreFl.setOnClickListener(this);
- //给按钮图片设置监听
- toggleImageView.setOnClickListener(this);
- }
- @Override
- publicvoidonClick(Viewv){
- switch(v.getId()){
- //点击动态按钮
- caseR.id.layout_friendfeed:
- clickFriendfeedBtn();
- break;
- //点击与我相关按钮
- caseR.id.layout_myfeed:
- clickMyfeedBtn();
- break;
- //点击我的空间按钮
- caseR.id.layout_home:
- clickHomeBtn();
- break;
- //点击更多按钮
- caseR.id.layout_more:
- clickMoreBtn();
- break;
- //点击中间按钮
- caseR.id.toggle_btn:
- clickToggleBtn();
- break;
- }
- }
- /**
- *显示PopupWindow弹出菜单
- */
- privatevoidshowPopupWindow(Viewparent){
- if(popWindow==null){
- LayoutInflaterlayoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- Viewview=layoutInflater.inflate(R.layout.popwindow_layout,null);
- //创建一个PopuWidow对象
- popWindow=newPopupWindow(view,LinearLayout.LayoutParams.FILL_PARENT,200);
- }
- //使其聚集,要想监听菜单里控件的事件就必须要调用此方法
- popWindow.setFocusable(true);
- //设置允许在外点击消失
- popWindow.setOutsideTouchable(true);
- //设置背景,这个是为了点击“返回Back”也能使其消失,并且并不会影响你的背景
- popWindow.setBackgroundDrawable(newBitmapDrawable());
- //设置菜单显示的位置
- popWindow.showAsDropDown(parent,Gravity.CENTER,0);
- //监听菜单的关闭事件
- popWindow.setOnDismissListener(newOnDismissListener(){
- @Override
- publicvoidonDismiss(){
- //改变显示的按钮图片为正常状态
- changeButtonImage();
- }
- });
- //监听触屏事件
- popWindow.setTouchInterceptor(newOnTouchListener(){
- publicbooleanonTouch(Viewview,MotionEventevent){
- //改变显示的按钮图片为正常状态
- changeButtonImage();
- returnfalse;
- }
- });
- }
- /**
- *点击了“动态”按钮
- */
- privatevoidclickFriendfeedBtn(){
- //实例化Fragment页面
- fragmentPage1=newFragmentPage1();
- //得到Fragment事务管理器
- FragmentTransactionfragmentTransaction=this.getSupportFragmentManager().beginTransaction();
- //替换当前的页面
- fragmentTransaction.replace(R.id.frame_content,fragmentPage1);
- //事务管理提交
- fragmentTransaction.commit();
- friendfeedFl.setSelected(true);
- friendfeedIv.setSelected(true);
- myfeedFl.setSelected(false);
- myfeedIv.setSelected(false);
- homeFl.setSelected(false);
- homeIv.setSelected(false);
- moreFl.setSelected(false);
- moreIv.setSelected(false);
- }
- /**
- *点击了“与我相关”按钮
- */
- privatevoidclickMyfeedBtn(){
- //实例化Fragment页面
- fragmentPage2=newFragmentPage2();
- //得到Fragment事务管理器
- FragmentTransactionfragmentTransaction=this.getSupportFragmentManager().beginTransaction();
- //替换当前的页面
- fragmentTransaction.replace(R.id.frame_content,fragmentPage2);
- //事务管理提交
- fragmentTransaction.commit();
- friendfeedFl.setSelected(false);
- friendfeedIv.setSelected(false);
- myfeedFl.setSelected(true);
- myfeedIv.setSelected(true);
- homeFl.setSelected(false);
- homeIv.setSelected(false);
- moreFl.setSelected(false);
- moreIv.setSelected(false);
- }
- /**
- *点击了“我的空间”按钮
- */
- privatevoidclickHomeBtn(){
- //实例化Fragment页面
- fragmentPage3=newFragmentPage3();
- //得到Fragment事务管理器
- FragmentTransactionfragmentTransaction=this.getSupportFragmentManager().beginTransaction();
- //替换当前的页面
- fragmentTransaction.replace(R.id.frame_content,fragmentPage3);
- //事务管理提交
- fragmentTransaction.commit();
- friendfeedFl.setSelected(false);
- friendfeedIv.setSelected(false);
- myfeedFl.setSelected(false);
- myfeedIv.setSelected(false);
- homeFl.setSelected(true);
- homeIv.setSelected(true);
- moreFl.setSelected(false);
- moreIv.setSelected(false);
- }
- /**
- *点击了“更多”按钮
- */
- privatevoidclickMoreBtn(){
- //实例化Fragment页面
- fragmentPage4=newFragmentPage4();
- //得到Fragment事务管理器
- FragmentTransactionfragmentTransaction=this.getSupportFragmentManager().beginTransaction();
- //替换当前的页面
- fragmentTransaction.replace(R.id.frame_content,fragmentPage4);
- //事务管理提交
- fragmentTransaction.commit();
- friendfeedFl.setSelected(false);
- friendfeedIv.setSelected(false);
- myfeedFl.setSelected(false);
- myfeedIv.setSelected(false);
- homeFl.setSelected(false);
- homeIv.setSelected(false);
- moreFl.setSelected(true);
- moreIv.setSelected(true);
- }
- /**
- *点击了中间按钮
- */
- privatevoidclickToggleBtn(){
- showPopupWindow(toggleImageView);
- //改变按钮显示的图片为按下时的状态
- plusImageView.setImageResource(R.drawable.toolbar_plusback);
- toggleImageView.setImageResource(R.drawable.toolbar_btn_pressed);
- }
- /**
- *改变显示的按钮图片为正常状态
- */
- privatevoidchangeButtonImage(){
- plusImageView.setImageResource(R.drawable.toolbar_plus);
- toggleImageView.setImageResource(R.drawable.toolbar_btn_normal);
- }
- }</span><spanstyle="font-size:18px;">
- </span>
[java] view plain copy
- packagecom.yangyu.mycustomtab03;
- importandroid.os.Bundle;
- importandroid.support.v4.app.Fragment;
- importandroid.view.LayoutInflater;
- importandroid.view.View;
- importandroid.view.ViewGroup;
- publicclassFragmentPage1extendsFragment{
- @Override
- publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
- BundlesavedInstanceState){
- returninflater.inflate(R.layout.fragment_1,null);
- }
- }
到这里整个项目就基本上讲完了,大家还可以为此项目继续完善下去,实现点击菜单选项后实现的效果以及顶部标题栏的实现。对于这个项目,博主还有一个地方不明白,就是针对此项目,在弹出菜单后,有什么好的简单一点的方法将背景置为灰色?我也试了一些方法,但是效果都不是特别的理想,希望读者有什么想法可以给博主留言,大家可以互相交流学习一下。
源码下载地址
更多相关文章
- Android客户端如何从Web服务端加载图片
- Android实现多渠道打包,动态替换包名、Icon、图片等资源,解决因app
- android 图片处理 (滤镜,图片位置)
- 关于android图片的传输,android图片传输方式,xml传输图片,android
- Android UI组件进阶(1)——带进度条的按钮
- 【Android 内存优化】Bitmap 内存占用计算 ( Bitmap 图片内存占
- 转载——Android大图片裁剪终极解决方案
- Android ListView 图片异步加载和图片内存缓存