Android:高仿UC浏览器popupWindow菜单栏

来源:互联网 发布:淘宝联盟怎么加优惠券 编辑:程序博客网 时间:2024/05/17 05:51

在模拟UC浏览器的popupWindow菜单栏的时候遇到了一些问题,自己通过在网上搜索资源,整合,解决了一些。例如在学习别人的代码的时候遇到了第一个标题选中不变色,菜单栏不能够响应menu事件消失等问题,当然模仿的程度还没有达到最好,希望以后可以做的更好。

 上传代码的时候没有注意到,菜单栏再次出现的时候,标题定位有问题,所以在这里的代码进行了修改,但是源代码下载没有改,改的地方在popupmenu里

模仿的效果有 菜单上下推拉效果出现于消失 中间分割线可以随选择而移动的动画 下面的菜单选项也可以移动 但模仿不完全

效果图

 

 

布局代码

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity" ></RelativeLayout>


popmenu.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:orientation="vertical" >        <GridView         android:id="@+id/gridview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:horizontalSpacing="10dip"        android:numColumns="3"        android:stretchMode="columnWidth"        android:verticalSpacing="10dip"        /></LinearLayout>


标题adapter

package com.example.mypopupwindow;import java.util.List;import android.content.Context;import android.graphics.Color;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.TextView;public class TitleAdapter extends BaseAdapter {private List<String> titles;private Context context;public TextView[] tv_titles;int position = 0;public TitleAdapter(List<String> titles, Context context,int position) {this.titles = titles;this.context = context;tv_titles = new TextView[titles.size()];this.position = position;}@Overridepublic int getCount() {return titles.size();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}/**曾用来在选中标题后改变字体颜色,但发现标题第一项 * 不能响应,暂时未找到解决办法,所以用了其他方式, * 这里就注释掉了public void setFocus(int position) {for (int i = 0; i < getCount(); i++) { if(i == position){ tv_titles[i].setTextColor(Color.WHITE); }else{ tv_titles[i].setTextColor(Color.GRAY); }}}*/@Overridepublic View getView(int position, View convertView, ViewGroup parent) {/** * 动态添加标题textView控件,并设置布局属性 */tv_titles[position] = new TextView(context);/** * 设置textView中的字居中 */tv_titles[position].setGravity(Gravity.CENTER);tv_titles[position].setText(titles.get(position));tv_titles[position].setTextSize(20);/** * 设置TextView的大小 */tv_titles[position].setLayoutParams(new GridView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));tv_titles[position].setPadding(0, 20, 0, 10);/** * 在选中某一标题后,重新声明adapter对象,通过构造函数给的position * 确定把哪个标题的字体颜色直接初始化 */if(position == this.position){tv_titles[position].setTextColor(Color.WHITE);}else{tv_titles[position].setTextColor(Color.GRAY);}return tv_titles[position];}}


 

功能图片adapter

 

package com.example.mypopupwindow;import java.util.List;import android.content.Context;import android.graphics.Color;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;public class BodyAdapter extends BaseAdapter{private List<String> item_names;private List<Integer> item_images;private Context context;public BodyAdapter(Context context,List<String> item_names,List<Integer> item_images){this.context = context;this.item_names = item_names;this.item_images = item_images;}@Overridepublic int getCount() {return item_images.size();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {/** * 设置图标与图标名称的布局 */LinearLayout layout = new LinearLayout(context);layout.setOrientation(LinearLayout.VERTICAL);layout.setGravity(Gravity.CENTER);/** * TextView名称 */TextView tv_item = new TextView(context);tv_item.setLayoutParams(new GridView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));tv_item.setGravity(Gravity.CENTER);tv_item.setTextColor(Color.WHITE);tv_item.setPadding(10, 10, 10, 10);tv_item.setText(item_names.get(position));/** * ImageView图标 */ImageView img_item = new ImageView(context);img_item.setLayoutParams(new LayoutParams(50,50));img_item.setImageResource(item_images.get(position));layout.addView(img_item);layout.addView(tv_item);return layout;}}


popupmenu

