有时有这样一个需求,页面底部有几个图标能够点击,假设一个screenWidth显示不下这些图标,则这一列图标最后一个是more,点击more,能够通过动画展示两列图标

这样来增加layout中:

  1. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent" >
  4.  
  5. <RelativeLayout
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. android:background="#FFFFFF" >
  9.  
  10. <include
  11. android:id="@+id/title"
  12. layout="@layout/title_list" />
  13.  
  14. <View
  15. android:id="@+id/line"
  16. android:layout_width="fill_parent"
  17. android:layout_height="2dip"
  18. android:layout_below="@id/title"
  19. android:background="@drawable/rc_list_divider" />
  20.  
  21. <ListView
  22. android:id="@+id/mylist"
  23. android:layout_width="match_parent"
  24. android:layout_height="match_parent"
  25. android:layout_below="@id/title"
  26. android:background="@null"
  27. android:cacheColorHint="@color/bgColorMain"
  28. android:divider="@null"
  29. android:dividerHeight="0dp"
  30. android:fadeScrollbars="false"
  31. android:visibility="gone" >
  32. </ListView>
  33.  
  34. <LinearLayout
  35. android:id="@+id/loading_layout"
  36. android:layout_width="fill_parent"
  37. android:layout_height="fill_parent"
  38. android:layout_below="@id/line"
  39. android:background="@color/white"
  40. android:gravity="center" >
  41.  
  42. <ProgressBar
  43. style="?android:attr/progressBarStyleLarge"
  44. android:layout_width="wrap_content"
  45. android:layout_height="wrap_content" />
  46. </LinearLayout>
  47. </RelativeLayout>
  48.  
  49. <RelativeLayout
  50. android:layout_width="wrap_content"
  51. android:layout_height="wrap_content"
  52. android:layout_gravity="bottom" >
  53.  
  54. <strong> <com.example.view.ExpandableView
  55. android:id="@+id/launcher_expand_view"
  56. android:layout_width="fill_parent"
  57. android:layout_height="wrap_content" /></strong>
  58. </RelativeLayout>
  59.  
  60. </FrameLayout>

代码里这样来写:

  1. private void prepareLauncherView() {
  2.  
  3. mRootView = LayoutInflater.from(this).inflate(R.layout.activity_main, null);
  4. setContentView(mRootView);
  5.  
  6. DisplayMetrics dm = new DisplayMetrics();
  7. getWindowManager().getDefaultDisplay().getMetrics(dm);
  8. int screenWidth = dm.widthPixels;
  9. int height = dm.heightPixels;
  10. //取出底部几个Button的图标资源
  11. mLauncherDrawables = getResources().obtainTypedArray(R.array.launcher_item_drawables);
  12.  
  13. mExpandableView = (ExpandableView) findViewById(R.id.launcher_expand_view);
  14. mItemViews = new ArrayList<View>();
  15. for (int i = 0; i < mLauncherDrawables.length(); i++) {
  16. addLauncherItem(i);
  17. }
  18. //点击more的时候响应(运行TransLate动画)
  19. mExpandableView.setOnExpandItemClickListener(this);
  20.  
  21. int contentHeight = height - getStatusBarHeight();
  22. mExpandableView.setScreenSize(contentHeight, screenWidth);
  23. mExpandableView.addListView(mItemViews);
  24.  
  25. }
  26.  
  27. @Override
  28. protected void onStart() {
  29. super.onStart();
  30. mExpandableView.setRestart(true);
  31. }
  32.  
  33. private int getStatusBarHeight() { <strong>//这个是取statusbar高度的做法</strong>
  34.  
  35. Class<?
  36.  
  37. > c = null;
  38. Object obj = null;
  39. Field field = null;
  40. int x = 0, sbar = 0;
  41. try {
  42.  
  43. c = Class.forName("com.android.internal.R$dimen");
  44. obj = c.newInstance();
  45. field = c.getField("status_bar_height");
  46. x = Integer.parseInt(field.get(obj).toString());
  47. sbar = getResources().getDimensionPixelSize(x);
  48. } catch (Exception e1) {
  49. e1.printStackTrace();
  50. }
  51. return sbar;
  52. }
  53.  
  54. private void addLauncherItem(int i) {
  55. View view = LayoutInflater.from(this).inflate(R.layout.launch_bar_item, null).findViewById(R.id.launcher_content);
  56. view.setBackgroundDrawable(mLauncherDrawables.getDrawable(i));
  57. mItemViews.add(view);
  58. }
  59.  
  60. @Override
  61. public void onExpandItemClick(View parentView, View view, int position, int maxNum, int line) {
  62. if (!mExpandableView.isInAnimation()) {
  63. if (position != maxNum) {
  64. mExpandableView.excuteAnimation(false);
  65. } else {
  66. mExpandableView.excuteAnimation(true);
  67. }
  68. }
  69. }