package com.example.mypopupwindow;import java.util.List;import android.content.Context;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.view.KeyEvent;import android.view.View;import android.view.View.OnKeyListener;import android.view.ViewGroup.LayoutParams;import android.view.WindowManager;import android.view.animation.Animation;import android.view.animation.TranslateAnimation;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.GridView;import android.widget.LinearLayout;import android.widget.PopupWindow;import android.widget.RelativeLayout;import android.widget.TextView;public class MyPopupMenu extends PopupWindow {/** * 菜单栏的整体布局LinearLayout */private LinearLayout linearLayout;/** * 菜单栏分类标题布局GridView */private GridView gv_title;/** * 菜单栏功能图标与名称GridView */private GridView gv_body;/** * 菜单栏功能图标与名称GridView的适配 */private BodyAdapter[] bodyAdapter;/** * 菜单栏分类标题GridView的适配 */private TitleAdapter titleAdapter;private Context context;/** * 当前选中的分类标题 */private int currentIndex = 0;/** * 上一次选中的分类标题 * 用于选择分类标题时的左右移动动画,判断应该怎样移动 */private int preIndex = 0;/** * 标题与功能布局中间的分界线 * RelativeLayout + TextView  */private RelativeLayout divisionLayout;/** * 屏幕宽度 */private int screenWidth = 0;@SuppressWarnings("deprecation")public MyPopupMenu(Context context, List<String> titles,final List<List<String>> item_names, List<List<Integer>> item_images) {super(context);this.context = context;/** * 菜单栏的整体布局LinearLayout初始化 */linearLayout = new LinearLayout(context);linearLayout.setOrientation(LinearLayout.VERTICAL);linearLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));/** * 获取屏幕宽度 */WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);screenWidth = wm.getDefaultDisplay().getWidth();/** * 分界线布局初始化 */divisionLayout = new RelativeLayout(context);divisionLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 3));divisionLayout.setBackgroundColor(Color.DKGRAY);/** * 标题布局初始化 */gv_title = new GridView(context);/** * 用于重新初始化adapter */final List<String> l = titles;final Context c = context;titleAdapter = new TitleAdapter(titles, context, currentIndex);/** * 设置被选中后,背景颜色不再是系统原有的黄色,改为TRANSPARENT */gv_title.setSelector(new ColorDrawable(Color.TRANSPARENT));gv_title.setAdapter(titleAdapter);gv_title.setSelection(0);/** * 设置GridView列数 */gv_title.setNumColumns(titleAdapter.getCount());gv_title.setBackgroundColor(Color.TRANSPARENT);/** * 选择分类标题时的响应事件 */gv_title.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {/** * 重新初始化adapter,为了改变标题选择颜色 */titleAdapter = new TitleAdapter(l, c, position);preIndex = currentIndex;currentIndex = position;gv_title.setAdapter(titleAdapter);/** * 分界线布局中的textView跟随选中标题移动位置的,设置为动画效果 */divisionTran(position);/** * 用于功能图标GridView动画效果 * TranslateAnimation方法中的参数设置暂时不太明确 * 似乎,参数都是相对于控件自身的位置 * 第一个参数是开始位置,第二个是结束位置 * 有时间会弄清楚 */Animation translateBody;if (preIndex < currentIndex) {translateBody = new TranslateAnimation(screenWidth, 0, 0,0);translateBody.setDuration(500);gv_body.startAnimation(translateBody);} else if (preIndex > currentIndex) {translateBody = new TranslateAnimation(-screenWidth, 0, 0, 0);translateBody.setDuration(500);gv_body.startAnimation(translateBody);}gv_body.setAdapter(bodyAdapter[position]);}});bodyAdapter = new BodyAdapter[item_names.size()];for (int i = 0; i < item_names.size(); i++) {bodyAdapter[i] = new BodyAdapter(context, item_names.get(i),item_images.get(i));}gv_body = new GridView(context);gv_body.setNumColumns(4);gv_body.setBackgroundColor(Color.TRANSPARENT);gv_body.setPadding(0, 10, 0, 10);gv_body.setAdapter(bodyAdapter[0]);/** * 选择功能图标时的响应事件 */gv_body.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {/** * 这里只是在控制台输出了一下功能的名称 */System.out.println(item_names.get(currentIndex).get(position));}});/** * 初始化textView位置 */divisionTran(0);/** * 把三个子布局加入到整体布局中去 */linearLayout.addView(gv_title);linearLayout.addView(divisionLayout);linearLayout.addView(gv_body);this.setContentView(linearLayout);this.setWidth(LayoutParams.MATCH_PARENT);this.setHeight(LayoutParams.WRAP_CONTENT);/** * 以下代码是为了解决,菜单栏出现后,不能响应再次按menu按键使菜单栏消失的问题 * 在这个网址找到的答案http://blog.csdn.net/admin_/article/details/7278402 * 可以自己去看 */this.setFocusable(true);linearLayout.setFocusableInTouchMode(true);linearLayout.setOnKeyListener(new OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {if ((keyCode == KeyEvent.KEYCODE_MENU)&& (MyPopupMenu.this.isShowing())) {MyPopupMenu.this.dismiss();/** * 使菜单栏消失后,再出现时,依然定位在第一个 */titleAdapter = new TitleAdapter(l, c, 0);gv_title.setAdapter(titleAdapter);gv_body.setAdapter(bodyAdapter[0]);divisionTran(0);return true;}return false;}});}/** * 分界线布局中的textView跟随选中标题移动位置的,设置为动画效果 */public void divisionTran(int position) {/** * 先移除了RelativeLayout中原有的textView */divisionLayout.removeAllViews();/** * 重新设置textView布局属性 * 动态改变控件位置 第一步 */RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(screenWidth / 3, LayoutParams.MATCH_PARENT);/** * 设置动画效果 */Animation translateTextView;translateTextView = new TranslateAnimation((preIndex-currentIndex) * screenWidth / 3,0, 0, 0);/** * 根据选中的标题确定布局 * 动态改变控件位置 第二步 */if (position == 0) {lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);} else if (position == 1) {lp.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);} else {lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);}/** * 动态改变控件位置 第三步 */TextView line = new TextView(context);line.setBackgroundColor(Color.WHITE);divisionLayout.addView(line, lp);/** * 设置动画执行时间 */translateTextView.setDuration(200);/** * 启动动画 */line.startAnimation(translateTextView);}}


 

 


主界面

 

package com.example.mypopupwindow;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.view.Gravity;import android.view.Menu;public class MainActivity extends Activity {private List<String> titles;private List<List<String>> item_names; // 选项名称private List<List<Integer>> item_images; // 选项图标private MyPopupMenu myPopupMenu;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);/** * 菜单栏分类标题 */titles = new ArrayList<String>();titles = addItems(new String[]{"常用", "设置", "工具"});/** * 选项图标 */item_images = new ArrayList<List<Integer>>();item_images.add(addItems(new Integer[] { R.drawable.ic_action_call,R.drawable.ic_action_camera, R.drawable.ic_action_copy,R.drawable.ic_action_crop, R.drawable.ic_action_cut,R.drawable.ic_action_discard, R.drawable.ic_action_download,R.drawable.ic_action_edit }));item_images.add(addItems(new Integer[] { R.drawable.ic_action_email,R.drawable.ic_action_full_screen, R.drawable.ic_action_help,R.drawable.ic_action_important, R.drawable.ic_action_map,R.drawable.ic_action_mic, R.drawable.ic_action_picture,R.drawable.ic_action_place }));item_images.add(addItems(new Integer[] { R.drawable.ic_action_refresh,R.drawable.ic_action_save, R.drawable.ic_action_search,R.drawable.ic_action_share, R.drawable.ic_action_switch_camera,R.drawable.ic_action_video, R.drawable.ic_action_web_site,R.drawable.ic_action_screen_rotation }));/** * 选项名称 */item_names = new ArrayList<List<String>>();item_names.add(addItems(new String[] { "电话", "相机", "复制", "裁剪", "剪切","删除", "下载", "编辑" }));item_names.add(addItems(new String[] { "邮件", "全屏", "帮助", "收藏", "地图","语音", "图片", "定位" }));item_names.add(addItems(new String[] { "刷新", "保存", "搜索", "分享", "切换","录像", "浏览器", "旋转屏幕" }));myPopupMenu = new MyPopupMenu(this, titles, item_names, item_images);/** * 设置菜单栏推拉动画效果 * res/anim中的xml文件与res/values中的popupAnimation.xml一起使用 */myPopupMenu.setAnimationStyle(R.style.PopupAnimation);}/** * 转换为List<String> * 用于菜单栏中的菜单项图标赋值 * @param values * @return */private List<String> addItems(String[] values) {List<String> list = new ArrayList<String>();for (String var : values) {list.add(var);}return list;}/** * 转换为List<Integer> * 用于菜单栏中的标题赋值 * @param values * @return */private List<Integer> addItems(Integer[] values) {List<Integer> list = new ArrayList<Integer>();for (Integer var : values) {list.add(var);}return list;}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {/** * 系统菜单必须要加一个,才有效果 */menu.add("menu");return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onMenuOpened(int featureId, Menu menu) {if (myPopupMenu.isShowing()) {myPopupMenu.dismiss();} else {/** * 这句代码可以使菜单栏如对话框一样弹出的效果 * myPopupMenu.setAnimationStyle(android.R.style.Animation_Dialog); *//** * 设置菜单栏显示位置 */myPopupMenu.showAtLocation(findViewById(R.id.layout),Gravity.BOTTOM, 0, 0);myPopupMenu.isShowing();}return false;}}


动画文件 放在res/anim文件夹中 anim文件夹 自己创建

popup_enter.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="300"        android:fromYDelta="100%p"        android:toYDelta="0" />    <alpha        android:duration="300"        android:fromAlpha="0.0"        android:toAlpha="1.0" /></set>


popup_exit.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="1000"        android:fromYDelta="0"        android:toYDelta="100%p" />    <alpha        android:duration="1000"        android:fromAlpha="1.0"        android:toAlpha="0.0" /></set>


 

res/values/popup_animation.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <style name="PopupAnimation" parent="android:Animation">        <item name="android:windowEnterAnimation">@anim/popup_enter</item>        <item name="android:windowExitAnimation">@anim/popup_exit</item>    </style></resources>


源代码下载地址

http://download.csdn.net/detail/u012251822/6501533
原创粉丝点击