关于ExpandableView这个类:

  1. package com.example.view;
  2.  
  3. import java.util.List;
  4.  
  5. import com.example.shoplistdownload.R;
  6.  
  7. import android.content.Context;
  8. import android.content.res.Configuration;
  9. import android.util.AttributeSet;
  10. import android.view.LayoutInflater;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.view.animation.Animation;
  14. import android.view.animation.TranslateAnimation;
  15. import android.view.animation.Animation.AnimationListener;
  16. import android.widget.LinearLayout;
  17. import android.widget.LinearLayout.LayoutParams;
  18.  
  19. public class ExpandableView extends LinearLayout {
  20.  
  21. private int mScreenWidth;
  22. private int mScreenHeight;
  23. private int mButtonWidth;
  24. private int mButtonHeight;
  25. private LinearLayout mLayoutShow;
  26. private LinearLayout mLayoutHide;
  27. private ExpandItemClickListener onExpandItemClickListener;
  28. private int mMaxNum;
  29. private boolean mIsInAnimation = false;
  30. private boolean mCanMoveToBottom = false;
  31. private View mMoreView;
  32. private int mOldBottom;
  33. private Context mContext;
  34. private int mHeaderHeight;
  35. private double mAverageSize;
  36. private boolean mIsFirstLayout= true;
  37. private LinearLayout.LayoutParams mParams;
  38. private boolean mRestart = false;
  39. private LayoutInflater mInflater;
  40. public static final int LAUNCHER_BAR_LINE_ONE = 0;
  41. public static final int LAUNCHER_BAR_LINE_TWO = 1;
  42.  
  43. private static final boolean LAUNCHER_HIDE_LAYOUT_TAG = true;
  44.  
  45. public ExpandableView(Context context, AttributeSet attrs) {
  46. super(context, attrs);
  47. mContext = context;
  48. mInflater = LayoutInflater.from(mContext);
  49. }
  50.  
  51. public void setScreenSize(int height, int width) {
  52. mScreenHeight = height;
  53. mScreenWidth = width;
  54. initParameter();
  55. initSubView();
  56. }
  57.  
  58. private void initParameter(){
  59. mButtonWidth = mContext.getResources().getDimensionPixelSize(R.dimen.expand_item_minwidth);
  60. mButtonHeight = mContext.getResources().getDimensionPixelSize(R.dimen.expand_item_minheight);
  61. mHeaderHeight = mContext.getResources().getDimensionPixelSize(R.dimen.header_bar_height);
  62. mMaxNum = mScreenWidth / mButtonWidth;
  63. mAverageSize = ((double) mScreenWidth) / mMaxNum;
  64. this.setOrientation(LinearLayout.VERTICAL);
  65. }
  66.  
  67. public void addListView(List<View> views) {
  68. setPortraitView(views);
  69. //mLayoutShow为第一列
  70. addView(mLayoutShow);
  71. //mLayoutHide为第二列,第一次展示时会隐藏
  72. addView(mLayoutHide);
  73.  
  74. }
  75.  
  76. private void initSubView() {
  77. mMoreView = mInflater.inflate(R.layout.launch_bar_item, null).findViewById(R.id.launcher_content);
  78. mMoreView.setBackgroundResource(R.drawable.btn_launcher_more);
  79. mMoreView.setOnClickListener(new OnClickListener() {
  80. @Override
  81. public void onClick(View v) {
  82. mRestart = false;
  83. onExpandItemClickListener.onExpandItemClick(mLayoutShow, v, mMaxNum, mMaxNum, LAUNCHER_BAR_LINE_ONE);
  84. }
  85. });
  86.  
  87. mLayoutShow = new LinearLayout(mContext);
  88. mLayoutHide = new LinearLayout(mContext);
  89. mLayoutHide.setTag(LAUNCHER_HIDE_LAYOUT_TAG);
  90. mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, mButtonHeight);
  91. mLayoutShow.setOrientation(LinearLayout.HORIZONTAL);
  92. mLayoutHide.setOrientation(LinearLayout.HORIZONTAL);
  93. mLayoutShow.setBackgroundResource(R.drawable.bg_launcher_port_nor);
  94. mLayoutHide.setBackgroundResource(R.drawable.bg_launcher_port_nor);
  95. mLayoutShow.setLayoutParams(mParams);
  96. mLayoutHide.setLayoutParams(mParams);
  97. }
  98.  
  99. private void setPortraitView(List<View> views) {
  100. if (views.size() > mMaxNum) {
  101. //将底部Button增加mLayoutShow和mLayoutHide
  102. mLayoutShow = adjustPortraitView(mLayoutShow, 0, mMaxNum - 1, views, true);
  103. mLayoutHide = adjustPortraitView(mLayoutHide, mMaxNum - 1, views.size(), views, false);
  104. } else {
  105. //假设底部图标数比較少,那么mLayoutHide就永远隐藏
  106. mLayoutHide.setVisibility(View.GONE);
  107. mLayoutShow = adjustPortraitView(mLayoutShow, 0, views.size(), views, false);
  108. }
  109. }
  110.  
  111. private LinearLayout adjustPortraitView(LinearLayout layout, int start, int end, List<View> views, boolean isAddMore) {
  112. for (int i = start; i < end; i++) {
  113. final View view = views.get(i);
  114. view.setLayoutParams(new LayoutParams((int) mAverageSize, LayoutParams.FILL_PARENT));
  115. view.setTag(i);
  116. setClick(layout, view, LAUNCHER_BAR_LINE_ONE);
  117. layout.addView(view);
  118. }
  119. if (isAddMore) {
  120. mMoreView.setLayoutParams(new LayoutParams((int)mAverageSize, LayoutParams.FILL_PARENT));
  121. mLayoutShow.addView(mMoreView);
  122. }
  123. return layout;
  124. }
  125.  
  126. private void setClick(final LinearLayout layout, final View view, final int line) {
  127. view.setOnClickListener(new OnClickListener() {
  128. @Override
  129. public void onClick(View v) {
  130. mRestart = false;
  131. if (onExpandItemClickListener != null) {
  132. onExpandItemClickListener.onExpandItemClick(layout, view, (Integer) view.getTag(), mMaxNum, line);
  133. }
  134. }
  135. });
  136. }
  137.  
  138. public boolean isInAnimation() {
  139. return mIsInAnimation;
  140. }
  141.  
  142. public boolean isCanMoveToBottom(){
  143. //这里依据getBottom来推断页面仅仅是展示mLayoutShow或是同一时候展示mLayoutShow和mLayoutHide
  144. //假设getBottom() < mOldBottom,这个时候就是页面仅仅有mlayoutShow,由于mLayoutShow和mLayoutHide同一时候存在时显然getBottom比較大
  145. if (mLayoutHide != null && mLayoutHide.getVisibility() == View.VISIBLE) {
  146. int bottom = this.getBottom();
  147. if (bottom > mOldBottom) {
  148. mCanMoveToBottom = false;
  149. } else if(bottom <= mOldBottom) {
  150. mCanMoveToBottom = true;
  151. }
  152. }
  153. return mCanMoveToBottom;
  154. }
  155.  
  156. public void excuteAnimation(boolean isClickMore) {
  157. if (mLayoutHide != null && mLayoutHide.getVisibility() == View.VISIBLE) {
  158. if (!mIsInAnimation) {
  159. if (isCanMoveToBottom()) {
  160. mIsInAnimation = true;
  161. mMoreView.setSelected(false);
  162. //这个动画是向下的
  163. this.startAnimation(getAnimation(true, 0, 0, 0, mButtonHeight));
  164. mCanMoveToBottom = false;
  165. } else {
  166. if (isClickMore) {
  167. mIsInAnimation = true;
  168. mMoreView.setSelected(true);
  169. //这个动画是向上的
  170. this.startAnimation(getAnimation(false, 0, 0, 0, -mButtonHeight));
  171. mCanMoveToBottom = true;
  172. }
  173. }
  174. }
  175. }
  176. }
  177.  
  178. private Animation getAnimation(final boolean moToBottom, int fromXDelta, final int toXDelta,
  179. int fromYDelta, final int toYDelta) {
  180. TranslateAnimation animation = new TranslateAnimation(fromXDelta,
  181. toXDelta, fromYDelta, toYDelta);
  182. animation.setDuration(200);
  183. animation.setFillAfter(true);
  184. animation.setAnimationListener(new AnimationListener() {
  185.  
  186. @Override
  187. public void onAnimationStart(Animation animation) {
  188. }
  189.  
  190. @Override
  191. public void onAnimationRepeat(Animation animation) {
  192. }
  193.  
  194. @Override
  195. public void onAnimationEnd(Animation animation) {
  196. ExpandableView.this.clearAnimation();
  197. ExpandableView.this.layout(ExpandableView.this.getLeft(),
  198. (ExpandableView.this.getTop() + toYDelta),
  199. ExpandableView.this.getRight(),
  200. (ExpandableView.this.getBottom() + toYDelta));
  201. mIsInAnimation = false;
  202. }
  203. });
  204. return animation;
  205. }
  206.  
  207. public void setOnExpandItemClickListener(ExpandItemClickListener listener) {
  208. onExpandItemClickListener = listener;
  209. }
  210.  
  211. public interface ExpandItemClickListener {
  212. void onExpandItemClick(final View parentView, View view, int position, int maxNum, int line);
  213. }
  214.  
  215. @Override
  216. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  217. super.onLayout(changed, l, t, r, b);
  218. if (mLayoutHide != null && mLayoutHide.getVisibility() == View.VISIBLE) {
  219. if(mIsFirstLayout && this.getWidth() > 0){
  220. mIsFirstLayout = false;
  221. mOldBottom = this.getBottom();
  222. this.layout(this.getLeft(), (this.getTop() + mHeaderHeight), this.getRight(), (this.getBottom() + mHeaderHeight));
  223. }
  224. //假设是第一次显示该view,mLayoutHide是不显示的
  225. if (mRestart && this.getBottom() <= mOldBottom && !mIsFirstLayout) {
  226. this.layout(this.getLeft(), (this.getTop() + mHeaderHeight), this.getRight(), (this.getBottom() + mHeaderHeight));
  227. }
  228. }
  229. }
  230.  
  231. public void setRestart(boolean restart){
  232. mRestart = restart;
  233. }
  234.  
  235. }

代码:http://download.csdn.net/download/baidu_nod/7748987

一个带动画的页面底部的TabBar的实现的更多相关文章

  1. 收藏一个带动画效果的ScrollViewer以及ScrollBar的模板

    这里介绍一个带动画效果的ScrollViewer和ScrollBar,总共分为两个资源字典,直接拿来引用即可: 1 ScrollBarStyle.xaml <ResourceDictionary ...

  2. 利用css transition属性实现一个带动画显隐的微信小程序部件

    我们先来看效果图 像这样的一个带过渡效果的小部件在我们实际开发中的应用几率还是比较大的,但是在开发微信小程序的过程中可能有的小伙伴发现transition这个属性它不好使(下面说明)所以我们这个时候会 ...

  3. iOS使用push隐藏子页面底部bottom TabBar

    下面两种情况是我在开发过程中遇到的,一种是代码使用pushViewController,还有一种是storyboard直接使用push.之前也查阅了非常多关于隐藏底部tabbar的资料.可是要么使用起 ...

  4. IOS的一个带动画的多项选择的控件(一)

    先上效果图: 这个程序分2个层次,一个是顶部的带UITextField的bar,一个是下拉选择的view,下拉选择的view带有4个自己定义的UIView 我们先定义一个UIViewControlle ...

  5. 一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog

    android4.4的日历中选择日程显示颜色的时候有一个颜色选择对话框非常漂亮,模仿他的界面我实现了一个类似的对话框,而且带有动画效果. 代码的实现可讲的地方不多,主要是采用了和AlertDialog ...

  6. 兼容IE6的页面底部固定层CSS代码

    有时候当我们需要把一个元素固定在页面的某个部位,一般都是用css中的“position:fixed;”方法来解决,但是IE6不支持fixed,所以今天分享一个兼容IE6的页面底部固定层CSS代码.如下 ...

  7. Android开发:带动画的分享效果

    这几天做了个带动画的分享页面.如今把它分享出来,假设你认为实用,请直接使用,避免反复造轮子 先看下效果图 认为仅仅是看效果图不明显.那么用手机扫描以下的二维码下载安装包:

  8. jquery插件——点击交换元素位置(带动画效果)

    一.需求的诞生 在我们的网页或者web应用中,想要对列表中的元素进行位置调整(或者说排序)是一个常见的需求.实现方式大概就以下两种,一种是带有类似“上移”.“下移”的按钮,点击可与相邻元素交换位置,另 ...

  9. jQuery之锚点带动画跳转特效

    背景图片为金木研,这是我最爱的一张图. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo ...

随机推荐

  1. linux下C/C++,多线程pthread《转载》

    原文网址:http://www.cnblogs.com/xianghang123/archive/2011/08/11/2134927.html ·线程创建   函数原型:int pthread_cr ...

  2. Java中取某一个范围的随机数

    一.取模操作 public static void main(String[] args) { for (int i = 1; i <= 20; i++) { int j = i % 11; S ...

  3. 【ASP.NET Web API教程】3.4 HttpClient消息处理器

    原文:[ASP.NET Web API教程]3.4 HttpClient消息处理器 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. 3.4 ...

  4. Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme

    原文:Android菜鸟的成长笔记(6)--剖析源码学自定义主题Theme 还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上 ...

  5. 14.2.4 InnoDB Undo Logs

    14.2.4 InnoDB Undo Logs : 一个Undo log (或者成为回滚段) 是一个存储区域 持有被活动事务修改的数据的copy. 如果另外的事务需要看原始的数据(作为一致性读操作的一 ...

  6. c/c++使用VS2013连接MySQL与ubuntu下c链接mysql

    vs连接数据库事实上就是将mysql数据库.h头文件接口.lib链接文件和dll运行文件增加到项目中.以下是配置怎样增加. 转于http://www.cnblogs.com/justinzhang/a ...

  7. Swift - 故事板storyboard的用法

    故事板(UIStoryboard)可以很方便的进行界面的设计,下面总结了常用的几个操作方法: 1,初始场景 选中View Controller,在属性面板里勾选Is Initial View Cont ...

  8. roll pitch yaw 的分别

    原文地址:http://blog.sina.com.cn/s/blog_452706120100scwu.html yaw,pitch,roll这三个旋转的确切意思.如果有一个人站在(0,0,0)点, ...

  9. 得到一个临时的文件名称(使用GetTempFileName API函数)

    function GetExePath: string; begin Result := ExtractFilePath(ParamStr()); end; function GetTempFileN ...

  10. OpenRisc-50-or1200的freeze模块分析

    引言 之前,我们分析or1200的控制通路中的sprs模块和except模块,本小节,我们就分析一下or1200控制通路的最后一个模块,就是freeze模块. 1,整体分析 freeze模块,顾名思义 ...